diff options
Diffstat (limited to 'source')
20 files changed, 998 insertions, 35 deletions
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index 821dc211591..a70d2a99c41 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -198,7 +198,7 @@ typedef struct SculptSession { /* Layer brush persistence between strokes */ float (*layer_co)[3]; /* Copy of the mesh vertices' locations */ - + int brush_size; struct SculptStroke *stroke; struct StrokeCache *cache; } SculptSession; diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index aae323a5056..31d67c7962a 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -406,6 +406,11 @@ void BKE_brush_sculpt_reset(Brush *br) br->sub_col[0] = 0.250000; br->sub_col[1] = 1.000000; break; + case SCULPT_TOOL_CLIP: + br->add_col[1] = 1.000000; + br->sub_col[0] = 0.250000; + br->sub_col[1] = 1.000000; + break; case SCULPT_TOOL_ROTATE: br->alpha = 1.0; break; @@ -417,6 +422,7 @@ void BKE_brush_sculpt_reset(Brush *br) br->add_col[2] = 0.750000; break; case SCULPT_TOOL_GRAB: + case SCULPT_TOOL_TOPO_GRAB: case SCULPT_TOOL_SNAKE_HOOK: case SCULPT_TOOL_THUMB: br->size = 75; diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c index c7cfe55f659..b83bd524618 100644 --- a/source/blender/blenkernel/intern/paint.c +++ b/source/blender/blenkernel/intern/paint.c @@ -863,7 +863,7 @@ void BKE_sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob, ss->multires = mmd; ss->totvert = dm->getNumVerts(dm); ss->totpoly = dm->getNumPolys(dm); - ss->mvert = NULL; + ss->mvert = me->mvert; ss->mpoly = NULL; ss->mloop = NULL; } diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index 44b71416bf0..c4dbec940a2 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -815,6 +815,11 @@ void BKE_scene_init(Scene *sce) gp_brush->size = 50; gp_brush->strength = 0.5f; // XXX? gp_brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF; + + gp_brush = &gset->brush[GP_EDITBRUSH_TYPE_CLIP]; /*clipping*/ + gp_brush->size = 40; + gp_brush->strength = 0.5f; // XXX? + gp_brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF; gp_brush = &gset->brush[GP_EDITBRUSH_TYPE_RANDOMIZE]; gp_brush->size = 25; diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c index e7e0054e7a1..f813c8ca79b 100644 --- a/source/blender/blenloader/intern/versioning_defaults.c +++ b/source/blender/blenloader/intern/versioning_defaults.c @@ -144,6 +144,11 @@ void BLO_update_defaults_startup_blend(Main *bmain) brush->size = 50; brush->strength = 0.5f; // XXX? brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF; + + brush = &gset->brush[GP_EDITBRUSH_TYPE_CLIP]; /* clipping */ + brush->size = 40; + brush->strength = 0.5f; // XXX? + brush->flag = GP_EDITBRUSH_FLAG_USE_FALLOFF; brush = &gset->brush[GP_EDITBRUSH_TYPE_RANDOMIZE]; brush->size = 25; @@ -269,6 +274,12 @@ void BLO_update_defaults_startup_blend(Main *bmain) br->flag |= BRUSH_ORIGINAL_NORMAL; } + /* use original normal for topo grab brush (otherwise flickers with normal weighting). */ + br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Topo"); + if (br) { + br->flag |= BRUSH_ORIGINAL_NORMAL; + } + /* increase strength, better for smoothing method */ br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Blur"); if (br) { diff --git a/source/blender/bmesh/intern/bmesh_log.c b/source/blender/bmesh/intern/bmesh_log.c index 1d16dbc1836..5a44ce98b16 100644 --- a/source/blender/bmesh/intern/bmesh_log.c +++ b/source/blender/bmesh/intern/bmesh_log.c @@ -1031,6 +1031,14 @@ void BM_log_before_all_removed(BMesh *bm, BMLog *log) /* Get the logged coordinates of a vertex * * Does not modify the log or the vertex */ +uint BM_log_vert_id_t(BMLog *log, BMVert *v){ + return bm_log_vert_id_get(log, v); +} + +BMVert *BM_log_id_vert_t(BMLog *log, uint id){ + return bm_log_vert_from_id(log, id); +} + const float *BM_log_original_vert_co(BMLog *log, BMVert *v) { BMLogEntry *entry = log->current_entry; diff --git a/source/blender/bmesh/intern/bmesh_log.h b/source/blender/bmesh/intern/bmesh_log.h index dd1772af068..6305f43769e 100644 --- a/source/blender/bmesh/intern/bmesh_log.h +++ b/source/blender/bmesh/intern/bmesh_log.h @@ -90,6 +90,10 @@ void BM_log_before_all_removed(BMesh *bm, BMLog *log); /* Get the logged coordinates of a vertex */ const float *BM_log_original_vert_co(BMLog *log, BMVert *v); +uint BM_log_vert_id_t(BMLog *log, BMVert *v); + +BMVert *BM_log_id_vert_t(BMLog *log, uint id); + /* Get the logged normal of a vertex */ const short *BM_log_original_vert_no(BMLog *log, BMVert *v); diff --git a/source/blender/bmesh/operators/bmo_triangulate.c b/source/blender/bmesh/operators/bmo_triangulate.c index 4e8bace59e0..19986d6132d 100644 --- a/source/blender/bmesh/operators/bmo_triangulate.c +++ b/source/blender/bmesh/operators/bmo_triangulate.c @@ -270,4 +270,4 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op) } BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "geom.out", BM_EDGE | BM_FACE, ELE_NEW); -} +}
\ No newline at end of file diff --git a/source/blender/bmesh/tools/bmesh_triangulate.c b/source/blender/bmesh/tools/bmesh_triangulate.c index ce1bc46d5e8..9b5f587064b 100644 --- a/source/blender/bmesh/tools/bmesh_triangulate.c +++ b/source/blender/bmesh/tools/bmesh_triangulate.c @@ -159,3 +159,11 @@ void BM_mesh_triangulate( BLI_edgehash_free(pf_ehash, NULL); } } + +void BM_mesh_clip_project( + BMesh *bm, const int quad_method, const int ngon_method, const bool tag_only, + BMOperator *op, BMOpSlot *slot_facemap_out, BMOpSlot *slot_facemap_double_out) +{ + BMIter iter; + BMFace *face; +}
\ No newline at end of file diff --git a/source/blender/editors/datafiles/CMakeLists.txt b/source/blender/editors/datafiles/CMakeLists.txt index 2a84ca7f297..7196625725e 100644 --- a/source/blender/editors/datafiles/CMakeLists.txt +++ b/source/blender/editors/datafiles/CMakeLists.txt @@ -70,6 +70,7 @@ if(WITH_BLENDER) data_to_c_simple(../../../../release/datafiles/brushicons/blob.png SRC) data_to_c_simple(../../../../release/datafiles/brushicons/blur.png SRC) data_to_c_simple(../../../../release/datafiles/brushicons/clay.png SRC) + data_to_c_simple(../../../../release/datafiles/brushicons/clip.png SRC) data_to_c_simple(../../../../release/datafiles/brushicons/claystrips.png SRC) data_to_c_simple(../../../../release/datafiles/brushicons/clone.png SRC) data_to_c_simple(../../../../release/datafiles/brushicons/crease.png SRC) @@ -96,6 +97,7 @@ if(WITH_BLENDER) data_to_c_simple(../../../../release/datafiles/brushicons/texfill.png SRC) data_to_c_simple(../../../../release/datafiles/brushicons/texmask.png SRC) data_to_c_simple(../../../../release/datafiles/brushicons/thumb.png SRC) + data_to_c_simple(../../../../release/datafiles/brushicons/topograb.png SRC) data_to_c_simple(../../../../release/datafiles/brushicons/twist.png SRC) data_to_c_simple(../../../../release/datafiles/brushicons/vertexdraw.png SRC) diff --git a/source/blender/editors/include/ED_datafiles.h b/source/blender/editors/include/ED_datafiles.h index 661ab58b98c..1fb549dd412 100644 --- a/source/blender/editors/include/ED_datafiles.h +++ b/source/blender/editors/include/ED_datafiles.h @@ -105,6 +105,9 @@ extern char datatoc_flatten_png[]; extern int datatoc_grab_png_size; extern char datatoc_grab_png[]; +extern int datatoc_clip_png_size; +extern char datatoc_clip_png[]; + extern int datatoc_inflate_png_size; extern char datatoc_inflate_png[]; @@ -156,6 +159,9 @@ extern char datatoc_texfill_png[]; extern int datatoc_texmask_png_size; extern char datatoc_texmask_png[]; +extern int datatoc_topograb_png_size; +extern char datatoc_topograb_png[]; + extern int datatoc_thumb_png_size; extern char datatoc_thumb_png[]; diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h index 0c83038b7a3..d395cb3e16d 100644 --- a/source/blender/editors/include/UI_icons.h +++ b/source/blender/editors/include/UI_icons.h @@ -950,6 +950,7 @@ DEF_ICON(BRUSH_BLOB) DEF_ICON(BRUSH_BLUR) DEF_ICON(BRUSH_CLAY) DEF_ICON(BRUSH_CLAY_STRIPS) +DEF_ICON(BRUSH_CLIP) DEF_ICON(BRUSH_CLONE) DEF_ICON(BRUSH_CREASE) DEF_ICON(BRUSH_DARKEN) @@ -973,6 +974,7 @@ DEF_ICON(BRUSH_SOFTEN) DEF_ICON(BRUSH_SUBTRACT) DEF_ICON(BRUSH_TEXDRAW) DEF_ICON(BRUSH_TEXFILL) +DEF_ICON(BRUSH_TOPO_GRAB) DEF_ICON(BRUSH_TEXMASK) DEF_ICON(BRUSH_THUMB) DEF_ICON(BRUSH_ROTATE) diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index 65b12fcd64e..5f9a17891f3 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -374,6 +374,7 @@ static void init_brush_icons(void) INIT_BRUSH_ICON(ICON_BRUSH_FILL, fill); INIT_BRUSH_ICON(ICON_BRUSH_FLATTEN, flatten); INIT_BRUSH_ICON(ICON_BRUSH_GRAB, grab); + INIT_BRUSH_ICON(ICON_BRUSH_CLIP, clip); INIT_BRUSH_ICON(ICON_BRUSH_INFLATE, inflate); INIT_BRUSH_ICON(ICON_BRUSH_LAYER, layer); INIT_BRUSH_ICON(ICON_BRUSH_LIGHTEN, lighten); @@ -390,6 +391,7 @@ static void init_brush_icons(void) INIT_BRUSH_ICON(ICON_BRUSH_SUBTRACT, subtract); INIT_BRUSH_ICON(ICON_BRUSH_TEXDRAW, texdraw); INIT_BRUSH_ICON(ICON_BRUSH_TEXFILL, texfill); + INIT_BRUSH_ICON(ICON_BRUSH_TOPO_GRAB, topograb); INIT_BRUSH_ICON(ICON_BRUSH_TEXMASK, texmask); INIT_BRUSH_ICON(ICON_BRUSH_THUMB, thumb); INIT_BRUSH_ICON(ICON_BRUSH_ROTATE, twist); diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c index f88b64129e7..55b119787ef 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.c @@ -1592,11 +1592,13 @@ void ED_keymap_paint(wmKeyConfig *keyconf) keymap_brush_select(keymap, OB_MODE_SCULPT, SCULPT_TOOL_PINCH, PKEY, 0); keymap_brush_select(keymap, OB_MODE_SCULPT, SCULPT_TOOL_INFLATE, IKEY, 0); keymap_brush_select(keymap, OB_MODE_SCULPT, SCULPT_TOOL_GRAB, GKEY, 0); + keymap_brush_select(keymap, OB_MODE_SCULPT, SCULPT_TOOL_CLIP, YKEY, 0); keymap_brush_select(keymap, OB_MODE_SCULPT, SCULPT_TOOL_LAYER, LKEY, 0); keymap_brush_select(keymap, OB_MODE_SCULPT, SCULPT_TOOL_FLATTEN, TKEY, KM_SHIFT); keymap_brush_select(keymap, OB_MODE_SCULPT, SCULPT_TOOL_CLAY, CKEY, 0); keymap_brush_select(keymap, OB_MODE_SCULPT, SCULPT_TOOL_CREASE, CKEY, KM_SHIFT); keymap_brush_select(keymap, OB_MODE_SCULPT, SCULPT_TOOL_SNAKE_HOOK, KKEY, 0); + keymap_brush_select(keymap, OB_MODE_SCULPT, SCULPT_TOOL_TOPO_GRAB, OKEY, 0); kmi = keymap_brush_select(keymap, OB_MODE_SCULPT, SCULPT_TOOL_MASK, MKEY, 0); RNA_boolean_set(kmi->ptr, "toggle", 1); RNA_boolean_set(kmi->ptr, "create_missing", 1); diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c index 05270dbfa09..96b5f49bf37 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.c +++ b/source/blender/editors/sculpt_paint/paint_stroke.c @@ -196,7 +196,7 @@ static bool paint_tool_require_location(Brush *brush, PaintMode mode) { switch (mode) { case ePaintSculpt: - if (ELEM(brush->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_ROTATE, + if (ELEM(brush->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_TOPO_GRAB, SCULPT_TOOL_CLIP, SCULPT_TOOL_ROTATE, SCULPT_TOOL_SNAKE_HOOK, SCULPT_TOOL_THUMB)) { return false; @@ -763,6 +763,8 @@ static bool sculpt_is_grab_tool(Brush *br) { return ELEM(br->sculpt_tool, SCULPT_TOOL_GRAB, + SCULPT_TOOL_TOPO_GRAB, + SCULPT_TOOL_CLIP, SCULPT_TOOL_THUMB, SCULPT_TOOL_ROTATE, SCULPT_TOOL_SNAKE_HOOK); diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 44cc2720a32..bdf923cba5c 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -42,6 +42,7 @@ #include "BLI_threads.h" #include "BLI_utildefines.h" #include "BLI_ghash.h" +#include "BLI_array.h" #include "BLT_translation.h" @@ -99,6 +100,10 @@ #include <stdlib.h> #include <string.h> +#define MM 6000 +static void print_array_i(int *a, int len); +int find_connect_bmesh(const BMLog *bml, BMVert *vert, short *ch, const uint *vert_index, int len); + /** \name Tool Capabilities * * Avoid duplicate checks, internal logic only, @@ -126,10 +131,12 @@ static bool sculpt_has_active_modifiers(Scene *scene, Object *ob) 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); + SCULPT_TOOL_GRAB, + SCULPT_TOOL_TOPO_GRAB, + SCULPT_TOOL_ROTATE, + SCULPT_TOOL_THUMB, + SCULPT_TOOL_LAYER, + SCULPT_TOOL_CLIP); } static bool sculpt_tool_is_proxy_used(const char sculpt_tool) @@ -151,6 +158,7 @@ static int sculpt_brush_needs_normal(const Brush *brush, float normal_weight) SCULPT_TOOL_BLOB, SCULPT_TOOL_CREASE, SCULPT_TOOL_DRAW, + SCULPT_TOOL_TOPO_GRAB, SCULPT_TOOL_LAYER, SCULPT_TOOL_NUDGE, SCULPT_TOOL_ROTATE, @@ -199,6 +207,8 @@ typedef struct StrokeCache { float true_location[3]; float location[3]; + int brush_size; + bool pen_flip; bool invert; float pressure; @@ -206,6 +216,7 @@ typedef struct StrokeCache { float bstrength; float normal_weight; /* from brush (with optional override) */ + /* The rest is temporary storage that isn't saved as a property */ bool first_time; /* Beginning of stroke may do some things special */ @@ -231,6 +242,14 @@ typedef struct StrokeCache { int mirror_symmetry_pass; /* the symmetry pass we are currently on between 0 and 7*/ float true_view_normal[3]; float view_normal[3]; + float mesh_normal[3][3]; + float central_v[3]; + float mesh_v[3]; + + int m_id[2]; + uint bm_id[2]; + uint bver[MM]; + uint bver_f[MM]; /* sculpt_normal gets calculated by calc_sculpt_normal(), then the * sculpt_normal_symm gets updated quickly with the usual symmetry @@ -287,6 +306,8 @@ typedef struct { } SculptOrigVertData; + + /* Initialize a SculptOrigVertData for accessing original vertex data; * handles BMesh, mesh, and multires */ static void sculpt_orig_vert_data_unode_init(SculptOrigVertData *data, @@ -476,6 +497,8 @@ static bool sculpt_stroke_is_dynamic_topology( /*** paint mesh ***/ + + /* Single struct used by all BLI_task threaded callbacks, let's avoid adding 10's of those... */ typedef struct SculptThreadedTaskData { Sculpt *sd; @@ -502,7 +525,15 @@ typedef struct SculptThreadedTaskData { float *area_co; float (*mat)[4]; float (*vertCos)[3]; + uint *v_index; + int *t_index; + float *t_dis; + int *cn; + int *mid; + uint *bmid; + + float *dis; /* 0=towards view, 1=flipped */ float (*area_cos)[3]; float (*area_nos)[3]; @@ -655,19 +686,37 @@ typedef struct SculptBrushTest { float location[3]; float dist; int mirror_symmetry_pass; - + float normal[3]; /* View3d clipping - only set rv3d for clipping */ RegionView3D *clip_rv3d; + + ViewContext* vc; + int brush_size; + float true_location[3]; + float foot[3]; + float radius; + + float m_no[3][3]; + float center[3]; + float s_no[3]; + float no[3]; + } SculptBrushTest; static void sculpt_brush_test_init(SculptSession *ss, SculptBrushTest *test) { RegionView3D *rv3d = ss->cache->vc->rv3d; - + test->vc = ss->cache->vc; + test->brush_size = ss->cache->brush_size; + copy_v3_v3(test->true_location, ss->cache->true_location); + copy_v3_v3(test->normal, ss->cache->view_normal); test->radius_squared = ss->cache->radius_squared; + copy_v3_v3(test->s_no, ss->cache->sculpt_normal); + //copy_v3_v3(test->m_no[0], ss->cache->mesh_normal[0]); + //copy_v3_v3(test->m_no[1], ss->cache->mesh_normal[1]); copy_v3_v3(test->location, ss->cache->location); test->dist = 0.0f; /* just for initialize */ - + copy_v3_v3(test->no, ss->cache->view_normal); test->mirror_symmetry_pass = ss->cache->mirror_symmetry_pass; if (rv3d->rflag & RV3D_CLIPPING) { @@ -1026,7 +1075,7 @@ static void calc_area_center( /* 0=towards view, 1=flipped */ float area_cos[2][3] = {{0.0f}}; - + printf("yes!\n"); int count[2] = {0}; SculptThreadedTaskData data = { @@ -1089,6 +1138,117 @@ static void calc_area_normal( } } +static void calc_mesh_normal_task_cb(void *userdata, const int n) +{ + SculptThreadedTaskData *data = userdata; + SculptSession *ss = data->ob->sculpt; + float(*area_nos)[3] = data->area_nos; + float(*area_cos)[3] = data->area_cos; + + PBVHVertexIter vd; + SculptBrushTest test; + + float private_co[3][3] = { { 0.0f } }; + float private_no[3][3] = { { 0.0f } }; + int private_count[2] = { 0 }; + + sculpt_brush_test_init(ss, &test); + + BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) + { + + if (sculpt_brush_test_fast(&test, vd.co)) { + const float *co; + const short *no_s; /* bm_vert only */ + + float no_buf[3]; + const float *no; + int flip_index; + + + if (vd.no) { + normal_short_to_float_v3(no_buf, vd.no); + no = no_buf; + } + else { + no = vd.fno; + } + + add_v3_v3(private_co[2], vd.co); + add_v3_v3(private_no[2], no); + flip_index = (dot_v3v3(ss->cache->view_normal, no) <= 0.0f); + if (area_cos) + add_v3_v3(private_co[flip_index], co); + if (area_nos) + add_v3_v3(private_no[flip_index], no); + private_count[flip_index] += 1; + } + } + BKE_pbvh_vertex_iter_end; + + + BLI_mutex_lock(&data->mutex); + + /* for flatten center */ + if (area_cos) { + add_v3_v3(area_cos[0], private_co[0]); + add_v3_v3(area_cos[1], private_co[1]); + } + + /* for area normal */ + if (area_nos) { + add_v3_v3(area_nos[0], private_no[0]); + add_v3_v3(area_nos[1], private_no[1]); + } + add_v3_v3(area_nos[2], private_no[2]); + add_v3_v3(area_cos[2], private_co[2]); + + /* weights */ + data->count[0] += private_count[0]; + data->count[1] += private_count[1]; + + BLI_mutex_unlock(&data->mutex); +} + +static void calc_mesh_normal( +Sculpt *sd, Object *ob, +PBVHNode **nodes, int totnode, +float rarea_no[][3], float rarea_co[3]) +{ + const Brush *brush = BKE_paint_brush(&sd->paint); + SculptSession *ss = ob->sculpt; + const bool has_bm_orco = ss->bm && sculpt_stroke_is_dynamic_topology(ss, brush); + int n; + + /* 0=towards view, 1=flipped */ + float area_nos[3][3] = { { 0.0f } }; + float area_cos[3][3] = { { 0.0f } }; + + int count[2] = { 0 }; + + SculptThreadedTaskData data = { + .sd = sd, .ob = ob, .nodes = nodes, .totnode = totnode, + .has_bm_orco = has_bm_orco, .area_cos = area_cos, .area_nos = area_nos, .count = count, + }; + BLI_mutex_init(&data.mutex); + + BLI_task_parallel_range( + 0, totnode, &data, calc_mesh_normal_task_cb, + ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT)); + + BLI_mutex_end(&data.mutex); + + /* for area normal */ + for (n = 0; n < 3; n++) { + normalize_v3_v3(rarea_no[n], area_nos[n]); + //mul_v3_fl(area_nos[n], 1 / count[n]); + //copy_v3_v3(rarea_no[n], area_nos[n]); + + } + mul_v3_fl(area_cos[2],(1/(count[0]*1.0f + count[1]*1.0f))); + copy_v3_v3(rarea_co, area_cos[2]); +} + /* 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( @@ -1227,10 +1387,12 @@ static float brush_strength( case SCULPT_TOOL_GRAB: return root_alpha * feather; + + case SCULPT_TOOL_TOPO_GRAB: + return root_alpha * feather; case SCULPT_TOOL_ROTATE: return alpha * pressure * feather; - default: return 0; } @@ -1421,6 +1583,159 @@ static void update_sculpt_normal(Sculpt *sd, Object *ob, } } +static void update_mesh_area_normal(Sculpt *sd, Object *ob, + PBVHNode **nodes, int totnode) +{ + const Brush *brush = BKE_paint_brush(&sd->paint); + StrokeCache *cache = ob->sculpt->cache; + + if (cache->first_time) + calc_mesh_normal(sd, ob, nodes, totnode, cache->mesh_normal,cache->central_v); +} + + +static void calc_central_vertex_cb(void *userdata, const int n) +{ + SculptThreadedTaskData *data = userdata; + SculptSession *ss = data->ob->sculpt; + float(*cent_cos)[3] = data->area_cos; + float *dist = data->dis; + float ds[2] = { 1000.0f, 0.0f }; + PBVHVertexIter vd; + SculptBrushTest test; + float *cp = ss->cache->central_v; + float private_co[3] = { 0.0f }; + int private_count[2] = { 0 }; + + uint *v_i = data->v_index; + int *cn = data->cn; + int *mid = data->mid; + uint *bmid = data->bmid; + + int a = 0; + uint b = 0; + + PBVHType type = BKE_pbvh_type(ss->pbvh); + + sculpt_brush_test_init(ss, &test); + + BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) + { + + if (sculpt_brush_test_fast(&test, vd.co)) { + + if (type == PBVH_BMESH) + v_i[cn[0]++] = BM_log_vert_id_t(ss->bm_log, vd.bm_vert); + + float dx = len_squared_v3v3(cp,vd.co); + if (dx < ds[0]){ + ds[0] = dx; + copy_v3_v3(private_co, vd.co); + //if (type == PBVH_FACES) mvt = vd.mvert; + //else if (type == PBVH_BMESH) bmvt = vd.bm_vert; + if (vd.mverts) { //printf("m"); + a = vd.vert_indices[vd.i]; } + else + if (vd.bm_vert) { //printf("b"); + b = BM_log_vert_id_t(ss->bm_log, vd.bm_vert); } + } + + } + } + BKE_pbvh_vertex_iter_end; + + + BLI_mutex_lock(&data->mutex); + + //print_array_i(v_i, cn[0]); + //float dx = len_squared_v3v3(cp, vd.co); + if (dist[0] > ds[0]){ + dist[0] = ds[0]; + copy_v3_v3(cent_cos, private_co); + mid[0] = a; + //if (mid[0]) printf("e"); + bmid[0] = b; + //if (bmid[0]) printf("f"); + } + + BLI_mutex_unlock(&data->mutex); +} + +static void calc_central_vertex( + Sculpt *sd, Object *ob, + PBVHNode **nodes, int totnode, float rarea_co[3], float dis[2], + int mm[2],uint bmm[2], uint *b_ls) +{ + const Brush *brush = BKE_paint_brush(&sd->paint); + SculptSession *ss = ob->sculpt; + const bool has_bm_orco = ss->bm && sculpt_stroke_is_dynamic_topology(ss, brush); + int n; + + float cent_cos[3] = { 0.0f }; + int md[2] = { 0 }; + uint bmd[2] = { 0 }; + uint b_ls_temp[MM] = { 0 }; + int cn[1] = { 0 }; + int count[2] = { 0 }; + float dist[2] = { 1000.0f, 0.0f }; + SculptThreadedTaskData data = { + .sd = sd, .ob = ob, .nodes = nodes, .totnode = totnode, + .has_bm_orco = has_bm_orco, .area_cos = cent_cos, .count = count, .dis = dist, + .mid = md, .bmid = bmd, .v_index = b_ls_temp, .cn = cn, + }; + BLI_mutex_init(&data.mutex); + + BLI_task_parallel_range( + 0, totnode, &data, calc_central_vertex_cb, + ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT)); + + BLI_mutex_end(&data.mutex); + + for (int i = 0; i < cn[0];i++) b_ls[i] = b_ls_temp[i]; + mm[1] = cn[0]; + copy_v3_v3(rarea_co, cent_cos); + mm[0] = md[0]; + //if (mm[0]) { printf("g"); } + bmm[0] = bmd[0]; + //if (bmm[0]) { printf("h"); } +} +static void update_mesh_central_vertex(Sculpt *sd, Object *ob, + PBVHNode **nodes, int totnode) +{ + const Brush *brush = BKE_paint_brush(&sd->paint); + StrokeCache *cache = ob->sculpt->cache; + float dis[2] = { 1000.0f, 0.0f }; + printf(" r %d ", BKE_pbvh_type(ob->sculpt->pbvh)); + if (cache->first_time) + calc_central_vertex(sd, ob, nodes, totnode, cache->mesh_v, dis, cache->m_id,cache->bm_id, + cache->bver); + printf("\n-- This is: -- %d %d ", cache->bm_id[0], cache->m_id[1]); + print_array_i(cache->bver, cache->m_id[1]); + printf("-- \n"); + + if (BKE_pbvh_type(ob->sculpt->pbvh) == PBVH_BMESH){ + SculptSession *ss = ob->sculpt; + short ch1[MM] = { 0 }; + //print_array_i(ver_b, cn[1]); + BMVert *vm = BM_log_id_vert_t(ss->bm_log, cache->bm_id[0]); + find_connect_bmesh(ss->bm_log, vm, ch1, cache->bver, cache->m_id[1]); + //printf("\n"); + //loop(i, 0, cn[1], 1) ch1[i] = 1; + //printf(" \nBV: %f %f %d %f\n", vx->co[0], vx->co[1], cn[2], d[0]); + int k = 0; + for (int ir = 0; ir < cache->m_id[1]; ir++){ + if (ch1[ir]){ + cache->bver_f[k++] = cache->bver[ir]; + //c_ver[cn[4] + k] = ver_b[ir]; + //k++; + } + } + cache->m_id[1] = k; + //cn[1] = 0; + //cn[4] = cn[4] + k; + } +} + static void calc_local_y(ViewContext *vc, const float center[3], float y[3]) { Object *ob = vc->obact; @@ -1508,7 +1823,6 @@ static void neighbor_average(SculptSession *ss, float avg[3], unsigned vert) 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]; @@ -1711,7 +2025,7 @@ static void do_smooth_brush_bmesh_task_cb_ex( } else { float avg[3], val[3]; - + //if(ss->cache->first_time) printf("%d ", BM_elem_index_get( vd.bm_vert)); bmesh_neighbor_average(avg, vd.bm_vert); sub_v3_v3v3(val, avg, vd.co); @@ -1881,6 +2195,8 @@ static void smooth( int iteration, count; float last; + //if (ss->cache->first_time) printf("%d\n", type); + CLAMP(bstrength, 0.0f, 1.0f); count = (int)(bstrength * max_iterations); @@ -2212,8 +2528,10 @@ static void do_grab_brush_task_cb_ex( BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { sculpt_orig_vert_data_update(&orig_data, &vd); - + float valx[3]; if (sculpt_brush_test(&test, orig_data.co)) { + + //if (ss->cache->first_time && BKE_pbvh_type(ss->pbvh) == PBVH_BMESH ) printf("(%d %.3f %.3f) ", BM_elem_index_get(vd.bm_vert), vd.co[0], vd.co[1]); const float fade = bstrength * tex_strength( ss, brush, orig_data.co, test.dist, orig_data.no, NULL, vd.mask ? *vd.mask : 0.0f, thread_id); @@ -2225,6 +2543,7 @@ static void do_grab_brush_task_cb_ex( } } BKE_pbvh_vertex_iter_end; + if (ss->cache->first_time) printf("\n"); } static void do_grab_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) @@ -2555,8 +2874,11 @@ static void do_layer_brush_task_cb_ex( BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) { sculpt_orig_vert_data_update(&orig_data, &vd); - + float valx[3]; if (sculpt_brush_test(&test, orig_data.co)) { + + + //if (ss->cache->first_time && BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) printf("%d \n", BM_elem_index_get(vd.bm_vert)); const float fade = bstrength * tex_strength( ss, brush, vd.co, test.dist, vd.no, vd.fno, vd.mask ? *vd.mask : 0.0f, thread_id); float *disp = &layer_disp[vd.i]; @@ -2583,7 +2905,8 @@ static void do_layer_brush_task_cb_ex( sculpt_clip(sd, ss, vd.co, val); if (vd.mvert) - vd.mvert->flag |= ME_VERT_PBVH_UPDATE; + vd.mvert->flag |= ME_VERT_PBVH_UPDATE, + vd.mvert->flag |= SELECT; } } BKE_pbvh_vertex_iter_end; @@ -3053,6 +3376,517 @@ static void do_clay_strips_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int t ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT), false); } + + +static void calc_foot_perp_v3_v3v3v3(float* foot, const float* a, const float* l_dir, const float* p) +/*to calculate foot of perpendicular */ +{ + float v1[3]; + + sub_v3_v3v3(v1, a, p); + + float vp[3]; + mul_v3_v3fl(vp, l_dir, dot_v3v3(l_dir, v1)); + add_v3_v3v3(foot, p, vp); +} +float dist_squared_to_line_direction_v3v3(const float v1[3], const float v2[3], const float dir[3]) +{ + float v2v1[3]; + sub_v3_v3v3(v2v1, v1, v2); + float e[3]; + cross_v3_v3v3(e, v2v1, dir); + return len_squared_v3(e); +} +static bool sculpt_brush_test_clippc(SculptBrushTest *test, const float co[]) +{ + calc_foot_perp_v3_v3v3v3(test->foot, co, test->normal, test->location); + test->radius =paint_calc_object_space_radius(test->vc, + test->foot, + test->brush_size); + test->radius_squared = test->radius * test->radius; + + float distsq = dist_squared_to_line_direction_v3v3(co, test->location, test->normal); + + if (distsq <= test->radius_squared) { + if (sculpt_brush_test_clipping(test, co)) { + return 0; + } + test->dist = sqrtf(distsq); + return 1; + } + else { + return 0; + } +} +static void do_clip_brush_task_cb_ex( + void *userdata, void *UNUSED(userdata_chunk), const int n, const int thread_id) +{ + SculptThreadedTaskData *data = userdata; + SculptSession *ss = data->ob->sculpt; + Brush *brush = data->brush; + + PBVHVertexIter vd; + SculptBrushTest test; + + + SculptOrigVertData orig_data; + float(*proxy)[3]; + const float bstrength = ss->cache->bstrength; + + sculpt_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]); + + proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co; + + sculpt_brush_test_init(ss, &test); + float ray_normal[3], rays[3], raye[3]; + + ED_view3d_win_to_segment(test.vc->ar, test.vc->v3d, ss->cache->mouse, rays, raye, true); + sub_v3_v3v3(ray_normal, raye, rays); + normalize_v3(ray_normal); + + copy_v3_v3(test.normal, ray_normal); + BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) + { + sculpt_orig_vert_data_update(&orig_data, &vd); + + if (sculpt_brush_test_clippc(&test, vd.co)){ /*initially vd = orig_data*/ + /* + float vec[3] = { 0 }; + const float fade = bstrength * tex_strength( + ss, brush, vd.co, test.dist, vd.no, NULL, vd.mask ? *vd.mask : 0.0f, + thread_id); + + sub_v3_v3v3(vec, orig_data.co, ss->cache->location); + axis_angle_normalized_to_mat3(rot, ss->cache->sculpt_normal_symm, angle * fade); + mul_v3_m3v3(proxy[vd.i], rot, vec); + add_v3_v3(proxy[vd.i], ss->cache->location); + + float foot[3]; + calc_foot_perp_v3_v3v3v3(foot, vd.co, test.no, ss->cache->location); + sub_v3_v3v3(vec, vd.co, foot); + normalize_v3(vec); + + + float length = dot_v3v3(vec, vec); + float r = ss->cache->radius_squared; + float p1[3]; + + mul_v3_v3fl(p1, vec, sqrt(1 / length)); + add_v3_v3v3(p1, p1, foot); + sub_v3_v3v3(vec, vd.co, ss->cache->location); + copy_v3_v3(proxy[vd.i], p1); + + mul_v3_fl(vec, test.radius - test.dist); + copy_v3_v3(proxy[vd.i], vec); + + mul_v3_v3fl(proxy[vd.i], vd.co, 1.5); just testing the working + + BM_vert_kill(ss->bm, vd.bm_vert);*/ + float ver[3]; + + sub_v3_v3v3(ver, vd.co, test.foot); + + normalize_v3(ver); + + mul_v3_fl(ver, test.radius - test.dist); + copy_v3_v3(proxy[vd.i], ver); + + if (vd.mvert) + vd.mvert->flag |= ME_VERT_PBVH_UPDATE; + + } + } + BKE_pbvh_vertex_iter_end; +} + +static void do_clip_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) /*clipping*/ +{ + SculptSession *ss = ob->sculpt; + Brush *brush = BKE_paint_brush(&sd->paint); + + /*static const int flip[8] = { 1, -1, -1, 1, -1, 1, 1, -1 }; + const float angle = ss->cache->vertex_rotation * flip[ss->cache->mirror_symmetry_pass];*/ + + SculptThreadedTaskData data = { + .sd = sd, .ob = ob, .brush = brush, .nodes = nodes, + }; + + BLI_task_parallel_range_ex( + 0, totnode, &data, NULL, 0, do_clip_brush_task_cb_ex, + ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT), false); +} + +void mulv3_v3fl(float r[3], const short a[3], float f) +{ + r[0] = a[0] * f; + r[1] = a[1] * f; + r[2] = a[2] * f; +} + + +#define loop(i,a,b,n) for(int i=a;i<b;i+=n) + +static void print_array_i(int *a, int len){ + printf("\n[ "); + loop(i, 0, len, 1){ + printf("%d ", a[i]); + } + printf("] "); +} + +#define print_vd(ar) printf("[ %.3f %.3f %.3f ] ",ar[0],ar[1],ar[2]); +#define print_vd2(ar,i) printf("[ %.3f %.3f %.3f ] ",ar[i][0],ar[i][1],ar[i][2]); + +int check_present(int a,const int *array, int len){ + loop(i, 0, len, 1){ + if (array[i] == a) + return i; + } + return -1; +} + +int check_present_un(uint a,const uint *array, int len){ + loop(i, 0, len, 1){ + if (array[i] == a) + return i; + } + return -1; +} + +int check_topo_connected(int vert, int *vert_array, int totvert){ + return check_present(vert, vert_array, totvert); +} + +int check_btopo_connected(uint vert, uint *vert_array, int totvert){ + return check_present_un(vert, vert_array, totvert); +} + +#define VERLEN 50000 + +int ver[VERLEN] = { 0 }; +uint ver_b[VERLEN] = { 0 }; +int c_ver[VERLEN] = { 0 }; +int cn[6] = { 0 }; +float d[3] = { 0.0f }; +BMVert *vx; +/* +int *arrx = NULL; +BLI_array_declare(arrx); +loop(i,0,10,1){ + BLI_array_grow_one(arr); + arr[i] = i*2; + +} +BLI_array_free(arr); + +*/ +//int *arrx = NULL; + + +static void init_zero(int *a, int len){ loop(i, 0, len, 1) a[i] = 0; } + +int find_connect_mesh(SculptSession *ss, int vert, short *ch, int *vert_index, int len){ + int p = check_present(vert, vert_index, len); + if (p == -1 || ch[p] == 1){ + return 0; + } + ch[p] = 1; + const MeshElemMap *v_map = &ss->pmap[vert]; + const MVert *mvert = ss->mvert; + loop(i, 0, v_map->count, 1){ + + const MPoly *poly = &ss->mpoly[v_map->indices[i]]; + unsigned adj[2]; + + if (poly_get_adj_loops_from_vert(poly, ss->mloop, vert, adj) != -1) { + int j; + for (j = 0; j < ARRAY_SIZE(adj); j += 1) { + if (v_map->count != 2 || ss->pmap[adj[j]].count <= 2) { + find_connect_mesh(ss, adj[j], ch, vert_index, len); + } + } + } + + } + return 0; +} +//BM_log_vert_id_t(ss->bm_log, vd.bm_vert); +int find_connect_bmesh(const BMLog *bml, BMVert *vert, short *ch, const uint *vert_index, int len){ + int p = check_present_un(BM_log_vert_id_t(bml, vert), vert_index, len); + if (p == -1 || ch[p] == 1){ + return 0; + } + ch[p] = 1; + + /* + const MeshElemMap *v_map = &ss->pmap[vert]; + const MVert *mvert = ss->mvert; + loop(i, 0, v_map->count, 1){ + + const MPoly *poly = &ss->mpoly[v_map->indices[i]]; + unsigned adj[2]; + + if (poly_get_adj_loops_from_vert(poly, ss->mloop, vert, adj) != -1) { + int j; + for (j = 0; j < ARRAY_SIZE(adj); j += 1) { + if (v_map->count != 2 || ss->pmap[adj[j]].count <= 2) { + find_connect_mesh(ss, adj[j], ch, vert_index, len); + } + } + } + + }*/ + const int vfcount = BM_vert_face_count_ex(vert, 2); + BMIter iter; + BMLoop *l; + int i, total = 0; + + BM_ITER_ELEM(l,&iter, vert, BM_LOOPS_OF_VERT){ + const BMVert *adjv[2] = { l->prev->v, l->next->v }; + for (i = 0; i < ARRAY_SIZE(adjv); i++) { + const BMVert *v_other = adjv[i]; + if (vfcount != 2 || BM_vert_face_count_ex(v_other, 2) <= 2) { + find_connect_bmesh(bml, v_other, ch, vert_index, len); + } + } + } + + return 0; +} + +static void do_topo_grab_brush_task_cb_ex( + void *userdata, void *UNUSED(userdata_chunk), const int n, const int thread_id) +{ + SculptThreadedTaskData *data = userdata; + SculptSession *ss = data->ob->sculpt; + Brush *brush = data->brush; + const float *grab_delta = data->grab_delta; + + PBVHVertexIter vd; + SculptBrushTest test; + SculptOrigVertData orig_data; + float(*proxy)[3]; + + const float bstrength = ss->cache->bstrength; + + sculpt_orig_vert_data_init(&orig_data, data->ob, data->nodes[n]); + + proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co; + float center_v[3]; + sculpt_brush_test_init(ss, &test); + /* + float ray_normal[3], rays[3], raye[3]; + ED_view3d_win_to_segment(test.vc->ar, test.vc->v3d, ss->cache->mouse, rays, raye, true); + sub_v3_v3v3(ray_normal, raye, rays); + normalize_v3(ray_normal); + + copy_v3_v3(test.normal, ray_normal);*/ + //if (ss->cache->first_time){ printf("\n"); } + PBVHType type = BKE_pbvh_type(ss->pbvh); + //BLI_mutex_init(&data->mutex); + copy_v3_v3(test.normal, ss->cache->mesh_normal[2]); + copy_v3_v3(center_v,ss->cache->mesh_v); + uint bmn[2]; + uint *cver; + int *cenver; + bmn[0] = ss->cache->bm_id[0]; + BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE) + { + sculpt_orig_vert_data_update(&orig_data, &vd); + + if (sculpt_brush_test(&test, orig_data.co)){ + + + + float valx[3]; + if (ss->cache->first_time){ + if (type == PBVH_GRIDS){ + //printf("%d %.3f %.3f\n", vd.vert_indices[vd.i], vd.co[0], vd.co[1]); + + } + //printf("\n F \n"); + /* + if (ss->cache->first_time) { + if (ss->bm) copy_v3_v3(valx, BM_log_original_vert_co(ss->bm_log, vd.bm_vert)); + //printf("\n%.3f %.3f %.3f ", valx[0], valx[1], valx[2]); + }*/ + //if (ss->cache->first_time && BKE_pbvh_type(ss->pbvh) == PBVH_BMESH) printf("%d \n", BM_elem_index_get(vd.bm_vert)); + if (type == PBVH_FACES){ + //printf("%d ", vd.vert_indices[vd.i]); + ver[cn[1]] = vd.vert_indices[vd.i]; + //printf(" %.3f %.3f %.3f %d %d %d \n", test.s_no[0], test.s_no[1], test.s_no[2], + // vd.no[0], vd.no[1], vd.no[2]); + + float vvno[3] = {1.0f,1.0f,1.0f}; + //mulv3_v3fl(vvno,vd.no,1.0f); + + //float length = dot_v3v3(vvno, vvno); + + //mul_v3_v3fl(vvno, vvno, sqrt(1 / length)); + + //normalize_v3() + //normal_short_to_float_v3(vvno, vd.no); + + copy_v3_v3(vvno, test.location); + normalize_v3(vvno); + //print_vd(center_v); + //print_vd(vvno); + //printf("\n"); + //printf(" %.3f %.3f %.3f \n", vvno[0], vvno[1], vvno[2]); + float distsq = dist_squared_to_line_direction_v3v3(vd.co, center_v, test.normal); + if (distsq < d[0]){ + d[0] = distsq; + cn[2] = ver[cn[1]]; + } + cn[0] = 1; + cn[1]++; + }else + if (type == PBVH_BMESH){ + //printf("(%d %.3f %.3f) ", BM_elem_index_get(vd.bm_vert), vd.co[0], vd.co[1]); + + copy_v3_v3(valx, BM_log_original_vert_co(ss->bm_log, vd.bm_vert)); + ver_b[cn[1]] = BM_log_vert_id_t(ss->bm_log, vd.bm_vert); + + //BM_log_id_vert_t + + + //copy_v3_v3(cor[cn[1]], valx); + + ver[cn[1]] = BM_elem_index_get( vd.bm_vert); + float vk[3] = { 0.0f }; + //printf("%u %.3f %.3f %.3f \n", ver_b[cn[1]], vd.fno[0], vd.fno[1], vd.fno[2]); + //printf(" %d %d %d \n", vd.no[0], vd.no[1], vd.no[2]); + + float distsq = dist_squared_to_line_direction_v3v3(vd.co, center_v, test.normal); + if (distsq < d[0]){ + d[0] = distsq; + cn[2] = ver_b[cn[1]]; + vx = vd.bm_vert; + } + cn[0] = 1; + cn[1]++; + } + } + else{ + //if (type == PBVH_GRIDS) return 0; + + //printf("G"); + int check = -1; + //int vert_m; + if (type == PBVH_FACES) { + int vert_m = vd.vert_indices[vd.i]; + check = check_topo_connected(vert_m, c_ver, cn[4]); + } + else if (type == PBVH_BMESH) { + uint vert_m = BM_log_vert_id_t(ss->bm_log, vd.bm_vert); //BM_elem_index_get(vd.bm_vert); + check = check_btopo_connected(vert_m, c_ver, cn[4]); + } + + + if (check != -1) { + const float fade = bstrength * tex_strength( + ss, brush, orig_data.co, test.dist, orig_data.no, NULL, vd.mask ? *vd.mask : 0.0f, + thread_id); + + //printf("%d, ", cn[2]); + mul_v3_v3fl(proxy[vd.i], grab_delta, fade); + if (vd.mvert) { + vd.mvert->flag |= ME_VERT_PBVH_UPDATE; + vd.mvert->flag |= SELECT; + } + } + } + + } + } + BKE_pbvh_vertex_iter_end; + //BLI_mutex_end(&data->mutex); + //PBVHType type = BKE_pbvh_type(ss->pbvh); + BLI_mutex_lock(&data->mutex); + //BLI_mutex_init(&data->mutex); + if (ss->cache->first_time){ + if (type == PBVH_FACES){ + d[0] = 1000.0f; + //printf(" V = %d ",cn[2]); + short ch1[VERLEN] = { 0 }; + find_connect_mesh(ss, cn[2], ch1, ver, cn[1]); + //printf(" V: %d\n", cn[2]); + int k = 0; + loop(ir, 0, cn[1], 1){ + if (ch1[ir]){ + c_ver[cn[4] + k] = ver[ir]; + k++; + } + } + //printf("\n"); + cn[1] = 0; + cn[4] = cn[4] + k; + }else + + if (type == PBVH_BMESH){ + + //do nothing + + loop(ir, 0, cn[1], 1){ + //printf("%ud %d %.3f %.3f %.3f \n", ver_b[ir], ver[ir], cor[ir][0], cor[ir][1], cor[ir][2]); + } + //printf(" bV = %d %d\n", BM_log_vert_id_t(ss->bm_log, vx), + // ss->cache->bm_id[0]); + d[0] = 1000.0f; + short ch1[VERLEN] = {0}; + //print_array_i(ver_b, cn[1]); + BMVert *vm = BM_log_id_vert_t(ss->bm_log,bmn[0]); + find_connect_bmesh(ss->bm_log, vm, ch1, ver_b, cn[1]); + //printf("\n"); + //loop(i, 0, cn[1], 1) ch1[i] = 1; + //printf(" \nBV: %f %f %d %f\n", vx->co[0], vx->co[1], cn[2], d[0]); + int k = 0; + loop(ir, 0, cn[1], 1){ + if (ch1[ir]){ + c_ver[cn[4] + k] = ver_b[ir]; + k++; + } + } + cn[1] = 0; + cn[4] = cn[4] + k; + + + //cver = ss->cache->bver_f; + //cenver = ss->cache->m_id; + } + } + BLI_mutex_unlock(&data->mutex); + //BLI_mutex_end(&data->mutex); +} + +static void do_topo_grab_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) +{ + SculptSession *ss = ob->sculpt; + Brush *brush = BKE_paint_brush(&sd->paint); + float grab_delta[3]; + + copy_v3_v3(grab_delta, ss->cache->grab_delta_symmetry); + + if (ss->cache->normal_weight > 0.0f) { + sculpt_project_v3_normal_align(ss, ss->cache->normal_weight, grab_delta); + } + //if (!ss->pmap) {printf("NO!"); return;} + + PBVHType type = BKE_pbvh_type(ss->pbvh); + if (type == PBVH_GRIDS) { //printf("GRIDS"); + return 0; } //removing dyntopo for now + + SculptThreadedTaskData data = { + .sd = sd, .ob = ob, .brush = brush, .nodes = nodes, + .grab_delta = grab_delta, + }; + BLI_mutex_init(&data.mutex); + BLI_task_parallel_range_ex( + 0, totnode, &data, NULL, 0, do_topo_grab_brush_task_cb_ex, + ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT), false); + BLI_mutex_end(&data.mutex); +} + static void do_fill_brush_task_cb_ex( void *userdata, void *UNUSED(userdata_chunk), const int n, const int thread_id) { @@ -3381,6 +4215,7 @@ static void do_brush_action_task_cb(void *userdata, const int n) BKE_pbvh_node_mark_update(data->nodes[n]); } +//int *arrx = NULL; static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSettings *ups) { SculptSession *ss = ob->sculpt; @@ -3413,6 +4248,47 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_AREA) update_brush_local_mat(sd, ob); + if (ELEM(brush->sculpt_tool, SCULPT_TOOL_TOPO_GRAB)&&ss->cache->first_time){ + update_mesh_area_normal(sd, ob, nodes, totnode); + update_mesh_central_vertex(sd, ob, nodes, totnode); + + printf("\n\n-- This is 2: -- %d %d ", ss->cache->bm_id[0], ss->cache->m_id[1]); + print_array_i(ss->cache->bver_f, ss->cache->m_id[1]); + printf("-- \n\n"); + + //printf("It is: "); + //print_vd2(ss->cache->mesh_normal,0); + //print_vd2(ss->cache->mesh_normal, 1); + //print_vd2(ss->cache->mesh_normal, 2); + //print_vd(ss->cache->central_v); + //printf(" * \n"); + //print_vd(ss->cache->central_v); + //print_vd(ss->cache->mesh_v); + + //if (ss->cache->m_id[0]) + //printf(" %d Y N ", ss->cache->m_id[0]); + //printf(" %d Y N \n", ss->cache->bm_id[0]); + //if (ss->cache->bm_id[0]) printf("N Y \n"); + + + /* + int *arrx = NULL; + + BLI_array_declare(arrx); + int i; + loop(i,0,10,1){ + BLI_array_grow_one(arrx); + arrx[i] = i * 2; + + } + print_array_i(arrx, 10); + //MEM_freeN(arrx); + BLI_array_free(arrx); + printf(" * \n"); + */ + } + + /* Apply one type of brush action */ switch (brush->sculpt_tool) { case SCULPT_TOOL_DRAW: @@ -3439,6 +4315,9 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe case SCULPT_TOOL_ROTATE: do_rotate_brush(sd, ob, nodes, totnode); break; + case SCULPT_TOOL_CLIP: /*CLIP*/ + do_clip_brush(sd, ob, nodes, totnode); + break; case SCULPT_TOOL_SNAKE_HOOK: do_snake_hook_brush(sd, ob, nodes, totnode); break; @@ -3451,6 +4330,9 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSe case SCULPT_TOOL_LAYER: do_layer_brush(sd, ob, nodes, totnode); break; + case SCULPT_TOOL_TOPO_GRAB: + do_topo_grab_brush(sd, ob, nodes, totnode); + break; case SCULPT_TOOL_FLATTEN: do_flatten_brush(sd, ob, nodes, totnode); break; @@ -3525,7 +4407,8 @@ static void sculpt_combine_proxies_task_cb(void *userdata, const int n) Object *ob = data->ob; /* these brushes start from original coordinates */ - const bool use_orco = ELEM(data->brush->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_ROTATE, SCULPT_TOOL_THUMB); + const bool use_orco = ELEM(data->brush->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_TOPO_GRAB, + SCULPT_TOOL_ROTATE, SCULPT_TOOL_THUMB, SCULPT_TOOL_CLIP); PBVHVertexIter vd; PBVHProxyNode *proxies; @@ -3915,6 +4798,8 @@ static const char *sculpt_tool_name(Sculpt *sd) return "Inflate Brush"; case SCULPT_TOOL_GRAB: return "Grab Brush"; + case SCULPT_TOOL_CLIP: /*clip*/ + return "Clip Brush"; case SCULPT_TOOL_NUDGE: return "Nudge Brush"; case SCULPT_TOOL_THUMB: @@ -3937,6 +4822,8 @@ static const char *sculpt_tool_name(Sculpt *sd) return "Rotate Brush"; case SCULPT_TOOL_MASK: return "Mask Brush"; + case SCULPT_TOOL_TOPO_GRAB: + return "Mask Brush"; case SCULPT_TOOL_SIMPLIFY: return "Simplify Brush"; } @@ -4032,7 +4919,7 @@ static void sculpt_update_cache_invariants( copy_v2_v2(cache->initial_mouse, mouse); else zero_v2(cache->initial_mouse); - + mode = RNA_enum_get(op->ptr, "mode"); cache->invert = mode == BRUSH_STROKE_INVERT; cache->alt_smooth = mode == BRUSH_STROKE_SMOOTH; @@ -4152,10 +5039,11 @@ static void sculpt_update_cache_invariants( } } - cache->first_time = 1; + cache->first_time = 1; + #define PIXEL_INPUT_THRESHHOLD 5 - if (brush->sculpt_tool == SCULPT_TOOL_ROTATE) + if (brush->sculpt_tool == SCULPT_TOOL_ROTATE || brush->sculpt_tool == SCULPT_TOOL_CLIP) cache->dial = BLI_dial_initialize(cache->initial_mouse, PIXEL_INPUT_THRESHHOLD); #undef PIXEL_INPUT_THRESHHOLD @@ -4172,7 +5060,7 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru int tool = brush->sculpt_tool; if (ELEM(tool, - SCULPT_TOOL_GRAB, SCULPT_TOOL_NUDGE, + SCULPT_TOOL_GRAB, SCULPT_TOOL_NUDGE, SCULPT_TOOL_TOPO_GRAB, SCULPT_TOOL_CLAY_STRIPS, SCULPT_TOOL_SNAKE_HOOK, SCULPT_TOOL_THUMB)) { @@ -4193,7 +5081,9 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru if (!cache->first_time) { switch (tool) { case SCULPT_TOOL_GRAB: + case SCULPT_TOOL_TOPO_GRAB: case SCULPT_TOOL_THUMB: + case SCULPT_TOOL_CLIP: sub_v3_v3v3(delta, grab_location, cache->old_grab_location); invert_m4_m4(imat, ob->obmat); mul_mat3_m4_v3(imat, delta); @@ -4223,12 +5113,12 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru copy_v3_v3(cache->old_grab_location, grab_location); - if (tool == SCULPT_TOOL_GRAB) + if (tool == SCULPT_TOOL_GRAB || tool == SCULPT_TOOL_TOPO_GRAB) copy_v3_v3(cache->anchored_location, cache->true_location); else if (tool == SCULPT_TOOL_THUMB) copy_v3_v3(cache->anchored_location, cache->orig_grab_location); - if (ELEM(tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_THUMB)) { + if (ELEM(tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_TOPO_GRAB, SCULPT_TOOL_THUMB)) { /* location stays the same for finding vertices in brush radius */ copy_v3_v3(cache->true_location, cache->orig_grab_location); @@ -4236,7 +5126,7 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru copy_v2_v2(ups->anchored_initial_mouse, cache->initial_mouse); ups->anchored_size = ups->pixel_radius; } - + if (cache->first_time && tool == SCULPT_TOOL_TOPO_GRAB) init_zero(cn,5) , d[0] = 1000.0f, vx = NULL; /* handle 'rake' */ cache->is_rake_rotation_valid = false; @@ -4288,6 +5178,8 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru } /* Initialize the stroke cache variants from operator properties */ + + static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, PointerRNA *ptr) { @@ -4323,9 +5215,10 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, /* Truly temporary data that isn't stored in properties */ if (cache->first_time) { if (!BKE_brush_use_locked_size(scene, brush)) { + cache->brush_size = BKE_brush_size_get(scene, brush); cache->initial_radius = paint_calc_object_space_radius(cache->vc, cache->true_location, - BKE_brush_size_get(scene, brush)); + cache->brush_size); BKE_brush_unprojected_radius_set(scene, brush, cache->initial_radius); } else { @@ -4358,6 +5251,8 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, sculpt_update_brush_delta(ups, ob, brush); + + if (brush->sculpt_tool == SCULPT_TOOL_ROTATE) { cache->vertex_rotation = -BLI_dial_angle(cache->dial, cache->mouse) * cache->bstrength; @@ -4367,7 +5262,11 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, ups->anchored_size = ups->pixel_radius; } + + cache->special_rotation = ups->brush_rotation; + + } /* Returns true if any of the smoothing modes are active (currently @@ -4382,7 +5281,7 @@ static bool sculpt_any_smooth_mode(const Brush *brush, (brush->sculpt_tool == SCULPT_TOOL_SMOOTH) || (brush->autosmooth_factor > 0) || ((brush->sculpt_tool == SCULPT_TOOL_MASK) && - (brush->mask_tool == BRUSH_MASK_SMOOTH))); + (brush->mask_tool == BRUSH_MASK_SMOOTH)) || (brush->sculpt_tool == SCULPT_TOOL_TOPO_GRAB)); } static void sculpt_stroke_modifiers_check(const bContext *C, Object *ob) diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h index f4a1677efc4..4e9534d2d15 100644 --- a/source/blender/makesdna/DNA_brush_types.h +++ b/source/blender/makesdna/DNA_brush_types.h @@ -252,7 +252,9 @@ typedef enum BrushSculptTool { SCULPT_TOOL_CREASE = 16, SCULPT_TOOL_BLOB = 17, SCULPT_TOOL_CLAY_STRIPS = 18, - SCULPT_TOOL_MASK = 19 + SCULPT_TOOL_MASK = 19, + SCULPT_TOOL_CLIP = 20, + SCULPT_TOOL_TOPO_GRAB = 21 } BrushSculptTool; /** When #BRUSH_ACCUMULATE is used */ @@ -270,6 +272,7 @@ typedef enum BrushSculptTool { #define SCULPT_TOOL_HAS_NORMAL_WEIGHT(t) ELEM(t, \ SCULPT_TOOL_GRAB, \ + SCULPT_TOOL_TOPO_GRAB, \ SCULPT_TOOL_SNAKE_HOOK \ ) @@ -280,6 +283,7 @@ typedef enum BrushSculptTool { #define SCULPT_TOOL_HAS_DYNTOPO(t) (ELEM(t, \ /* These brushes, as currently coded, cannot support dynamic topology */ \ SCULPT_TOOL_GRAB, \ + SCULPT_TOOL_TOPO_GRAB, \ SCULPT_TOOL_ROTATE, \ SCULPT_TOOL_THUMB, \ SCULPT_TOOL_LAYER, \ diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h index c2711c465e1..ffd895aa7d6 100644 --- a/source/blender/makesdna/DNA_scene_types.h +++ b/source/blender/makesdna/DNA_scene_types.h @@ -1191,7 +1191,7 @@ typedef enum eGP_EditBrush_Types { GP_EDITBRUSH_TYPE_SIMPLIFY = 8, GP_EDITBRUSH_TYPE_CLONE = 9, GP_EDITBRUSH_TYPE_STRENGTH = 10, - + GP_EDITBRUSH_TYPE_CLIP = 11, /* !!! Update GP_EditBrush_Data brush[###]; below !!! */ TOT_GP_EDITBRUSH_TYPES } eGP_EditBrush_Types; @@ -1229,7 +1229,7 @@ typedef enum eGP_EditBrush_Flag { /* GPencil Stroke Sculpting Settings */ typedef struct GP_BrushEdit_Settings { - GP_EditBrush_Data brush[11]; /* TOT_GP_EDITBRUSH_TYPES */ + GP_EditBrush_Data brush[12]; /* TOT_GP_EDITBRUSH_TYPES */ void *paintcursor; /* runtime */ int brushtype; /* eGP_EditBrush_Types */ diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index ac348c1750c..671b78e36df 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -71,6 +71,7 @@ EnumPropertyItem rna_enum_brush_sculpt_tool_items[] = { {SCULPT_TOOL_FILL, "FILL", ICON_BRUSH_FILL, "Fill", ""}, {SCULPT_TOOL_FLATTEN, "FLATTEN", ICON_BRUSH_FLATTEN, "Flatten", ""}, {SCULPT_TOOL_GRAB, "GRAB", ICON_BRUSH_GRAB, "Grab", ""}, + {SCULPT_TOOL_CLIP, "CLIP", ICON_BRUSH_CLIP, "Clip", ""}, {SCULPT_TOOL_INFLATE, "INFLATE", ICON_BRUSH_INFLATE, "Inflate", ""}, {SCULPT_TOOL_LAYER, "LAYER", ICON_BRUSH_LAYER, "Layer", ""}, {SCULPT_TOOL_MASK, "MASK", ICON_BRUSH_MASK, "Mask", ""}, @@ -80,6 +81,7 @@ EnumPropertyItem rna_enum_brush_sculpt_tool_items[] = { {SCULPT_TOOL_SCRAPE, "SCRAPE", ICON_BRUSH_SCRAPE, "Scrape", ""}, {SCULPT_TOOL_SIMPLIFY, "SIMPLIFY", ICON_BRUSH_SUBTRACT /* icon TODO */, "Simplify", ""}, {SCULPT_TOOL_SMOOTH, "SMOOTH", ICON_BRUSH_SMOOTH, "Smooth", ""}, + {SCULPT_TOOL_TOPO_GRAB, "TOPO_GRAB", ICON_BRUSH_TOPO_GRAB, "Topo", "" }, {SCULPT_TOOL_SNAKE_HOOK, "SNAKE_HOOK", ICON_BRUSH_SNAKE_HOOK, "Snake Hook", ""}, {SCULPT_TOOL_THUMB, "THUMB", ICON_BRUSH_THUMB, "Thumb", ""}, {0, NULL, 0, NULL, NULL} @@ -144,7 +146,7 @@ static int rna_SculptToolCapabilities_has_jitter_get(PointerRNA *ptr) return (!(br->flag & BRUSH_ANCHORED) && !(br->flag & BRUSH_DRAG_DOT) && !ELEM(br->sculpt_tool, - SCULPT_TOOL_GRAB, SCULPT_TOOL_ROTATE, + SCULPT_TOOL_GRAB, SCULPT_TOOL_TOPO_GRAB, SCULPT_TOOL_ROTATE, SCULPT_TOOL_SNAKE_HOOK, SCULPT_TOOL_THUMB)); } @@ -192,7 +194,7 @@ static int rna_SculptToolCapabilities_has_random_texture_angle_get(PointerRNA *p { Brush *br = (Brush *)ptr->data; return (!ELEM(br->sculpt_tool, - SCULPT_TOOL_GRAB, SCULPT_TOOL_ROTATE, + SCULPT_TOOL_GRAB, SCULPT_TOOL_TOPO_GRAB, SCULPT_TOOL_ROTATE, SCULPT_TOOL_SNAKE_HOOK, SCULPT_TOOL_THUMB)); } @@ -255,7 +257,7 @@ static int rna_SculptToolCapabilities_has_space_attenuation_get(PointerRNA *ptr) { Brush *br = (Brush *)ptr->data; return ((br->flag & (BRUSH_SPACE | BRUSH_LINE | BRUSH_CURVE)) && - !ELEM(br->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_ROTATE, + !ELEM(br->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_TOPO_GRAB, SCULPT_TOOL_ROTATE, SCULPT_TOOL_SMOOTH, SCULPT_TOOL_SNAKE_HOOK)); } @@ -275,7 +277,7 @@ static int rna_BrushCapabilities_has_spacing_get(PointerRNA *ptr) static int rna_SculptToolCapabilities_has_strength_pressure_get(PointerRNA *ptr) { Brush *br = (Brush *)ptr->data; - return !ELEM(br->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_SNAKE_HOOK); + return !ELEM(br->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_TOPO_GRAB, SCULPT_TOOL_SNAKE_HOOK); } static int rna_TextureCapabilities_has_texture_angle_get(PointerRNA *ptr) diff --git a/source/tools b/source/tools -Subproject b11375e89061303401376f7aeae42ac2fd64692 +Subproject 4ace84b09b04f62192c0cdf4f3b87a68f45aabe |