diff options
author | Joseph Eagar <joeedh@gmail.com> | 2021-08-17 02:34:35 +0300 |
---|---|---|
committer | Joseph Eagar <joeedh@gmail.com> | 2021-08-17 02:34:35 +0300 |
commit | dcaba4c5e3494240464ed6cc6330f40c30ba0e0e (patch) | |
tree | 99ba0851fca03d5779131197beba753583286066 /source | |
parent | fb463a13cdc6ac825b9717931abc066ce317d5d5 (diff) |
Sculpt dyntopo: fix various faceset init operator bugs
that crept in.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt_curvature.c | 34 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt_face_set.c | 118 |
2 files changed, 115 insertions, 37 deletions
diff --git a/source/blender/editors/sculpt_paint/sculpt_curvature.c b/source/blender/editors/sculpt_paint/sculpt_curvature.c index a23afb93407..9bc2f840e3a 100644 --- a/source/blender/editors/sculpt_paint/sculpt_curvature.c +++ b/source/blender/editors/sculpt_paint/sculpt_curvature.c @@ -24,6 +24,8 @@ #include "MEM_guardedalloc.h" +#include "BLI_alloca.h" +#include "BLI_array.h" #include "BLI_blenlib.h" #include "BLI_dial_2d.h" #include "BLI_ghash.h" @@ -151,15 +153,35 @@ bool SCULPT_calc_principle_curvatures(SculptSession *ss, SCULPT_vertex_normal_get(ss, vertex, no); normal_covariance(nmat, no); - SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vertex, ni) { - SCULPT_vertex_normal_get(ss, ni.vertex, no2); - sub_v3_v3(no2, no); + if (useAccurateSolver) { + int val = SCULPT_vertex_valence_get(ss, vertex); + float *ws = BLI_array_alloca(ws, val); + float *cot1 = BLI_array_alloca(cot1, val); + float *cot2 = BLI_array_alloca(cot2, val); + float *areas = BLI_array_alloca(areas, val); + float totarea = 0.0f; - normal_covariance(nmat2, no2); + SCULPT_get_cotangents(ss, vertex, ws, cot1, cot2, areas, &totarea); - add_m3_m3m3(nmat, nmat, nmat2); + SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vertex, ni) { + SCULPT_vertex_normal_get(ss, ni.vertex, no2); + sub_v3_v3(no2, no); + + normal_covariance(nmat2, no2); + madd_m3_m3m3fl(nmat, nmat, nmat2, ws[ni.i]); + } + SCULPT_VERTEX_NEIGHBORS_ITER_END(ni); + } + else { + SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vertex, ni) { + SCULPT_vertex_normal_get(ss, ni.vertex, no2); + sub_v3_v3(no2, no); + + normal_covariance(nmat2, no2); + add_m3_m3m3(nmat, nmat, nmat2); + } + SCULPT_VERTEX_NEIGHBORS_ITER_END(ni); } - SCULPT_VERTEX_NEIGHBORS_ITER_END(ni); if (!useAccurateSolver || !BLI_eigen_solve_selfadjoint_m3(nmat, out->ks, out->principle)) { // do simple power solve in one direction diff --git a/source/blender/editors/sculpt_paint/sculpt_face_set.c b/source/blender/editors/sculpt_paint/sculpt_face_set.c index aa8bf3dc9ff..963f1b1b4fb 100644 --- a/source/blender/editors/sculpt_paint/sculpt_face_set.c +++ b/source/blender/editors/sculpt_paint/sculpt_face_set.c @@ -51,6 +51,7 @@ #include "BKE_paint.h" #include "BKE_pbvh.h" #include "BKE_scene.h" +#include "BKE_subdiv_ccg.h" #include "DEG_depsgraph.h" @@ -74,14 +75,37 @@ #include <math.h> #include <stdlib.h> -int SCULPT_face_set_get(SculptSession *ss, SculptFaceRef face) +static int sculpt_face_material_get(SculptSession *ss, SculptFaceRef face) { - if (ss->bm) { - BMFace *f = (BMFace *)face.i; - return BM_ELEM_CD_GET_INT(f, ss->cd_faceset_offset); + int ret = 0; + + switch (BKE_pbvh_type(ss->pbvh)) { + case PBVH_BMESH: { + BMFace *f = (BMFace *)face.i; + return f->mat_nr; + } + case PBVH_GRIDS: + case PBVH_FACES: + return ss->mpoly[face.i].mat_nr; } - return ss->face_sets[face.i]; + return -1; +} + +int SCULPT_face_set_get(SculptSession *ss, SculptFaceRef face) +{ + int ret = 0; + + switch (BKE_pbvh_type(ss->pbvh)) { + case PBVH_BMESH: { + BMFace *f = (BMFace *)face.i; + return BM_ELEM_CD_GET_INT(f, ss->cd_faceset_offset); + } + case PBVH_GRIDS: + case PBVH_FACES: + return ss->face_sets[face.i]; + } + return -1; } // returns previous face set @@ -89,15 +113,19 @@ int SCULPT_face_set_set(SculptSession *ss, SculptFaceRef face, int fset) { int ret = 0; - if (ss->bm) { - BMFace *f = (BMFace *)face.i; - ret = BM_ELEM_CD_GET_INT(f, ss->cd_faceset_offset); + switch (BKE_pbvh_type(ss->pbvh)) { + case PBVH_BMESH: { + BMFace *f = (BMFace *)face.i; + ret = BM_ELEM_CD_GET_INT(f, ss->cd_faceset_offset); - BM_ELEM_CD_SET_INT(f, ss->cd_faceset_offset, fset); - } - else { - ret = ss->face_sets[face.i]; - ss->face_sets[face.i] = fset; + BM_ELEM_CD_SET_INT(f, ss->cd_faceset_offset, fset); + break; + } + case PBVH_FACES: + case PBVH_GRIDS: + ret = ss->face_sets[face.i]; + ss->face_sets[face.i] = fset; + break; } return ret; @@ -793,30 +821,58 @@ static void sculpt_face_sets_init_loop(Object *ob, const int mode) { Mesh *mesh = ob->data; SculptSession *ss = ob->sculpt; - BMesh *bm = sculpt_faceset_bm_begin(ss, mesh); - BMIter iter; - BMFace *f; + SCULPT_face_random_access_ensure(ss); + + int cd_fmaps_offset = -1; + if (ss->bm) { + cd_fmaps_offset = CustomData_get_offset(&ss->bm->pdata, CD_FACEMAP); + } - const int cd_fmaps_offset = CustomData_get_offset(&bm->pdata, CD_FACEMAP); + Mesh *me = NULL; + int *fmaps = NULL; - BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { - SculptFaceRef fref = {(intptr_t)f}; + if (BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS) { + me = ob->data; + fmaps = CustomData_get_layer(&me->pdata, CD_FACEMAP); + } + else if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES) { + fmaps = CustomData_get_layer(ss->pdata, CD_FACEMAP); + } + + for (int i = 0; i < ss->totfaces; i++) { + SculptFaceRef fref = BKE_pbvh_table_index_to_face(ss->pbvh, i); if (mode == SCULPT_FACE_SETS_FROM_MATERIALS) { - SCULPT_face_set_set(ss, fref, (int)(f->mat_nr + 1)); + SCULPT_face_set_set(ss, fref, (int)(sculpt_face_material_get(ss, fref) + 1)); } else if (mode == SCULPT_FACE_SETS_FROM_FACE_MAPS) { - if (cd_fmaps_offset != -1) { - SCULPT_face_set_set(ss, fref, BM_ELEM_CD_GET_INT(f, cd_fmaps_offset) + 2); - } - else { - SCULPT_face_set_set(ss, fref, 1); + int fmap = 1; + + switch (BKE_pbvh_type(ss->pbvh)) { + case PBVH_BMESH: { + BMFace *f = (BMFace *)fref.i; + + if (cd_fmaps_offset >= 0) { + fmap = BM_ELEM_CD_GET_INT(f, cd_fmaps_offset) + 2; + } + + break; + } + case PBVH_FACES: + case PBVH_GRIDS: { + int f_i = fref.i; + + if (fmaps) { + fmap = fmaps[i] + 2; + } + break; + } } + + SCULPT_face_set_set(ss, fref, fmap); } } - - sculpt_faceset_bm_end(ss, bm); } static int sculpt_face_set_init_exec(bContext *C, wmOperator *op) @@ -1095,8 +1151,8 @@ static int sculpt_face_sets_change_visibility_invoke(bContext *C, Object *ob = CTX_data_active_object(C); SculptSession *ss = ob->sculpt; - /* Update the active vertex and Face Set using the cursor position to avoid relying on the paint - * cursor updates. */ + /* Update the active vertex and Face Set using the cursor position to avoid relying on the + * paint cursor updates. */ SculptCursorGeometryInfo sgi; float mouse[2]; mouse[0] = event->mval[0]; @@ -1578,8 +1634,8 @@ static bool sculpt_face_set_edit_is_operation_valid(SculptSession *ss, if (BKE_pbvh_type(ss->pbvh) == PBVH_GRIDS) { /* Modification of base mesh geometry requires special remapping of multires displacement, * which does not happen here. - * Disable delete operation. It can be supported in the future by doing similar displacement - * data remapping as what happens in the mesh edit mode. */ + * Disable delete operation. It can be supported in the future by doing similar + * displacement data remapping as what happens in the mesh edit mode. */ return false; } if (check_single_face_set(ss, !modify_hidden)) { |