Sculpt-dev: fix crash related to curve
cache * Fixed a few bugs in the curvemapping cache code. * Fixed bug in how BKE_channelset_compat_load was copying brush.curve to/from the falloff_curve brush channel.
This commit is contained in:
parent
bfd1dc3a75
commit
15cb3130c3
|
@ -129,7 +129,11 @@ void BKE_brush_channel_system_exit()
|
|||
bool BKE_brush_mapping_ensure_write(BrushMapping *mp)
|
||||
{
|
||||
if (IS_CACHE_CURVE(mp->curve)) {
|
||||
mp->curve = BKE_curvemapping_copy(mp->curve);
|
||||
CurveMapping *newcurve = BKE_curvemapping_copy(mp->curve);
|
||||
RELEASE_CACHE_CURVE(mp->curve);
|
||||
|
||||
mp->curve = newcurve;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -391,6 +395,7 @@ void BKE_brush_channel_copy_data(BrushChannel *dst,
|
|||
}
|
||||
else if (dst->curve.curve) {
|
||||
BKE_curvemapping_free(dst->curve.curve);
|
||||
dst->curve.curve = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1090,6 +1095,9 @@ 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);
|
||||
f2 = mp->min + (mp->max - mp->min) * f2;
|
||||
|
||||
|
@ -1182,7 +1190,9 @@ bool BKE_brush_mapping_is_enabled(BrushChannel *child, BrushChannel *parent, int
|
|||
}
|
||||
}
|
||||
|
||||
void BKE_brush_channel_apply_mapping_flags(BrushChannel *dst, BrushChannel *child, BrushChannel *parent)
|
||||
void BKE_brush_channel_apply_mapping_flags(BrushChannel *dst,
|
||||
BrushChannel *child,
|
||||
BrushChannel *parent)
|
||||
{
|
||||
for (int i = 0; i < BRUSH_MAPPING_MAX; i++) {
|
||||
BrushMapping *mp = dst->mappings + i;
|
||||
|
@ -2034,7 +2044,7 @@ void BKE_brush_channelset_read(BlendDataReader *reader, BrushChannelSet *chset)
|
|||
BKE_curvemapping_init(curve);
|
||||
}
|
||||
|
||||
ch->mappings[i].curve = GET_CACHE_CURVE(curve); // frees curve, returns new one
|
||||
mp->curve = GET_CACHE_CURVE(curve); // frees curve, returns new one
|
||||
|
||||
// paranoia check to make sure BrushMapping.type is correct
|
||||
mp->type = i;
|
||||
|
@ -2065,7 +2075,10 @@ void BKE_brush_channelset_write(BlendWriter *writer, BrushChannelSet *chset)
|
|||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
#include "BKE_colorband.h"
|
||||
#include "BKE_colortools.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_curvemapping_cache.h"
|
||||
#include "BKE_node.h"
|
||||
#include "BKE_paint.h"
|
||||
|
||||
|
@ -266,7 +267,7 @@ static bool check_builtin_init()
|
|||
SUBTYPE_SET(smooth_stroke_radius, BRUSH_CHANNEL_PIXEL);
|
||||
SUBTYPE_SET(normal_mask_limit, BRUSH_CHANNEL_ANGLE);
|
||||
SUBTYPE_SET(view_normal_mask_limit, BRUSH_CHANNEL_ANGLE);
|
||||
|
||||
|
||||
SUBTYPE_SET(jitter_absolute, BRUSH_CHANNEL_PIXEL);
|
||||
|
||||
SUBTYPE_SET(radius, BRUSH_CHANNEL_PIXEL);
|
||||
|
@ -304,7 +305,7 @@ static bool check_builtin_init()
|
|||
mdef->blendmode = MA_RAMP_ADD;
|
||||
}
|
||||
|
||||
//SETCAT(enhance_detail_presteps, "Enhancement");
|
||||
// SETCAT(enhance_detail_presteps, "Enhancement");
|
||||
SETCAT(concave_mask_factor, "Automasking");
|
||||
SETCAT(automasking, "Automasking");
|
||||
SETCAT(automasking_boundary_edges_propagation_steps, "Automasking");
|
||||
|
@ -972,16 +973,32 @@ void BKE_brush_channelset_compat_load(BrushChannelSet *chset, Brush *brush, bool
|
|||
}
|
||||
}
|
||||
|
||||
#if 1
|
||||
if (brush_to_channels) {
|
||||
BrushChannel *ch = BRUSHSET_LOOKUP(chset, falloff_curve);
|
||||
|
||||
if (ch) {
|
||||
ch->curve.preset = brush->curve_preset;
|
||||
BKE_brush_channel_curve_ensure_write(&ch->curve);
|
||||
|
||||
if (brush->curve && brush->curve_preset == BRUSH_CURVE_CUSTOM) {
|
||||
BKE_curvemapping_free_data(ch->curve.curve);
|
||||
BKE_curvemapping_copy_data(ch->curve.curve, brush->curve);
|
||||
if (brush->curve_preset == BRUSH_CURVE_CUSTOM) {
|
||||
BKE_curvemapping_cache_release_or_free(brush_curve_cache, ch->curve.curve);
|
||||
|
||||
if (brush->curve) {
|
||||
ch->curve.curve = BKE_curvemapping_copy(brush->curve);
|
||||
}
|
||||
else {
|
||||
printf("%s: missing curve in brush\n", __func__);
|
||||
|
||||
ch->curve.curve = MEM_callocN(sizeof(CurveMapping), "CurveMapping");
|
||||
|
||||
BKE_curvemapping_set_defaults(ch->curve.curve, 1, 0.0f, 0.0f, 1.0f, 1.0f);
|
||||
BKE_curvemap_reset(ch->curve.curve->cm,
|
||||
&(struct rctf){.xmin = 0, .ymin = 0.0, .xmax = 1.0, .ymax = 1.0},
|
||||
CURVE_PRESET_LINE,
|
||||
1);
|
||||
|
||||
}
|
||||
BKE_curvemapping_init(ch->curve.curve);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -991,12 +1008,14 @@ void BKE_brush_channelset_compat_load(BrushChannelSet *chset, Brush *brush, bool
|
|||
if (ch) {
|
||||
brush->curve_preset = ch->curve.preset;
|
||||
|
||||
if (ch->curve.curve && ch->curve.preset == BRUSH_CURVE_CUSTOM) {
|
||||
BKE_curvemapping_free_data(brush->curve);
|
||||
BKE_curvemapping_copy_data(brush->curve, ch->curve.curve);
|
||||
if (ch->curve.preset == BRUSH_CURVE_CUSTOM) {
|
||||
BKE_curvemapping_cache_release_or_free(brush_curve_cache, brush->curve);
|
||||
brush->curve = BKE_curvemapping_copy(ch->curve.curve);
|
||||
BKE_curvemapping_init(brush->curve);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* todo: move into BKE_brush_reset_mapping*/
|
||||
|
|
|
@ -120,6 +120,7 @@ void BKE_curvemapping_free(CurveMapping *cumap)
|
|||
{
|
||||
if (cumap) {
|
||||
BKE_curvemapping_free_data(cumap);
|
||||
cumap->flag |= CUMA_IS_FREED;
|
||||
MEM_freeN(cumap);
|
||||
}
|
||||
}
|
||||
|
@ -194,6 +195,7 @@ CurveMapping *BKE_curvemapping_copy(const CurveMapping *cumap)
|
|||
CurveMapping *cumapn = MEM_dupallocN(cumap);
|
||||
BKE_curvemapping_copy_data(cumapn, cumap);
|
||||
cumapn->flag &= ~CUMA_PART_OF_CACHE;
|
||||
cumapn->cache_users = 0;
|
||||
return cumapn;
|
||||
}
|
||||
return NULL;
|
||||
|
|
|
@ -182,13 +182,17 @@ CurveMappingCache *BKE_curvemapping_cache_create()
|
|||
void BKE_curvemapping_cache_aquire(CurveMappingCache *cache, CurveMapping *curve)
|
||||
{
|
||||
curve->cache_users++;
|
||||
|
||||
// printf("%s: %d flag: %d\n", __func__, curve->cache_users, curve->flag);
|
||||
}
|
||||
|
||||
void BKE_curvemapping_cache_release(CurveMappingCache *cache, CurveMapping *curve)
|
||||
{
|
||||
curve->cache_users--;
|
||||
|
||||
if ((curve->flag & CUMA_PART_OF_CACHE) && curve->cache_users < 0) {
|
||||
//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)) {
|
||||
printf("error, curve was not in cache! %p\n", curve);
|
||||
}
|
||||
|
@ -272,6 +276,10 @@ void BKE_curvemapping_cache_exit()
|
|||
// releases a curve if it's in the cache, otherwise frees it
|
||||
void BKE_curvemapping_cache_release_or_free(CurveMappingCache *cache, CurveMapping *curve)
|
||||
{
|
||||
if (!curve) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (curve->flag & CUMA_PART_OF_CACHE) {
|
||||
BKE_curvemapping_cache_release(cache, curve);
|
||||
}
|
||||
|
|
|
@ -5050,7 +5050,7 @@ static void sculpt_topology_update(Sculpt *sd,
|
|||
BMVert *v = (BMVert *)BM_ELEM_FROM_ID_SAFE(ss->bm, actv);
|
||||
|
||||
if (v && v->head.htype == BM_VERT) {
|
||||
ss->active_vertex_index.i == (intptr_t)v;
|
||||
ss->active_vertex_index.i = (intptr_t)v;
|
||||
}
|
||||
else {
|
||||
ss->active_vertex_index.i = SCULPT_REF_NONE;
|
||||
|
@ -5061,7 +5061,7 @@ static void sculpt_topology_update(Sculpt *sd,
|
|||
BMFace *f = (BMFace *)BM_ELEM_FROM_ID_SAFE(ss->bm, actf);
|
||||
|
||||
if (f && f->head.htype == BM_FACE) {
|
||||
ss->active_face_index.i == (intptr_t)f;
|
||||
ss->active_face_index.i = (intptr_t)f;
|
||||
}
|
||||
else {
|
||||
ss->active_face_index.i = SCULPT_REF_NONE;
|
||||
|
@ -5847,14 +5847,11 @@ static void SCULPT_run_command(
|
|||
|
||||
*brush2 = *brush;
|
||||
|
||||
BrushChannel *ch = BRUSHSET_LOOKUP(cmd->params_final, falloff_curve);
|
||||
if (ch) {
|
||||
brush2->curve_preset = ch->curve.preset;
|
||||
brush2->curve = ch->curve.curve;
|
||||
}
|
||||
/* prevent auto freeing of brush2->curve in BKE_brush_channelset_compat_load */
|
||||
brush2->curve = NULL;
|
||||
|
||||
// Load parameters into brush2 for compatibility with old code
|
||||
// Make sure to remove all pen pressure/tilt old code
|
||||
/* Load parameters into brush2 for compatibility with old code
|
||||
Make sure to remove all old code for pen pressure/tilt */
|
||||
BKE_brush_channelset_compat_load(cmd->params_mapped, brush2, false);
|
||||
|
||||
ss->cache->use_plane_trim = BRUSHSET_GET_INT(cmd->params_mapped, use_plane_trim, NULL);
|
||||
|
@ -6154,6 +6151,9 @@ static void SCULPT_run_commandlist(
|
|||
Brush brush2 = *brush;
|
||||
brush2.sculpt_tool = cmd->tool;
|
||||
|
||||
/* prevent auto freeing of brush2->curve in BKE_brush_channelset_compat_load */
|
||||
brush2.curve = NULL;
|
||||
|
||||
// Load parameters into brush2 for compatibility with old code
|
||||
BKE_brush_channelset_compat_load(cmd->params_final, &brush2, false);
|
||||
|
||||
|
@ -6863,6 +6863,8 @@ static const char *sculpt_tool_name(Sculpt *sd)
|
|||
return "Relax";
|
||||
case SCULPT_TOOL_ENHANCE_DETAILS:
|
||||
return "Enhance Details";
|
||||
case SCULPT_TOOL_DISPLACEMENT_HEAL:
|
||||
return "Multires Heal";
|
||||
}
|
||||
|
||||
return "Sculpting";
|
||||
|
|
|
@ -105,7 +105,8 @@ typedef enum eCurveMappingFlags {
|
|||
|
||||
/** The curve is extended by extrapolation. When not set the curve is extended horizontally. */
|
||||
CUMA_EXTEND_EXTRAPOLATE = (1 << 4),
|
||||
CUMA_PART_OF_CACHE = (1 << 5)
|
||||
CUMA_PART_OF_CACHE = (1 << 5),
|
||||
CUMA_IS_FREED = (1 << 6)
|
||||
} eCurveMappingFlags;
|
||||
|
||||
/** #CurveMapping.preset */
|
||||
|
|
Loading…
Reference in New Issue