Curve: CurveMapping Extend Option

Extend options are currently stored per curve. This was not clearly
communicated to the user and they expected this to be a setting per
CurveMapping.

This change will move the option from `Curve` to `CurveMapping`. In
order to support this the API had to be changed.

BPY: CurveMap.evaluate is also moved to CurveMapping.evaluate what
breaks Python API. Cycles has been updated but other add-ons have
not. After release of 2.81 we can merge this to master and adapt
the add-ons.

Reviewed By: campbellbarton

Differential Revision: https://developer.blender.org/D6169
This commit is contained in:
Jeroen Bakker 2019-11-01 12:09:55 +01:00
parent 6992fc0b3b
commit 2e6159a494
Notes: blender-bot 2023-02-14 02:27:56 +01:00
Referenced by commit 3ee6d74f93, Fix T73125: Crash when opening a file containing a Line Style.
Referenced by issue #73125, Crash when opening a file containing a Line Style
Referenced by issue #72289, 2.82 Freestyle lines won't render with modifiers set to 'Curve' mapping
19 changed files with 405 additions and 138 deletions

View File

@ -159,7 +159,7 @@ static inline void curvemapping_to_array(BL::CurveMapping &cumap, array<float> &
data.resize(size);
for (int i = 0; i < size; i++) {
float t = (float)i / (float)(size - 1);
data[i] = curve.evaluate(t);
data[i] = cumap.evaluate(curve, t);
}
}
@ -197,15 +197,16 @@ static inline void curvemapping_color_to_array(BL::CurveMapping &cumap,
BL::CurveMap mapI = cumap.curves[3];
for (int i = 0; i < size; i++) {
const float t = min_x + (float)i / (float)(size - 1) * range_x;
data[i] = make_float3(mapR.evaluate(mapI.evaluate(t)),
mapG.evaluate(mapI.evaluate(t)),
mapB.evaluate(mapI.evaluate(t)));
data[i] = make_float3(cumap.evaluate(mapR, cumap.evaluate(mapI, t)),
cumap.evaluate(mapG, cumap.evaluate(mapI, t)),
cumap.evaluate(mapB, cumap.evaluate(mapI, t)));
}
}
else {
for (int i = 0; i < size; i++) {
float t = min_x + (float)i / (float)(size - 1) * range_x;
data[i] = make_float3(mapR.evaluate(t), mapG.evaluate(t), mapB.evaluate(t));
data[i] = make_float3(
cumap.evaluate(mapR, t), cumap.evaluate(mapG, t), cumap.evaluate(mapB, t));
}
}
}

View File

@ -16,7 +16,7 @@ out vec4 fragColor;
*/
uniform sampler1D curve_mapping_texture;
uniform int curve_mapping_lut_size;
uniform ivec4 use_curve_mapping_extend_extrapolate;
uniform int use_curve_mapping_extend_extrapolate;
uniform vec4 curve_mapping_mintable;
uniform vec4 curve_mapping_range;
uniform vec4 curve_mapping_ext_in_x;
@ -42,8 +42,8 @@ float read_curve_mapping(int table, int index)
float curvemap_calc_extend(int table, float x, vec2 first, vec2 last)
{
if (x <= first[0]) {
if (use_curve_mapping_extend_extrapolate[table] == 0) {
/* no extrapolate */
if (use_curve_mapping_extend_extrapolate == 0) {
/* horizontal extrapolation */
return first[1];
}
else {
@ -55,8 +55,8 @@ float curvemap_calc_extend(int table, float x, vec2 first, vec2 last)
}
}
else if (x >= last[0]) {
if (use_curve_mapping_extend_extrapolate[table] == 0) {
/* no extrapolate */
if (use_curve_mapping_extend_extrapolate == 0) {
/* horizontal extrapolation */
return last[1];
}
else {

View File

@ -73,10 +73,10 @@ typedef struct OCIO_CurveMappingSettings {
int lut_size;
/* Extend extrapolation flags for all the tables.
* if use_extend_extrapolate[T] != 0 means extrapolation for
* table T is needed.
* if use_extend_extrapolate != 0 means extrapolation for
* curve.
*/
int use_extend_extrapolate[4];
int use_extend_extrapolate;
/* Minimal X value of the curve mapping tables. */
float mintable[4];

View File

@ -499,8 +499,8 @@ bool OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r,
if (use_curve_mapping) {
immUniform1i("curve_mapping_texture", 2);
immUniform1i("curve_mapping_lut_size", curve_mapping_settings->lut_size);
immUniform4iv("use_curve_mapping_extend_extrapolate",
curve_mapping_settings->use_extend_extrapolate);
immUniform1i("use_curve_mapping_extend_extrapolate",
curve_mapping_settings->use_extend_extrapolate);
immUniform4fv("curve_mapping_mintable", curve_mapping_settings->mintable);
immUniform4fv("curve_mapping_range", curve_mapping_settings->range);
immUniform4fv("curve_mapping_ext_in_x", curve_mapping_settings->ext_in_x);

View File

@ -27,7 +27,7 @@
* \note Use #STRINGIFY() rather than defining with quotes.
*/
#define BLENDER_VERSION 282
#define BLENDER_SUBVERSION 1
#define BLENDER_SUBVERSION 2
/** Several breakages with 280, e.g. collections vs layers. */
#define BLENDER_MINVERSION 280
#define BLENDER_MINSUBVERSION 0

View File

@ -68,7 +68,9 @@ void BKE_curvemapping_initialize(struct CurveMapping *cumap);
/* keep these (const CurveMap) - to help with thread safety */
/* single curve, no table check */
float BKE_curvemap_evaluateF(const struct CurveMap *cuma, float value);
float BKE_curvemap_evaluateF(const struct CurveMapping *cumap,
const struct CurveMap *cuma,
float value);
/* single curve, with table check */
float BKE_curvemapping_evaluateF(const struct CurveMapping *cumap, int cur, float value);
void BKE_curvemapping_evaluate3F(const struct CurveMapping *cumap,

View File

@ -1069,18 +1069,19 @@ void BKE_brush_sculpt_reset(Brush *br)
*/
void BKE_brush_curve_preset(Brush *b, eCurveMappingPreset preset)
{
CurveMap *cm = NULL;
CurveMapping *cumap = NULL;
CurveMap *cuma = NULL;
if (!b->curve) {
b->curve = BKE_curvemapping_add(1, 0, 0, 1, 1);
}
cumap = b->curve;
cumap->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
cumap->preset = preset;
cm = b->curve->cm;
cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
b->curve->preset = preset;
BKE_curvemap_reset(cm, &b->curve->clipr, b->curve->preset, CURVEMAP_SLOPE_NEGATIVE);
BKE_curvemapping_changed(b->curve, false);
cuma = b->curve->cm;
BKE_curvemap_reset(cuma, &cumap->clipr, cumap->preset, CURVEMAP_SLOPE_NEGATIVE);
BKE_curvemapping_changed(cumap, false);
}
/* Generic texture sampler for 3D painting systems. point has to be either in

View File

@ -54,7 +54,7 @@ void BKE_curvemapping_set_defaults(
int a;
float clipminx, clipminy, clipmaxx, clipmaxy;
cumap->flag = CUMA_DO_CLIP;
cumap->flag = CUMA_DO_CLIP | CUMA_EXTEND_EXTRAPOLATE;
if (tot == 4) {
cumap->cur = 3; /* rhms, hack for 'col' curve? */
}
@ -71,7 +71,6 @@ void BKE_curvemapping_set_defaults(
cumap->bwmul[0] = cumap->bwmul[1] = cumap->bwmul[2] = 1.0f;
for (a = 0; a < tot; a++) {
cumap->cm[a].flag = CUMA_EXTEND_EXTRAPOLATE;
cumap->cm[a].totpoint = 2;
cumap->cm[a].curve = MEM_callocN(2 * sizeof(CurveMapPoint), "curve points");
@ -591,14 +590,15 @@ static void calchandle_curvemap(BezTriple *bezt, const BezTriple *prev, const Be
/* in X, out Y.
* X is presumed to be outside first or last */
static float curvemap_calc_extend(const CurveMap *cuma,
static float curvemap_calc_extend(const CurveMapping *cumap,
const CurveMap *cuma,
float x,
const float first[2],
const float last[2])
{
if (x <= first[0]) {
if ((cuma->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) {
/* no extrapolate */
if ((cumap->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) {
/* extrapolate horizontally */
return first[1];
}
else {
@ -611,8 +611,8 @@ static float curvemap_calc_extend(const CurveMap *cuma,
}
}
else if (x >= last[0]) {
if ((cuma->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) {
/* no extrapolate */
if ((cumap->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) {
/* extrapolate horizontally */
return last[1];
}
else {
@ -628,8 +628,9 @@ static float curvemap_calc_extend(const CurveMap *cuma,
}
/* only creates a table for a single channel in CurveMapping */
static void curvemap_make_table(CurveMap *cuma, const rctf *clipr)
static void curvemap_make_table(const CurveMapping *cumap, CurveMap *cuma)
{
const rctf *clipr = &cumap->clipr;
CurveMapPoint *cmp = cuma->curve;
BezTriple *bezt;
@ -782,7 +783,7 @@ static void curvemap_make_table(CurveMap *cuma, const rctf *clipr)
}
else {
/* Extrapolate values that lie outside the start and end point. */
cmp[a].y = curvemap_calc_extend(cuma, cur_x, firstpoint, lastpoint);
cmp[a].y = curvemap_calc_extend(cumap, cuma, cur_x, firstpoint, lastpoint);
}
}
else {
@ -829,7 +830,7 @@ void BKE_curvemapping_premultiply(CurveMapping *cumap, int restore)
/* verify and copy */
for (a = 0; a < 3; a++) {
if (cumap->cm[a].table == NULL) {
curvemap_make_table(cumap->cm + a, &cumap->clipr);
curvemap_make_table(cumap, cumap->cm + a);
}
cumap->cm[a].premultable = cumap->cm[a].table;
cumap->cm[a].table = MEM_mallocN((CM_TABLE + 1) * sizeof(CurveMapPoint), "premul table");
@ -838,14 +839,15 @@ void BKE_curvemapping_premultiply(CurveMapping *cumap, int restore)
}
if (cumap->cm[3].table == NULL) {
curvemap_make_table(cumap->cm + 3, &cumap->clipr);
curvemap_make_table(cumap, cumap->cm + 3);
}
/* premul */
for (a = 0; a < 3; a++) {
int b;
for (b = 0; b <= CM_TABLE; b++) {
cumap->cm[a].table[b].y = BKE_curvemap_evaluateF(cumap->cm + 3, cumap->cm[a].table[b].y);
cumap->cm[a].table[b].y = BKE_curvemap_evaluateF(
cumap, cumap->cm + 3, cumap->cm[a].table[b].y);
}
copy_v2_v2(cumap->cm[a].premul_ext_in, cumap->cm[a].ext_in);
@ -949,7 +951,7 @@ void BKE_curvemapping_changed(CurveMapping *cumap, const bool rem_doubles)
BKE_curvemap_remove(cuma, 2);
}
}
curvemap_make_table(cuma, clipr);
curvemap_make_table(cumap, cuma);
}
void BKE_curvemapping_changed_all(CurveMapping *cumap)
@ -967,7 +969,7 @@ void BKE_curvemapping_changed_all(CurveMapping *cumap)
}
/* table should be verified */
float BKE_curvemap_evaluateF(const CurveMap *cuma, float value)
float BKE_curvemap_evaluateF(const CurveMapping *cumap, const CurveMap *cuma, float value)
{
float fi;
int i;
@ -978,7 +980,7 @@ float BKE_curvemap_evaluateF(const CurveMap *cuma, float value)
/* fi is table float index and should check against table range i.e. [0.0 CM_TABLE] */
if (fi < 0.0f || fi > CM_TABLE) {
return curvemap_calc_extend(cuma, value, &cuma->table[0].x, &cuma->table[CM_TABLE].x);
return curvemap_calc_extend(cumap, cuma, value, &cuma->table[0].x, &cuma->table[CM_TABLE].x);
}
else {
if (i < 0) {
@ -997,7 +999,7 @@ float BKE_curvemap_evaluateF(const CurveMap *cuma, float value)
float BKE_curvemapping_evaluateF(const CurveMapping *cumap, int cur, float value)
{
const CurveMap *cuma = cumap->cm + cur;
float val = BKE_curvemap_evaluateF(cuma, value);
float val = BKE_curvemap_evaluateF(cumap, cuma, value);
/* account for clipping */
if (cumap->flag & CUMA_DO_CLIP) {
@ -1015,9 +1017,9 @@ float BKE_curvemapping_evaluateF(const CurveMapping *cumap, int cur, float value
/* vector case */
void BKE_curvemapping_evaluate3F(const CurveMapping *cumap, float vecout[3], const float vecin[3])
{
vecout[0] = BKE_curvemap_evaluateF(&cumap->cm[0], vecin[0]);
vecout[1] = BKE_curvemap_evaluateF(&cumap->cm[1], vecin[1]);
vecout[2] = BKE_curvemap_evaluateF(&cumap->cm[2], vecin[2]);
vecout[0] = BKE_curvemap_evaluateF(cumap, &cumap->cm[0], vecin[0]);
vecout[1] = BKE_curvemap_evaluateF(cumap, &cumap->cm[1], vecin[1]);
vecout[2] = BKE_curvemap_evaluateF(cumap, &cumap->cm[2], vecin[2]);
}
/* RGB case, no black/white points, no premult */
@ -1025,12 +1027,12 @@ void BKE_curvemapping_evaluateRGBF(const CurveMapping *cumap,
float vecout[3],
const float vecin[3])
{
vecout[0] = BKE_curvemap_evaluateF(&cumap->cm[0],
BKE_curvemap_evaluateF(&cumap->cm[3], vecin[0]));
vecout[1] = BKE_curvemap_evaluateF(&cumap->cm[1],
BKE_curvemap_evaluateF(&cumap->cm[3], vecin[1]));
vecout[2] = BKE_curvemap_evaluateF(&cumap->cm[2],
BKE_curvemap_evaluateF(&cumap->cm[3], vecin[2]));
vecout[0] = BKE_curvemap_evaluateF(
cumap, &cumap->cm[0], BKE_curvemap_evaluateF(cumap, &cumap->cm[3], vecin[0]));
vecout[1] = BKE_curvemap_evaluateF(
cumap, &cumap->cm[1], BKE_curvemap_evaluateF(cumap, &cumap->cm[3], vecin[1]));
vecout[2] = BKE_curvemap_evaluateF(
cumap, &cumap->cm[2], BKE_curvemap_evaluateF(cumap, &cumap->cm[3], vecin[2]));
}
static void curvemapping_evaluateRGBF_filmlike(const CurveMapping *cumap,
@ -1042,8 +1044,8 @@ static void curvemapping_evaluateRGBF_filmlike(const CurveMapping *cumap,
const float v1in = vecin[channel_offset[1]];
const float v2in = vecin[channel_offset[2]];
const float v0 = BKE_curvemap_evaluateF(&cumap->cm[channel_offset[0]], v0in);
const float v2 = BKE_curvemap_evaluateF(&cumap->cm[channel_offset[2]], v2in);
const float v0 = BKE_curvemap_evaluateF(cumap, &cumap->cm[channel_offset[0]], v0in);
const float v2 = BKE_curvemap_evaluateF(cumap, &cumap->cm[channel_offset[2]], v2in);
const float v1 = v2 + ((v0 - v2) * (v1in - v2in) / (v0in - v2in));
vecout[channel_offset[0]] = v0;
@ -1074,9 +1076,9 @@ void BKE_curvemapping_evaluate_premulRGBF_ex(const CurveMapping *cumap,
switch (cumap->tone) {
default:
case CURVE_TONE_STANDARD: {
vecout[0] = BKE_curvemap_evaluateF(&cumap->cm[0], r);
vecout[1] = BKE_curvemap_evaluateF(&cumap->cm[1], g);
vecout[2] = BKE_curvemap_evaluateF(&cumap->cm[2], b);
vecout[0] = BKE_curvemap_evaluateF(cumap, &cumap->cm[0], r);
vecout[1] = BKE_curvemap_evaluateF(cumap, &cumap->cm[1], g);
vecout[2] = BKE_curvemap_evaluateF(cumap, &cumap->cm[2], b);
break;
}
case CURVE_TONE_FILMLIKE: {
@ -1099,8 +1101,8 @@ void BKE_curvemapping_evaluate_premulRGBF_ex(const CurveMapping *cumap,
else {
/* Case 4: r >= g == b */
copy_v2_fl2(vecout,
BKE_curvemap_evaluateF(&cumap->cm[0], r),
BKE_curvemap_evaluateF(&cumap->cm[1], g));
BKE_curvemap_evaluateF(cumap, &cumap->cm[0], r),
BKE_curvemap_evaluateF(cumap, &cumap->cm[1], g));
vecout[2] = vecout[1];
}
}
@ -1208,7 +1210,7 @@ void BKE_curvemapping_initialize(CurveMapping *cumap)
for (a = 0; a < CM_TOT; a++) {
if (cumap->cm[a].table == NULL) {
curvemap_make_table(cumap->cm + a, &cumap->clipr);
curvemap_make_table(cumap, cumap->cm + a);
}
}
}

View File

@ -655,19 +655,19 @@ bool BKE_paint_select_elem_test(Object *ob)
void BKE_paint_cavity_curve_preset(Paint *p, int preset)
{
CurveMap *cm = NULL;
CurveMapping *cumap = NULL;
CurveMap *cuma = NULL;
if (!p->cavity_curve) {
p->cavity_curve = BKE_curvemapping_add(1, 0, 0, 1, 1);
}
cumap = p->cavity_curve;
cumap->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
cumap->preset = preset;
cm = p->cavity_curve->cm;
cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
p->cavity_curve->preset = preset;
BKE_curvemap_reset(
cm, &p->cavity_curve->clipr, p->cavity_curve->preset, CURVEMAP_SLOPE_POSITIVE);
BKE_curvemapping_changed(p->cavity_curve, false);
cuma = cumap->cm;
BKE_curvemap_reset(cuma, &cumap->clipr, cumap->preset, CURVEMAP_SLOPE_POSITIVE);
BKE_curvemapping_changed(cumap, false);
}
eObjectMode BKE_paint_object_mode_from_paintmode(ePaintMode mode)

View File

@ -558,7 +558,7 @@ void BKE_texture_pointdensity_init_data(PointDensity *pd)
pd->falloff_curve = BKE_curvemapping_add(1, 0, 0, 1, 1);
pd->falloff_curve->preset = CURVE_PRESET_LINE;
pd->falloff_curve->cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
pd->falloff_curve->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
BKE_curvemap_reset(pd->falloff_curve->cm,
&pd->falloff_curve->clipr,
pd->falloff_curve->preset,

View File

@ -37,10 +37,14 @@
#include "DNA_collection_types.h"
#include "DNA_constraint_types.h"
#include "DNA_curveprofile_types.h"
#include "DNA_freestyle_types.h"
#include "DNA_gpu_types.h"
#include "DNA_gpencil_types.h"
#include "DNA_gpencil_modifier_types.h"
#include "DNA_light_types.h"
#include "DNA_layer_types.h"
#include "DNA_lightprobe_types.h"
#include "DNA_linestyle_types.h"
#include "DNA_material_types.h"
#include "DNA_mesh_types.h"
#include "DNA_modifier_types.h"
@ -50,12 +54,12 @@
#include "DNA_screen_types.h"
#include "DNA_view3d_types.h"
#include "DNA_genfile.h"
#include "DNA_gpencil_types.h"
#include "DNA_workspace_types.h"
#include "DNA_key_types.h"
#include "DNA_curve_types.h"
#include "DNA_armature_types.h"
#include "DNA_text_types.h"
#include "DNA_texture_types.h"
#include "DNA_world_types.h"
#include "BKE_animsys.h"
@ -861,6 +865,232 @@ static void do_versions_local_collection_bits_set(LayerCollection *layer_collect
}
}
static void do_version_curvemapping_flag_extend_extrapolate(CurveMapping *cumap)
{
#define CUMA_EXTEND_EXTRAPOLATE_OLD 1
for (int curve_map_index = 0; curve_map_index < 4; curve_map_index++) {
CurveMap *cuma = &cumap->cm[curve_map_index];
if (cuma->flag & CUMA_EXTEND_EXTRAPOLATE_OLD) {
cumap->flag |= CUMA_EXTEND_EXTRAPOLATE;
return;
}
}
#undef CUMA_EXTEND_EXTRAPOLATE_OLD
}
/* Util version to walk over all CurveMappings in the given `bmain` */
static void do_version_curvemapping_walker(Main *bmain, void (*callback)(CurveMapping *cumap))
{
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
callback(&scene->r.mblur_shutter_curve);
if (scene->view_settings.curve_mapping) {
callback(scene->view_settings.curve_mapping);
}
if (scene->ed != NULL) {
LISTBASE_FOREACH (Sequence *, seq, &scene->ed->seqbase) {
LISTBASE_FOREACH (SequenceModifierData *, smd, &seq->modifiers) {
const SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(smd->type);
if (smti) {
if (smd->type == seqModifierType_Curves) {
CurvesModifierData *cmd = (CurvesModifierData *)smd;
callback(&cmd->curve_mapping);
}
else if (smd->type == seqModifierType_HueCorrect) {
HueCorrectModifierData *hcmd = (HueCorrectModifierData *)smd;
callback(&hcmd->curve_mapping);
}
}
}
}
}
// toolsettings
ToolSettings *ts = scene->toolsettings;
if (ts->vpaint) {
callback(ts->vpaint->paint.cavity_curve);
}
if (ts->wpaint) {
callback(ts->wpaint->paint.cavity_curve);
}
if (ts->sculpt) {
callback(ts->sculpt->paint.cavity_curve);
}
if (ts->uvsculpt) {
callback(ts->uvsculpt->paint.cavity_curve);
}
if (ts->gp_paint) {
callback(ts->gp_paint->paint.cavity_curve);
}
if (ts->gp_interpolate.custom_ipo) {
callback(ts->gp_interpolate.custom_ipo);
}
if (ts->gp_sculpt.cur_falloff) {
callback(ts->gp_sculpt.cur_falloff);
}
if (ts->gp_sculpt.cur_primitive) {
callback(ts->gp_sculpt.cur_primitive);
}
callback(ts->imapaint.paint.cavity_curve);
}
FOREACH_NODETREE_BEGIN (bmain, node_tree, id) {
LISTBASE_FOREACH (bNode *, node, &node_tree->nodes) {
if (ELEM(node->type,
SH_NODE_CURVE_VEC,
SH_NODE_CURVE_RGB,
CMP_NODE_CURVE_VEC,
CMP_NODE_CURVE_RGB,
CMP_NODE_TIME,
CMP_NODE_HUECORRECT,
TEX_NODE_CURVE_RGB,
TEX_NODE_CURVE_TIME)) {
callback((CurveMapping *)node->storage);
}
}
}
FOREACH_NODETREE_END;
LISTBASE_FOREACH (Light *, light, &bmain->lights) {
if (light->curfalloff) {
callback(light->curfalloff);
}
}
LISTBASE_FOREACH (Brush *, brush, &bmain->brushes) {
if (brush->curve) {
callback(brush->curve);
}
if (brush->gpencil_settings) {
if (brush->gpencil_settings->curve_sensitivity) {
callback(brush->gpencil_settings->curve_sensitivity);
}
if (brush->gpencil_settings->curve_strength) {
callback(brush->gpencil_settings->curve_strength);
}
if (brush->gpencil_settings->curve_jitter) {
callback(brush->gpencil_settings->curve_jitter);
}
}
}
LISTBASE_FOREACH (ParticleSettings *, part, &bmain->particles) {
if (part->clumpcurve) {
callback(part->clumpcurve);
}
if (part->roughcurve) {
callback(part->roughcurve);
}
if (part->twistcurve) {
callback(part->twistcurve);
}
}
/* Object */
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
/* Object modifiers */
LISTBASE_FOREACH (ModifierData *, md, &ob->modifiers) {
if (md->type == eModifierType_Hook) {
HookModifierData *hmd = (HookModifierData *)md;
if (hmd->curfalloff) {
callback(hmd->curfalloff);
}
}
else if (md->type == eModifierType_Warp) {
WarpModifierData *tmd = (WarpModifierData *)md;
if (tmd->curfalloff) {
callback(tmd->curfalloff);
}
}
else if (md->type == eModifierType_WeightVGEdit) {
WeightVGEditModifierData *wmd = (WeightVGEditModifierData *)md;
if (wmd->cmap_curve) {
callback(wmd->cmap_curve);
}
}
}
/* Grease pencil modifiers */
LISTBASE_FOREACH (ModifierData *, md, &ob->greasepencil_modifiers) {
if (md->type == eGpencilModifierType_Thick) {
ThickGpencilModifierData *gpmd = (ThickGpencilModifierData *)md;
if (gpmd->curve_thickness) {
callback(gpmd->curve_thickness);
}
}
else if (md->type == eGpencilModifierType_Hook) {
HookGpencilModifierData *gpmd = (HookGpencilModifierData *)md;
if (gpmd->curfalloff) {
callback(gpmd->curfalloff);
}
}
}
}
/* Free Style */
LISTBASE_FOREACH (struct FreestyleLineStyle *, linestyle, &bmain->linestyles) {
LISTBASE_FOREACH (LineStyleModifier *, m, &linestyle->thickness_modifiers) {
switch (m->type) {
case LS_MODIFIER_ALONG_STROKE:
callback(((LineStyleAlphaModifier_AlongStroke *)m)->curve);
break;
case LS_MODIFIER_DISTANCE_FROM_CAMERA:
callback(((LineStyleAlphaModifier_DistanceFromCamera *)m)->curve);
break;
case LS_MODIFIER_DISTANCE_FROM_OBJECT:
callback(((LineStyleAlphaModifier_DistanceFromObject *)m)->curve);
break;
case LS_MODIFIER_MATERIAL:
callback(((LineStyleAlphaModifier_Material *)m)->curve);
break;
case LS_MODIFIER_TANGENT:
callback(((LineStyleAlphaModifier_Tangent *)m)->curve);
break;
case LS_MODIFIER_NOISE:
callback(((LineStyleAlphaModifier_Noise *)m)->curve);
break;
case LS_MODIFIER_CREASE_ANGLE:
callback(((LineStyleAlphaModifier_CreaseAngle *)m)->curve);
break;
case LS_MODIFIER_CURVATURE_3D:
callback(((LineStyleAlphaModifier_Curvature_3D *)m)->curve);
break;
}
}
LISTBASE_FOREACH (LineStyleModifier *, m, &linestyle->thickness_modifiers) {
switch (m->type) {
case LS_MODIFIER_ALONG_STROKE:
callback(((LineStyleThicknessModifier_AlongStroke *)m)->curve);
break;
case LS_MODIFIER_DISTANCE_FROM_CAMERA:
callback(((LineStyleThicknessModifier_DistanceFromCamera *)m)->curve);
break;
case LS_MODIFIER_DISTANCE_FROM_OBJECT:
callback(((LineStyleThicknessModifier_DistanceFromObject *)m)->curve);
break;
case LS_MODIFIER_MATERIAL:
callback(((LineStyleThicknessModifier_Material *)m)->curve);
break;
case LS_MODIFIER_TANGENT:
callback(((LineStyleThicknessModifier_Tangent *)m)->curve);
break;
case LS_MODIFIER_CREASE_ANGLE:
callback(((LineStyleThicknessModifier_CreaseAngle *)m)->curve);
break;
case LS_MODIFIER_CURVATURE_3D:
callback(((LineStyleThicknessModifier_Curvature_3D *)m)->curve);
break;
}
}
}
}
void do_versions_after_linking_280(Main *bmain, ReportList *UNUSED(reports))
{
bool use_collection_compat_28 = true;
@ -910,11 +1140,10 @@ void do_versions_after_linking_280(Main *bmain, ReportList *UNUSED(reports))
}
}
/* We need to assign lib pointer to generated hidden collections *after* all have been created,
* otherwise we'll end up with several data-blocks sharing same name/library,
* which is FORBIDDEN!
* Note: we need this to be recursive,
* since a child collection may be sorted before its parent in bmain. */
/* We need to assign lib pointer to generated hidden collections *after* all have been
* created, otherwise we'll end up with several data-blocks sharing same name/library,
* which is FORBIDDEN! Note: we need this to be recursive, since a child collection may be
* sorted before its parent in bmain. */
for (Collection *collection = bmain->collections.first; collection != NULL;
collection = collection->id.next) {
do_version_collection_propagate_lib_to_children(collection);
@ -1218,7 +1447,8 @@ void do_versions_after_linking_280(Main *bmain, ReportList *UNUSED(reports))
}
if (!MAIN_VERSION_ATLEAST(bmain, 280, 38)) {
/* Ensure we get valid rigidbody object/constraint data in relevant collections' objects. */
/* Ensure we get valid rigidbody object/constraint data in relevant collections' objects.
*/
for (Scene *scene = bmain->scenes.first; scene; scene = scene->id.next) {
RigidBodyWorld *rbw = scene->rigidbody_world;
@ -1431,7 +1661,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
if (error & NTREE_DOVERSION_NEED_OUTPUT) {
BKE_report(fd->reports, RPT_ERROR, "Eevee material conversion problem. Error in console");
printf(
"You need to connect Principled and Eevee Specular shader nodes to new material output "
"You need to connect Principled and Eevee Specular shader nodes to new material "
"output "
"nodes.\n");
}
@ -3931,8 +4162,9 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
{
/* Versioning code until next subversion bump goes here. */
if (!MAIN_VERSION_ATLEAST(bmain, 282, 2)) {
do_version_curvemapping_walker(bmain, do_version_curvemapping_flag_extend_extrapolate);
for (bScreen *screen = bmain->screens.first; screen; screen = screen->id.next) {
for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
sa->flag &= ~AREA_FLAG_UNUSED_6;
@ -3988,4 +4220,8 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
}
{
/* Versioning code until next subversion bump goes here. */
}
}

View File

@ -2019,7 +2019,7 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, const uiWidgetColors *wcol, cons
rctf line_range;
/* First curve point. */
if ((cuma->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) {
if ((cumap->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) {
line_range.xmin = rect->xmin;
line_range.ymin = rect->ymin + zoomy * (cmp[0].y - offsy);
}
@ -2028,7 +2028,7 @@ void ui_draw_but_CURVE(ARegion *ar, uiBut *but, const uiWidgetColors *wcol, cons
line_range.ymin = rect->ymin + zoomy * (cmp[0].y - offsy + cuma->ext_in[1]);
}
/* Last curve point. */
if ((cuma->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) {
if ((cumap->flag & CUMA_EXTEND_EXTRAPOLATE) == 0) {
line_range.xmax = rect->xmax;
line_range.ymax = rect->ymin + zoomy * (cmp[CM_TABLE].y - offsy);
}

View File

@ -3992,11 +3992,11 @@ static void curvemap_tools_dofunc(bContext *C, void *cumap_v, int event)
BKE_curvemapping_changed(cumap, false);
break;
case UICURVE_FUNC_EXTEND_HOZ: /* extend horiz */
cuma->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
cumap->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
BKE_curvemapping_changed(cumap, false);
break;
case UICURVE_FUNC_EXTEND_EXP: /* extend extrapolate */
cuma->flag |= CUMA_EXTEND_EXTRAPOLATE;
cumap->flag |= CUMA_EXTEND_EXTRAPOLATE;
BKE_curvemapping_changed(cumap, false);
break;
}

View File

@ -1173,7 +1173,7 @@ static int render_shutter_curve_preset_exec(bContext *C, wmOperator *op)
CurveMap *cm = mblur_shutter_curve->cm;
int preset = RNA_enum_get(op->ptr, "shape");
cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
mblur_shutter_curve->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
mblur_shutter_curve->preset = preset;
BKE_curvemap_reset(
cm, &mblur_shutter_curve->clipr, mblur_shutter_curve->preset, CURVEMAP_SLOPE_POS_NEG);

View File

@ -266,8 +266,8 @@ static PyObject *Freestyle_evaluateCurveMappingF(PyObject * /*self*/, PyObject *
cumap = (CurveMapping *)py_srna->ptr.data;
BKE_curvemapping_initialize(cumap);
/* disable extrapolation if enabled */
if ((cumap->cm[cur].flag & CUMA_EXTEND_EXTRAPOLATE)) {
cumap->cm[cur].flag &= ~(CUMA_EXTEND_EXTRAPOLATE);
if ((cumap->flag & CUMA_EXTEND_EXTRAPOLATE)) {
cumap->flag &= ~(CUMA_EXTEND_EXTRAPOLATE);
BKE_curvemapping_changed(cumap, 0);
}
return PyFloat_FromDouble(BKE_curvemapping_evaluateF(cumap, cur, value));

View File

@ -1029,11 +1029,11 @@ void IMB_colormanagement_init_default_view_settings(
static void curve_mapping_apply_pixel(CurveMapping *curve_mapping, float *pixel, int channels)
{
if (channels == 1) {
pixel[0] = BKE_curvemap_evaluateF(curve_mapping->cm, pixel[0]);
pixel[0] = BKE_curvemap_evaluateF(curve_mapping, curve_mapping->cm, pixel[0]);
}
else if (channels == 2) {
pixel[0] = BKE_curvemap_evaluateF(curve_mapping->cm, pixel[0]);
pixel[1] = BKE_curvemap_evaluateF(curve_mapping->cm, pixel[1]);
pixel[0] = BKE_curvemap_evaluateF(curve_mapping, curve_mapping->cm, pixel[0]);
pixel[1] = BKE_curvemap_evaluateF(curve_mapping, curve_mapping->cm, pixel[1]);
}
else {
BKE_curvemapping_evaluate_premulRGBF(curve_mapping, pixel, pixel);
@ -3904,10 +3904,11 @@ static void curve_mapping_to_ocio_settings(CurveMapping *curve_mapping,
BKE_curvemapping_table_RGBA(
curve_mapping, &curve_mapping_settings->lut, &curve_mapping_settings->lut_size);
curve_mapping_settings->use_extend_extrapolate = (curve_mapping->flag &
CUMA_EXTEND_EXTRAPOLATE) != 0;
for (i = 0; i < 4; i++) {
CurveMap *cuma = curve_mapping->cm + i;
curve_mapping_settings->use_extend_extrapolate[i] = (cuma->flag & CUMA_EXTEND_EXTRAPOLATE) !=
0;
curve_mapping_settings->range[i] = cuma->range;
curve_mapping_settings->mintable[i] = cuma->mintable;
curve_mapping_settings->ext_in_x[i] = cuma->ext_in[0];

View File

@ -24,6 +24,7 @@
#ifndef __DNA_COLOR_TYPES_H__
#define __DNA_COLOR_TYPES_H__
#include "DNA_defs.h"
#include "DNA_vec_types.h"
/* general defines for kernel functions */
@ -47,7 +48,8 @@ enum {
};
typedef struct CurveMap {
short totpoint, flag;
short totpoint;
short flag DNA_DEPRECATED;
/** Quick multiply value for reading table. */
float range;
@ -67,9 +69,6 @@ typedef struct CurveMap {
float premul_ext_out[2];
} CurveMap;
/* cuma->flag */
#define CUMA_EXTEND_EXTRAPOLATE 1
typedef struct CurveMapping {
/** Cur; for buttons, to show active curve. */
int flag, cur;
@ -93,11 +92,17 @@ typedef struct CurveMapping {
char _pad[6];
} CurveMapping;
/* cumapping->flag */
#define CUMA_DO_CLIP (1 << 0)
#define CUMA_PREMULLED (1 << 1)
#define CUMA_DRAW_CFRA (1 << 2)
#define CUMA_DRAW_SAMPLE (1 << 3)
/* CurveMapping.flag */
typedef enum eCurveMappingFlags {
CUMA_DO_CLIP = (1 << 0),
CUMA_PREMULLED = (1 << 1),
CUMA_DRAW_CFRA = (1 << 2),
CUMA_DRAW_SAMPLE = (1 << 3),
/* The curve is extended by extrapolation. When not set the curve is extended
* Horizontally */
CUMA_EXTEND_EXTRAPOLATE = (1 << 4),
} eCurveMappingFlags;
/* cumapping->preset */
typedef enum eCurveMappingPreset {

View File

@ -123,6 +123,14 @@ static void rna_CurveMapping_tone_update(Main *UNUSED(bmain),
WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, NULL);
}
static void rna_CurveMapping_extend_update(Main *UNUSED(bmain),
Scene *UNUSED(scene),
PointerRNA *UNUSED(ptr))
{
WM_main_add_notifier(NC_NODE | NA_EDITED, NULL);
WM_main_add_notifier(NC_SCENE | ND_SEQUENCER, NULL);
}
static void rna_CurveMapping_clipminx_range(
PointerRNA *ptr, float *min, float *max, float *UNUSED(softmin), float *UNUSED(softmax))
{
@ -670,8 +678,17 @@ static void rna_ColorManagement_update(Main *UNUSED(bmain), Scene *UNUSED(scene)
}
/* this function only exists because #BKE_curvemap_evaluateF uses a 'const' qualifier */
static float rna_CurveMap_evaluateF(struct CurveMap *cuma, ReportList *reports, float value)
static float rna_CurveMapping_evaluateF(struct CurveMapping *cumap,
ReportList *reports,
struct CurveMap *cuma,
float value)
{
if (&cumap->cm[0] != cuma && &cumap->cm[1] != cuma && &cumap->cm[2] != cuma &&
&cumap->cm[3] != cuma) {
BKE_report(reports, RPT_ERROR, "CurveMapping does not own CurveMap");
return 0.0f;
}
if (!cuma->table) {
BKE_report(
reports,
@ -679,7 +696,7 @@ static float rna_CurveMap_evaluateF(struct CurveMap *cuma, ReportList *reports,
"CurveMap table not initialized, call initialize() on CurveMapping owner of the CurveMap");
return 0.0f;
}
return BKE_curvemap_evaluateF(cuma, value);
return BKE_curvemap_evaluateF(cumap, cuma, value);
}
static void rna_CurveMap_initialize(struct CurveMapping *cumap)
@ -758,58 +775,22 @@ static void rna_def_curvemap_points_api(BlenderRNA *brna, PropertyRNA *cprop)
static void rna_def_curvemap(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop, *parm;
FunctionRNA *func;
static const EnumPropertyItem prop_extend_items[] = {
{0, "HORIZONTAL", 0, "Horizontal", ""},
{CUMA_EXTEND_EXTRAPOLATE, "EXTRAPOLATED", 0, "Extrapolated", ""},
{0, NULL, 0, NULL, NULL},
};
PropertyRNA *prop;
srna = RNA_def_struct(brna, "CurveMap", NULL);
RNA_def_struct_ui_text(srna, "CurveMap", "Curve in a curve mapping");
prop = RNA_def_property(srna, "extend", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
RNA_def_property_enum_items(prop, prop_extend_items);
RNA_def_property_ui_text(prop, "Extend", "Extrapolate the curve or extend it horizontally");
prop = RNA_def_property(srna, "points", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "curve", "totpoint");
RNA_def_property_struct_type(prop, "CurveMapPoint");
RNA_def_property_ui_text(prop, "Points", "");
rna_def_curvemap_points_api(brna, prop);
func = RNA_def_function(srna, "evaluate", "rna_CurveMap_evaluateF");
RNA_def_function_flag(func, FUNC_USE_REPORTS);
RNA_def_function_ui_description(func, "Evaluate curve at given location");
parm = RNA_def_float(func,
"position",
0.0f,
-FLT_MAX,
FLT_MAX,
"Position",
"Position to evaluate curve at",
-FLT_MAX,
FLT_MAX);
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_float(func,
"value",
0.0f,
-FLT_MAX,
FLT_MAX,
"Value",
"Value of curve at given location",
-FLT_MAX,
FLT_MAX);
RNA_def_function_return(func, parm);
}
static void rna_def_curvemapping(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
PropertyRNA *prop, *parm;
FunctionRNA *func;
static const EnumPropertyItem tone_items[] = {
@ -818,6 +799,12 @@ static void rna_def_curvemapping(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL},
};
static const EnumPropertyItem prop_extend_items[] = {
{0, "HORIZONTAL", 0, "Horizontal", ""},
{CUMA_EXTEND_EXTRAPOLATE, "EXTRAPOLATED", 0, "Extrapolated", ""},
{0, NULL, 0, NULL, NULL},
};
srna = RNA_def_struct(brna, "CurveMapping", NULL);
RNA_def_struct_ui_text(
srna,
@ -860,6 +847,12 @@ static void rna_def_curvemapping(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Clip Max Y", "");
RNA_def_property_float_funcs(prop, NULL, NULL, "rna_CurveMapping_clipmaxy_range");
prop = RNA_def_property(srna, "extend", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
RNA_def_property_enum_items(prop, prop_extend_items);
RNA_def_property_ui_text(prop, "Extend", "Extrapolate the curve or extend it horizontally");
RNA_def_property_update(prop, 0, "rna_CurveMapping_extend_update");
prop = RNA_def_property(srna, "curves", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_funcs(prop,
"rna_CurveMapping_curves_begin",
@ -894,6 +887,32 @@ static void rna_def_curvemapping(BlenderRNA *brna)
func = RNA_def_function(srna, "initialize", "rna_CurveMap_initialize");
RNA_def_function_ui_description(func, "Initialize curve");
func = RNA_def_function(srna, "evaluate", "rna_CurveMapping_evaluateF");
RNA_def_function_flag(func, FUNC_USE_REPORTS);
RNA_def_function_ui_description(func, "Evaluate curve at given location");
parm = RNA_def_pointer(func, "curve", "CurveMap", "curve", "Curve to evaluate");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
parm = RNA_def_float(func,
"position",
0.0f,
-FLT_MAX,
FLT_MAX,
"Position",
"Position to evaluate curve at",
-FLT_MAX,
FLT_MAX);
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_float(func,
"value",
0.0f,
-FLT_MAX,
FLT_MAX,
"Value",
"Value of curve at given location",
-FLT_MAX,
FLT_MAX);
RNA_def_function_return(func, parm);
}
static void rna_def_color_ramp_element(BlenderRNA *brna)

View File

@ -147,7 +147,7 @@ static int gpu_shader_curve_rgb(GPUMaterial *mat,
ext_rgba[a][2] = cm->maxtable;
range_rgba[a] = 1.0f / max_ff(1e-8f, cm->maxtable - cm->mintable);
/* Compute extrapolation gradients. */
if ((cm->flag & CUMA_EXTEND_EXTRAPOLATE) != 0) {
if ((cumap->flag & CUMA_EXTEND_EXTRAPOLATE) != 0) {
ext_rgba[a][1] = (cm->ext_in[0] != 0.0f) ?
(cm->ext_in[1] / (cm->ext_in[0] * range_rgba[a])) :
1e8f;