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:
Joseph Eagar 2022-05-11 19:18:33 -07:00
parent ca8f30d54e
commit cfc46e43b2
11 changed files with 238 additions and 141 deletions

View File

@ -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')

View File

@ -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")

View File

@ -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);

View File

@ -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

View File

@ -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;
}
}

View File

@ -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)
{

View File

@ -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)) {

View File

@ -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 {

View File

@ -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"

View File

@ -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 {

View File

@ -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);