Sculpt-dev: Use brush curve presets for device curves
* Brush mapping (device) curves now use the BrushCurve API. This prevents having to save a CurveMapping instance for every single device mapping (of which there is ~5 or so) in every single channel (>40) for every single brush (~40-70). * Fixed regression where temporary attributes weren't being stripped on file save in all cases.
This commit is contained in:
parent
ca8f30d54e
commit
cfc46e43b2
|
@ -468,6 +468,7 @@ class DATA_PT_customdata(MeshButtonsPanel, Panel):
|
|||
|
||||
col.operator("mesh.customdata_mask_clear", icon='X')
|
||||
col.operator("mesh.customdata_skin_clear", icon='X')
|
||||
col.operator("mesh.customdata_ids_clear", icon='X')
|
||||
|
||||
if me.has_custom_normals:
|
||||
col.operator("mesh.customdata_custom_splitnormals_clear", icon='X')
|
||||
|
|
|
@ -659,13 +659,9 @@ class UnifiedPaintPanel:
|
|||
#here?
|
||||
box = layout.box()
|
||||
|
||||
box.template_curve_mapping(mp, "curve", brush=True, use_negative_slope=True)
|
||||
|
||||
col = box.column(align=True)
|
||||
col.use_property_split = True
|
||||
col.use_property_decorate = False
|
||||
|
||||
row = col.row(align=True)
|
||||
|
||||
if mp0.inherit_mode == "ALWAYS" or (mp0.inherit_mode == "USE_CHANNEL" and ch.inherits):
|
||||
path2 = path + ".mappings[\"%s\"].curve" % (mp.type)
|
||||
|
@ -673,13 +669,21 @@ class UnifiedPaintPanel:
|
|||
brushpath = "tool_settings.sculpt.brush.channels[\"%s\"]" % ch.idname
|
||||
path2 = brushpath + ".mappings[\"%s\"].curve" % (mp.type)
|
||||
|
||||
shapes = ['SMOOTH', 'ROUND', 'ROOT', 'SHARP', 'LINE', 'MAX']
|
||||
icons = ['SMOOTHCURVE', 'SPHERECURVE', 'ROOTCURVE', 'SHARPCURVE', 'LINCURVE', 'NOCURVE']
|
||||
|
||||
for i, shape in enumerate(shapes):
|
||||
props = row.operator("brush.curve_preset_load", icon=icons[i], text="")
|
||||
props.shape = shape
|
||||
props.path = path2
|
||||
col.prop(mp.curve, "curve_preset", text=text)
|
||||
|
||||
row = col.row(align=True)
|
||||
|
||||
if not header and mp.curve.curve_preset == "CUSTOM":
|
||||
template_curve(col, mp.curve, "curve", path2 + ".curve", use_negative_slope=True)
|
||||
|
||||
shapes = ['SMOOTH', 'ROUND', 'ROOT', 'SHARP', 'LINE', 'MAX']
|
||||
icons = ['SMOOTHCURVE', 'SPHERECURVE', 'ROOTCURVE', 'SHARPCURVE', 'LINCURVE', 'NOCURVE']
|
||||
|
||||
for i, shape in enumerate(shapes):
|
||||
props = row.operator("brush.curve_preset_load", icon=icons[i], text="")
|
||||
props.shape = shape
|
||||
props.path = path2 + ".curve"
|
||||
|
||||
col.prop(mp, "factor")
|
||||
col.prop(mp, "blendmode")
|
||||
|
|
|
@ -348,7 +348,7 @@ bool BKE_brush_channelset_set_int(BrushChannelSet *chset, const char *idname, in
|
|||
void BKE_brush_channel_set_int(BrushChannel *ch, int val);
|
||||
|
||||
/* mapdata may be NULL */
|
||||
float BKE_brush_channel_get_int(BrushChannel *ch, BrushMappingData *mapdata);
|
||||
int BKE_brush_channel_get_int(BrushChannel *ch, BrushMappingData *mapdata);
|
||||
|
||||
/* mapdata may be NULL */
|
||||
float BKE_brush_channel_get_float(BrushChannel *ch, BrushMappingData *mapdata);
|
||||
|
|
|
@ -296,10 +296,8 @@ template<typename T> class BrushChannelIF {
|
|||
inputf = 1.0f - inputf;
|
||||
}
|
||||
|
||||
/* ensure curve tables exist */
|
||||
BKE_curvemapping_init(mp->curve);
|
||||
|
||||
double f2 = (float)BKE_curvemapping_evaluateF(mp->curve, 0, inputf);
|
||||
double f2 = BKE_brush_curve_strength_ex(
|
||||
mp->mapping_curve.preset, mp->mapping_curve.curve, inputf, 1.0f);
|
||||
f2 = mp->min + (mp->max - mp->min) * f2;
|
||||
|
||||
/* make sure to update blend_items in rna_brush_engine.c
|
||||
|
|
|
@ -125,14 +125,36 @@ void BKE_brush_channel_system_exit()
|
|||
{
|
||||
BKE_curvemapping_cache_free(brush_curve_cache);
|
||||
}
|
||||
// returns true if curve was duplicated
|
||||
bool BKE_brush_mapping_ensure_write(BrushMapping *mp)
|
||||
{
|
||||
if (IS_CACHE_CURVE(mp->curve)) {
|
||||
CurveMapping *newcurve = BKE_curvemapping_copy(mp->curve);
|
||||
RELEASE_CACHE_CURVE(mp->curve);
|
||||
|
||||
mp->curve = newcurve;
|
||||
/* returns true if curve was duplicated or initialized. */
|
||||
ATTR_NO_OPT bool BKE_brush_mapping_ensure_write(BrushMapping *mp)
|
||||
{
|
||||
|
||||
if (mp->mapping_curve.curve && IS_CACHE_CURVE(mp->mapping_curve.curve)) {
|
||||
CurveMapping *newcurve = BKE_curvemapping_copy(mp->mapping_curve.curve);
|
||||
RELEASE_CACHE_CURVE(mp->mapping_curve.curve);
|
||||
|
||||
mp->mapping_curve.curve = newcurve;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
if (mp->mapping_curve.preset != BRUSH_CURVE_CUSTOM) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!mp->mapping_curve.curve) {
|
||||
CurveMapping *curve = mp->mapping_curve.curve = MEM_callocN(sizeof(CurveMapping),
|
||||
"brsh mapping curve");
|
||||
|
||||
BKE_curvemapping_set_defaults(curve, 1, 0, 0.0f, 1, 1.0f);
|
||||
|
||||
BKE_curvemap_reset(curve->cm,
|
||||
&(struct rctf){.xmin = 0.0f, .ymin = 0.0f, .xmax = 1.0f, .ymax = 1.0f},
|
||||
CURVE_PRESET_LINE,
|
||||
CURVEMAP_SLOPE_POSITIVE);
|
||||
|
||||
BKE_curvemapping_init(curve);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -176,7 +198,11 @@ bool BKE_brush_channel_curve_ensure_write(BrushCurve *curve)
|
|||
|
||||
static bool check_corrupted_curve(BrushMapping *dst)
|
||||
{
|
||||
CurveMapping *curve = dst->curve;
|
||||
CurveMapping *curve = dst->mapping_curve.curve;
|
||||
|
||||
if (!curve) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (BKE_curvemapping_in_cache(curve)) {
|
||||
return false;
|
||||
|
@ -189,15 +215,16 @@ static bool check_corrupted_curve(BrushMapping *dst)
|
|||
if (clip_size_x == 0.0f || clip_size_y == 0.0f) {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
BKE_curvemapping_free_data(curve);
|
||||
memset(&dst->curve, 0, sizeof(CurveMapping));
|
||||
|
||||
BKE_curvemapping_set_defaults(dst->curve, 1, 0.0, 0.0, 1.0, 1.0);
|
||||
memset(&dst->mapping_curve.curve, 0, sizeof(CurveMapping));
|
||||
|
||||
BKE_curvemapping_set_defaults(dst->mapping_curve.curve, 1, 0.0, 0.0, 1.0, 1.0);
|
||||
|
||||
BKE_curvemap_reset(curve->cm + i,
|
||||
&(struct rctf){.xmin = 0, .ymin = 0.0, .xmax = 1.0, .ymax = 1.0},
|
||||
CURVE_PRESET_LINE,
|
||||
1);
|
||||
BKE_curvemapping_init(dst->curve);
|
||||
BKE_curvemapping_init(dst->mapping_curve.curve);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -271,7 +298,9 @@ void BKE_brush_channel_free_data(BrushChannel *ch)
|
|||
for (int i = 0; i < BRUSH_MAPPING_MAX; i++) {
|
||||
BrushMapping *mp = ch->mappings + i;
|
||||
|
||||
RELEASE_OR_FREE_CURVE(mp->curve);
|
||||
if (mp->mapping_curve.curve) {
|
||||
RELEASE_OR_FREE_CURVE(mp->mapping_curve.curve);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -402,18 +431,18 @@ void BKE_brush_channel_copy_data(BrushChannel *dst,
|
|||
for (int i = 0; i < BRUSH_MAPPING_MAX; i++) {
|
||||
BrushMapping *mp = dst->mappings + i;
|
||||
|
||||
if (!mp->curve) {
|
||||
if (!mp->mapping_curve.curve) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (IS_CACHE_CURVE(mp->curve)) {
|
||||
RELEASE_CACHE_CURVE(mp->curve);
|
||||
if (IS_CACHE_CURVE(mp->mapping_curve.curve)) {
|
||||
RELEASE_CACHE_CURVE(mp->mapping_curve.curve);
|
||||
}
|
||||
else {
|
||||
BKE_curvemapping_free(mp->curve);
|
||||
BKE_curvemapping_free(mp->mapping_curve.curve);
|
||||
}
|
||||
|
||||
mp->curve = NULL;
|
||||
mp->mapping_curve.curve = NULL;
|
||||
}
|
||||
|
||||
// preserve linked list pointers
|
||||
|
@ -455,7 +484,7 @@ void BKE_brush_channel_copy_data(BrushChannel *dst,
|
|||
namestack_push(__func__);
|
||||
|
||||
for (int i = 0; i < BRUSH_MAPPING_MAX; i++) {
|
||||
dst->mappings[i].curve = NULL;
|
||||
dst->mappings[i].mapping_curve.curve = NULL;
|
||||
|
||||
BKE_brush_mapping_copy_data(dst->mappings + i, src->mappings + i);
|
||||
dst->mappings[i].type = i;
|
||||
|
@ -490,12 +519,10 @@ void BKE_brush_channel_init(BrushChannel *ch, BrushChannelType *def)
|
|||
for (int i = 0; i < BRUSH_MAPPING_MAX; i++) {
|
||||
BrushMapping *mp = ch->mappings + i;
|
||||
|
||||
if (mp->curve) {
|
||||
RELEASE_OR_FREE_CURVE(mp->curve);
|
||||
if (mp->mapping_curve.curve) {
|
||||
RELEASE_OR_FREE_CURVE(mp->mapping_curve.curve);
|
||||
}
|
||||
|
||||
CurveMapping *curve = mp->curve = (CurveMapping *)MEM_callocN(sizeof(*curve),
|
||||
"CurveMapping for BrushMapping");
|
||||
mp->type = i;
|
||||
|
||||
float min, max;
|
||||
|
@ -519,22 +546,30 @@ void BKE_brush_channel_init(BrushChannel *ch, BrushChannelType *def)
|
|||
mp->inherit_mode = BRUSH_MAPPING_INHERIT_ALWAYS;
|
||||
}
|
||||
|
||||
int slope = CURVEMAP_SLOPE_POSITIVE;
|
||||
|
||||
BKE_curvemapping_set_defaults(curve, 1, 0, 0.0f, 1, 1.0f);
|
||||
|
||||
for (int j = 0; j < 1; j++) {
|
||||
BKE_curvemap_reset(&curve->cm[j],
|
||||
&(struct rctf){.xmin = 0.0f, .ymin = 0.0f, .xmax = 1.0f, .ymax = 1.0f},
|
||||
mdef->curve,
|
||||
slope);
|
||||
}
|
||||
|
||||
BKE_curvemapping_init(curve);
|
||||
|
||||
mp->min = min;
|
||||
mp->max = max;
|
||||
mp->curve = GET_CACHE_CURVE(curve); // frees curve and returns cached copy
|
||||
|
||||
if (mdef->curve != CURVE_PRESET_LINE) {
|
||||
mp->mapping_curve.preset = BRUSH_CURVE_CUSTOM;
|
||||
BKE_brush_mapping_ensure_write(mp);
|
||||
|
||||
mp->mapping_curve.curve = MEM_callocN(sizeof(CurveMapping), "CurveMapping");
|
||||
|
||||
BKE_curvemapping_set_defaults(mp->mapping_curve.curve, 1, 0, 0.0f, 1, 1.0f);
|
||||
|
||||
BKE_curvemap_reset(mp->mapping_curve.curve->cm,
|
||||
&(struct rctf){.xmin = 0.0f, .ymin = 0.0f, .xmax = 1.0f, .ymax = 1.0f},
|
||||
mdef->curve,
|
||||
CURVEMAP_SLOPE_POSITIVE);
|
||||
|
||||
BKE_curvemapping_init(mp->mapping_curve.curve);
|
||||
|
||||
mp->mapping_curve.curve = GET_CACHE_CURVE(
|
||||
mp->mapping_curve.curve); /* Frees original curve */
|
||||
}
|
||||
else {
|
||||
mp->mapping_curve.preset = BRUSH_CURVE_LIN;
|
||||
}
|
||||
|
||||
mp->blendmode = !mdef->no_default ? MA_RAMP_MULT : mdef->blendmode;
|
||||
mp->factor = mdef->factor == 0.0f ? 1.0f : mdef->factor;
|
||||
|
@ -1040,10 +1075,10 @@ static bool channel_has_mappings(BrushChannel *ch)
|
|||
}
|
||||
|
||||
/* idx is used by vector channels */
|
||||
double BKE_brush_channel_eval_mappings(BrushChannel *ch,
|
||||
BrushMappingData *mapdata,
|
||||
double f,
|
||||
int idx)
|
||||
ATTR_NO_OPT double BKE_brush_channel_eval_mappings(BrushChannel *ch,
|
||||
BrushMappingData *mapdata,
|
||||
double f,
|
||||
int idx)
|
||||
{
|
||||
|
||||
if (idx == 3 && !(ch->flag & BRUSH_CHANNEL_APPLY_MAPPING_TO_ALPHA)) {
|
||||
|
@ -1095,10 +1130,8 @@ double BKE_brush_channel_eval_mappings(BrushChannel *ch,
|
|||
inputf = 1.0f - inputf;
|
||||
}
|
||||
|
||||
/* ensure curve tables exist */
|
||||
BKE_curvemapping_init(mp->curve);
|
||||
|
||||
double f2 = (float)BKE_curvemapping_evaluateF(mp->curve, 0, inputf);
|
||||
double f2 = BKE_brush_curve_strength_ex(
|
||||
mp->mapping_curve.preset, mp->mapping_curve.curve, inputf, 1.0f);
|
||||
f2 = mp->min + (mp->max - mp->min) * f2;
|
||||
|
||||
/* make sure to update blend_items in rna_brush_engine.c
|
||||
|
@ -1153,7 +1186,7 @@ int BKE_brush_channelset_get_int(BrushChannelSet *chset,
|
|||
return BKE_brush_channel_get_int(ch, mapdata);
|
||||
}
|
||||
|
||||
float BKE_brush_channel_get_int(BrushChannel *ch, BrushMappingData *mapdata)
|
||||
int BKE_brush_channel_get_int(BrushChannel *ch, BrushMappingData *mapdata)
|
||||
{
|
||||
|
||||
if (channel_has_mappings(ch)) {
|
||||
|
@ -1854,7 +1887,7 @@ void BKE_builtin_commandlist_create(Brush *brush,
|
|||
/* Build dyntopo command. */
|
||||
if (tool == SCULPT_TOOL_SNAKE_HOOK) {
|
||||
/* Add twice for snake hook. */
|
||||
commandlist_add_dyntopo(chset, cl, brush, tool, hard_edge_mode, radius*1.25);
|
||||
commandlist_add_dyntopo(chset, cl, brush, tool, hard_edge_mode, radius * 1.25);
|
||||
commandlist_add_dyntopo(chset, cl, brush, tool, hard_edge_mode, radius * 1.25);
|
||||
}
|
||||
else {
|
||||
|
@ -1991,7 +2024,7 @@ void BKE_brush_channelset_foreach_id(void *userdata,
|
|||
// for now, do nothing; in the future brush textures (might) have ID references
|
||||
}
|
||||
|
||||
void BKE_brush_channelset_read(BlendDataReader *reader, BrushChannelSet *chset)
|
||||
ATTR_NO_OPT void BKE_brush_channelset_read(BlendDataReader *reader, BrushChannelSet *chset)
|
||||
{
|
||||
BLO_read_list(reader, &chset->channels);
|
||||
|
||||
|
@ -2015,10 +2048,6 @@ void BKE_brush_channelset_read(BlendDataReader *reader, BrushChannelSet *chset)
|
|||
for (int i = 0; i < BRUSH_MAPPING_MAX; i++) {
|
||||
BrushMapping *mp = ch->mappings + i;
|
||||
|
||||
BLO_read_data_address(reader, &mp->curve);
|
||||
|
||||
CurveMapping *curve = mp->curve;
|
||||
|
||||
if (mp->premultiply_factor == 0.0f) {
|
||||
mp->premultiply_factor = 1.0f;
|
||||
}
|
||||
|
@ -2035,25 +2064,56 @@ void BKE_brush_channelset_read(BlendDataReader *reader, BrushChannelSet *chset)
|
|||
mp->max = 1.0f;
|
||||
}
|
||||
|
||||
if (curve) {
|
||||
BLO_read_data_address(reader, &mp->curve);
|
||||
BLO_read_data_address(reader, &mp->mapping_curve.curve);
|
||||
|
||||
/* Handle olf files. */
|
||||
if (mp->curve) {
|
||||
BKE_curvemapping_blend_read(reader, mp->curve);
|
||||
BKE_curvemapping_init(mp->curve);
|
||||
|
||||
/* Make a linear curve for comparison. */
|
||||
CurveMapping linear_curve = {0};
|
||||
|
||||
BKE_curvemapping_set_defaults(&linear_curve, 1, 0, 0.0f, 1, 1.0f);
|
||||
|
||||
BKE_curvemap_reset(linear_curve.cm,
|
||||
&(struct rctf){.xmin = 0.0f, .ymin = 0.0f, .xmax = 1.0f, .ymax = 1.0f},
|
||||
CURVE_PRESET_LINE,
|
||||
CURVEMAP_SLOPE_POSITIVE);
|
||||
|
||||
BKE_curvemapping_init(&linear_curve);
|
||||
|
||||
/* Only convert curve if it's not linear. */
|
||||
if (!BKE_curvemapping_equals(mp->curve, &linear_curve)) {
|
||||
mp->mapping_curve.preset = BRUSH_CURVE_CUSTOM;
|
||||
mp->mapping_curve.curve = GET_CACHE_CURVE(mp->curve);
|
||||
}
|
||||
else {
|
||||
mp->mapping_curve.preset = BRUSH_CURVE_LIN;
|
||||
|
||||
BKE_curvemapping_free_data(mp->curve);
|
||||
MEM_freeN(mp->curve);
|
||||
}
|
||||
|
||||
mp->curve = NULL;
|
||||
BKE_curvemapping_free_data(&linear_curve);
|
||||
}
|
||||
else if (mp->mapping_curve.curve) {
|
||||
CurveMapping *curve = mp->mapping_curve.curve;
|
||||
|
||||
BKE_curvemapping_blend_read(reader, curve);
|
||||
BKE_curvemapping_init(curve);
|
||||
|
||||
mp->mapping_curve.curve = GET_CACHE_CURVE(curve); /* Frees existing curve. */
|
||||
}
|
||||
else {
|
||||
curve = mp->curve = MEM_callocN(sizeof(CurveMapping), "CurveMapping");
|
||||
|
||||
BKE_curvemapping_set_defaults(curve, 1, 0.0f, 0.0f, 1.0f, 1.0f);
|
||||
BKE_curvemap_reset(curve->cm,
|
||||
&(struct rctf){.xmin = 0, .ymin = 0.0, .xmax = 1.0, .ymax = 1.0},
|
||||
CURVE_PRESET_LINE,
|
||||
!(mp->flag & BRUSH_MAPPING_INVERT));
|
||||
|
||||
BKE_curvemapping_init(curve);
|
||||
else if (mp->mapping_curve.preset ==
|
||||
BRUSH_CURVE_CUSTOM) { /* Ensure we have a curve instance. */
|
||||
BKE_brush_mapping_ensure_write(mp);
|
||||
mp->mapping_curve.curve = GET_CACHE_CURVE(mp->mapping_curve.curve);
|
||||
}
|
||||
|
||||
mp->curve = GET_CACHE_CURVE(curve); // frees curve, returns new one
|
||||
|
||||
// paranoia check to make sure BrushMapping.type is correct
|
||||
/* Paranoia check to make sure BrushMapping.type is correct. */
|
||||
mp->type = i;
|
||||
}
|
||||
|
||||
|
@ -2064,29 +2124,45 @@ void BKE_brush_channelset_read(BlendDataReader *reader, BrushChannelSet *chset)
|
|||
ch->def = BKE_brush_default_channel_def();
|
||||
}
|
||||
else {
|
||||
// ensure ->type is correct
|
||||
/* Ensure ->type is correct. */
|
||||
ch->type = ch->def->type;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_brush_channelset_write(BlendWriter *writer, BrushChannelSet *chset)
|
||||
ATTR_NO_OPT void BKE_brush_channelset_write(BlendWriter *writer, BrushChannelSet *chset)
|
||||
{
|
||||
BLO_write_struct(writer, BrushChannelSet, chset);
|
||||
BLO_write_struct_list(writer, BrushChannel, &chset->channels);
|
||||
/* Instantiate cached curves to ensure they get written
|
||||
* (and susequently read) seperately.
|
||||
*/
|
||||
|
||||
LISTBASE_FOREACH (BrushChannel *, ch, &chset->channels) {
|
||||
BKE_brush_channel_curve_ensure_write(&ch->curve);
|
||||
|
||||
BrushChannel *ch;
|
||||
for (ch = chset->channels.first; ch; ch = ch->next) {
|
||||
if (ch->curve.curve) {
|
||||
BKE_curvemapping_blend_write(writer, ch->curve.curve);
|
||||
}
|
||||
|
||||
for (int i = 0; i < BRUSH_MAPPING_MAX; i++) {
|
||||
/* instantiate cached curves to ensure they get written
|
||||
(and susequently read) seperately. */
|
||||
BKE_brush_mapping_ensure_write(ch->mappings + i);
|
||||
}
|
||||
}
|
||||
|
||||
BKE_curvemapping_blend_write(writer, ch->mappings[i].curve);
|
||||
BLO_write_struct(writer, BrushChannelSet, chset);
|
||||
|
||||
LISTBASE_FOREACH (BrushChannel *, ch, &chset->channels) {
|
||||
BLO_write_struct(writer, BrushChannel, ch);
|
||||
|
||||
if (ch->curve.curve) {
|
||||
BKE_curvemapping_blend_write(writer, ch->curve.curve);
|
||||
}
|
||||
|
||||
for (int i = 0; i < BRUSH_MAPPING_MAX; i++) {
|
||||
BrushMapping *mp = ch->mappings + i;
|
||||
|
||||
if (mp->mapping_curve.curve) {
|
||||
BKE_curvemapping_blend_write(writer, mp->mapping_curve.curve);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2141,19 +2217,23 @@ const char *BKE_brush_mapping_type_to_typename(eBrushMappingType mapping)
|
|||
|
||||
void BKE_brush_mapping_copy_data(BrushMapping *dst, BrushMapping *src)
|
||||
{
|
||||
RELEASE_OR_FREE_CURVE(dst->curve);
|
||||
if (src->mapping_curve.curve) {
|
||||
RELEASE_OR_FREE_CURVE(dst->mapping_curve.curve);
|
||||
|
||||
if (!IS_CACHE_CURVE(src->curve)) {
|
||||
// dst->curve = GET_CACHE_CURVE(src->curve);
|
||||
dst->mapping_curve = src->mapping_curve;
|
||||
|
||||
// hrm, let's not modify src->curve, GET_CACHE_CURVE might free it
|
||||
dst->curve = BKE_curvemapping_cache_get(brush_curve_cache, src->curve, false);
|
||||
}
|
||||
else {
|
||||
dst->curve = src->curve;
|
||||
CURVE_ADDREF(dst->curve);
|
||||
if (!IS_CACHE_CURVE(src->mapping_curve.curve)) {
|
||||
/* Remember that GET_CACHE_CURVE can free the input curve, call underlying API directly. */
|
||||
dst->mapping_curve.curve = BKE_curvemapping_cache_get(
|
||||
brush_curve_cache, src->mapping_curve.curve, false);
|
||||
}
|
||||
else {
|
||||
dst->mapping_curve.curve = src->mapping_curve.curve;
|
||||
CURVE_ADDREF(dst->mapping_curve.curve);
|
||||
}
|
||||
}
|
||||
|
||||
dst->mapping_curve.preset = src->mapping_curve.preset;
|
||||
dst->blendmode = src->blendmode;
|
||||
|
||||
dst->min = src->min;
|
||||
|
@ -2170,15 +2250,15 @@ void BKE_brush_channelset_to_unified_settings(BrushChannelSet *chset, UnifiedPai
|
|||
{
|
||||
BrushChannel *ch;
|
||||
|
||||
if (ch = BRUSHSET_LOOKUP(chset, radius)) {
|
||||
ups->size = ch->fvalue;
|
||||
if ((ch = BRUSHSET_LOOKUP(chset, radius))) {
|
||||
ups->size = (int)ch->fvalue;
|
||||
}
|
||||
|
||||
if (ch = BRUSHSET_LOOKUP(chset, strength)) {
|
||||
if ((ch = BRUSHSET_LOOKUP(chset, strength))) {
|
||||
ups->alpha = ch->fvalue;
|
||||
}
|
||||
|
||||
if (ch = BRUSHSET_LOOKUP(chset, weight)) {
|
||||
if ((ch = BRUSHSET_LOOKUP(chset, weight))) {
|
||||
ups->weight = ch->fvalue;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -996,7 +996,6 @@ void BKE_brush_channelset_compat_load(BrushChannelSet *chset, Brush *brush, bool
|
|||
&(struct rctf){.xmin = 0, .ymin = 0.0, .xmax = 1.0, .ymax = 1.0},
|
||||
CURVE_PRESET_LINE,
|
||||
1);
|
||||
|
||||
}
|
||||
BKE_curvemapping_init(ch->curve.curve);
|
||||
}
|
||||
|
@ -1022,8 +1021,11 @@ void BKE_brush_channelset_compat_load(BrushChannelSet *chset, Brush *brush, bool
|
|||
void reset_clay_mappings(BrushChannelSet *chset, bool strips)
|
||||
{
|
||||
BrushMapping *mp = BRUSHSET_LOOKUP(chset, radius)->mappings + BRUSH_MAPPING_PRESSURE;
|
||||
mp->mapping_curve.preset = BRUSH_CURVE_CUSTOM;
|
||||
|
||||
BKE_brush_mapping_ensure_write(mp);
|
||||
CurveMapping *curve = mp->curve;
|
||||
|
||||
CurveMapping *curve = mp->mapping_curve.curve;
|
||||
|
||||
BKE_curvemapping_set_defaults(curve, 1, 0.0f, 0.0f, 1.0f, 1.0f);
|
||||
BKE_curvemap_reset(curve->cm,
|
||||
|
@ -1057,8 +1059,10 @@ void reset_clay_mappings(BrushChannelSet *chset, bool strips)
|
|||
}
|
||||
|
||||
mp = BRUSHSET_LOOKUP(chset, strength)->mappings + BRUSH_MAPPING_PRESSURE;
|
||||
mp->mapping_curve.preset = BRUSH_CURVE_CUSTOM;
|
||||
|
||||
BKE_brush_mapping_ensure_write(mp);
|
||||
curve = mp->curve;
|
||||
curve = mp->mapping_curve.curve;
|
||||
|
||||
BKE_curvemapping_set_defaults(curve, 1, 0.0f, 0.0f, 1.0f, 1.0f);
|
||||
BKE_curvemap_reset(curve->cm,
|
||||
|
@ -1705,16 +1709,19 @@ void BKE_brush_mapping_reset(BrushChannel *ch, int tool, int mapping)
|
|||
BrushMapping *mp = ch->mappings + mapping;
|
||||
BrushMappingDef *mdef = (&ch->def->mappings.pressure) + mapping;
|
||||
|
||||
BKE_brush_mapping_ensure_write(mp);
|
||||
|
||||
CurveMapping *curve = mp->curve;
|
||||
|
||||
BKE_curvemapping_set_defaults(curve, 1, 0.0f, 0.0f, 1.0f, 1.0f);
|
||||
BKE_curvemap_reset(
|
||||
curve->cm, &(struct rctf){.xmin = 0, .ymin = 0.0, .xmax = 1.0, .ymax = 1.0}, mdef->curve, 1);
|
||||
BKE_curvemapping_init(curve);
|
||||
|
||||
if (STREQ(ch->idname, "hue_offset") && mapping == BRUSH_MAPPING_PRESSURE) {
|
||||
mp->mapping_curve.preset = BRUSH_CURVE_CUSTOM;
|
||||
BKE_brush_mapping_ensure_write(mp);
|
||||
|
||||
CurveMapping *curve = mp->mapping_curve.curve;
|
||||
|
||||
BKE_curvemapping_set_defaults(curve, 1, 0.0f, 0.0f, 1.0f, 1.0f);
|
||||
BKE_curvemap_reset(curve->cm,
|
||||
&(struct rctf){.xmin = 0, .ymin = 0.0, .xmax = 1.0, .ymax = 1.0},
|
||||
mdef->curve,
|
||||
1);
|
||||
BKE_curvemapping_init(curve);
|
||||
|
||||
CurveMap *cuma = curve->cm;
|
||||
cuma->curve[0].x = 0.0f;
|
||||
cuma->curve[0].y = 0.0f;
|
||||
|
@ -1724,9 +1731,9 @@ void BKE_brush_mapping_reset(BrushChannel *ch, int tool, int mapping)
|
|||
|
||||
BKE_curvemap_insert(cuma, 0.65f, 0.0f);
|
||||
cuma->curve[1].flag |= CUMA_HANDLE_VECTOR;
|
||||
}
|
||||
|
||||
BKE_curvemapping_changed(curve, true);
|
||||
BKE_curvemapping_changed(curve, true);
|
||||
}
|
||||
}
|
||||
void BKE_brush_builtin_create(Brush *brush, int tool)
|
||||
{
|
||||
|
|
|
@ -62,7 +62,7 @@ static int curvmapping_curve_count(const CurveMapping *cumap)
|
|||
return count;
|
||||
}
|
||||
|
||||
bool BKE_curvemapping_equals(const CurveMapping *a, const CurveMapping *b)
|
||||
ATTR_NO_OPT bool BKE_curvemapping_equals(const CurveMapping *a, const CurveMapping *b)
|
||||
{
|
||||
int count = curvmapping_curve_count(a);
|
||||
|
||||
|
@ -190,7 +190,7 @@ void BKE_curvemapping_cache_release(CurveMappingCache *cache, CurveMapping *curv
|
|||
{
|
||||
curve->cache_users--;
|
||||
|
||||
//printf("%s: %d flag: %d\n", __func__, curve->cache_users, curve->flag);
|
||||
// printf("%s: %d flag: %d\n", __func__, curve->cache_users, curve->flag);
|
||||
|
||||
if ((curve->flag & CUMA_PART_OF_CACHE) && curve->cache_users <= 0) {
|
||||
if (!BLI_ghash_remove(cache->gh, curve, NULL, NULL)) {
|
||||
|
|
|
@ -4980,9 +4980,12 @@ void CustomData_blend_write_prepare(CustomData *data,
|
|||
|
||||
for (i = 0, j = 0; i < totlayer; i++) {
|
||||
CustomDataLayer *layer = &data->layers[i];
|
||||
printf("layer: %d %s %d\n", layer->type, layer->name ? layer->name : "", layer->flag);
|
||||
|
||||
/* Layers with this flag set are not written to file. */
|
||||
if ((layer->flag & (CD_FLAG_NOCOPY | CD_FLAG_TEMPORARY)) || layer->anonymous_id != nullptr) {
|
||||
data->totlayer--;
|
||||
printf("skipping layer %p (%s)", layer, layer->name);
|
||||
// CLOG_WARN(&LOG, "skipping layer %p (%s)", layer, layer->name);
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -46,7 +46,9 @@
|
|||
#include "BKE_brush.h"
|
||||
#include "BKE_brush_engine.h"
|
||||
#include "BKE_collection.h"
|
||||
#include "BKE_colortools.h"
|
||||
#include "BKE_curve.h"
|
||||
#include "BKE_curvemapping_cache.h"
|
||||
#include "BKE_data_transfer.h"
|
||||
#include "BKE_deform.h"
|
||||
#include "BKE_fcurve.h"
|
||||
|
|
|
@ -31,6 +31,17 @@
|
|||
|
||||
struct GHash;
|
||||
|
||||
typedef struct BrushCurve {
|
||||
CurveMapping *curve;
|
||||
|
||||
/** curve preset, see eBrushCurvePreset.
|
||||
Note: this differs from BrushMappingDef's preset field
|
||||
*/
|
||||
int preset;
|
||||
char preset_slope_negative;
|
||||
char _pad[3];
|
||||
} BrushCurve;
|
||||
|
||||
/* Input mapping struct. An input mapping transform
|
||||
stroke inputs intos outputs. Inputs can be device
|
||||
events (like pen pressure/tilt) or synethesize
|
||||
|
@ -44,9 +55,11 @@ typedef struct BrushMapping {
|
|||
extensively (mostly to cache input mappings and resolve
|
||||
channel inheritance), to the point that copying the
|
||||
channel curves was a problem.
|
||||
|
||||
|
||||
*/
|
||||
CurveMapping *curve;
|
||||
|
||||
CurveMapping *curve; /* Deprecated. */
|
||||
BrushCurve mapping_curve;
|
||||
|
||||
float factor;
|
||||
int blendmode; /* blendmode, a subset of the MA_BLEND_XXX enums*/
|
||||
|
@ -66,17 +79,6 @@ typedef struct BrushMapping {
|
|||
char inherit_mode, _pad[3];
|
||||
} BrushMapping;
|
||||
|
||||
typedef struct BrushCurve {
|
||||
CurveMapping *curve;
|
||||
|
||||
/** curve preset, see eBrushCurvePreset.
|
||||
Note: this differs from BrushMappingDef's preset field
|
||||
*/
|
||||
int preset;
|
||||
char preset_slope_negative;
|
||||
char _pad[3];
|
||||
} BrushCurve;
|
||||
|
||||
typedef struct BrushChannel {
|
||||
struct BrushChannel *next, *prev;
|
||||
|
||||
|
@ -85,9 +87,9 @@ typedef struct BrushChannel {
|
|||
the BRUSHSET_XXX macros, SCULPT_get_XXX, etc. On the C++ side
|
||||
BrushChannelSetIF has accessor methods, e.g. BrushChannelSet::radius.
|
||||
*/
|
||||
char idname[64];
|
||||
char name[64]; /** user-friendly name */
|
||||
char *category; /** category; if NULL, def->category will be used */
|
||||
char idname[64];
|
||||
char name[64]; /** user-friendly name */
|
||||
char *category; /** category; if NULL, def->category will be used */
|
||||
|
||||
struct BrushChannelType *def; /* Brush channel definition */
|
||||
|
||||
|
@ -102,12 +104,12 @@ typedef struct BrushChannel {
|
|||
type and prevent the creation of group properties
|
||||
at the API level though.
|
||||
*/
|
||||
float fvalue; /** floating point value */
|
||||
int ivalue; /** stores integer, boolean, enum and bitmasks */
|
||||
float fvalue; /** floating point value */
|
||||
int ivalue; /** stores integer, boolean, enum and bitmasks */
|
||||
float vector[4]; /* stores 3 and 4 component vectors */
|
||||
BrushCurve curve;
|
||||
|
||||
BrushMapping mappings[7]; /* dimension should always be BRUSH_MAPPING_MAX */
|
||||
BrushMapping mappings[7]; /* dimension should always be BRUSH_MAPPING_MAX */
|
||||
|
||||
short type; /** eBrushChannelType */
|
||||
short ui_order;
|
||||
|
@ -163,8 +165,8 @@ typedef enum eBrushMappingType {
|
|||
} eBrushMappingType;
|
||||
|
||||
BLI_STATIC_ASSERT(offsetof(BrushChannel, type) - offsetof(BrushChannel, mappings) ==
|
||||
sizeof(BrushMapping) * BRUSH_MAPPING_MAX,
|
||||
"BrushChannel.mappings must == BRUSH_MAPPING_MAX");
|
||||
sizeof(BrushMapping) * BRUSH_MAPPING_MAX,
|
||||
"BrushChannel.mappings must == BRUSH_MAPPING_MAX");
|
||||
|
||||
// BrushChannel->flag
|
||||
typedef enum eBrushChannelFlag {
|
||||
|
|
|
@ -410,7 +410,7 @@ PointerRNA rna_BrushMapping_curve_get(PointerRNA *ptr)
|
|||
// make sure we can write to curve
|
||||
BKE_brush_mapping_ensure_write(mapping);
|
||||
|
||||
return rna_pointer_inherit_refine(ptr, &RNA_CurveMapping, mapping->curve);
|
||||
return rna_pointer_inherit_refine(ptr, &RNA_BrushCurve, &mapping->mapping_curve);
|
||||
}
|
||||
|
||||
PointerRNA rna_BrushCurve_curve_get(PointerRNA *ptr)
|
||||
|
@ -747,7 +747,7 @@ void RNA_def_brush_mapping(BlenderRNA *brna)
|
|||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
|
||||
prop = RNA_def_property(srna, "curve", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "CurveMapping");
|
||||
RNA_def_property_struct_type(prop, "BrushCurve");
|
||||
RNA_def_property_ui_text(prop, "Curve Sensitivity", "Curve used for the sensitivity");
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_pointer_funcs(prop, "rna_BrushMapping_curve_get", NULL, NULL, NULL);
|
||||
|
|
Loading…
Reference in New Issue