[Bf-blender-cvs] [e36ae3c1e44] sculpt-mode-features: Merge branch 'master' into sculpt-mode-features
Pablo Dobarro
noreply at git.blender.org
Fri May 31 23:12:04 CEST 2019
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. @@
More information about the Bf-blender-cvs
mailing list