diff options
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r-- | source/blender/blenkernel/intern/anim_sys.c | 34 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/armature.c | 39 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/brush.c | 33 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/colortools.c | 68 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/crazyspace.c | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/kelvinlet.c | 215 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/material.c | 5 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/paint.c | 16 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/scene.c | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/texture.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/workspace.c | 7 |
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) { |