Added per-brush DynTopo settings which are stored in a new DynTopoSettings struct.

This system is designed to inherit settings from scene dyntopo defaults
in a highly flexible way; settings can be individually overridden via the
.inherit bitmask.

At stroke time the scene settings and brush->dyntopo are merged
and stored in brush->cached_dyntopo.

Note that brush->flag has a bit flag, DYNTOPO_DISABLED, with a few
subtlies.  It does not switch the PBVH back to PBVH_FACES mode, it
simply disbles dyntopo topology update.  It also doesn't inherit from
any default settings.  And it's the only setting
that's currently exposed in the UI.
This commit is contained in:
Joseph Eagar 2021-03-30 00:08:09 -07:00
parent 7be027075f
commit aa116ba5ba
14 changed files with 257 additions and 15 deletions

View File

@ -574,7 +574,8 @@ def brush_settings(layout, context, brush, popover=False):
context.sculpt_object.use_dynamic_topology_sculpting
):
layout.prop(brush, "topology_rake_factor", slider=True)
layout.prop(brush.dyntopo, "disabled", text="Disable Dyntopo");
# normal_weight
if capabilities.has_normal_weight:
layout.prop(brush, "normal_weight", slider=True)

View File

@ -36,6 +36,8 @@ struct Main;
struct Scene;
struct ToolSettings;
struct UnifiedPaintSettings;
struct DynTopoSettings;
struct Sculpt;
// enum eCurveMappingPreset;
@ -151,6 +153,8 @@ void BKE_brush_scale_size(int *r_brush_size,
/* debugging only */
void BKE_brush_debug_print_state(struct Brush *br);
void BKE_brush_get_dyntopo(struct Brush *brush, struct Sculpt *sd, struct DynTopoSettings *out);
#ifdef __cplusplus
}
#endif

View File

@ -349,7 +349,7 @@ int BKE_pbvh_get_grid_num_faces(const PBVH *pbvh);
/* Only valid for type == PBVH_BMESH */
struct BMesh *BKE_pbvh_get_bmesh(PBVH *pbvh);
void BKE_pbvh_bmesh_detail_size_set(PBVH *pbvh, float detail_size);
void BKE_pbvh_bmesh_detail_size_set(PBVH *pbvh, float detail_size, float detail_range);
typedef enum {
PBVH_Subdivide = 1,

View File

@ -478,6 +478,7 @@ static void brush_defaults(Brush *brush)
FROM_DEFAULT(stencil_dimension);
FROM_DEFAULT(mtex);
FROM_DEFAULT(mask_mtex);
FROM_DEFAULT(dyntopo);
#undef FROM_DEFAULT
#undef FROM_DEFAULT_PTR
@ -1691,6 +1692,8 @@ void BKE_brush_sculpt_reset(Brush *br)
* assign this so logic below can remain the same. */
br->alpha = 0.5f;
bool disable_dyntopo = false;
/* Brush settings */
switch (br->sculpt_tool) {
case SCULPT_TOOL_DRAW_SHARP:
@ -1702,11 +1705,16 @@ void BKE_brush_sculpt_reset(Brush *br)
br->curve_preset = BRUSH_CURVE_SMOOTHER;
br->spacing = 10;
br->alpha = 1.0f;
disable_dyntopo = true;
break;
case SCULPT_TOOL_SLIDE_RELAX:
br->spacing = 10;
br->alpha = 1.0f;
br->slide_deform_type = BRUSH_SLIDE_DEFORM_DRAG;
disable_dyntopo = true;
break;
case SCULPT_TOOL_CLAY:
br->flag |= BRUSH_SIZE_PRESSURE;
@ -1754,6 +1762,8 @@ void BKE_brush_sculpt_reset(Brush *br)
break;
case SCULPT_TOOL_ROTATE:
br->alpha = 1.0;
disable_dyntopo = true;
break;
case SCULPT_TOOL_SMOOTH:
br->flag &= ~BRUSH_SPACE_ATTEN;
@ -1762,6 +1772,8 @@ void BKE_brush_sculpt_reset(Brush *br)
br->surface_smooth_shape_preservation = 0.5f;
br->surface_smooth_current_vertex = 0.5f;
br->surface_smooth_iterations = 4;
disable_dyntopo = true;
break;
case SCULPT_TOOL_SNAKE_HOOK:
br->alpha = 1.0f;
@ -1779,6 +1791,8 @@ void BKE_brush_sculpt_reset(Brush *br)
br->flag &= ~BRUSH_ALPHA_PRESSURE;
br->flag &= ~BRUSH_SPACE;
br->flag &= ~BRUSH_SPACE_ATTEN;
disable_dyntopo = true;
break;
case SCULPT_TOOL_POSE:
br->pose_smooth_iterations = 4;
@ -1787,18 +1801,24 @@ void BKE_brush_sculpt_reset(Brush *br)
br->flag &= ~BRUSH_ALPHA_PRESSURE;
br->flag &= ~BRUSH_SPACE;
br->flag &= ~BRUSH_SPACE_ATTEN;
disable_dyntopo = true;
break;
case SCULPT_TOOL_BOUNDARY:
br->flag &= ~BRUSH_ALPHA_PRESSURE;
br->flag &= ~BRUSH_SPACE;
br->flag &= ~BRUSH_SPACE_ATTEN;
br->curve_preset = BRUSH_CURVE_CONSTANT;
disable_dyntopo = true;
break;
case SCULPT_TOOL_DRAW_FACE_SETS:
br->alpha = 0.5f;
br->flag &= ~BRUSH_ALPHA_PRESSURE;
br->flag &= ~BRUSH_SPACE;
br->flag &= ~BRUSH_SPACE_ATTEN;
disable_dyntopo = true;
break;
case SCULPT_TOOL_GRAB:
br->alpha = 0.4f;
@ -1806,6 +1826,8 @@ void BKE_brush_sculpt_reset(Brush *br)
br->flag &= ~BRUSH_ALPHA_PRESSURE;
br->flag &= ~BRUSH_SPACE;
br->flag &= ~BRUSH_SPACE_ATTEN;
disable_dyntopo = true;
break;
case SCULPT_TOOL_CLOTH:
br->cloth_mass = 1.0f;
@ -1814,6 +1836,8 @@ void BKE_brush_sculpt_reset(Brush *br)
br->cloth_sim_falloff = 0.75f;
br->cloth_deform_type = BRUSH_CLOTH_DEFORM_DRAG;
br->flag &= ~(BRUSH_ALPHA_PRESSURE | BRUSH_SIZE_PRESSURE);
disable_dyntopo = true;
break;
case SCULPT_TOOL_LAYER:
br->flag &= ~BRUSH_SPACE_ATTEN;
@ -1831,6 +1855,8 @@ void BKE_brush_sculpt_reset(Brush *br)
br->density = 1.0f;
br->flag &= ~BRUSH_SPACE_ATTEN;
zero_v3(br->rgb);
disable_dyntopo = true;
break;
case SCULPT_TOOL_SMEAR:
br->alpha = 1.0f;
@ -1838,6 +1864,8 @@ void BKE_brush_sculpt_reset(Brush *br)
br->flag &= ~BRUSH_ALPHA_PRESSURE;
br->flag &= ~BRUSH_SPACE_ATTEN;
br->curve_preset = BRUSH_CURVE_SPHERE;
disable_dyntopo = true;
break;
case SCULPT_TOOL_VCOL_BOUNDARY:
br->flag &= ~BRUSH_SPACE_ATTEN;
@ -1846,6 +1874,9 @@ void BKE_brush_sculpt_reset(Brush *br)
br->surface_smooth_shape_preservation = 0.5f;
br->surface_smooth_current_vertex = 0.5f;
br->surface_smooth_iterations = 4;
disable_dyntopo = true;
break;
case SCULPT_TOOL_DISPLACEMENT_SMEAR:
br->alpha = 1.0f;
br->spacing = 5;
@ -1853,11 +1884,17 @@ void BKE_brush_sculpt_reset(Brush *br)
br->flag &= ~BRUSH_ALPHA_PRESSURE;
br->flag &= ~BRUSH_SPACE_ATTEN;
br->curve_preset = BRUSH_CURVE_SMOOTHER;
disable_dyntopo = true;
break;
default:
break;
}
if (disable_dyntopo) {
//disabled flag is never inherited
br->dyntopo.flag |= DYNTOPO_DISABLED;
}
/* Cursor colors */
/* Default Alpha */
@ -2550,3 +2587,59 @@ struct ImBuf *BKE_brush_gen_radial_control_imbuf(Brush *br, bool secondary, bool
return im;
}
void BKE_brush_get_dyntopo(Brush *brush, Sculpt *sd, DynTopoSettings *out)
{
*out = brush->dyntopo;
int inherit = out->inherit;
if (out->inherit & DYNTOPO_INHERIT_ALL) {
inherit = 0x7FFF;
}
if (inherit & DYNTOPO_INHERIT_MODE) {
if (sd->flags & SCULPT_DYNTOPO_DETAIL_CONSTANT) {
out->mode = DYNTOPO_DETAIL_CONSTANT;
}
else if (sd->flags & SCULPT_DYNTOPO_DETAIL_BRUSH) {
out->mode = DYNTOPO_DETAIL_BRUSH;
}
else if (sd->flags & SCULPT_DYNTOPO_DETAIL_MANUAL) {
out->mode = DYNTOPO_DETAIL_MANUAL;
}
else {
out->mode = DYNTOPO_DETAIL_RELATIVE;
}
}
if (inherit & DYNTOPO_INHERIT_DETAIL_RANGE) {
out->detail_range = sd->detail_range;
}
if (inherit & DYNTOPO_INHERIT_DETAIL_PERCENT) {
out->detail_percent = sd->detail_percent;
}
if (inherit & DYNTOPO_INHERIT_CONSTANT_DETAIL) {
out->constant_detail = sd->constant_detail;
}
if (inherit & DYNTOPO_SUBDIVIDE) {
if (sd->flags & SCULPT_DYNTOPO_SUBDIVIDE) {
out->flag |= DYNTOPO_SUBDIVIDE;
}
else {
out->flag &= ~DYNTOPO_SUBDIVIDE;
}
}
if (inherit & DYNTOPO_COLLAPSE) {
if (sd->flags & SCULPT_DYNTOPO_COLLAPSE) {
out->flag |= DYNTOPO_COLLAPSE;
}
else {
out->flag &= ~DYNTOPO_COLLAPSE;
}
}
};

View File

@ -1907,6 +1907,9 @@ void BKE_sculpt_toolsettings_data_ensure(struct Scene *scene)
if (!sd->detail_size) {
sd->detail_size = 12;
}
if (!sd->detail_range) {
sd->detail_range = 0.4f;
}
if (!sd->detail_percent) {
sd->detail_percent = 25;
}

View File

@ -2957,7 +2957,7 @@ void BKE_pbvh_build_bmesh(PBVH *pbvh,
pbvh->bm = bm;
BKE_pbvh_bmesh_detail_size_set(pbvh, 0.75);
BKE_pbvh_bmesh_detail_size_set(pbvh, 0.75f, 0.4f);
pbvh->type = PBVH_BMESH;
pbvh->bm_log = log;
@ -3664,10 +3664,10 @@ void BKE_pbvh_bmesh_after_stroke(PBVH *pbvh)
BKE_pbvh_update_bounds(pbvh, (PBVH_UpdateBB | PBVH_UpdateOriginalBB | PBVH_UpdateRedraw));
}
void BKE_pbvh_bmesh_detail_size_set(PBVH *pbvh, float detail_size)
void BKE_pbvh_bmesh_detail_size_set(PBVH *pbvh, float detail_size, float detail_range)
{
pbvh->bm_max_edge_len = detail_size;
pbvh->bm_min_edge_len = pbvh->bm_max_edge_len * 0.4f;
pbvh->bm_min_edge_len = pbvh->bm_max_edge_len * detail_range;
}
void BKE_pbvh_node_mark_topology_update(PBVHNode *node)

View File

@ -48,6 +48,7 @@
#include "DNA_space_types.h"
#include "DNA_tracking_types.h"
#include "DNA_workspace_types.h"
#include "DNA_defaults.h"
#include "BKE_animsys.h"
#include "BKE_armature.h"
@ -61,6 +62,7 @@
#include "BKE_mesh.h"
#include "BKE_multires.h"
#include "BKE_node.h"
#include "BKE_brush.h"
#include "IMB_imbuf.h"
#include "MEM_guardedalloc.h"
@ -1914,6 +1916,24 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
if (!MAIN_VERSION_ATLEAST(bmain, 293, 14)) {
LISTBASE_FOREACH(Scene*, scene, &bmain->scenes) {
ToolSettings *ts = scene->toolsettings;
if (ts && ts->sculpt) {
ts->sculpt->detail_range = 0.4f;
}
}
LISTBASE_FOREACH(Brush *, brush, &bmain->brushes) {
if (brush->dyntopo.detail_range == 0.0f) {
Brush defbrush = *brush;
BKE_brush_sculpt_reset(&defbrush);
brush->dyntopo = defbrush.dyntopo;
}
}
}
/**
* Versioning code until next subversion bump goes here.
*

View File

@ -1039,7 +1039,7 @@ static void sculpt_vertex_neighbors_get_bmesh(SculptSession *ss,
iter->neighbors = iter->neighbors_fixed;
iter->neighbor_indices = iter->neighbor_indices_fixed;
#if 1 //note that BM_EDGES_OF_VERT should be faster then BM_LOOPS_OF_VERT
#if 1 // note that BM_EDGES_OF_VERT should be faster then BM_LOOPS_OF_VERT
BMEdge *e;
BM_ITER_ELEM (e, &liter, v, BM_EDGES_OF_VERT) {
BMVert *v_other = BM_edge_other_vert(e, v);
@ -1807,7 +1807,8 @@ bool SCULPT_stroke_is_dynamic_topology(const SculptSession *ss, const Brush *bru
/* Requires mesh restore, which doesn't work with
* dynamic-topology. */
!(brush->flag & BRUSH_ANCHORED) && !(brush->flag & BRUSH_DRAG_DOT) &&
(brush->cached_dyntopo.flag & (DYNTOPO_SUBDIVIDE | DYNTOPO_COLLAPSE)) &&
!(brush->cached_dyntopo.flag & DYNTOPO_DISABLED) &&
SCULPT_TOOL_HAS_DYNTOPO(brush->sculpt_tool));
}
@ -8395,21 +8396,30 @@ static void sculpt_stroke_update_step(bContext *C,
SculptSession *ss = ob->sculpt;
const Brush *brush = BKE_paint_brush(&sd->paint);
BKE_brush_get_dyntopo(brush, sd, &brush->cached_dyntopo);
SCULPT_stroke_modifiers_check(C, ob, brush);
sculpt_update_cache_variants(C, sd, ob, itemptr);
sculpt_restore_mesh(sd, ob);
if (sd->flags & (SCULPT_DYNTOPO_DETAIL_CONSTANT | SCULPT_DYNTOPO_DETAIL_MANUAL)) {
float object_space_constant_detail = 1.0f / (sd->constant_detail * mat4_to_scale(ob->obmat));
BKE_pbvh_bmesh_detail_size_set(ss->pbvh, object_space_constant_detail);
if (brush->cached_dyntopo.mode == DYNTOPO_DETAIL_CONSTANT ||
brush->cached_dyntopo.mode == DYNTOPO_DETAIL_MANUAL) {
float object_space_constant_detail = 1.0f / (brush->cached_dyntopo.constant_detail *
mat4_to_scale(ob->obmat));
BKE_pbvh_bmesh_detail_size_set(
ss->pbvh, object_space_constant_detail, brush->cached_dyntopo.detail_range);
}
else if (sd->flags & SCULPT_DYNTOPO_DETAIL_BRUSH) {
BKE_pbvh_bmesh_detail_size_set(ss->pbvh, ss->cache->radius * sd->detail_percent / 100.0f);
else if (brush->cached_dyntopo.mode == DYNTOPO_DETAIL_BRUSH) {
BKE_pbvh_bmesh_detail_size_set(ss->pbvh,
ss->cache->radius * brush->cached_dyntopo.detail_percent /
100.0f,
brush->cached_dyntopo.detail_range);
}
else {
BKE_pbvh_bmesh_detail_size_set(ss->pbvh,
(ss->cache->radius / ss->cache->dyntopo_pixel_radius) *
(sd->detail_size * U.pixelsize) / 0.4f);
(sd->detail_size * U.pixelsize) / 0.4f,
brush->cached_dyntopo.detail_range);
}
if (SCULPT_stroke_is_dynamic_topology(ss, brush)) {

View File

@ -110,7 +110,7 @@ static int sculpt_detail_flood_fill_exec(bContext *C, wmOperator *UNUSED(op))
/* Update topology size. */
float object_space_constant_detail = 1.0f / (sd->constant_detail * mat4_to_scale(ob->obmat));
BKE_pbvh_bmesh_detail_size_set(ss->pbvh, object_space_constant_detail);
BKE_pbvh_bmesh_detail_size_set(ss->pbvh, object_space_constant_detail, sd->detail_range);
SCULPT_undo_push_begin(ob, "Dynamic topology flood fill");
SCULPT_undo_push_node(ob, NULL, SCULPT_UNDO_COORDS);

View File

@ -111,6 +111,7 @@
\
.mtex = _DNA_DEFAULT_MTex, \
.mask_mtex = _DNA_DEFAULT_MTex, \
.dyntopo = {0.4f, 25.0f, 3.0f, DYNTOPO_COLLAPSE|DYNTOPO_SUBDIVIDE, DYNTOPO_DETAIL_RELATIVE, DYNTOPO_INHERIT_ALL}\
}
/** \} */

View File

@ -518,7 +518,6 @@ typedef enum eBrushUVSculptTool {
\
/* These brushes could handle dynamic topology, \ \
* but user feedback indicates it's better not to */ \
SCULPT_TOOL_SMOOTH, \
SCULPT_TOOL_VCOL_BOUNDARY, \
SCULPT_TOOL_MASK) == 0)
@ -619,6 +618,31 @@ enum {
PAINT_FALLOFF_SHAPE_TUBE = 1,
};
//dyntopo flags
//synced with PBVHTopologyUpdateMode
enum {
DYNTOPO_SUBDIVIDE = 1<<0,
DYNTOPO_COLLAPSE = 1<<1,
DYNTOPO_DISABLED = 1<<2
};
//dyntopo override flags, copies all flags from dyntopo flags
enum {
DYNTOPO_INHERIT_ALL = 1<<10,
DYNTOPO_INHERIT_DETAIL_RANGE = 1<<11,
DYNTOPO_INHERIT_DETAIL_PERCENT = 1<<12,
DYNTOPO_INHERIT_MODE = 1<<13,
DYNTOPO_INHERIT_CONSTANT_DETAIL = 1<<14
};
//dyntopo mode
enum {
DYNTOPO_DETAIL_RELATIVE = 0,
DYNTOPO_DETAIL_MANUAL = 1,
DYNTOPO_DETAIL_BRUSH = 2,
DYNTOPO_DETAIL_CONSTANT = 3
};
#define MAX_BRUSH_PIXEL_RADIUS 500
#define GP_MAX_BRUSH_PIXEL_RADIUS 1000

View File

@ -150,6 +150,14 @@ typedef struct BrushGpencilSettings {
struct Material *material;
} BrushGpencilSettings;
typedef struct DynTopoSettings {
float detail_range;
float detail_percent;
float constant_detail;
short flag, mode;
int inherit, _pad[1];
} DynTopoSettings;
typedef struct Brush {
ID id;
@ -374,6 +382,8 @@ typedef struct Brush {
float concave_mask_factor;
struct BrushGpencilSettings *gpencil_settings;
DynTopoSettings dyntopo, cached_dyntopo;
} Brush;
/* Struct to hold palette colors for sorting. */

View File

@ -983,6 +983,7 @@ typedef struct Sculpt {
/* Maximum edge length for dynamic topology sculpting (in pixels) */
float detail_size;
float detail_range;
/* Direction used for SCULPT_OT_symmetrize operator */
int symmetrize_direction;
@ -994,6 +995,7 @@ typedef struct Sculpt {
/** Constant detail resolution (Blender unit / constant_detail). */
float constant_detail;
float detail_percent;
int _pad[1];
struct Object *gravity_object;
} Sculpt;

View File

@ -342,6 +342,34 @@ static EnumPropertyItem rna_enum_gpencil_brush_vertex_icons_items[] = {
{GP_BRUSH_ICON_VERTEX_REPLACE, "REPLACE", ICON_BRUSH_MIX, "Replace", ""},
{0, NULL, 0, NULL, NULL},
};
static EnumPropertyItem rna_enum_brush_dyntopo_mode[] = {
{DYNTOPO_DETAIL_RELATIVE, "RELATIVE", ICON_NONE, "Relative", ""},
{DYNTOPO_DETAIL_CONSTANT, "CONSTANT", ICON_NONE, "Constant", ""},
{DYNTOPO_DETAIL_MANUAL, "MANUAL", ICON_NONE, "Manual", ""},
{DYNTOPO_DETAIL_BRUSH, "BRUSH", ICON_NONE, "Brush", ""},
{0, NULL, 0, NULL, NULL},
};
static EnumPropertyItem rna_enum_brush_dyntopo_flag[] = {
{DYNTOPO_SUBDIVIDE, "SUBDIVIDE", ICON_NONE, "Subdivide", ""},
{DYNTOPO_COLLAPSE, "COLLAPSE", ICON_NONE, "Collapse", ""},
{DYNTOPO_DISABLED, "DISABLED", ICON_NONE, "Disable", ""},
{0, NULL, 0, NULL, NULL},
};
static EnumPropertyItem rna_enum_brush_dyntopo_inherit[] = {
{DYNTOPO_SUBDIVIDE, "SUBDIVIDE", ICON_NONE, "Subdivide", ""},
{DYNTOPO_COLLAPSE, "COLLAPSE", ICON_NONE, "Collapse", ""},
{DYNTOPO_DISABLED, "DISABLED", ICON_NONE, "Disable", ""},
{DYNTOPO_INHERIT_ALL, "ALL", ICON_NONE, "All", "Inherit All"},
{DYNTOPO_INHERIT_DETAIL_RANGE, "RANGE", ICON_NONE, "All", ""},
{DYNTOPO_INHERIT_DETAIL_PERCENT, "PERCENT", ICON_NONE, "Percent", ""},
{DYNTOPO_INHERIT_MODE, "MODE", ICON_NONE, "Mode", ""},
{DYNTOPO_INHERIT_CONSTANT_DETAIL, "CONSTANT_DETAIL", ICON_NONE, "Constant Detail", ""},
{0, NULL, 0, NULL, NULL},
};
#endif
#ifdef RNA_RUNTIME
@ -1134,6 +1162,45 @@ static void rna_def_brush_texture_slot(BlenderRNA *brna)
TEXTURE_CAPABILITY(has_texture_angle, "Has Texture Angle Source");
}
static void rna_def_dyntopo_settings(BlenderRNA *brna) {
StructRNA *srna;
PropertyRNA *prop;
srna = RNA_def_struct(brna, "DynTopoSettings", NULL);
RNA_def_struct_sdna(srna, "DynTopoSettings");
RNA_def_struct_ui_text(srna,
"Dyntopo Settings",
"");
prop = RNA_def_property(srna, "subdivide", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", DYNTOPO_SUBDIVIDE);
RNA_def_property_ui_icon(prop, ICON_NONE, 0);
RNA_def_property_ui_text(prop, "Subdivide", "Enable Dyntopo Subdivision");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, 0, "rna_Brush_update");
prop = RNA_def_property(srna, "disabled", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", DYNTOPO_DISABLED);
RNA_def_property_ui_icon(prop, ICON_NONE, 0);
RNA_def_property_ui_text(prop, "Disable", "Disable Dyntopo for this brush");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, 0, "rna_Brush_update");
prop = RNA_def_property(srna, "collapse", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", DYNTOPO_COLLAPSE);
RNA_def_property_ui_icon(prop, ICON_NONE, 0);
RNA_def_property_ui_text(prop, "Collapse", "Enable Dyntopo Decimation");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_update(prop, 0, "rna_Brush_update");
prop = RNA_def_property(srna, "inherit", PROP_ENUM, 0);
RNA_def_property_enum_sdna(prop, NULL, "inherit");
RNA_def_property_enum_items(prop, rna_enum_brush_dyntopo_inherit);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_flag(prop, PROP_ENUM_FLAG);
RNA_def_property_ui_text(prop, "Inherit", "Which default dyntopo settings to use");
}
static void rna_def_sculpt_capabilities(BlenderRNA *brna)
{
StructRNA *srna;
@ -3517,6 +3584,12 @@ static void rna_def_brush(BlenderRNA *brna)
RNA_def_property_pointer_sdna(prop, NULL, "gpencil_settings");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Gpencil Settings", "");
prop = RNA_def_property(srna, "dyntopo", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "DynTopoSettings");
RNA_def_property_pointer_sdna(prop, NULL, "dyntopo");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Dyntopo Settings", "");
}
/**
@ -3596,6 +3669,7 @@ static void rna_def_operator_stroke_element(BlenderRNA *brna)
void RNA_def_brush(BlenderRNA *brna)
{
rna_def_dyntopo_settings(brna);
rna_def_brush(brna);
rna_def_brush_capabilities(brna);
rna_def_sculpt_capabilities(brna);