Sculpt: Fix topology rake updating original coordinates
This commit is contained in:
parent
4d8648a9f3
commit
e557b2096a
|
@ -791,6 +791,8 @@ void BKE_brush_channelset_merge(BrushChannelSet *dst,
|
|||
continue;
|
||||
}
|
||||
|
||||
/*TODO: should inherit if unset should always apply, i.e. this block should be moved above the
|
||||
* previous one?*/
|
||||
if (ch->type == BRUSH_CHANNEL_TYPE_BITMASK && (ch->flag & BRUSH_CHANNEL_INHERIT_IF_UNSET)) {
|
||||
mch->ivalue = ch->ivalue | pch->ivalue;
|
||||
}
|
||||
|
@ -1537,7 +1539,7 @@ void BKE_builtin_apply_hard_edge_mode(BrushChannelSet *chset, bool do_apply)
|
|||
ch->ivalue = 1;
|
||||
}
|
||||
|
||||
//turn off dyntopo surface smoothing
|
||||
// turn off dyntopo surface smoothing
|
||||
ch = BRUSHSET_LOOKUP(chset, dyntopo_disable_smooth);
|
||||
if (ch) {
|
||||
ch->flag &= ~BRUSH_CHANNEL_INHERIT;
|
||||
|
|
|
@ -514,6 +514,7 @@ BrushFlagMap brush_flags_map[] = {
|
|||
DEF(flag, use_plane_trim, BRUSH_PLANE_TRIM)
|
||||
DEF(flag2, use_surface_falloff, BRUSH_USE_SURFACE_FALLOFF)
|
||||
DEF(flag2, use_grab_active_vertex, BRUSH_GRAB_ACTIVE_VERTEX)
|
||||
DEF(flag, accumulate, BRUSH_ACCUMULATE)
|
||||
};
|
||||
|
||||
int brush_flags_map_len = ARRAY_SIZE(brush_flags_map);
|
||||
|
@ -1465,7 +1466,7 @@ void BKE_brush_builtin_create(Brush *brush, int tool)
|
|||
BRUSHSET_SET_FLOAT(chset, strength, 0.5);
|
||||
BRUSHSET_SET_FLOAT(chset, autosmooth, 0.05);
|
||||
BRUSHSET_SET_INT(chset, topology_rake_mode, 1); // curvature mode
|
||||
BRUSHSET_SET_FLOAT(chset, topology_rake, 0.35);
|
||||
BRUSHSET_SET_FLOAT(chset, topology_rake, 0.5);
|
||||
|
||||
BrushChannel *ch = BRUSHSET_LOOKUP(chset, dyntopo_mode);
|
||||
ch->flag &= ~BRUSH_CHANNEL_INHERIT;
|
||||
|
|
|
@ -1512,7 +1512,7 @@ static void layerDynTopoVert_interp(
|
|||
{
|
||||
float co[3], no[3], origmask, color[4];
|
||||
MDynTopoVert *mv = (MDynTopoVert *)dest;
|
||||
float totweight = 0.0f;
|
||||
// float totweight = 0.0f;
|
||||
|
||||
if (count == 0) {
|
||||
memset(mv, 0, sizeof(*mv));
|
||||
|
@ -1533,28 +1533,29 @@ static void layerDynTopoVert_interp(
|
|||
mv->stroke_id = mv2->stroke_id;
|
||||
}
|
||||
|
||||
if (sub_weights) {
|
||||
w = sub_weights[i];
|
||||
}
|
||||
else {
|
||||
w = 1.0f;
|
||||
}
|
||||
w = weights[i];
|
||||
|
||||
madd_v3_v3fl(co, mv2->origco, w);
|
||||
madd_v3_v3fl(no, mv2->origno, w);
|
||||
madd_v4_v4fl(color, mv2->origcolor, w);
|
||||
origmask += mv2->origmask * w;
|
||||
|
||||
totweight += w;
|
||||
// totweight += w;
|
||||
}
|
||||
|
||||
normalize_v3(no);
|
||||
|
||||
#if 0
|
||||
if (fabsf(totweight - 1.0) > 0.001) {
|
||||
printf("eek\n");
|
||||
}
|
||||
float mul = 1.0f / totweight;
|
||||
|
||||
mul_v3_fl(co, mul);
|
||||
normalize_v3(no);
|
||||
|
||||
mul_v4_fl(color, mul);
|
||||
origmask *= mul;
|
||||
#endif
|
||||
|
||||
copy_v3_v3(mv->origco, co);
|
||||
copy_v3_v3(mv->origno, no);
|
||||
|
|
|
@ -1980,9 +1980,9 @@ BLI_INLINE int dyntopo_thread_rand(int seed)
|
|||
return (seed * multiplier + addend) & mask;
|
||||
}
|
||||
|
||||
static void long_edge_queue_task_cb(void *__restrict userdata,
|
||||
const int n,
|
||||
const TaskParallelTLS *__restrict tls)
|
||||
static void long_edge_queue_task_cb(void *__restrict userdata,
|
||||
const int n,
|
||||
const TaskParallelTLS *__restrict tls)
|
||||
{
|
||||
EdgeQueueThreadData *tdata = ((EdgeQueueThreadData *)userdata) + n;
|
||||
PBVHNode *node = tdata->node;
|
||||
|
@ -3930,7 +3930,13 @@ static void pbvh_bmesh_collapse_edge(PBVH *pbvh,
|
|||
copy_v3_v3(v_conn->co, co);
|
||||
}
|
||||
else {
|
||||
float co[3];
|
||||
|
||||
add_v3_v3v3(co, v_del->co, v_conn->co);
|
||||
mul_v3_fl(co, 0.5f);
|
||||
|
||||
BM_edge_collapse(pbvh->bm, e, v_del, true, true, true);
|
||||
copy_v3_v3(v_conn->co, co);
|
||||
}
|
||||
|
||||
for (int i = 0; i < BLI_array_len(delvs); i++) {
|
||||
|
|
|
@ -4476,7 +4476,7 @@ static void do_topology_rake_bmesh_task_cb_ex(void *__restrict userdata,
|
|||
ss, &test, data->brush->falloff_shape);
|
||||
const int thread_id = BLI_task_parallel_thread_id(tls);
|
||||
|
||||
const bool use_curvature = ss->cache->brush->flag2 & BRUSH_CURVATURE_RAKE;
|
||||
const bool use_curvature = data->use_curvature;
|
||||
int check_fsets = ss->cache->brush->flag2 & BRUSH_SMOOTH_PRESERVE_FACE_SETS;
|
||||
check_fsets = check_fsets ? SCULPT_BOUNDARY_FACE_SET : 0;
|
||||
|
||||
|
@ -4542,39 +4542,55 @@ static void do_topology_rake_bmesh_task_cb_ex(void *__restrict userdata,
|
|||
}
|
||||
#endif
|
||||
|
||||
int steps = data->do_origco ? 2 : 1;
|
||||
// check origdata to be sure we don't mess it up
|
||||
SCULPT_vertex_check_origdata(ss, vd.vertex);
|
||||
|
||||
for (int step = 0; step < steps; step++) {
|
||||
float *co = step ? (float *)SCULPT_vertex_origco_get(ss, vd.vertex) : vd.co;
|
||||
float *co = vd.co;
|
||||
|
||||
SCULPT_bmesh_four_neighbor_average(ss,
|
||||
avg,
|
||||
direction2,
|
||||
vd.bm_vert,
|
||||
data->rake_projection,
|
||||
check_fsets,
|
||||
data->cd_temp,
|
||||
data->cd_dyn_vert,
|
||||
step);
|
||||
float oldco[3];
|
||||
copy_v3_v3(oldco, co);
|
||||
|
||||
sub_v3_v3v3(val, avg, co);
|
||||
madd_v3_v3v3fl(val, co, val, fade);
|
||||
SCULPT_clip(sd, ss, co, val);
|
||||
}
|
||||
SCULPT_bmesh_four_neighbor_average(ss,
|
||||
avg,
|
||||
direction2,
|
||||
vd.bm_vert,
|
||||
data->rake_projection,
|
||||
check_fsets,
|
||||
data->cd_temp,
|
||||
data->cd_dyn_vert,
|
||||
0);
|
||||
|
||||
sub_v3_v3v3(val, avg, co);
|
||||
|
||||
float tan[3];
|
||||
copy_v3_v3(tan, val);
|
||||
madd_v3_v3fl(tan, vd.bm_vert->no, -dot_v3v3(tan, vd.bm_vert->no));
|
||||
|
||||
MDynTopoVert *mv = BKE_PBVH_DYNVERT(ss->cd_dyn_vert, vd.bm_vert);
|
||||
madd_v3_v3v3fl(mv->origco, mv->origco, tan, fade * 0.5);
|
||||
|
||||
madd_v3_v3v3fl(val, co, val, fade);
|
||||
SCULPT_clip(sd, ss, co, val);
|
||||
|
||||
if (vd.mvert) {
|
||||
vd.mvert->flag |= ME_VERT_PBVH_UPDATE;
|
||||
}
|
||||
}
|
||||
BKE_pbvh_vertex_iter_end;
|
||||
|
||||
BKE_pbvh_node_mark_normals_update(data->nodes[n]);
|
||||
}
|
||||
|
||||
static void bmesh_topology_rake(
|
||||
Sculpt *sd, Object *ob, PBVHNode **nodes, const int totnode, float bstrength)
|
||||
static void bmesh_topology_rake(Sculpt *sd,
|
||||
Object *ob,
|
||||
PBVHNode **nodes,
|
||||
const int totnode,
|
||||
float bstrength,
|
||||
bool needs_origco)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
Brush *brush = ss->cache ? ss->cache->brush : BKE_paint_brush(&sd->paint);
|
||||
const float strength = clamp_f(bstrength, 0.0f, 1.0f);
|
||||
const float strength = bstrength; // clamp_f(bstrength, 0.0f, 1.0f);
|
||||
|
||||
Brush local_brush;
|
||||
|
||||
|
@ -4632,23 +4648,26 @@ static void bmesh_topology_rake(
|
|||
|
||||
int iteration;
|
||||
const int count = iterations * strength + 1;
|
||||
const float factor = iterations * strength / count;
|
||||
const float factor = iterations * strength / count * 0.25;
|
||||
|
||||
for (iteration = 0; iteration <= count; iteration++) {
|
||||
|
||||
SculptThreadedTaskData data = {.sd = sd,
|
||||
.ob = ob,
|
||||
.brush = brush,
|
||||
.nodes = nodes,
|
||||
.strength = factor,
|
||||
.cd_temp = cd_temp,
|
||||
.cd_dyn_vert = ss->cd_dyn_vert,
|
||||
.rake_projection = brush->topology_rake_projection,
|
||||
.do_origco = SCULPT_stroke_needs_original(brush)};
|
||||
SculptThreadedTaskData data = {
|
||||
.sd = sd,
|
||||
.ob = ob,
|
||||
.brush = brush,
|
||||
.nodes = nodes,
|
||||
.strength = factor,
|
||||
.cd_temp = cd_temp,
|
||||
.use_curvature = SCULPT_get_int(ss, topology_rake_mode, sd, brush),
|
||||
.cd_dyn_vert = ss->cd_dyn_vert,
|
||||
.rake_projection = brush->topology_rake_projection,
|
||||
.do_origco = needs_origco};
|
||||
TaskParallelSettings settings;
|
||||
BKE_pbvh_parallel_range_settings(&settings, true, totnode);
|
||||
|
||||
BLI_task_parallel_range(0, totnode, &data, do_topology_rake_bmesh_task_cb_ex, &settings);
|
||||
BKE_pbvh_update_normals(ss->pbvh, ss->subdiv_ccg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7471,6 +7490,8 @@ static void do_clay_brush_task_cb_ex(void *__restrict userdata,
|
|||
continue;
|
||||
}
|
||||
|
||||
SCULPT_vertex_check_origdata(ss, vd.vertex);
|
||||
|
||||
float intr[3];
|
||||
float val[3];
|
||||
closest_to_plane_normalized_v3(intr, test.plane_tool, vd.co);
|
||||
|
@ -8965,7 +8986,14 @@ void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSettings
|
|||
break;
|
||||
case SCULPT_TOOL_SMOOTH:
|
||||
if (brush->smooth_deform_type == BRUSH_SMOOTH_DEFORM_LAPLACIAN) {
|
||||
SCULPT_do_smooth_brush(sd, ob, nodes, totnode, brush->autosmooth_projection);
|
||||
SCULPT_do_smooth_brush(
|
||||
sd,
|
||||
ob,
|
||||
nodes,
|
||||
totnode,
|
||||
brush->autosmooth_projection,
|
||||
SCULPT_stroke_needs_original(
|
||||
brush)); // TODO: extract need original from commandlist and not parent brush
|
||||
}
|
||||
else if (brush->smooth_deform_type == BRUSH_SMOOTH_DEFORM_SURFACE) {
|
||||
SCULPT_do_surface_smooth_brush(sd, ob, nodes, totnode);
|
||||
|
@ -9173,7 +9201,8 @@ void do_brush_action(Sculpt *sd, Object *ob, Brush *brush, UnifiedPaintSettings
|
|||
ss->cache->radius_squared = ss->cache->radius * ss->cache->radius;
|
||||
}
|
||||
|
||||
bmesh_topology_rake(sd, ob, nodes, totnode, brush->topology_rake_factor);
|
||||
bmesh_topology_rake(
|
||||
sd, ob, nodes, totnode, brush->topology_rake_factor, SCULPT_stroke_needs_original(brush));
|
||||
|
||||
if (brush->topology_rake_radius_factor != 1.0f) {
|
||||
ss->cache->radius = start_radius;
|
||||
|
@ -9548,8 +9577,12 @@ static void SCULPT_run_command_list(
|
|||
break;
|
||||
case SCULPT_TOOL_SMOOTH:
|
||||
if (brush2->smooth_deform_type == BRUSH_SMOOTH_DEFORM_LAPLACIAN) {
|
||||
SCULPT_do_smooth_brush(
|
||||
sd, ob, nodes, totnode, BRUSHSET_GET_FLOAT(cmd->params_mapped, projection, NULL));
|
||||
SCULPT_do_smooth_brush(sd,
|
||||
ob,
|
||||
nodes,
|
||||
totnode,
|
||||
BRUSHSET_GET_FLOAT(cmd->params_mapped, projection, NULL),
|
||||
SCULPT_stroke_needs_original(brush));
|
||||
}
|
||||
else if (brush2->smooth_deform_type == BRUSH_SMOOTH_DEFORM_SURFACE) {
|
||||
SCULPT_do_surface_smooth_brush(sd, ob, nodes, totnode);
|
||||
|
@ -9680,7 +9713,8 @@ static void SCULPT_run_command_list(
|
|||
break;
|
||||
case SCULPT_TOOL_TOPOLOGY_RAKE:
|
||||
if (ss->bm) {
|
||||
bmesh_topology_rake(sd, ob, nodes, totnode, ss->cache->bstrength);
|
||||
bmesh_topology_rake(
|
||||
sd, ob, nodes, totnode, ss->cache->bstrength, SCULPT_stroke_needs_original(brush));
|
||||
}
|
||||
break;
|
||||
case SCULPT_TOOL_DYNTOPO:
|
||||
|
|
|
@ -784,7 +784,7 @@ void SCULPT_smooth(Sculpt *sd,
|
|||
bool do_origco);
|
||||
|
||||
void SCULPT_do_smooth_brush(
|
||||
Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float projection);
|
||||
Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float projection, bool do_origco);
|
||||
|
||||
/* Surface Smooth Brush. */
|
||||
|
||||
|
@ -1059,6 +1059,7 @@ typedef struct SculptThreadedTaskData {
|
|||
|
||||
float fset_slide, bound_smooth;
|
||||
float crease_pinch_factor;
|
||||
bool use_curvature;
|
||||
} SculptThreadedTaskData;
|
||||
|
||||
/*************** Brush testing declarations ****************/
|
||||
|
|
|
@ -1020,6 +1020,10 @@ static void do_smooth_brush_task_cb_ex(void *__restrict userdata,
|
|||
if (!sculpt_brush_test_sq_fn(&test, vd.co)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// check origdata to be sure we don't mess it up
|
||||
SCULPT_vertex_check_origdata(ss, vd.vertex);
|
||||
|
||||
const float fade = bstrength * SCULPT_brush_strength_factor(
|
||||
ss,
|
||||
brush,
|
||||
|
@ -1172,7 +1176,7 @@ void SCULPT_smooth(Sculpt *sd,
|
|||
.bound_smooth = bound_smooth,
|
||||
.scl = have_scl ? &scl : NULL,
|
||||
.scl2 = bound_scl,
|
||||
.do_origco = SCULPT_stroke_needs_original(ss->cache->brush),
|
||||
.do_origco = do_origco,
|
||||
};
|
||||
|
||||
TaskParallelSettings settings;
|
||||
|
@ -1186,7 +1190,7 @@ void SCULPT_smooth(Sculpt *sd,
|
|||
}
|
||||
|
||||
void SCULPT_do_smooth_brush(
|
||||
Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float projection)
|
||||
Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode, float projection, bool do_origco)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
|
||||
|
@ -1206,7 +1210,7 @@ void SCULPT_do_smooth_brush(
|
|||
}
|
||||
else {
|
||||
/* Regular mode, smooth. */
|
||||
SCULPT_smooth(sd, ob, nodes, totnode, ss->cache->bstrength, false, projection, false);
|
||||
SCULPT_smooth(sd, ob, nodes, totnode, ss->cache->bstrength, false, projection, do_origco);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1063,7 +1063,8 @@ GPU_PBVH_Buffers *GPU_pbvh_grid_buffers_build(int totgrid, BLI_bitmap **grid_hid
|
|||
static int debug_pass = 0;
|
||||
|
||||
/* Output a BMVert into a VertexBufferFormat array at v_index. */
|
||||
static void gpu_bmesh_vert_to_buffer_copy(BMVert *v,
|
||||
static void gpu_bmesh_vert_to_buffer_copy(BMesh *bm,
|
||||
BMVert *v,
|
||||
GPUVertBuf *vert_buf,
|
||||
int v_index,
|
||||
const float fno[3],
|
||||
|
@ -1086,12 +1087,21 @@ static void gpu_bmesh_vert_to_buffer_copy(BMVert *v,
|
|||
vert_buf, g_vbo_id.vertex_attrs, g_vbo_id.vertex_attrs_len, (BMElem *)v, v_index);
|
||||
#endif
|
||||
|
||||
/* Set coord, normal, and mask */
|
||||
GPU_vertbuf_attr_set(vert_buf, g_vbo_id.pos, v_index, v->co);
|
||||
|
||||
short no_short[3];
|
||||
|
||||
normal_float_to_short_v3(no_short, fno ? fno : v->no);
|
||||
/* Set coord, normal, and mask */
|
||||
if (G.debug_value == 890) {
|
||||
const int cd_dyn_vert = bm->vdata.layers[bm->vdata.typemap[CD_DYNTOPO_VERT]].offset;
|
||||
MDynTopoVert *mv = BM_ELEM_CD_GET_VOID_P(v, cd_dyn_vert);
|
||||
|
||||
GPU_vertbuf_attr_set(vert_buf, g_vbo_id.pos, v_index, mv->origco);
|
||||
normal_float_to_short_v3(no_short, mv->origno);
|
||||
}
|
||||
else {
|
||||
GPU_vertbuf_attr_set(vert_buf, g_vbo_id.pos, v_index, v->co);
|
||||
normal_float_to_short_v3(no_short, fno ? fno : v->no);
|
||||
}
|
||||
|
||||
GPU_vertbuf_attr_set(vert_buf, g_vbo_id.nor, v_index, no_short);
|
||||
|
||||
#ifndef GPU_PERF_TEST
|
||||
|
@ -1746,7 +1756,8 @@ static void GPU_pbvh_bmesh_buffers_update_indexed(GPU_PBVH_Buffers *buffers,
|
|||
|
||||
GPU_vertbuf_attr_set(vert_buf, g_vbo_id.nor, i, no_short);
|
||||
#else
|
||||
gpu_bmesh_vert_to_buffer_copy(v,
|
||||
gpu_bmesh_vert_to_buffer_copy(bm,
|
||||
v,
|
||||
buffers->vert_buf,
|
||||
i,
|
||||
NULL,
|
||||
|
@ -1961,7 +1972,8 @@ void GPU_pbvh_bmesh_buffers_update(GPU_PBVH_Buffers *buffers,
|
|||
for (int j = 0; j < 3; j++) {
|
||||
float *no = buffers->smooth ? v[j]->no : f->no;
|
||||
|
||||
gpu_bmesh_vert_to_buffer_copy(v[j],
|
||||
gpu_bmesh_vert_to_buffer_copy(bm,
|
||||
v[j],
|
||||
buffers->vert_buf,
|
||||
v_index,
|
||||
no,
|
||||
|
@ -2079,7 +2091,8 @@ void GPU_pbvh_bmesh_buffers_update(GPU_PBVH_Buffers *buffers,
|
|||
for (i = 0; i < 3; i++) {
|
||||
float *no = buffers->smooth ? v[i]->no : f->no;
|
||||
|
||||
gpu_bmesh_vert_to_buffer_copy(v[i],
|
||||
gpu_bmesh_vert_to_buffer_copy(bm,
|
||||
v[i],
|
||||
buffers->vert_buf,
|
||||
v_index,
|
||||
no,
|
||||
|
|
Loading…
Reference in New Issue