[Bf-blender-cvs] [26a82fd5ccc] sculpt-dev: Sculpt-dev: improve uv smooth brush a bit
Joseph Eagar
noreply at git.blender.org
Fri Nov 19 13:50:37 CET 2021
Commit: 26a82fd5cccbbc04075aa93be15a8d8f1de4601c
Author: Joseph Eagar
Date: Fri Nov 19 04:50:20 2021 -0800
Branches: sculpt-dev
https://developer.blender.org/rB26a82fd5cccbbc04075aa93be15a8d8f1de4601c
Sculpt-dev: improve uv smooth brush a bit
===================================================================
M source/blender/editors/sculpt_paint/sculpt.c
M source/blender/editors/sculpt_paint/sculpt_dyntopo.c
===================================================================
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 35b4925782a..c9846021b1c 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -2056,7 +2056,8 @@ static void sculpt_vertex_neighbors_get_grids(const SculptSession *ss,
}
}
-#define SCULPT_NEIGHBORS_CACHE
+/* still a bit buggy */
+/* #define SCULPT_NEIGHBORS_CACHE */
#ifdef SCULPT_NEIGHBORS_CACHE
typedef struct NeighborCacheItem {
@@ -2268,7 +2269,8 @@ SculptBoundaryType SCULPT_edge_is_boundary(const SculptSession *ss,
MSculptVert *mv1 = BKE_PBVH_SCULPTVERT(ss->cd_sculpt_vert, e->v1);
MSculptVert *mv2 = BKE_PBVH_SCULPTVERT(ss->cd_sculpt_vert, e->v2);
- bool ok = (mv1->flag & SCULPTVERT_FSET_BOUNDARY) && (mv2->flag & SCULPTVERT_FSET_BOUNDARY);
+ bool ok = (mv1->flag & SCULPTVERT_FSET_BOUNDARY) &&
+ (mv2->flag & SCULPTVERT_FSET_BOUNDARY);
ret |= ok ? SCULPT_BOUNDARY_FACE_SET : 0;
}
else {
diff --git a/source/blender/editors/sculpt_paint/sculpt_dyntopo.c b/source/blender/editors/sculpt_paint/sculpt_dyntopo.c
index 3eac8e55e82..f905eb896b2 100644
--- a/source/blender/editors/sculpt_paint/sculpt_dyntopo.c
+++ b/source/blender/editors/sculpt_paint/sculpt_dyntopo.c
@@ -692,9 +692,6 @@ void SCULPT_dynamic_topology_enable_ex(Main *bmain, Depsgraph *depsgraph, Scene
SCULPT_update_customdata_refs(ss, ob);
BMIter iter;
- BMVert *v;
-
- int i = 0;
BMEdge *e;
BM_ITER_MESH (e, &iter, ss->bm, BM_EDGES_OF_MESH) {
@@ -985,6 +982,8 @@ void SCULPT_OT_dynamic_topology_toggle(wmOperatorType *ot)
#define MAXUVLOOPS 32
#define MAXUVNEIGHBORS 32
+struct UVSmoothTri;
+
typedef struct UVSmoothVert {
double uv[2];
float co[3]; // world co
@@ -993,7 +992,11 @@ typedef struct UVSmoothVert {
int totw;
bool pinned, boundary;
BMLoop *ls[MAXUVLOOPS];
+
struct UVSmoothVert *neighbors[MAXUVNEIGHBORS];
+ struct UVSmoothTri *neighbor_tris[MAXUVNEIGHBORS];
+ float neighbor_weights[MAXUVNEIGHBORS];
+
int totloop, totneighbor;
float brushfade;
} UVSmoothVert;
@@ -1084,7 +1087,7 @@ void *uvsolver_calc_loop_key(UVSolver *solver, BMLoop *l)
intptr_t key;
MSculptVert *mv = BKE_PBVH_SCULPTVERT(solver->cd_sculpt_vert, l->v);
- if ((mv->flag & SCULPTVERT_SEAM_BOUNDARY) ||
+ if ((mv->flag & (SCULPTVERT_SEAM_BOUNDARY | SCULPTVERT_UV_BOUNDARY)) ||
(l->e->head.hflag | l->prev->e->head.hflag) & BM_ELEM_SEAM) {
key = y * 16384LL + x;
}
@@ -1144,12 +1147,12 @@ static UVSmoothVert *uvsolver_get_vert(UVSolver *solver, BMLoop *l)
MINLINE double area_tri_signed_v2_db(const double v1[2], const double v2[2], const double v3[2])
{
- return 0.5f * ((v1[0] - v2[0]) * (v2[1] - v3[1]) + (v1[1] - v2[1]) * (v3[0] - v2[0]));
+ return 0.5 * ((v1[0] - v2[0]) * (v2[1] - v3[1]) + (v1[1] - v2[1]) * (v3[0] - v2[0]));
}
MINLINE double area_tri_v2_db(const double v1[2], const double v2[2], const double v3[2])
{
- return fabsf(area_tri_signed_v2_db(v1, v2, v3));
+ return fabs(area_tri_signed_v2_db(v1, v2, v3));
}
void cross_tri_v3_db(double n[3], const double v1[3], const double v2[3], const double v3[3])
@@ -1174,7 +1177,7 @@ double area_tri_v3_db(const double v1[3], const double v2[3], const double v3[3]
return len_v3_db(n) * 0.5;
}
-static UVSmoothTri *uvsolver_ensure_face(UVSolver *solver, BMFace *f)
+ATTR_NO_OPT static UVSmoothTri *uvsolver_ensure_face(UVSolver *solver, BMFace *f)
{
void **entry = NULL;
@@ -1208,27 +1211,28 @@ static UVSmoothTri *uvsolver_ensure_face(UVSolver *solver, BMFace *f)
} while ((l = l->next) != f->l_first);
double area3d = (double)area_tri_v3(tri->vs[0]->co, tri->vs[1]->co, tri->vs[2]->co);
- double area2d = area_tri_v2_db(tri->vs[0]->uv, tri->vs[1]->uv, tri->vs[2]->uv);
+ double area2d = area_tri_signed_v2_db(tri->vs[0]->uv, tri->vs[1]->uv, tri->vs[2]->uv);
+
+ if (fabs(area2d) < 0.0000001) {
+ tri->vs[0]->uv[0] -= 0.00001;
+ tri->vs[0]->uv[1] -= 0.00001;
- if (area2d < 0.000001) {
- tri->vs[0]->uv[0] -= 0.0001;
- tri->vs[0]->uv[1] -= 0.0001;
- tri->vs[1]->uv[0] += 0.0001;
- tri->vs[2]->uv[1] += 0.0001;
+ tri->vs[1]->uv[0] += 0.00001;
+ tri->vs[2]->uv[1] += 0.00001;
}
- solver->totarea2d += area2d;
+ solver->totarea2d += fabs(area2d);
solver->totarea3d += area3d;
tri->area2d = area2d;
tri->area3d = area3d;
for (int i = 0; !nocon && i < 3; i++) {
-
UVSmoothConstraint *con = BLI_mempool_alloc(solver->constraints);
memset((void *)con, 0, sizeof(*con));
+
con->type = CON_ANGLES;
- con->k = 0.5;
+ con->k = 1.0;
UVSmoothVert *v0 = tri->vs[(i + 2) % 3];
UVSmoothVert *v1 = tri->vs[i];
@@ -1255,13 +1259,16 @@ static UVSmoothTri *uvsolver_ensure_face(UVSolver *solver, BMFace *f)
con = BLI_mempool_alloc(solver->constraints);
memset((void *)con, 0, sizeof(*con));
+ con->type = CON_AREA;
+ con->k = 1.0;
+
+ con->totvert = 3;
+
+ con->tri = tri;
+
con->vs[0] = v0;
con->vs[1] = v1;
con->vs[2] = v2;
- con->totvert = 3;
- con->tri = tri;
- con->type = CON_AREA;
- con->k = 1.0;
}
#if 1
@@ -1284,8 +1291,15 @@ static UVSmoothTri *uvsolver_ensure_face(UVSolver *solver, BMFace *f)
continue;
}
- v1->neighbors[v1->totneighbor++] = v2;
- v2->neighbors[v2->totneighbor++] = v1;
+ v1->neighbor_tris[v1->totneighbor] = tri;
+ v1->neighbors[v1->totneighbor] = v2;
+ v1->neighbor_weights[v1->totneighbor] = 1.0; // area3d > 0.0 ? 1.0 / area3d : 100000.0;
+ v1->totneighbor++;
+
+ v2->neighbor_tris[v2->totneighbor] = tri;
+ v2->neighbors[v2->totneighbor] = v1;
+ v2->neighbor_weights[v2->totneighbor] = 1.0; // area3d > 0.0 ? 1.0 / area3d : 100000.0;
+ v2->totneighbor++;
}
#endif
@@ -1331,7 +1345,7 @@ static double uvsolver_eval_constraint(UVSolver *solver, UVSmoothConstraint *con
double wind = t1[0] * t2[1] - t1[1] * t2[0];
if (wind >= 0.0) {
- th = M_PI - th;
+ // th = M_PI - th;
}
return th - con->params[0];
@@ -1349,10 +1363,10 @@ static double uvsolver_eval_constraint(UVSolver *solver, UVSmoothConstraint *con
double goal = con->tri->area3d * solver->totarea2d / solver->totarea3d;
con->tri->area2d = area2d;
- return (area2d - goal) * 1024.0;
+ return (fabs(area2d) - goal) * 1024.0; /* avoid excesively small numbers */
}
default:
- return 0.0f;
+ return 0.0;
}
}
@@ -1391,7 +1405,7 @@ static void uvsolver_solve_begin(UVSolver *solver)
}
}
-static void uvsolver_simple_relax(UVSolver *solver, float strength)
+ATTR_NO_OPT static void uvsolver_simple_relax(UVSolver *solver, float strength)
{
BLI_mempool_iter iter;
@@ -1402,11 +1416,15 @@ static void uvsolver_simple_relax(UVSolver *solver, float strength)
for (; sv1; sv1 = BLI_mempool_iterstep(&iter)) {
double uv[2] = {0.0, 0.0};
double tot = 0.0;
+ int totneighbor = 0;
+ float strength2 = strength;
if (!sv1->totneighbor || sv1->pinned) {
continue;
}
+ bool lastsign;
+
for (int i = 0; i < sv1->totneighbor; i++) {
UVSmoothVert *sv2 = sv1->neighbors[i];
@@ -1414,20 +1432,33 @@ static void uvsolver_simple_relax(UVSolver *solver, float strength)
continue;
}
- uv[0] += sv2->uv[0];
- uv[1] += sv2->uv[1];
- tot += 1.0;
+ bool sign = sv1->neighbor_tris[i]->area2d < 0.0f;
+
+ //try to unfold folded uvs
+ if (totneighbor > 0 && sign != lastsign) {
+ strength2 = 1.0;
+ }
+
+ lastsign = sign;
+
+ double w = (double)sv1->neighbor_weights[i];
+
+ uv[0] += sv2->uv[0] * w;
+ uv[1] += sv2->uv[1] * w;
+
+ tot += w;
+ totneighbor++;
}
- if (tot < 2.0) {
+ if (totneighbor < 2.0) {
continue;
}
uv[0] /= tot;
uv[1] /= tot;
- sv1->uv[0] += (uv[0] - sv1->uv[0]) * strength;
- sv1->uv[1] += (uv[1] - sv1->uv[1]) * strength;
+ sv1->uv[0] += (uv[0] - sv1->uv[0]) * strength2;
+ sv1->uv[1] += (uv[1] - sv1->uv[1]) * strength2;
}
// update real uvs
@@ -1452,7 +1483,7 @@ static float uvsolver_solve_step(UVSolver *solver)
BLI_mempool_iter iter;
if (solver->strength < 0) {
- uvsolver_simple_relax(solver, fabs(solver->strength));
+ uvsolver_simple_relax(solver, -solver->strength);
return 0.0f;
}
else {
@@ -1504,7 +1535,7 @@ static float uvsolver_solve_step(UVSolver *solver)
continue;
}
- r1 *= -solver->strength * 0.75 * con->k / totg;
+ r1 *= -0.75 * con->k / totg;
if (totw == 0.0) {
continue;
@@ -1514,8 +1545,13 @@ static float uvsolver_solve_step(UVSolver *solver)
for (int i = 0; i < con->totvert; i++) {
UVSmoothVert *sv = con->vs[i];
- double w = uvsolver_vert_weight(sv) * totw * sv->brushfade;
+ MSculptVert *mv = BKE_PBVH_SCULPTVERT(solver->cd_sculpt_vert, sv->v);
+
+ mv->flag |= SCULPTVERT_NEED_BOUNDARY;
+
+ double w = uvsolver_vert_weight(sv) * totw;
w = MIN2(w, 1.0);
+ w = 1.0;
for (int j = 0; j < 2; j++) {
double off = r1 * con->gs[i][j] * w;
@@ -1537,8 +1573,10 @@ static float uvsolver_solve_step(UVSolver *solver)
BMLoop *l = sv->ls[i];
MLoopUV *uv = BM_ELEM_CD_GET_VOID_P(l, cd_uv);
- uv->uv[0] = (float)sv->uv[0];
- uv->uv[1] = (float)sv->uv[1];
+ float fac = solver->strength * sv->brushfade;
+
+ uv->uv[0] += ((float)sv->uv[0] - uv->uv[0]) * fac;
+ uv->uv[1] += ((float)sv->uv[1] - uv->uv[1]) * fac;
}
}
@@ -1601,7 +1639,7 @@ static void sculpt_uv_brush_cb(void *__restrict userdata,
BM_ITER_ELEM (l2, &iter, l->v, BM_LOOPS_OF_VERT) {
if (l2->v != l->v) {
- l2 = l2->prev->v == l->v ? l2->prev : l2->next;
+ l2 = l2->next;
}
UVSmoothVert *sv = uvsolver_get_vert(data1->solver, l2);
@@ -1692,6 +1730,7 @@ void SCULPT_uv_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode)
UVSolver *solver = uvsolver_new(cd_uv);
solver->cd_sculpt_vert = ss->cd_sculpt_vert;
+ //solver->strength = powf(fabs(ss->cache
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list