[Bf-blender-cvs] [2f6562fee87] temp-sculpt-cavity-mask: Sculpt: Cavity automasking mode.
Joseph Eagar
noreply at git.blender.org
Sat Jun 4 04:05:55 CEST 2022
Commit: 2f6562fee8716e6aab2df04a66e6a30960df1a9c
Author: Joseph Eagar
Date: Fri Jun 3 19:02:30 2022 -0700
Branches: temp-sculpt-cavity-mask
https://developer.blender.org/rB2f6562fee8716e6aab2df04a66e6a30960df1a9c
Sculpt: Cavity automasking mode.
Implements cavity automasking. Note that
this is a tad bit different from the sculpt-dev
branch implementation:
* It uses the word "cavity" I actually came up with
this idea on my own and, for reasons that escape
me today, decided to call it "concavity."
* The cavity factor works a bit differently. It's
no longer non-linear and functions as a simple
scale around 0.5f.
* Boundary propegation steps blurs the cavity
mask.
===================================================================
M release/scripts/startup/bl_ui/properties_paint_common.py
M release/scripts/startup/bl_ui/space_view3d.py
M release/scripts/startup/bl_ui/space_view3d_toolbar.py
M source/blender/blenkernel/intern/brush.c
M source/blender/blenloader/intern/versioning_300.c
M source/blender/editors/sculpt_paint/sculpt_automasking.c
M source/blender/editors/sculpt_paint/sculpt_intern.h
M source/blender/editors/sculpt_paint/sculpt_paint_color.c
M source/blender/makesdna/DNA_brush_enums.h
M source/blender/makesdna/DNA_brush_types.h
M source/blender/makesrna/intern/rna_brush.c
M source/blender/makesrna/intern/rna_sculpt_paint.c
===================================================================
diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py
index 5a9a8882bd9..a37c6814424 100644
--- a/release/scripts/startup/bl_ui/properties_paint_common.py
+++ b/release/scripts/startup/bl_ui/properties_paint_common.py
@@ -944,6 +944,14 @@ def brush_settings_advanced(layout, context, brush, popover=False):
# boundary edges/face sets automasking
col.prop(brush, "use_automasking_boundary_edges", text="Mesh Boundary")
col.prop(brush, "use_automasking_boundary_face_sets", text="Face Sets Boundary")
+ col.prop(brush, "use_automasking_cavity", text="Cavity Masking")
+
+ col.separator()
+
+ if brush.use_automasking_cavity:
+ col.prop(brush, "invert_automasking_cavity", text="Invert Cavity")
+ col.prop(brush, "automasking_cavity_factor", text="Cavity Factor")
+
col.prop(brush, "automasking_boundary_edges_propagation_steps")
layout.separator()
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 80ea33f8a75..32a9ecb210d 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -5450,6 +5450,8 @@ class VIEW3D_MT_sculpt_automasking_pie(Menu):
pie.prop(sculpt, "use_automasking_face_sets", text="Face Sets")
pie.prop(sculpt, "use_automasking_boundary_edges", text="Mesh Boundary")
pie.prop(sculpt, "use_automasking_boundary_face_sets", text="Face Sets Boundary")
+ pie.prop(sculpt, "use_automasking_cavity", text="Cavity")
+ pie.prop(sculpt, "invert_automasking_cavity", text="Invert Cavity")
class VIEW3D_MT_sculpt_face_sets_edit_pie(Menu):
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 892dc9a1e42..c3c7685cd7a 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -971,6 +971,15 @@ class VIEW3D_PT_sculpt_options(Panel, View3DPaintPanel):
col.prop(sculpt, "use_automasking_face_sets", text="Face Sets")
col.prop(sculpt, "use_automasking_boundary_edges", text="Mesh Boundary")
col.prop(sculpt, "use_automasking_boundary_face_sets", text="Face Sets Boundary")
+ col.prop(sculpt, "use_automasking_cavity", text="Cavity Masking")
+
+ col.separator()
+
+ if sculpt.use_automasking_cavity:
+ col.prop(sculpt, "invert_automasking_cavity", text="Invert Cavity")
+ col.prop(sculpt.brush, "automasking_cavity_factor", text="Cavity Factor")
+
+ col.prop(sculpt.brush, "automasking_boundary_edges_propagation_steps")
class VIEW3D_PT_sculpt_options_gravity(Panel, View3DPaintPanel):
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 083d5af063a..a514646b1f3 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -1698,6 +1698,8 @@ void BKE_brush_sculpt_reset(Brush *br)
* assign this so logic below can remain the same. */
br->alpha = 0.5f;
+ br->automasking_cavity_factor = 0.5f;
+
/* Brush settings */
switch (br->sculpt_tool) {
case SCULPT_TOOL_DRAW_SHARP:
diff --git a/source/blender/blenloader/intern/versioning_300.c b/source/blender/blenloader/intern/versioning_300.c
index 76d12cc1109..18bc0565433 100644
--- a/source/blender/blenloader/intern/versioning_300.c
+++ b/source/blender/blenloader/intern/versioning_300.c
@@ -3021,6 +3021,12 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
+ if (!DNA_struct_elem_find(fd->filesdna, "Brush", "float", "automasking_cavity_factor")) {
+ LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
+ brush->automasking_cavity_factor = 0.5f;
+ }
+ }
+
/**
* Versioning code until next subversion bump goes here.
*
diff --git a/source/blender/editors/sculpt_paint/sculpt_automasking.c b/source/blender/editors/sculpt_paint/sculpt_automasking.c
index d7a2a18504c..4358abad81e 100644
--- a/source/blender/editors/sculpt_paint/sculpt_automasking.c
+++ b/source/blender/editors/sculpt_paint/sculpt_automasking.c
@@ -84,6 +84,10 @@ bool SCULPT_is_automasking_enabled(const Sculpt *sd, const SculptSession *ss, co
if (SCULPT_is_automasking_mode_enabled(sd, br, BRUSH_AUTOMASKING_BOUNDARY_FACE_SETS)) {
return true;
}
+ if (SCULPT_is_automasking_mode_enabled(sd, br, BRUSH_AUTOMASKING_CAVITY)) {
+ return true;
+ }
+
return false;
}
@@ -102,15 +106,66 @@ static bool SCULPT_automasking_needs_factors_cache(const Sculpt *sd, const Brush
if (automasking_flags & BRUSH_AUTOMASKING_TOPOLOGY) {
return true;
}
- if (automasking_flags & BRUSH_AUTOMASKING_BOUNDARY_EDGES) {
- return brush && brush->automasking_boundary_edges_propagation_steps != 1;
- }
- if (automasking_flags & BRUSH_AUTOMASKING_BOUNDARY_FACE_SETS) {
+ if (automasking_flags & (BRUSH_AUTOMASKING_BOUNDARY_FACE_SETS |
+ BRUSH_AUTOMASKING_BOUNDARY_EDGES | BRUSH_AUTOMASKING_CAVITY)) {
return brush && brush->automasking_boundary_edges_propagation_steps != 1;
}
return false;
}
+float SCULPT_calc_cavity(SculptSession *ss, const int vertex)
+{
+ SculptVertexNeighborIter ni;
+ const float *co = SCULPT_vertex_co_get(ss, vertex);
+ float avg[3];
+ float elen = 0.0f;
+ float e_num = 0.0f;
+
+ zero_v3(avg);
+
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, vertex, ni) {
+ const float *co2 = SCULPT_vertex_co_get(ss, ni.index);
+
+ elen += len_v3v3(co, co2);
+ e_num += 1.0f;
+ add_v3_v3(avg, co2);
+ }
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
+
+ if (e_num == 0.0f) {
+ return 0.0f;
+ }
+
+ mul_v3_fl(avg, 1.0f / (float)e_num);
+ elen /= e_num;
+
+ float no[3];
+
+ SCULPT_vertex_normal_get(ss, vertex, no);
+
+ sub_v3_v3(avg, co);
+
+ /* Use distance to plane. */
+ float factor = dot_v3v3(avg, no) / elen;
+
+ return factor;
+}
+
+static float sculpt_automasking_cavity_factor(AutomaskingCache *automasking,
+ SculptSession *ss,
+ int vert)
+{
+ float factor = SCULPT_calc_cavity(ss, vert);
+ float sign = signf(factor);
+
+ factor = fabsf(factor) * automasking->settings.cavity_factor * 50.0f;
+
+ factor = factor * sign * 0.5f + 0.5f;
+ CLAMP(factor, 0.0f, 1.0f);
+
+ return (automasking->settings.flags & BRUSH_AUTOMASKING_CAVITY_INVERT) ? 1.0f - factor : factor;
+}
+
float SCULPT_automasking_factor_get(AutomaskingCache *automasking, SculptSession *ss, int vert)
{
if (!automasking) {
@@ -141,6 +196,10 @@ float SCULPT_automasking_factor_get(AutomaskingCache *automasking, SculptSession
}
}
+ if (automasking->settings.flags & BRUSH_AUTOMASKING_CAVITY) {
+ return sculpt_automasking_cavity_factor(automasking, ss, vert);
+ }
+
return 1.0f;
}
@@ -247,6 +306,76 @@ static float *sculpt_face_sets_automasking_init(Sculpt *sd, Object *ob, float *a
return automask_factor;
}
+static float *sculpt_cavity_automasking_init(Sculpt *sd,
+ Object *ob,
+ AutomaskingCache *automasking,
+ float *automask_factor,
+ int boundary_propagation_steps)
+{
+ SculptSession *ss = ob->sculpt;
+ Brush *brush = BKE_paint_brush(&sd->paint);
+ float *factor = automask_factor, *scratch;
+
+ if (!SCULPT_is_automasking_enabled(sd, ss, brush)) {
+ return NULL;
+ }
+
+ if (BKE_pbvh_type(ss->pbvh) == PBVH_FACES && !ss->pmap) {
+ BLI_assert_msg(0, "Cavity mask automasking: pmap missing");
+ return NULL;
+ }
+
+ int tot_vert = SCULPT_vertex_count_get(ss);
+
+ /* Prepare a few scratch arrays for blur if necassary. */
+ if (boundary_propagation_steps > 1) {
+ factor = MEM_malloc_arrayN(tot_vert, sizeof(float), __func__);
+ scratch = MEM_malloc_arrayN(tot_vert, sizeof(float), __func__);
+
+ for (int i = 0; i < tot_vert; i++) {
+ factor[i] = scratch[i] = 1.0f;
+ }
+ }
+
+ for (int i = 0; i < tot_vert; i++) {
+ factor[i] *= sculpt_automasking_cavity_factor(automasking, ss, i);
+ }
+
+ /* Blur. */
+ for (int iteration = 0; iteration < boundary_propagation_steps - 1; iteration++) {
+ SWAP(float *, factor, scratch);
+
+ for (int i = 0; i < tot_vert; i++) {
+ SculptVertexNeighborIter ni;
+ float sum = 0.0f;
+ int tot = 0;
+
+ SCULPT_VERTEX_NEIGHBORS_ITER_BEGIN (ss, i, ni) {
+ sum += scratch[ni.index];
+ tot++;
+ }
+ SCULPT_VERTEX_NEIGHBORS_ITER_END(ni);
+
+ if (tot) {
+ sum /= tot;
+ }
+
+ factor[i] = (sum + factor[i]) * 0.5f;
+ }
+ }
+
+ if (boundary_propagation_steps > 1) {
+ for (int i = 0; i < tot_vert; i++) {
+ automask_factor[i] *= factor[i];
+ }
+
+ MEM_SAFE_FREE(factor);
+ MEM_SAFE_FREE(scratch);
+ }
+
+ return automask_factor;
+}
+
#define EDGE_DISTANCE_INF -1
float *SCULPT_boundary_automasking_init(Object *ob,
@@ -315,6 +444,7 @@ static void SCULPT_automasking_cache_settings_update(AutomaskingCache *automaski
{
automasking->settings.flags = sculpt_automasking_mode_effective_bits(sd, brush);
automasking->settings.initial_face_set = SCULPT_active_face_set_get(ss);
+ automasking->settings.cavity_factor = brush->automasking_cavity_factor;
}
AutomaskingCache *SCULPT_automasking_cache_init(Sculpt *sd, Brush *brush, Object *ob)
@@ -352,6 +482,12 @@ AutomaskingCache *SCULPT_automasking_cache_init(Sculpt *sd, Brush *brush, Object
sculpt_face_sets_automasking_init(sd, ob, automasking->factor);
}
+ if (SCULPT_is_automasking_mode_enabled(sd, brush, BRUSH_AUTOMASKING_CAVITY)) {
+ SCULPT_vertex_random_access_ensure(ss);
+ sculpt_cavity_automasking_init(
+ sd, ob, automasking, automasking->factor, boundary_propagation_steps);
+ }
+
if (SCULPT_is_automasking_mode_enabled(sd, brush, BRUSH_AUTOMASKING_BOUNDARY_EDGES)) {
SCULPT_vertex_random_access_ensure(ss);
SCULPT_boundary_automaski
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list