Sculpt: brush input mapping improvements
* Input mappings now take a premultiply factor to scale the input data prior to evaluation; * Mapping data can also now be fed through a (wave) function prior to evaluation. * The UI now has seperate inputs and outputs sections for input mapping to avoid confusion. * Added a distance mapping and implemented the speed mapping. * Also fixed original data bug in color filter.
This commit is contained in:
parent
1e194722e5
commit
6777176691
|
@ -569,6 +569,13 @@ class UnifiedPaintPanel:
|
|||
|
||||
col.prop(mp, "factor")
|
||||
col.prop(mp, "blendmode")
|
||||
|
||||
col.label(text="Input Mapping")
|
||||
row = col.row()
|
||||
row.prop(mp, "premultiply")
|
||||
row.prop(mp, "mapfunc")
|
||||
|
||||
col.label(text="Output Mapping")
|
||||
row = col.row()
|
||||
row.prop(mp, "min")
|
||||
row.prop(mp, "max")
|
||||
|
|
|
@ -1144,7 +1144,12 @@ class VIEW3D_PT_sculpt_dyntopo(Panel, View3DPaintPanel):
|
|||
ch = UnifiedPaintPanel.get_channel(context, brush, "dyntopo_mode")
|
||||
|
||||
col2.use_property_split = False
|
||||
col2.prop_enum(ch, "flags_value", "CLEANUP", icon="CHECKBOX_HLT" if "CLEANUP" in ch.flags_value else "CHECKBOX_DEHLT")
|
||||
row2 = col2.row()
|
||||
row2.prop_enum(ch, "flags_value", "CLEANUP", icon="CHECKBOX_HLT" if "CLEANUP" in ch.flags_value else "CHECKBOX_DEHLT")
|
||||
|
||||
row3 = row2.row()
|
||||
row3.enabled = "COLLAPSE" not in ch.flags_value
|
||||
row3.prop_enum(ch, "flags_value", "LOCAL_COLLAPSE", icon="CHECKBOX_HLT" if "LOCAL_COLLAPSE" in ch.flags_value else "CHECKBOX_DEHLT")
|
||||
|
||||
"""
|
||||
UnifiedPaintPanel.channel_unified(
|
||||
|
@ -1250,7 +1255,20 @@ class VIEW3D_PT_sculpt_options(Panel, View3DPaintPanel):
|
|||
brush,
|
||||
"smooth_strength_projection", ui_editing=False, slider=True)
|
||||
|
||||
#col.prop(sculpt, "smooth_strength_factor")
|
||||
"""
|
||||
smoothbrush = None
|
||||
|
||||
for ts in sculpt.tool_slots:
|
||||
if ts.brush and ts.brush.sculpt_tool == "SMOOTH":
|
||||
smoothbrush = ts.brush
|
||||
break
|
||||
|
||||
if smoothbrush:
|
||||
UnifiedPaintPanel.channel_unified(layout.column(),
|
||||
context,
|
||||
smoothbrush,
|
||||
"dyntopo_disabled", ui_editing=False, text="Disable Dyntopo For Smooth")
|
||||
"""
|
||||
|
||||
col.separator()
|
||||
|
||||
|
|
|
@ -110,11 +110,11 @@ typedef struct BrushMappingDef {
|
|||
|
||||
typedef struct BrushMappingPreset {
|
||||
// must match order of BRUSH_MAPPING_XXX enums
|
||||
struct BrushMappingDef pressure, xtilt, ytilt, angle, speed, random;
|
||||
struct BrushMappingDef pressure, xtilt, ytilt, angle, speed, random, stroke_t;
|
||||
} BrushMappingPreset;
|
||||
|
||||
typedef struct BrushMappingData {
|
||||
float pressure, xtilt, ytilt, angle, speed, random;
|
||||
float pressure, xtilt, ytilt, angle, speed, random, stroke_t;
|
||||
} BrushMappingData;
|
||||
|
||||
#define MAX_BRUSH_ENUM_DEF 32
|
||||
|
|
|
@ -262,7 +262,7 @@ places in rna_engine_codebase are relevent:
|
|||
{DYNTOPO_COLLAPSE, "COLLAPSE", "NONE", "Collapse", ""},
|
||||
{DYNTOPO_SUBDIVIDE, "SUBDIVIDE", "NONE", "Subdivide", ""},
|
||||
{DYNTOPO_CLEANUP, "CLEANUP", "NONE", "Cleanup", ""},
|
||||
{DYNTOPO_LOCAL_COLLAPSE, "LOCAL_COLLAPSE", "NONE", "Local Collapse", ""},
|
||||
{DYNTOPO_LOCAL_COLLAPSE, "LOCAL_COLLAPSE", "NONE", "Local Collapse", "Cleanup edges based on local edge lengths if collapse is off."},
|
||||
{DYNTOPO_LOCAL_SUBDIVIDE, "LOCAL_SUBDIVIDE", "NONE", "Local Subdivide", ""},
|
||||
{-1}
|
||||
})
|
||||
|
|
|
@ -448,6 +448,11 @@ void BKE_brush_channel_init(BrushChannel *ch, BrushChannelType *def)
|
|||
|
||||
mp->blendmode = !mdef->no_default ? MA_RAMP_MULT : mdef->blendmode;
|
||||
mp->factor = mdef->factor == 0.0f ? 1.0f : mdef->factor;
|
||||
mp->premultiply = 1.0f;
|
||||
|
||||
if (i == BRUSH_MAPPING_STROKE_T) {
|
||||
mp->mapfunc = BRUSH_MAPFUNC_COS;
|
||||
}
|
||||
|
||||
if (mdef->enabled) {
|
||||
mp->flag |= BRUSH_MAPPING_ENABLED;
|
||||
|
@ -946,10 +951,39 @@ double BKE_brush_channel_eval_mappings(BrushChannel *ch,
|
|||
continue;
|
||||
}
|
||||
|
||||
float inputf = ((float *)mapdata)[i];
|
||||
float inputf = ((float *)mapdata)[i] * mp->premultiply;
|
||||
|
||||
switch ((BrushMappingFunc)mp->mapfunc) {
|
||||
case BRUSH_MAPFUNC_NONE:
|
||||
break;
|
||||
case BRUSH_MAPFUNC_SQUARE:
|
||||
inputf -= floorf(inputf);
|
||||
inputf = (float)(inputf > 0.5f);
|
||||
break;
|
||||
case BRUSH_MAPFUNC_SAW:
|
||||
inputf -= floorf(inputf);
|
||||
break;
|
||||
case BRUSH_MAPFUNC_TENT:
|
||||
inputf -= floorf(inputf);
|
||||
inputf = 1.0f - fabs(inputf - 0.5f) * 2.0f;
|
||||
break;
|
||||
case BRUSH_MAPFUNC_COS:
|
||||
inputf = 1.0f - (cos(inputf * (float)M_PI * 2.0f) * 0.5f + 0.5f);
|
||||
break;
|
||||
case BRUSH_MAPFUNC_CUTOFF:
|
||||
/*Cutoff is meant to create a fadeout effect,
|
||||
which requires inverting the input. To avoid
|
||||
user confusion we just do it here instead of making
|
||||
them check the inverse checkbox.*/
|
||||
inputf = 1.0f - inputf;
|
||||
CLAMP(inputf, 0.0f, 1.0f);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (mp->flag & BRUSH_MAPPING_INVERT) {
|
||||
inputf = 1.0 - inputf;
|
||||
inputf = 1.0f - inputf;
|
||||
}
|
||||
|
||||
double f2 = (float)BKE_curvemapping_evaluateF(mp->curve, 0, inputf);
|
||||
|
@ -1774,6 +1808,14 @@ void BKE_brush_channelset_read(BlendDataReader *reader, BrushChannelSet *chset)
|
|||
|
||||
CurveMapping *curve = mp->curve;
|
||||
|
||||
if (mp->premultiply == 0.0f) {
|
||||
mp->premultiply = 1.0f;
|
||||
}
|
||||
|
||||
if (mp->factor == 0.0f) {
|
||||
mp->factor = 1.0f;
|
||||
}
|
||||
|
||||
if (mp->min == mp->max == 0.0f) {
|
||||
mp->max = 1.0f;
|
||||
}
|
||||
|
@ -1846,6 +1888,8 @@ const char *BKE_brush_mapping_type_to_str(BrushMappingType mapping)
|
|||
return "Y Tilt";
|
||||
case BRUSH_MAPPING_RANDOM:
|
||||
return "Random";
|
||||
case BRUSH_MAPPING_STROKE_T:
|
||||
return "Distance";
|
||||
case BRUSH_MAPPING_MAX:
|
||||
return "Error";
|
||||
}
|
||||
|
@ -1868,6 +1912,8 @@ const char *BKE_brush_mapping_type_to_typename(BrushMappingType mapping)
|
|||
return "YTILT";
|
||||
case BRUSH_MAPPING_RANDOM:
|
||||
return "RANDOM";
|
||||
case BRUSH_MAPPING_STROKE_T:
|
||||
return "DISTANCE";
|
||||
case BRUSH_MAPPING_MAX:
|
||||
return "Error";
|
||||
}
|
||||
|
|
|
@ -3858,6 +3858,11 @@ static BMVert *pbvh_bmesh_collapse_edge(PBVH *pbvh,
|
|||
copy_v3_v3(v_conn->co, co);
|
||||
}
|
||||
|
||||
if (!v_conn->e) {
|
||||
printf("%s: pbvh error, v_conn->e was null\n", __func__);
|
||||
return v_conn;
|
||||
}
|
||||
|
||||
e2 = v_conn->e;
|
||||
do {
|
||||
BMLoop *l = e2->l;
|
||||
|
|
|
@ -1901,6 +1901,11 @@ void BKE_pbvh_build_bmesh(PBVH *pbvh,
|
|||
BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
|
||||
BMLoop *l_iter = l_first;
|
||||
|
||||
// check for currupted faceset
|
||||
if (BM_ELEM_CD_GET_INT(f, pbvh->cd_faceset_offset) == 0) {
|
||||
BM_ELEM_CD_SET_INT(f, pbvh->cd_faceset_offset, 1);
|
||||
}
|
||||
|
||||
BB_reset((BB *)bbc);
|
||||
do {
|
||||
BB_expand((BB *)bbc, l_iter->v->co);
|
||||
|
@ -3119,11 +3124,11 @@ static void pbvh_bmesh_balance_tree(PBVH *pbvh)
|
|||
/* use higher threshold for the root node and its immediate children */
|
||||
switch (BLI_array_len(stack)) {
|
||||
case 0:
|
||||
factor = 0.75;
|
||||
factor = 0.5;
|
||||
break;
|
||||
case 1:
|
||||
case 2:
|
||||
factor = 0.5;
|
||||
factor = 0.2;
|
||||
break;
|
||||
default:
|
||||
factor = 0.2;
|
||||
|
@ -3138,7 +3143,12 @@ static void pbvh_bmesh_balance_tree(PBVH *pbvh)
|
|||
printf("factor: %.3f\n", factor);
|
||||
#endif
|
||||
|
||||
if (overlap > volume * factor) {
|
||||
bool bad = overlap > volume * factor;
|
||||
|
||||
bad |= child1->bm_faces && !BLI_table_gset_len(child1->bm_faces);
|
||||
bad |= child2->bm_faces && !BLI_table_gset_len(child2->bm_faces);
|
||||
|
||||
if (bad) {
|
||||
modified = true;
|
||||
printf(" DELETE! %.4f %.4f %d\n", overlap, volume, BLI_array_len(stack));
|
||||
|
||||
|
|
|
@ -1907,8 +1907,7 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
|
|||
BKE_brush_mapping_reset(ch, brush->sculpt_tool, BRUSH_MAPPING_PRESSURE);
|
||||
}
|
||||
|
||||
ch = (BrushChannel *)brush->channels->channels.first;
|
||||
for (; ch; ch = ch->next) {
|
||||
LISTBASE_FOREACH (BrushChannel *, ch, &brush->channels->channels) {
|
||||
if (!ch->mappings[BRUSH_MAPPING_RANDOM].factor) {
|
||||
ch->mappings[BRUSH_MAPPING_RANDOM].factor = 1.0f;
|
||||
}
|
||||
|
@ -1927,6 +1926,64 @@ void blo_do_versions_300(FileData *fd, Library *UNUSED(lib), Main *bmain)
|
|||
}
|
||||
}
|
||||
|
||||
if (!MAIN_VERSION_ATLEAST(bmain, 300, 38)) {
|
||||
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
||||
if (!scene->toolsettings || !scene->toolsettings->sculpt ||
|
||||
!scene->toolsettings->sculpt->channels) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Sculpt *sd = scene->toolsettings->sculpt;
|
||||
|
||||
LISTBASE_FOREACH (BrushChannel *, ch, &sd->channels->channels) {
|
||||
if (!ch->mappings[BRUSH_MAPPING_RANDOM].factor) {
|
||||
ch->mappings[BRUSH_MAPPING_RANDOM].factor = 1.0f;
|
||||
}
|
||||
|
||||
for (int i = 0; i < BRUSH_MAPPING_MAX; i++) {
|
||||
if (ch->mappings[i].premultiply == 0.0f) {
|
||||
ch->mappings[i].premultiply = 1.0f;
|
||||
}
|
||||
|
||||
if (ch->mappings[i].blendmode == MA_RAMP_BLEND) {
|
||||
ch->mappings[i].blendmode = MA_RAMP_MULT;
|
||||
}
|
||||
|
||||
if (ch->mappings[i].min == ch->mappings[i].max) {
|
||||
ch->mappings[i].min = 0.0f;
|
||||
ch->mappings[i].max = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
BrushMapping *mp = ch->mappings + BRUSH_MAPPING_STROKE_T;
|
||||
|
||||
mp->max = 1.0f;
|
||||
mp->factor = 1.0f;
|
||||
mp->blendmode = MA_RAMP_MULT;
|
||||
mp->mapfunc = BRUSH_MAPFUNC_COS;
|
||||
}
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
|
||||
if (!brush->channels) {
|
||||
continue;
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (BrushChannel *, ch, &brush->channels->channels) {
|
||||
for (int i = 0; i < BRUSH_MAPPING_MAX; i++) {
|
||||
ch->mappings[i].premultiply = 1.0f;
|
||||
}
|
||||
|
||||
BrushMapping *mp = ch->mappings + BRUSH_MAPPING_STROKE_T;
|
||||
|
||||
mp->blendmode = MA_RAMP_MULT;
|
||||
mp->max = 1.0f;
|
||||
mp->mapfunc = BRUSH_MAPFUNC_COS;
|
||||
mp->factor = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Versioning code until next subversion bump goes here.
|
||||
*
|
||||
|
|
|
@ -10932,6 +10932,12 @@ static void sculpt_update_cache_invariants(
|
|||
zero_v2(cache->initial_mouse);
|
||||
}
|
||||
|
||||
/* initialize speed moving average */
|
||||
for (int i = 0; i < SCULPT_SPEED_MA_SIZE; i++) {
|
||||
cache->speed_avg[i] = -1.0f;
|
||||
}
|
||||
cache->last_speed_time = PIL_check_seconds_timer();
|
||||
|
||||
copy_v3_v3(cache->initial_location, ss->cursor_location);
|
||||
copy_v3_v3(cache->true_initial_location, ss->cursor_location);
|
||||
|
||||
|
@ -11354,6 +11360,37 @@ static void sculpt_update_cache_paint_variants(StrokeCache *cache, const Brush *
|
|||
}
|
||||
}
|
||||
|
||||
static float sculpt_update_speed_average(SculptSession *ss, float speed)
|
||||
{
|
||||
int tot = 0.0;
|
||||
bool found = false;
|
||||
|
||||
for (int i = 0; i < SCULPT_SPEED_MA_SIZE; i++) {
|
||||
tot++;
|
||||
|
||||
if (ss->cache->speed_avg[i] == -1.0f) {
|
||||
ss->cache->speed_avg[i] = speed;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
ss->cache->speed_avg[ss->cache->speed_avg_cur] = speed;
|
||||
ss->cache->speed_avg_cur = (ss->cache->speed_avg_cur + 1) % SCULPT_SPEED_MA_SIZE;
|
||||
}
|
||||
|
||||
speed = 0.0f;
|
||||
tot = 0;
|
||||
for (int i = 0; i < SCULPT_SPEED_MA_SIZE; i++) {
|
||||
if (ss->cache->speed_avg[i] != -1.0f) {
|
||||
speed += ss->cache->speed_avg[i];
|
||||
tot++;
|
||||
}
|
||||
}
|
||||
|
||||
return speed / (float)tot;
|
||||
}
|
||||
/* Initialize the stroke cache variants from operator properties. */
|
||||
static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, PointerRNA *ptr)
|
||||
{
|
||||
|
@ -11369,10 +11406,22 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, Po
|
|||
RNA_float_get_array(ptr, "location", cache->true_location);
|
||||
}
|
||||
|
||||
float last_mouse[2];
|
||||
copy_v2_v2(last_mouse, cache->mouse);
|
||||
|
||||
cache->pen_flip = RNA_boolean_get(ptr, "pen_flip");
|
||||
RNA_float_get_array(ptr, "mouse", cache->mouse);
|
||||
RNA_float_get_array(ptr, "mouse_event", cache->mouse_event);
|
||||
|
||||
float delta_mouse[2];
|
||||
|
||||
sub_v3_v3v3(delta_mouse, cache->mouse, cache->mouse_event);
|
||||
float speed = len_v3(delta_mouse) / (800000.0f); /*get a reasonably usable value*/
|
||||
speed /= PIL_check_seconds_timer() - cache->last_speed_time;
|
||||
|
||||
cache->input_mapping.speed = sculpt_update_speed_average(ss, speed);
|
||||
cache->last_speed_time = PIL_check_seconds_timer();
|
||||
|
||||
/* XXX: Use pressure value from first brush step for brushes which don't support strokes (grab,
|
||||
* thumb). They depends on initial state and brush coord/pressure/etc.
|
||||
* It's more an events design issue, which doesn't split coordinate/pressure/angle changing
|
||||
|
@ -11408,7 +11457,6 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, Po
|
|||
mul_v4_m4v4(direction, cache->projection_mat, direction);
|
||||
|
||||
cache->input_mapping.angle = (atan2(direction[1], direction[0]) / (float)M_PI) * 0.5 + 0.5;
|
||||
|
||||
// cache->vc
|
||||
}
|
||||
|
||||
|
@ -11481,8 +11529,10 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, Po
|
|||
}
|
||||
|
||||
cache->special_rotation = ups->brush_rotation;
|
||||
|
||||
cache->iteration_count++;
|
||||
|
||||
cache->input_mapping.stroke_t = cache->stroke_distance_t /
|
||||
10.0f; /*scale to a more user-friendly value*/
|
||||
}
|
||||
|
||||
/* Returns true if any of the smoothing modes are active (currently
|
||||
|
|
|
@ -299,6 +299,9 @@ static int sculpt_color_filter_invoke(bContext *C, wmOperator *op, const wmEvent
|
|||
const bool needs_topology_info = mode == COLOR_FILTER_SMOOTH || use_automasking;
|
||||
BKE_sculpt_update_object_for_edit(depsgraph, ob, needs_topology_info, false, true);
|
||||
|
||||
/*flag update for original data*/
|
||||
ss->stroke_id++;
|
||||
|
||||
if (BKE_pbvh_type(pbvh) == PBVH_FACES && needs_topology_info && !ob->sculpt->pmap) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
|
|
@ -1187,6 +1187,7 @@ bool SCULPT_pbvh_calc_area_normal(const struct Brush *brush,
|
|||
*/
|
||||
|
||||
#define SCULPT_CLAY_STABILIZER_LEN 10
|
||||
#define SCULPT_SPEED_MA_SIZE 4
|
||||
|
||||
typedef struct AutomaskingSettings {
|
||||
/* Flags from eAutomasking_flag. */
|
||||
|
@ -1399,6 +1400,9 @@ typedef struct StrokeCache {
|
|||
bool use_plane_trim;
|
||||
|
||||
struct NeighborCache *ncache;
|
||||
float speed_avg[SCULPT_SPEED_MA_SIZE]; // moving average for speed
|
||||
int speed_avg_cur;
|
||||
double last_speed_time;
|
||||
} StrokeCache;
|
||||
|
||||
/* Sculpt Filters */
|
||||
|
|
|
@ -40,6 +40,8 @@ typedef struct BrushMapping {
|
|||
int flag, type;
|
||||
|
||||
float min, max;
|
||||
float premultiply; // premultiply input data
|
||||
int mapfunc;
|
||||
} BrushMapping;
|
||||
|
||||
typedef struct BrushCurve {
|
||||
|
@ -61,7 +63,7 @@ typedef struct BrushChannel {
|
|||
float vector[4];
|
||||
BrushCurve curve;
|
||||
|
||||
BrushMapping mappings[6]; // should always be BRUSH_MAPPING_MAX
|
||||
BrushMapping mappings[7]; // should always be BRUSH_MAPPING_MAX
|
||||
|
||||
short type, ui_order;
|
||||
int flag;
|
||||
|
@ -83,6 +85,16 @@ enum {
|
|||
BRUSH_MAPPING_INHERIT = 1 << 3, // inherit mapping even if channel overall is not inherited
|
||||
};
|
||||
|
||||
// BrushMapping->mapfunc
|
||||
typedef enum {
|
||||
BRUSH_MAPFUNC_NONE,
|
||||
BRUSH_MAPFUNC_SAW,
|
||||
BRUSH_MAPFUNC_TENT,
|
||||
BRUSH_MAPFUNC_COS,
|
||||
BRUSH_MAPFUNC_CUTOFF,
|
||||
BRUSH_MAPFUNC_SQUARE,
|
||||
} BrushMappingFunc;
|
||||
|
||||
// mapping types
|
||||
typedef enum {
|
||||
BRUSH_MAPPING_PRESSURE = 0,
|
||||
|
@ -91,7 +103,8 @@ typedef enum {
|
|||
BRUSH_MAPPING_ANGLE = 3,
|
||||
BRUSH_MAPPING_SPEED = 4,
|
||||
BRUSH_MAPPING_RANDOM = 5,
|
||||
BRUSH_MAPPING_MAX = 6 // see BrushChannel.mappings
|
||||
BRUSH_MAPPING_STROKE_T = 6,
|
||||
BRUSH_MAPPING_MAX = 7 // see BrushChannel.mappings
|
||||
} BrushMappingType;
|
||||
|
||||
#ifndef __GNUC__
|
||||
|
|
|
@ -647,6 +647,7 @@ static EnumPropertyItem mapping_type_items[] = {
|
|||
{BRUSH_MAPPING_ANGLE, "ANGLE", ICON_NONE, "Angle"},
|
||||
{BRUSH_MAPPING_SPEED, "SPEED", ICON_NONE, "Speed"},
|
||||
{BRUSH_MAPPING_RANDOM, "RANDOM", ICON_NONE, "Random"},
|
||||
{BRUSH_MAPPING_STROKE_T, "DISTANCE", ICON_NONE, "Distance"},
|
||||
{0, NULL, 0, NULL, NULL},
|
||||
};
|
||||
|
||||
|
@ -664,6 +665,13 @@ void RNA_def_brush_mapping(BlenderRNA *brna)
|
|||
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
|
||||
RNA_def_property_ui_text(prop, "Factor", "Mapping factor");
|
||||
|
||||
prop = RNA_def_property(srna, "premultiply", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, "BrushMapping", "premultiply");
|
||||
RNA_def_property_range(prop, -100000, 100000);
|
||||
RNA_def_property_ui_range(prop, -100, 100, 0.01, 3);
|
||||
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
|
||||
RNA_def_property_ui_text(prop, "Pre-Multiply", "Multiply input data by this amount");
|
||||
|
||||
prop = RNA_def_property(srna, "min", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, "BrushMapping", "min");
|
||||
RNA_def_property_range(prop, -100000, 100000);
|
||||
|
@ -723,6 +731,20 @@ void RNA_def_brush_mapping(BlenderRNA *brna)
|
|||
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
|
||||
RNA_def_property_ui_text(prop, "Blend Mode", "Input mapping blend mode");
|
||||
|
||||
static EnumPropertyItem mapfunc_items[] = {
|
||||
{BRUSH_MAPFUNC_NONE, "NONE", ICON_NONE, "None", "Pass data through unmodified"},
|
||||
{BRUSH_MAPFUNC_SQUARE, "SQUARE", ICON_NONE, "Square", "Square wave"},
|
||||
{BRUSH_MAPFUNC_SAW, "SAW", ICON_NONE, "Saw", "Sawtooth wave"},
|
||||
{BRUSH_MAPFUNC_TENT, "TENT", ICON_NONE, "Tent", "Tent wave"},
|
||||
{BRUSH_MAPFUNC_COS, "COS", ICON_NONE, "Cos", "Cosine wave"},
|
||||
{BRUSH_MAPFUNC_CUTOFF, "CUTOFF", ICON_NONE, "Cutoff", "Inverts data and cuts off at 1.0"},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
prop = RNA_def_property(srna, "mapfunc", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, mapfunc_items);
|
||||
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
|
||||
RNA_def_property_ui_text(prop, "Function", "Input data function");
|
||||
|
||||
prop = RNA_def_property(srna, "ui_expanded", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, "BrushMapping", "flag", BRUSH_MAPPING_UI_EXPANDED);
|
||||
RNA_def_property_override_flag(prop, PROPOVERRIDE_OVERRIDABLE_LIBRARY);
|
||||
|
|
Loading…
Reference in New Issue