Commit: e36ae3c1e44a34f91f166839ead58bb5420b50e0 Author: Pablo Dobarro Date: Fri May 31 23:10:45 2019 +0200 Branches: sculpt-mode-features https://developer.blender.org/rBe36ae3c1e44a34f91f166839ead58bb5420b50e0
Merge branch 'master' into sculpt-mode-features =================================================================== =================================================================== diff --cc source/blender/editors/sculpt_paint/sculpt.c index 975889c7498,4e5c2a74023..131424ff592 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@@ -7054,33 -6021,7 +7054,33 @@@ static void sculpt_init_session(Depsgra ob->sculpt = MEM_callocN(sizeof(SculptSession), "sculpt session"); ob->sculpt->mode_type = OB_MODE_SCULPT; + + /* Create the customdalayer for vcol for testing */ + Mesh *me = ob->data; + if (!CustomData_has_layer(&me->vdata, CD_MVERTCOL)) { + ob->sculpt->vcol = CustomData_add_layer_named( + &me->vdata, CD_MVERTCOL, CD_CALLOC, NULL, me->totvert, "vcols"); + for (int i = 0; i < me->totvert; i++) { + ob->sculpt->vcol[i].r = 255; + ob->sculpt->vcol[i].g = 255; + ob->sculpt->vcol[i].b = 255; + ob->sculpt->vcol[i].a = 255; + } + } + else { + ob->sculpt->vcol = CustomData_get_layer(&me->vdata, CD_MVERTCOL); + } + + /* init sculpt pivot */ + zero_v3(ob->sculpt->pivot_pos); + zero_v4(ob->sculpt->pivot_rot); + ob->sculpt->pivot_rot[3] = 1.0f; + + zero_v3(ob->sculpt->init_pivot_pos); + zero_v4(ob->sculpt->init_pivot_rot); + ob->sculpt->init_pivot_rot[3] = 1.0f; + - BKE_sculpt_update_mesh_elements(depsgraph, scene, scene->toolsettings->sculpt, ob, false, false); + BKE_sculpt_update_object_for_edit(depsgraph, ob, false, false); } static int ed_object_sculptmode_flush_recalc_flag(Scene *scene, @@@ -7599,1436 -6513,6 +7599,1436 @@@ static void SCULPT_OT_set_detail_size(w ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +#define MESH_FILTER_RANDOM_MOD 50 + +static void filter_cache_init_task_cb(void *__restrict userdata, + const int i, + const ParallelRangeTLS *__restrict UNUSED(tls)) +{ + SculptThreadedTaskData *data = userdata; + SculptSession *ss = data->ob->sculpt; + PBVHNode *node = data->nodes[i]; + + PBVHVertexIter vd; + BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_UNIQUE) + { + int vi = vd.vert_indices[vd.i]; + if (vd.mask && (*vd.mask) < 1.0f) { + data->node_mask[i] = 1; + } + copy_v3_v3(ss->filter_cache->orco[vi], ss->mvert[vi].co); + if (data->filter_type && vi < MESH_FILTER_RANDOM_MOD) { + data->random_disp[vi % MESH_FILTER_RANDOM_MOD] = (float)rand() / (float)(RAND_MAX); + } + } + BKE_pbvh_vertex_iter_end; + + if (data->node_mask[i] == 1) { + if (data->init_colors) { + sculpt_undo_push_node(data->ob, node, SCULPT_UNDO_COLOR); + } + else { + sculpt_undo_push_node(data->ob, node, SCULPT_UNDO_COORDS); + } + } +} + +static void sculpt_filter_cache_init(Object *ob, Sculpt *sd, bool init_random, bool init_colors) +{ + SculptSession *ss = ob->sculpt; + PBVH *pbvh = ob->sculpt->pbvh; + PBVHNode **nodes; + int totnode; + + ss->filter_cache = MEM_callocN(sizeof(FilterCache), "filter cache"); + ss->filter_cache->orco = MEM_mallocN(3 * ss->totvert * sizeof(float), "orco"); + if (init_random) { + ss->filter_cache->random_disp = MEM_mallocN(MESH_FILTER_RANDOM_MOD * sizeof(float), + "random_disp"); + } + + if (init_colors && ss->vcol) { + ss->filter_cache->orvcol = MEM_dupallocN(ss->vcol); + } + + SculptSearchSphereData searchdata = { + .ss = ss, + .sd = sd, + .radius_squared = FLT_MAX, + }; + BKE_pbvh_search_gather(pbvh, sculpt_search_sphere_cb, &searchdata, &nodes, &totnode); + + int *node_mask = MEM_callocN(totnode * sizeof(int), "node mask"); + for (int i = 0; i < totnode; i++) { + node_mask[i] = 0; + } + + int filter_type; + if (init_random) { + filter_type = 1; + } + else { + filter_type = 0; + } + + SculptThreadedTaskData data = { + .sd = sd, + .ob = ob, + .nodes = nodes, + .filter_type = filter_type, + .init_colors = init_colors, + .random_disp = ss->filter_cache->random_disp, + .node_mask = node_mask, + }; + + ParallelRangeSettings settings; + BLI_parallel_range_settings_defaults(&settings); + settings.use_threading = ((sd->flags & SCULPT_USE_OPENMP) && totnode > SCULPT_THREADED_LIMIT); + BLI_task_parallel_range(0, totnode, &data, filter_cache_init_task_cb, &settings); + + int tot_active_nodes = 0; + int active_node_index = 0; + PBVHNode **active_nodes; + + for (int i = 0; i < totnode; i++) { + if (node_mask[i] == 1) { + tot_active_nodes++; + } + } + + active_nodes = MEM_callocN(tot_active_nodes * sizeof(PBVHNode *), "active nodes"); + + for (int i = 0; i < totnode; i++) { + if (node_mask[i] == 1) { + active_nodes[active_node_index] = nodes[i]; + active_node_index++; + } + } + + ss->filter_cache->nodes = active_nodes; + ss->filter_cache->totnode = tot_active_nodes; + + if (nodes) { + MEM_freeN(nodes); + } + + if (node_mask) { + MEM_freeN(node_mask); + } +} + +static void sculpt_filter_cache_free(SculptSession *ss) +{ + MEM_freeN(ss->filter_cache->orco); + MEM_freeN(ss->filter_cache->nodes); + if (ss->filter_cache->random_disp) { + MEM_freeN(ss->filter_cache->random_disp); + } + if (ss->filter_cache->orvcol) { + MEM_freeN(ss->filter_cache->orvcol); + } + MEM_freeN(ss->filter_cache); +} + +typedef enum eSculptMeshFilterTypes { + MESH_FILTER_SMOOTH = 0, + MESH_FILTER_GROW = 1, + MESH_FILTER_SCALE = 2, + MESH_FILTER_DILATE = 3, + MESH_FILTER_SPHERE = 4, + MESH_FILTER_RANDOM = 5, + MESH_FILTER_RELAX = 6, +} eSculptMeshFilterTypes; + +EnumPropertyItem prop_mesh_filter_types[] = { + {MESH_FILTER_SMOOTH, "SMOOTH", 0, "Smooth", "Smooth mesh"}, + // {MESH_FILTER_RELAX, "RELAX", 0, "Relax", "Relax mesh"}, + {MESH_FILTER_GROW, "GROW", 0, "Grow", "Grow mesh"}, + {MESH_FILTER_SCALE, "SCALE", 0, "Scale", "Scale mesh"}, + {MESH_FILTER_DILATE, "DILATE", 0, "Dilate", "Dilate mesh"}, + {MESH_FILTER_SPHERE, "SPHERE", 0, "Sphere", "Morph into sphere"}, + {MESH_FILTER_RANDOM, "RANDOM", 0, "Random", "Randomize mesh"}, + {0, NULL, 0, NULL, NULL}, +}; + +static void mesh_filter_task_cb(void *__restrict userdata, + const int i, + const ParallelRangeTLS *__restrict UNUSED(tls)) +{ + SculptThreadedTaskData *data = userdata; + SculptSession *ss = data->ob->sculpt; + PBVHNode *node = data->nodes[i]; + + const int mode = data->filter_type; + + PBVHVertexIter vd; + BKE_pbvh_vertex_iter_begin(ss->pbvh, node, vd, PBVH_ITER_UNIQUE) + { + float orig_co[3], val[3], avg[3], normal[3], disp[3], disp2[3], transform[3][3]; + float fade = vd.mask ? *vd.mask : 1.0f; + fade = 1 - fade; + fade *= data->filter_strength; + copy_v3_v3(orig_co, ss->filter_cache->orco[vd.vert_indices[vd.i]]); + switch (mode) { + case MESH_FILTER_SMOOTH: + CLAMP(fade, -1.0f, 1.0f); + neighbor_average(ss, avg, vd.vert_indices[vd.i]); + sub_v3_v3v3(val, avg, orig_co); + madd_v3_v3v3fl(val, orig_co, val, fade); + sub_v3_v3v3(disp, val, orig_co); + add_v3_v3v3(ss->mvert[vd.vert_indices[vd.i]].co, orig_co, disp); + break; + case MESH_FILTER_RELAX: + relax_vertex(disp, vd, ss, true); + add_v3_v3v3(ss->mvert[vd.vert_indices[vd.i]].co, orig_co, disp); + break; + case MESH_FILTER_DILATE: + normal_short_to_float_v3(normal, vd.no); + mul_v3_v3fl(disp, normal, fade); + add_v3_v3v3(ss->mvert[vd.vert_indices[vd.i]].co, orig_co, disp); + break; + case MESH_FILTER_GROW: + sub_v3_v3v3(disp, orig_co, data->ob->loc); + normalize_v3(disp); + mul_v3_fl(disp, fade); + add_v3_v3v3(ss->mvert[vd.vert_indices[vd.i]].co, orig_co, disp); + case MESH_FILTER_SCALE: + unit_m3(transform); + scale_m3_fl(transform, 1 + fade); + copy_v3_v3(val, orig_co); + mul_m3_v3(transform, val); + sub_v3_v3v3(disp, val, orig_co); + add_v3_v3v3(ss->mvert[vd.vert_indices[vd.i]].co, orig_co, disp); + break; + case MESH_FILTER_SPHERE: + sub_v3_v3v3(disp, orig_co, data->ob->loc); + normalize_v3(disp); + if (fade > 0) { + mul_v3_v3fl(disp, disp, fade); + } + else { + mul_v3_v3fl(disp, disp, -fade); + } + + unit_m3(transform); + if (fade > 0) { + scale_m3_fl(transform, 1 - fade); + } + else { + scale_m3_fl(transform, 1 + fade); + } + copy_v3_v3(val, orig_co); + mul_m3_v3(transform, val); + sub_v3_v3v3(disp2, val, orig_co); + + mid_v3_v3v3(disp, disp, disp2); + add_v3_v3v3(ss->mvert[vd.vert_indices[vd.i]].co, orig_co, disp); + break; + case MESH_FILTER_RANDOM: + normal_short_to_float_v3(normal, vd.no); + mul_v3_fl(normal, + data->random_disp[vd.vert_indices[vd.i] % MESH_FILTER_RANDOM_MOD] - 0.5f); + mul_v3_v3fl(disp, normal, fade); + add_v3_v3v3(ss->mvert[vd.vert_indices[vd.i]].co, orig_co, disp); + break; + } + if (vd.mvert) + vd.mvert->flag |= ME_VERT_PBVH_UPDATE; + } + BKE_pbvh_vertex_iter_end; + + BKE_pbvh_node_mark_redraw(node); +} + +int sculpt_mesh_filter_modal(bContext *C, wmOperator *op, const wmEvent *event) +{ + ARegion *ar = CTX_wm_region(C); + Object *ob = CTX_data_active_object(C); + SculptSession *ss = ob->sculpt; + Sculpt *sd = CTX_data_tool_settings(C)->sculpt; + int mode = RNA_enum_get(op->ptr, "type"); + float filter_strength = RNA_float_get(op->ptr, "strength"); + + float len = event->prevclickx - event->mval[0]; + filter_strength = filter_strength * -len * 0.001f; + + SculptThreadedTaskData data = { + .sd = sd, + .ob = ob, + .nodes = ss->filter_cache->nodes, + .smooth_value = 0.5f, + .filter_type = mode, + .filter_strength = filter_strength, + .random_disp = ss->filter_cache->random_disp, + }; + + Para @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs