Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoseph Eagar <joeedh@gmail.com>2021-08-17 02:34:35 +0300
committerJoseph Eagar <joeedh@gmail.com>2021-08-17 02:34:35 +0300
commitdcaba4c5e3494240464ed6cc6330f40c30ba0e0e (patch)
tree99ba0851fca03d5779131197beba753583286066
parentfb463a13cdc6ac825b9717931abc066ce317d5d5 (diff)
Sculpt dyntopo: fix various faceset init operator bugs
that crept in.
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_curvature.c34
-rw-r--r--source/blender/editors/sculpt_paint/sculpt_face_set.c118
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)) {