Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorJeroen Bakker <j.bakker@atmind.nl>2019-11-01 14:09:55 +0300
committerJeroen Bakker <j.bakker@atmind.nl>2019-11-27 18:05:54 +0300
commit2e6159a4948cd0f4e0b636734bfe506796bd87f2 (patch)
treefb04244033e45a69c514ec9a0ac6aa6fd28d5a33 /source
parent6992fc0b3bf85e985169157b2e7ced1e1ed7fcdf (diff)
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
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_blender_version.h2
-rw-r--r--source/blender/blenkernel/BKE_colortools.h4
-rw-r--r--source/blender/blenkernel/intern/brush.c15
-rw-r--r--source/blender/blenkernel/intern/colortools.c68
-rw-r--r--source/blender/blenkernel/intern/paint.c16
-rw-r--r--source/blender/blenkernel/intern/texture.c2
-rw-r--r--source/blender/blenloader/intern/versioning_280.c256
-rw-r--r--source/blender/editors/interface/interface_draw.c4
-rw-r--r--source/blender/editors/interface/interface_templates.c4
-rw-r--r--source/blender/editors/render/render_internal.c2
-rw-r--r--source/blender/freestyle/intern/python/BPy_Freestyle.cpp4
-rw-r--r--source/blender/imbuf/intern/colormanagement.c11
-rw-r--r--source/blender/makesdna/DNA_color_types.h23
-rw-r--r--source/blender/makesrna/intern/rna_color.c99
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_curves.c2
15 files changed, 389 insertions, 123 deletions
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h
index dd1fff9ce47..c38e6e14d70 100644
--- a/source/blender/blenkernel/BKE_blender_version.h
+++ b/source/blender/blenkernel/BKE_blender_version.h
@@ -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
diff --git a/source/blender/blenkernel/BKE_colortools.h b/source/blender/blenkernel/BKE_colortools.h
index 643073b3470..e4ea1dad086 100644
--- a/source/blender/blenkernel/BKE_colortools.h
+++ b/source/blender/blenkernel/BKE_colortools.h
@@ -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,
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 4d496fe758b..27c3df5ce6e 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -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
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index 8166bbea962..2ec04ee2747 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -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);
}
}
}
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 46ef24be5e9..e7c20ca4fb2 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -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)
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index f4e89160487..b1ae71c609f 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -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,
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index 0cb68cfd7fe..0b7ec8cf225 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -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. */
+ }
}
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index 499842a570b..31cbd2a3831 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -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);
}
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index 956fd4514af..17247736d3b 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -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;
}
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index 7106af25a82..5740dacd05f 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -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);
diff --git a/source/blender/freestyle/intern/python/BPy_Freestyle.cpp b/source/blender/freestyle/intern/python/BPy_Freestyle.cpp
index 367ad556d02..a6512a64776 100644
--- a/source/blender/freestyle/intern/python/BPy_Freestyle.cpp
+++ b/source/blender/freestyle/intern/python/BPy_Freestyle.cpp
@@ -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));
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index 1b911226c6f..71e9da70c35 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -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];
diff --git a/source/blender/makesdna/DNA_color_types.h b/source/blender/makesdna/DNA_color_types.h
index 219fc96554a..66adc547cf2 100644
--- a/source/blender/makesdna/DNA_color_types.h
+++ b/source/blender/makesdna/DNA_color_types.h
@@ -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 {
diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c
index 011e373cc61..679ccc9725b 100644
--- a/source/blender/makesrna/intern/rna_color.c
+++ b/source/blender/makesrna/intern/rna_color.c
@@ -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)
diff --git a/source/blender/nodes/shader/nodes/node_shader_curves.c b/source/blender/nodes/shader/nodes/node_shader_curves.c
index f5c89e6ba41..6292d7b5062 100644
--- a/source/blender/nodes/shader/nodes/node_shader_curves.c
+++ b/source/blender/nodes/shader/nodes/node_shader_curves.c
@@ -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;