diff options
Diffstat (limited to 'source/blender/editors/sculpt_paint/paint_mask.c')
-rw-r--r-- | source/blender/editors/sculpt_paint/paint_mask.c | 90 |
1 files changed, 61 insertions, 29 deletions
diff --git a/source/blender/editors/sculpt_paint/paint_mask.c b/source/blender/editors/sculpt_paint/paint_mask.c index a0f4bac2e7c..a78577a70f6 100644 --- a/source/blender/editors/sculpt_paint/paint_mask.c +++ b/source/blender/editors/sculpt_paint/paint_mask.c @@ -680,7 +680,7 @@ static bool sculpt_gesture_is_effected_lasso(SculptGestureContext *sgcontext, co static bool sculpt_gesture_is_vertex_effected(SculptGestureContext *sgcontext, PBVHVertexIter *vd) { float vertex_normal[3]; - SCULPT_vertex_normal_get(sgcontext->ss, vd->index, vertex_normal); + SCULPT_vertex_normal_get(sgcontext->ss, vd->vertex, vertex_normal); float dot = dot_v3v3(sgcontext->view_normal, vertex_normal); const bool is_effected_front_face = !(sgcontext->front_faces_only && dot < 0.0f); @@ -759,7 +759,7 @@ static void face_set_gesture_apply_task_cb(void *__restrict userdata, BKE_pbvh_vertex_iter_begin (sgcontext->ss->pbvh, node, vd, PBVH_ITER_UNIQUE) { if (sculpt_gesture_is_vertex_effected(sgcontext, &vd)) { - SCULPT_vertex_face_set_set(sgcontext->ss, vd.index, face_set_operation->new_face_set_id); + SCULPT_vertex_face_set_set(sgcontext->ss, vd.vertex, face_set_operation->new_face_set_id); any_updated = true; } } @@ -994,7 +994,8 @@ static void sculpt_gesture_trim_normals_update(SculptGestureContext *sgcontext) .use_toolflags = true, })); - BM_mesh_bm_from_me(bm, + BM_mesh_bm_from_me(NULL, + bm, trim_mesh, (&(struct BMeshFromMeshParams){ .calc_face_normal = true, @@ -1060,7 +1061,7 @@ static void sculpt_gesture_trim_calculate_depth(SculptGestureContext *sgcontext) trim_operation->depth_back = -FLT_MAX; for (int i = 0; i < totvert; i++) { - const float *vco = SCULPT_vertex_co_get(ss, i); + const float *vco = SCULPT_vertex_co_get(ss, BKE_pbvh_table_index_to_vertex(ss->pbvh, i)); /* Convert the coordinates to world space to calculate the depth. When generating the trimming * mesh, coordinates are first calculated in world space, then converted to object space to * store them. */ @@ -1252,7 +1253,7 @@ static void sculpt_gesture_trim_geometry_free(SculptGestureContext *sgcontext) static int bm_face_isect_pair(BMFace *f, void *UNUSED(user_data)) { - return BM_elem_flag_test(f, BM_ELEM_DRAW) ? 1 : 0; + return BM_elem_flag_test(f, BM_ELEM_DRAW) ? 0 : 1; } static void sculpt_gesture_apply_trim(SculptGestureContext *sgcontext) @@ -1262,20 +1263,30 @@ static void sculpt_gesture_apply_trim(SculptGestureContext *sgcontext) Mesh *trim_mesh = trim_operation->mesh; BMesh *bm; - const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(sculpt_mesh, trim_mesh); - bm = BM_mesh_create(&allocsize, - &((struct BMeshCreateParams){ - .use_toolflags = false, - })); - BM_mesh_bm_from_me(bm, - trim_mesh, - &((struct BMeshFromMeshParams){ - .calc_face_normal = true, - })); + if (sgcontext->ss && sgcontext->ss->bm) { + bm = sgcontext->ss->bm; + BM_mesh_normals_update(bm); + } - BM_mesh_bm_from_me(bm, - sculpt_mesh, + else { + const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(sculpt_mesh, trim_mesh); + bm = BM_mesh_create(&allocsize, + &((struct BMeshCreateParams){ + .use_toolflags = false, + })); + + BM_mesh_bm_from_me(NULL, + bm, + sculpt_mesh, + &((struct BMeshFromMeshParams){ + .calc_face_normal = true, + })); + } + + BM_mesh_bm_from_me(NULL, + bm, + trim_mesh, &((struct BMeshFromMeshParams){ .calc_face_normal = true, })); @@ -1336,15 +1347,32 @@ static void sculpt_gesture_apply_trim(SculptGestureContext *sgcontext) MEM_freeN(looptris); - Mesh *result = BKE_mesh_from_bmesh_nomain(bm, - (&(struct BMeshToMeshParams){ - .calc_object_remap = false, - }), - sculpt_mesh); - BM_mesh_free(bm); - BKE_mesh_normals_tag_dirty(result); - BKE_mesh_nomain_to_mesh( - result, sgcontext->vc.obact->data, sgcontext->vc.obact, &CD_MASK_MESH, true); + if (sgcontext->ss && sgcontext->ss->bm) { // rebuild pbvh + BKE_pbvh_free(sgcontext->ss->pbvh); + sgcontext->ss->pbvh = BKE_pbvh_new(); + + BKE_pbvh_build_bmesh(sgcontext->ss->pbvh, + sgcontext->ss->bm, + sgcontext->ss->bm_smooth_shading, + sgcontext->ss->bm_log, + sgcontext->ss->cd_vert_node_offset, + sgcontext->ss->cd_face_node_offset, + sgcontext->ss->cd_dyn_vert, + sgcontext->ss->cd_face_areas, + sgcontext->ss->fast_draw); + } + else { // save result to mesh + Mesh *result = BKE_mesh_from_bmesh_nomain(bm, + (&(struct BMeshToMeshParams){ + .calc_object_remap = false, + }), + sculpt_mesh); + BM_mesh_free(bm); + result->runtime.cd_dirty_vert |= CD_MASK_NORMAL; + BKE_mesh_normals_tag_dirty(result); + BKE_mesh_nomain_to_mesh( + result, sgcontext->vc.obact->data, sgcontext->vc.obact, &CD_MASK_MESH, true); + } } static void sculpt_gesture_trim_begin(bContext *C, SculptGestureContext *sgcontext) @@ -1381,6 +1409,10 @@ static void sculpt_gesture_trim_end(bContext *UNUSED(C), SculptGestureContext *s sculpt_gesture_trim_geometry_free(sgcontext); + if (sgcontext->ss && sgcontext->ss->bm) { + SCULPT_dynamic_topology_triangulate(sgcontext->ss, sgcontext->ss->bm); + } + SCULPT_undo_push_node(sgcontext->vc.obact, NULL, SCULPT_UNDO_GEOMETRY); BKE_mesh_batch_cache_dirty_tag(sgcontext->vc.obact->data, BKE_MESH_BATCH_DIRTY_ALL); DEG_id_tag_update(&sgcontext->vc.obact->id, ID_RECALC_GEOMETRY); @@ -1566,7 +1598,7 @@ static void project_gesture_project_fairing_boundary_task_cb( } SculptVertexNeighborIter ni; - SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.index, ni) { + SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vd.vertex, ni) { if (project_operation->fairing_mask[ni.index] != vertex_fairing_mask) { project_vertex = true; break; @@ -1754,8 +1786,8 @@ static int sculpt_trim_gesture_box_exec(bContext *C, wmOperator *op) { Object *object = CTX_data_active_object(C); SculptSession *ss = object->sculpt; - if (BKE_pbvh_type(ss->pbvh) != PBVH_FACES) { - /* Not supported in Multires and Dyntopo. */ + if (BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS) { + /* Not supported in Multires. */ return OPERATOR_CANCELLED; } |