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
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c34
-rw-r--r--source/blender/blenkernel/intern/armature.c39
-rw-r--r--source/blender/blenkernel/intern/brush.c33
-rw-r--r--source/blender/blenkernel/intern/colortools.c68
-rw-r--r--source/blender/blenkernel/intern/crazyspace.c6
-rw-r--r--source/blender/blenkernel/intern/kelvinlet.c215
-rw-r--r--source/blender/blenkernel/intern/material.c5
-rw-r--r--source/blender/blenkernel/intern/paint.c16
-rw-r--r--source/blender/blenkernel/intern/scene.c1
-rw-r--r--source/blender/blenkernel/intern/texture.c2
-rw-r--r--source/blender/blenkernel/intern/workspace.c7
11 files changed, 323 insertions, 103 deletions
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index eea71d52ab6..32420e2e894 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -1717,7 +1717,7 @@ static bool animsys_store_rna_setting(PointerRNA *ptr,
/* less than 1.0 evaluates to false, use epsilon to avoid float error */
#define ANIMSYS_FLOAT_AS_BOOL(value) ((value) > ((1.0f - FLT_EPSILON)))
-static bool animsys_read_rna_setting(PathResolvedRNA *anim_rna, float *r_value)
+bool BKE_animsys_read_rna_setting(PathResolvedRNA *anim_rna, float *r_value)
{
PropertyRNA *prop = anim_rna->prop;
PointerRNA *ptr = &anim_rna->ptr;
@@ -1780,7 +1780,7 @@ static bool animsys_read_rna_setting(PathResolvedRNA *anim_rna, float *r_value)
}
/* Write the given value to a setting using RNA, and return success */
-static bool animsys_write_rna_setting(PathResolvedRNA *anim_rna, const float value)
+bool BKE_animsys_write_rna_setting(PathResolvedRNA *anim_rna, const float value)
{
PropertyRNA *prop = anim_rna->prop;
PointerRNA *ptr = &anim_rna->ptr;
@@ -1791,7 +1791,7 @@ static bool animsys_write_rna_setting(PathResolvedRNA *anim_rna, const float val
/* Check whether value is new. Otherwise we skip all the updates. */
float old_value;
- if (!animsys_read_rna_setting(anim_rna, &old_value)) {
+ if (!BKE_animsys_read_rna_setting(anim_rna, &old_value)) {
return false;
}
if (old_value == value) {
@@ -1845,20 +1845,6 @@ static bool animsys_write_rna_setting(PathResolvedRNA *anim_rna, const float val
return true;
}
-/* Simple replacement based data-setting of the FCurve using RNA */
-bool BKE_animsys_execute_fcurve(PointerRNA *ptr, FCurve *fcu, float curval)
-{
- PathResolvedRNA anim_rna;
- bool ok = false;
-
- if (animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
- ok = animsys_write_rna_setting(&anim_rna, curval);
- }
-
- /* return whether we were successful */
- return ok;
-}
-
static bool animsys_construct_orig_pointer_rna(const PointerRNA *ptr, PointerRNA *ptr_orig)
{
*ptr_orig = *ptr;
@@ -1895,7 +1881,7 @@ static void animsys_write_orig_anim_rna(PointerRNA *ptr,
PathResolvedRNA orig_anim_rna;
/* TODO(sergey): Should be possible to cache resolved path in dependency graph somehow. */
if (animsys_store_rna_setting(&ptr_orig, rna_path, array_index, &orig_anim_rna)) {
- animsys_write_rna_setting(&orig_anim_rna, value);
+ BKE_animsys_write_rna_setting(&orig_anim_rna, value);
}
}
@@ -1926,7 +1912,7 @@ static void animsys_evaluate_fcurves(PointerRNA *ptr,
PathResolvedRNA anim_rna;
if (animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
const float curval = calculate_fcurve(&anim_rna, fcu, ctime);
- animsys_write_rna_setting(&anim_rna, curval);
+ BKE_animsys_write_rna_setting(&anim_rna, curval);
if (flush_to_original) {
animsys_write_orig_anim_rna(ptr, fcu->rna_path, fcu->array_index, curval);
}
@@ -1960,7 +1946,7 @@ static void animsys_evaluate_drivers(PointerRNA *ptr, AnimData *adt, float ctime
PathResolvedRNA anim_rna;
if (animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
const float curval = calculate_fcurve(&anim_rna, fcu, ctime);
- ok = animsys_write_rna_setting(&anim_rna, curval);
+ ok = BKE_animsys_write_rna_setting(&anim_rna, curval);
}
/* set error-flag if evaluation failed */
@@ -2039,7 +2025,7 @@ void animsys_evaluate_action_group(PointerRNA *ptr, bAction *act, bActionGroup *
PathResolvedRNA anim_rna;
if (animsys_store_rna_setting(ptr, fcu->rna_path, fcu->array_index, &anim_rna)) {
const float curval = calculate_fcurve(&anim_rna, fcu, ctime);
- animsys_write_rna_setting(&anim_rna, curval);
+ BKE_animsys_write_rna_setting(&anim_rna, curval);
}
}
}
@@ -3333,7 +3319,7 @@ void nladata_flush_channels(PointerRNA *ptr,
if (nec->is_array) {
rna.prop_index = i;
}
- animsys_write_rna_setting(&rna, value);
+ BKE_animsys_write_rna_setting(&rna, value);
if (flush_to_original) {
animsys_write_orig_anim_rna(ptr, nec->rna_path, rna.prop_index, value);
}
@@ -3818,7 +3804,7 @@ static void animsys_evaluate_overrides(PointerRNA *ptr, AnimData *adt)
for (aor = adt->overrides.first; aor; aor = aor->next) {
PathResolvedRNA anim_rna;
if (animsys_store_rna_setting(ptr, aor->rna_path, aor->array_index, &anim_rna)) {
- animsys_write_rna_setting(&anim_rna, aor->value);
+ BKE_animsys_write_rna_setting(&anim_rna, aor->value);
}
}
}
@@ -4143,7 +4129,7 @@ void BKE_animsys_eval_driver(Depsgraph *depsgraph, ID *id, int driver_index, FCu
/* Evaluate driver, and write results to COW-domain destination */
const float ctime = DEG_get_ctime(depsgraph);
const float curval = calculate_fcurve(&anim_rna, fcu, ctime);
- ok = animsys_write_rna_setting(&anim_rna, curval);
+ ok = BKE_animsys_write_rna_setting(&anim_rna, curval);
/* Flush results & status codes to original data for UI (T59984) */
if (ok && DEG_is_active(depsgraph)) {
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 58b0c9b41ea..a694a335069 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -281,22 +281,22 @@ static void armature_transform_recurse(ListBase *bonebase,
{
for (Bone *bone = bonebase->first; bone; bone = bone->next) {
- /* Transform the bone's roll. */
- if (bone_parent == NULL) {
-
- float roll_mat[3][3];
- {
- float delta[3];
- sub_v3_v3v3(delta, bone->tail, bone->head);
- vec_roll_to_mat3(delta, bone->roll, roll_mat);
+ /* Store the initial bone roll in a matrix, this is needed even for child bones
+ * so any change in head/tail doesn't cause the roll to change.
+ *
+ * Logic here is different to edit-mode because
+ * this is calculated in relative to the parent. */
+ float roll_mat3_pre[3][3];
+ {
+ float delta[3];
+ sub_v3_v3v3(delta, bone->tail, bone->head);
+ vec_roll_to_mat3(delta, bone->roll, roll_mat3_pre);
+ if (bone->parent == NULL) {
+ mul_m3_m3m3(roll_mat3_pre, mat3, roll_mat3_pre);
}
-
- /* Transform the roll matrix. */
- mul_m3_m3m3(roll_mat, mat3, roll_mat);
-
- /* Apply the transformed roll back. */
- mat3_to_vec_roll(roll_mat, NULL, &bone->roll);
}
+ /* Optional, use this for predictable results since the roll is re-calculated below anyway. */
+ bone->roll = 0.0f;
mul_m4_v3(mat, bone->arm_head);
mul_m4_v3(mat, bone->arm_tail);
@@ -314,6 +314,17 @@ static void armature_transform_recurse(ListBase *bonebase,
copy_v3_v3(bone->tail, bone->arm_tail);
}
+ /* Now the head/tail have been updated, set the roll back, matching 'roll_mat3_pre'. */
+ {
+ float roll_mat3_post[3][3], delta_mat3[3][3];
+ float delta[3];
+ sub_v3_v3v3(delta, bone->tail, bone->head);
+ vec_roll_to_mat3(delta, 0.0f, roll_mat3_post);
+ invert_m3(roll_mat3_post);
+ mul_m3_m3m3(delta_mat3, roll_mat3_post, roll_mat3_pre);
+ bone->roll = atan2f(delta_mat3[2][0], delta_mat3[2][2]);
+ }
+
BKE_armature_where_is_bone(bone, bone_parent, false);
{
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 4d496fe758b..8b90eafdddf 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -931,7 +931,9 @@ void BKE_brush_sculpt_reset(Brush *br)
br->alpha = 1.0f;
break;
case SCULPT_TOOL_CLAY:
- br->spacing = 6;
+ br->flag |= BRUSH_SIZE_PRESSURE;
+ br->spacing = 3;
+ br->autosmooth_factor = 0.25f;
br->normal_radius_factor = 0.75f;
break;
case SCULPT_TOOL_CLAY_STRIPS:
@@ -1069,18 +1071,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
@@ -1398,20 +1401,14 @@ bool BKE_brush_use_locked_size(const Scene *scene, const Brush *brush)
(brush->flag & BRUSH_LOCK_SIZE);
}
-bool BKE_brush_use_size_pressure(const Scene *scene, const Brush *brush)
+bool BKE_brush_use_size_pressure(const Brush *brush)
{
- const short us_flag = scene->toolsettings->unified_paint_settings.flag;
-
- return (us_flag & UNIFIED_PAINT_SIZE) ? (us_flag & UNIFIED_PAINT_BRUSH_SIZE_PRESSURE) :
- (brush->flag & BRUSH_SIZE_PRESSURE);
+ return brush->flag & BRUSH_SIZE_PRESSURE;
}
-bool BKE_brush_use_alpha_pressure(const Scene *scene, const Brush *brush)
+bool BKE_brush_use_alpha_pressure(const Brush *brush)
{
- const short us_flag = scene->toolsettings->unified_paint_settings.flag;
-
- return (us_flag & UNIFIED_PAINT_ALPHA) ? (us_flag & UNIFIED_PAINT_BRUSH_ALPHA_PRESSURE) :
- (brush->flag & BRUSH_ALPHA_PRESSURE);
+ return brush->flag & BRUSH_ALPHA_PRESSURE;
}
bool BKE_brush_sculpt_has_secondary_color(const Brush *brush)
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/crazyspace.c b/source/blender/blenkernel/intern/crazyspace.c
index 9618ef8c78e..33f9b5b1012 100644
--- a/source/blender/blenkernel/intern/crazyspace.c
+++ b/source/blender/blenkernel/intern/crazyspace.c
@@ -417,12 +417,12 @@ int BKE_sculpt_get_first_deform_matrices(struct Depsgraph *depsgraph,
mti->deformMatrices(md, &mectx, me_eval, deformedVerts, defmats, me_eval->totvert);
}
else {
+ /* More complex handling will continue in BKE_crazyspace_build_sculpt.
+ * Exiting the loop on a non-deform modifier causes issues - T71213. */
+ BLI_assert(crazyspace_modifier_supports_deform(md));
break;
}
}
- else {
- break;
- }
}
for (; md; md = md->next) {
diff --git a/source/blender/blenkernel/intern/kelvinlet.c b/source/blender/blenkernel/intern/kelvinlet.c
new file mode 100644
index 00000000000..a7b48107873
--- /dev/null
+++ b/source/blender/blenkernel/intern/kelvinlet.c
@@ -0,0 +1,215 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) Blender Foundation.
+ * All rights reserved.
+ */
+
+/** \file
+ * \ingroup bke
+ */
+
+#include "BKE_kelvinlet.h"
+
+/* Regularized Kelvinlets: Sculpting Brushes based on Fundamental Solutions of Elasticity
+ * Pixar Technical Memo #17-03 */
+
+void BKE_kelvinlet_init_params(
+ KelvinletParams *params, float radius, float force, float shear_modulus, float poisson_ratio)
+{
+ params->a = 1.0f / (4.0f * (float)M_PI * shear_modulus);
+ params->b = params->a / (4.0f * (1.0f - poisson_ratio));
+ params->c = 2 * (3.0f * params->a - 2.0f * params->b);
+
+ /* Used in scale and twist. */
+ params->f = force;
+
+ /* This can be exposed if needed */
+ const float radius_e[KELVINLET_MAX_ITERATIONS] = {1.0f, 2.0f, 2.0f};
+ params->radius_scaled[0] = radius * radius_e[0];
+ params->radius_scaled[1] = params->radius_scaled[0] * radius_e[1];
+ params->radius_scaled[2] = params->radius_scaled[1] * radius_e[2];
+}
+
+static void init_kelvinlet_grab(float radius_e[3],
+ float kelvinlet[3],
+ const float radius,
+ const KelvinletParams *params,
+ const int num_iterations)
+{
+ const float a = params->a;
+ const float b = params->b;
+ const float *radius_scaled = params->radius_scaled;
+
+ for (int i = 0; i < num_iterations; i++) {
+ radius_e[i] = sqrtf(pow2f(radius) + pow2f(params->radius_scaled[i]));
+ }
+
+ /* Regularized Kelvinlets: Formula (6) */
+ for (int i = 0; i < num_iterations; i++) {
+ kelvinlet[i] = ((a - b) / radius_e[i]) + ((b * pow2f(radius)) / pow3f(radius_e[i])) +
+ ((a * pow2f(radius_scaled[i])) / (2.0f * pow3f(radius_e[i])));
+ }
+}
+
+void BKE_kelvinlet_grab(float radius_elem_disp[3],
+ const KelvinletParams *params,
+ const float elem_orig_co[3],
+ const float brush_location[3],
+ const float brush_delta[3])
+{
+ float radius_e[3], kelvinlet[3];
+ const float c = params->c;
+ const float radius = len_v3v3(brush_location, elem_orig_co);
+
+ init_kelvinlet_grab(radius_e, kelvinlet, radius, params, 1);
+
+ const float fade = kelvinlet[0] * c;
+
+ mul_v3_v3fl(radius_elem_disp, brush_delta, fade);
+}
+
+void BKE_kelvinlet_grab_biscale(float radius_elem_disp[3],
+ const KelvinletParams *params,
+ const float elem_orig_co[3],
+ const float brush_location[3],
+ const float brush_delta[3])
+{
+ float radius_e[3], kelvinlet[3];
+ const float c = params->c;
+ const float *radius_scaled = params->radius_scaled;
+ float radius = len_v3v3(brush_location, elem_orig_co);
+
+ init_kelvinlet_grab(radius_e, kelvinlet, radius, params, 2);
+
+ const float u = kelvinlet[0] - kelvinlet[1];
+ const float fade = u * c / ((1.0f / radius_scaled[0]) - (1.0f / radius_scaled[1]));
+
+ mul_v3_v3fl(radius_elem_disp, brush_delta, fade);
+}
+
+void BKE_kelvinlet_grab_triscale(float radius_elem_disp[3],
+ const KelvinletParams *params,
+ const float elem_orig_co[3],
+ const float brush_location[3],
+ const float brush_delta[3])
+{
+ float radius_e[3], kelvinlet[3], weights[3];
+ const float c = params->c;
+ const float *radius_scaled = params->radius_scaled;
+ const float radius = len_v3v3(brush_location, elem_orig_co);
+
+ init_kelvinlet_grab(radius_e, kelvinlet, radius, params, 3);
+
+ weights[0] = 1.0f;
+ weights[1] = -((pow2f(radius_scaled[2]) - pow2f(radius_scaled[0])) /
+ (pow2f(radius_scaled[2]) - pow2f(radius_scaled[1])));
+ weights[2] = ((pow2f(radius_scaled[1]) - pow2f(radius_scaled[0])) /
+ (pow2f(radius_scaled[2]) - pow2f(radius_scaled[1])));
+
+ const float u = weights[0] * kelvinlet[0] + weights[1] * kelvinlet[1] +
+ weights[2] * kelvinlet[2];
+ const float fade = u * c /
+ (weights[0] / radius_scaled[0] + weights[1] / radius_scaled[1] +
+ weights[2] / radius_scaled[2]);
+
+ mul_v3_v3fl(radius_elem_disp, brush_delta, fade);
+}
+
+typedef void (*kelvinlet_fn)(
+ float[3], const float *, const float *, const float *, const KelvinletParams *);
+
+static void sculpt_kelvinet_integrate(kelvinlet_fn kelvinlet,
+ float r_disp[3],
+ const float vertex_co[3],
+ const float location[3],
+ const float normal[3],
+ const KelvinletParams *p)
+{
+ float k[4][3], k_it[4][3];
+ kelvinlet(k[0], vertex_co, location, normal, p);
+ copy_v3_v3(k_it[0], k[0]);
+ mul_v3_fl(k_it[0], 0.5f);
+ add_v3_v3v3(k_it[0], vertex_co, k_it[0]);
+ kelvinlet(k[1], k_it[0], location, normal, p);
+ copy_v3_v3(k_it[1], k[1]);
+ mul_v3_fl(k_it[1], 0.5f);
+ add_v3_v3v3(k_it[1], vertex_co, k_it[1]);
+ kelvinlet(k[2], k_it[1], location, normal, p);
+ copy_v3_v3(k_it[2], k[2]);
+ add_v3_v3v3(k_it[2], vertex_co, k_it[2]);
+ sub_v3_v3v3(k_it[2], k_it[2], location);
+ kelvinlet(k[3], k_it[2], location, normal, p);
+ copy_v3_v3(r_disp, k[0]);
+ madd_v3_v3fl(r_disp, k[1], 2.0f);
+ madd_v3_v3fl(r_disp, k[2], 2.0f);
+ add_v3_v3(r_disp, k[3]);
+ mul_v3_fl(r_disp, 1.0f / 6.0f);
+}
+
+/* Regularized Kelvinlets: Formula (16) */
+static void kelvinlet_scale(float disp[3],
+ const float vertex_co[3],
+ const float location[3],
+ const float UNUSED(normal[3]),
+ const KelvinletParams *p)
+{
+ float radius_vertex[3];
+ sub_v3_v3v3(radius_vertex, vertex_co, location);
+ const float radius = len_v3(radius_vertex);
+ const float radius_e = sqrtf(pow2f(radius) + pow2f(p->radius_scaled[0]));
+ const float u = (2.0f * p->b - p->a) * ((1.0f / pow3f(radius_e))) +
+ ((3.0f * pow2f(p->radius_scaled[0])) / (2.0f * pow5f(radius_e)));
+ const float fade = u * p->c;
+ mul_v3_v3fl(disp, radius_vertex, fade * p->f);
+}
+
+void BKE_kelvinlet_scale(float radius_elem_disp[3],
+ const KelvinletParams *params,
+ const float elem_orig_co[3],
+ const float brush_location[3],
+ const float surface_normal[3])
+{
+ sculpt_kelvinet_integrate(
+ kelvinlet_scale, radius_elem_disp, elem_orig_co, brush_location, surface_normal, params);
+}
+
+/* Regularized Kelvinlets: Formula (15) */
+static void kelvinlet_twist(float disp[3],
+ const float vertex_co[3],
+ const float location[3],
+ const float normal[3],
+ const KelvinletParams *p)
+{
+ float radius_vertex[3], q_r[3];
+ sub_v3_v3v3(radius_vertex, vertex_co, location);
+ const float radius = len_v3(radius_vertex);
+ const float radius_e = sqrtf(pow2f(radius) + pow2f(p->radius_scaled[0]));
+ const float u = -p->a * ((1.0f / pow3f(radius_e))) +
+ ((3.0f * pow2f(p->radius_scaled[0])) / (2.0f * pow5f(radius_e)));
+ const float fade = u * p->c;
+ cross_v3_v3v3(q_r, normal, radius_vertex);
+ mul_v3_v3fl(disp, q_r, fade * p->f);
+}
+
+void BKE_kelvinlet_twist(float radius_elem_disp[3],
+ const KelvinletParams *params,
+ const float elem_orig_co[3],
+ const float brush_location[3],
+ const float surface_normal[3])
+{
+ sculpt_kelvinet_integrate(
+ kelvinlet_twist, radius_elem_disp, elem_orig_co, brush_location, surface_normal, params);
+}
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 73c278a0ab6..54432c8da74 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -598,6 +598,11 @@ Material *BKE_material_gpencil_get(Object *ob, short act)
}
}
+struct Material *BKE_material_gpencil_default_get(void)
+{
+ return &defgpencil_material;
+}
+
MaterialGPencilStyle *BKE_material_gpencil_settings_get(Object *ob, short act)
{
Material *ma = give_current_material(ob, act);
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/scene.c b/source/blender/blenkernel/intern/scene.c
index 9dcebbba56e..ab72b7d3b0d 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -1284,6 +1284,7 @@ static void prepare_mesh_for_viewport_render(Main *bmain, const ViewLayer *view_
mesh,
(&(struct BMeshToMeshParams){
.calc_object_remap = true,
+ .update_shapekey_indices = true,
}));
DEG_id_tag_update(&mesh->id, 0);
}
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/blenkernel/intern/workspace.c b/source/blender/blenkernel/intern/workspace.c
index dd2b182474e..3e449fa6b25 100644
--- a/source/blender/blenkernel/intern/workspace.c
+++ b/source/blender/blenkernel/intern/workspace.c
@@ -26,6 +26,7 @@
#include "BLI_string_utils.h"
#include "BLI_listbase.h"
+#include "BKE_global.h"
#include "BKE_idprop.h"
#include "BKE_library.h"
#include "BKE_main.h"
@@ -202,8 +203,10 @@ WorkSpaceInstanceHook *BKE_workspace_instance_hook_create(const Main *bmain)
}
void BKE_workspace_instance_hook_free(const Main *bmain, WorkSpaceInstanceHook *hook)
{
- /* workspaces should never be freed before wm (during which we call this function) */
- BLI_assert(!BLI_listbase_is_empty(&bmain->workspaces));
+ /* workspaces should never be freed before wm (during which we call this function).
+ * However, when running in background mode, loading a blend file may allocate windows (that need
+ * to be freed) without creating workspaces. This happens in BlendfileLoadingBaseTest. */
+ BLI_assert(!BLI_listbase_is_empty(&bmain->workspaces) || G.background);
/* Free relations for this hook */
for (WorkSpace *workspace = bmain->workspaces.first; workspace; workspace = workspace->id.next) {