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:
authorJason Wilkins <Jason.A.Wilkins@gmail.com>2012-10-07 15:55:49 +0400
committerJason Wilkins <Jason.A.Wilkins@gmail.com>2012-10-07 15:55:49 +0400
commite4c70deee87290363d02942ecbbf39216a3620a8 (patch)
treeb98b5477e6ce7c43e6aafac5cda851c3d95cbfaf /source/blender/blenkernel/intern
parent39d020da482c8859f1a9229c392145f904973387 (diff)
parent7748133bf2d0a99f37b2a0b0ce438b6726db36fa (diff)
Merge w/ trunk: r50097-r51140 (also, I got ahead of myself and fixed a lot of warnings before committing)
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/CCGSubSurf.c4
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c68
-rw-r--r--source/blender/blenkernel/intern/action.c483
-rw-r--r--source/blender/blenkernel/intern/anim.c195
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c95
-rw-r--r--source/blender/blenkernel/intern/armature.c59
-rw-r--r--source/blender/blenkernel/intern/blender.c88
-rw-r--r--source/blender/blenkernel/intern/bmfont.c2
-rw-r--r--source/blender/blenkernel/intern/brush.c8
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c1
-rw-r--r--source/blender/blenkernel/intern/cloth.c35
-rw-r--r--source/blender/blenkernel/intern/collision.c2
-rw-r--r--source/blender/blenkernel/intern/colortools.c113
-rw-r--r--source/blender/blenkernel/intern/constraint.c64
-rw-r--r--source/blender/blenkernel/intern/curve.c73
-rw-r--r--source/blender/blenkernel/intern/customdata.c156
-rw-r--r--source/blender/blenkernel/intern/customdata_file.c34
-rw-r--r--source/blender/blenkernel/intern/deform.c56
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c5
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c51
-rw-r--r--source/blender/blenkernel/intern/editderivedmesh.c8
-rw-r--r--source/blender/blenkernel/intern/fcurve.c31
-rw-r--r--source/blender/blenkernel/intern/fmodifier.c8
-rw-r--r--source/blender/blenkernel/intern/font.c1
-rw-r--r--source/blender/blenkernel/intern/gpencil.c11
-rw-r--r--source/blender/blenkernel/intern/group.c64
-rw-r--r--source/blender/blenkernel/intern/icons.c4
-rw-r--r--source/blender/blenkernel/intern/idprop.c16
-rw-r--r--source/blender/blenkernel/intern/image.c168
-rw-r--r--source/blender/blenkernel/intern/image_gen.c6
-rw-r--r--source/blender/blenkernel/intern/implicit.c26
-rw-r--r--source/blender/blenkernel/intern/ipo.c8
-rw-r--r--source/blender/blenkernel/intern/key.c113
-rw-r--r--source/blender/blenkernel/intern/lattice.c2
-rw-r--r--source/blender/blenkernel/intern/library.c53
-rw-r--r--source/blender/blenkernel/intern/mask.c770
-rw-r--r--source/blender/blenkernel/intern/mask_evaluate.c863
-rw-r--r--source/blender/blenkernel/intern/mask_rasterize.c65
-rw-r--r--source/blender/blenkernel/intern/material.c39
-rw-r--r--source/blender/blenkernel/intern/mball.c421
-rw-r--r--source/blender/blenkernel/intern/mesh.c37
-rw-r--r--source/blender/blenkernel/intern/modifier.c2
-rw-r--r--source/blender/blenkernel/intern/modifiers_bmesh.c21
-rw-r--r--source/blender/blenkernel/intern/movieclip.c63
-rw-r--r--source/blender/blenkernel/intern/multires.c19
-rw-r--r--source/blender/blenkernel/intern/nla.c2
-rw-r--r--source/blender/blenkernel/intern/node.c122
-rw-r--r--source/blender/blenkernel/intern/object.c250
-rw-r--r--source/blender/blenkernel/intern/object_deform.c156
-rw-r--r--source/blender/blenkernel/intern/ocean.c11
-rw-r--r--source/blender/blenkernel/intern/packedFile.c1
-rw-r--r--source/blender/blenkernel/intern/paint.c2
-rw-r--r--source/blender/blenkernel/intern/particle.c10
-rw-r--r--source/blender/blenkernel/intern/particle_system.c13
-rw-r--r--source/blender/blenkernel/intern/pointcache.c50
-rw-r--r--source/blender/blenkernel/intern/property.c65
-rw-r--r--source/blender/blenkernel/intern/sca.c26
-rw-r--r--source/blender/blenkernel/intern/scene.c48
-rw-r--r--source/blender/blenkernel/intern/seqeffects.c52
-rw-r--r--source/blender/blenkernel/intern/seqmodifier.c157
-rw-r--r--source/blender/blenkernel/intern/sequencer.c361
-rw-r--r--source/blender/blenkernel/intern/shrinkwrap.c4
-rw-r--r--source/blender/blenkernel/intern/smoke.c6
-rw-r--r--source/blender/blenkernel/intern/softbody.c10
-rw-r--r--source/blender/blenkernel/intern/sound.c38
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c30
-rw-r--r--source/blender/blenkernel/intern/text.c41
-rw-r--r--source/blender/blenkernel/intern/texture.c21
-rw-r--r--source/blender/blenkernel/intern/tracking.c49
-rw-r--r--source/blender/blenkernel/intern/unit.c2
-rw-r--r--source/blender/blenkernel/intern/world.c10
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c191
72 files changed, 3378 insertions, 2761 deletions
diff --git a/source/blender/blenkernel/intern/CCGSubSurf.c b/source/blender/blenkernel/intern/CCGSubSurf.c
index 387d4775ad4..82ac0736b07 100644
--- a/source/blender/blenkernel/intern/CCGSubSurf.c
+++ b/source/blender/blenkernel/intern/CCGSubSurf.c
@@ -1397,7 +1397,7 @@ CCGError ccgSubSurf_processSync(CCGSubSurf *ss)
return eCCGError_None;
}
-#define VERT_getNo(e, lvl) _vert_getNo(e, lvl, vertDataSize, normalDataOffset)
+#define VERT_getNo(e, lvl) _vert_getNo(v, lvl, vertDataSize, normalDataOffset)
#define EDGE_getNo(e, lvl, x) _edge_getNo(e, lvl, x, vertDataSize, normalDataOffset)
#define FACE_getIFNo(f, lvl, S, x, y) _face_getIFNo(f, lvl, S, x, y, subdivLevels, vertDataSize, normalDataOffset)
#define FACE_calcIFNo(f, lvl, S, x, y, no) _face_calcIFNo(f, lvl, S, x, y, no, subdivLevels, vertDataSize)
@@ -1491,7 +1491,7 @@ static void ccgSubSurf__calcVertNormals(CCGSubSurf *ss,
/* XXX can I reduce the number of normalisations here? */
for (ptrIdx = 0; ptrIdx < numEffectedV; ptrIdx++) {
CCGVert *v = (CCGVert *) effectedV[ptrIdx];
- float length, *no = _vert_getNo(v, lvl, vertDataSize, normalDataOffset);
+ float length, *no = VERT_getNo(v, lvl);
NormZero(no);
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 062a790dc71..5ff1ce2aec3 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -59,6 +59,7 @@
#include "BKE_modifier.h"
#include "BKE_mesh.h"
#include "BKE_object.h"
+#include "BKE_object_deform.h"
#include "BKE_paint.h"
#include "BKE_texture.h"
#include "BKE_multires.h"
@@ -382,7 +383,7 @@ void DM_ensure_tessface(DerivedMesh *dm)
}
}
- else if (dm->dirty && DM_DIRTY_TESS_CDLAYERS) {
+ else if (dm->dirty & DM_DIRTY_TESS_CDLAYERS) {
BLI_assert(CustomData_has_layer(&dm->faceData, CD_POLYINDEX));
DM_update_tessface_data(dm);
}
@@ -540,7 +541,7 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob)
CustomData_free(&me->pdata, me->totpoly);
/* ok, this should now use new CD shapekey data,
- * which shouuld be fed through the modifier
+ * which should be fed through the modifier
* stack*/
if (tmp.totvert != me->totvert && !did_shapekeys && me->key) {
printf("%s: YEEK! this should be recoded! Shape key loss!: ID '%s'\n", __func__, tmp.id.name);
@@ -576,6 +577,13 @@ void DM_set_only_copy(DerivedMesh *dm, CustomDataMask mask)
CustomData_set_only_copy(&dm->vertData, mask);
CustomData_set_only_copy(&dm->edgeData, mask);
CustomData_set_only_copy(&dm->faceData, mask);
+ /* this wasn't in 2.63 and is disabled for 2.64 because it gives problems with
+ * weight paint mode when there are modifiers applied, needs further investigation,
+ * see replies to r50969, Campbell */
+#if 0
+ CustomData_set_only_copy(&dm->loopData, mask);
+ CustomData_set_only_copy(&dm->polyData, mask);
+#endif
}
void DM_add_vert_layer(DerivedMesh *dm, int type, int alloctype, void *layer)
@@ -806,7 +814,7 @@ DerivedMesh *mesh_create_derived_for_modifier(Scene *scene, Object *ob,
if (mti->isDisabled && mti->isDisabled(md, 0)) return NULL;
if (build_shapekey_layers && me->key && (kb = BLI_findlink(&me->key->block, ob->shapenr - 1))) {
- key_to_mesh(kb, me);
+ BKE_key_convert_to_mesh(kb, me);
}
if (mti->type == eModifierTypeType_OnlyDeform) {
@@ -876,7 +884,7 @@ static void *get_orco_coords_dm(Object *ob, BMEditMesh *em, int layer, int *free
* by a more flexible customdata system, but not simple */
if (!em) {
ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
- KeyBlock *kb = key_get_keyblock(ob_get_key(ob), clmd->sim_parms->shapekey_rest);
+ KeyBlock *kb = BKE_keyblock_from_key(BKE_key_from_object(ob), clmd->sim_parms->shapekey_rest);
if (kb->data)
return kb->data;
@@ -1014,14 +1022,14 @@ static void calc_weightpaint_vert_color(
unsigned char r_col[4],
MDeformVert *dv, ColorBand *coba,
const int defbase_tot, const int defbase_act,
- const char *dg_flags,
- const int selected, const int draw_flag)
+ const char *defbase_sel, const int defbase_sel_tot,
+ const int draw_flag)
{
float input = 0.0f;
int make_black = FALSE;
- if ((selected > 1) && (draw_flag & CALC_WP_MULTIPAINT)) {
+ if ((defbase_sel_tot > 1) && (draw_flag & CALC_WP_MULTIPAINT)) {
int was_a_nonzero = FALSE;
unsigned int i;
@@ -1030,7 +1038,7 @@ static void calc_weightpaint_vert_color(
/* in multipaint, get the average if auto normalize is inactive
* get the sum if it is active */
if (dw->def_nr < defbase_tot) {
- if (dg_flags[dw->def_nr]) {
+ if (defbase_sel[dw->def_nr]) {
if (dw->weight) {
input += dw->weight;
was_a_nonzero = TRUE;
@@ -1044,7 +1052,7 @@ static void calc_weightpaint_vert_color(
make_black = TRUE;
}
else if ((draw_flag & CALC_WP_AUTO_NORMALIZE) == FALSE) {
- input /= selected; /* get the average */
+ input /= defbase_sel_tot; /* get the average */
}
}
else {
@@ -1089,14 +1097,21 @@ static unsigned char *calc_weightpaint_vert_array(Object *ob, DerivedMesh *dm, i
/* variables for multipaint */
const int defbase_tot = BLI_countlist(&ob->defbase);
const int defbase_act = ob->actdef - 1;
- char *dg_flags = MEM_mallocN(defbase_tot * sizeof(char), __func__);
- const int selected = get_selected_defgroups(ob, dg_flags, defbase_tot);
+
+ int defbase_sel_tot = 0;
+ char *defbase_sel = NULL;
+
+ if (draw_flag & CALC_WP_MULTIPAINT) {
+ defbase_sel = BKE_objdef_selected_get(ob, defbase_tot, &defbase_sel_tot);
+ }
for (i = numVerts; i != 0; i--, wc += 4, dv++) {
- calc_weightpaint_vert_color(wc, dv, coba, defbase_tot, defbase_act, dg_flags, selected, draw_flag);
+ calc_weightpaint_vert_color(wc, dv, coba, defbase_tot, defbase_act, defbase_sel, defbase_sel_tot, draw_flag);
}
- MEM_freeN(dg_flags);
+ if (defbase_sel) {
+ MEM_freeN(defbase_sel);
+ }
}
else {
int col_i;
@@ -1267,7 +1282,7 @@ static void shapekey_layers_to_keyblocks(DerivedMesh *dm, Mesh *me, int actshape
}
if (!kb) {
- kb = add_keyblock(me->key, layer->name);
+ kb = BKE_keyblock_add(me->key, layer->name);
kb->uid = layer->uid;
}
@@ -1792,7 +1807,7 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
{
finaldm->recalcTessellation(finaldm);
}
- /* Even if tessellation is not needed, some modifiers migh have modified CD layers
+ /* Even if tessellation is not needed, some modifiers might have modified CD layers
* (like mloopcol or mloopuv), hence we have to update those. */
else if (finaldm->dirty & DM_DIRTY_TESS_CDLAYERS) {
/* A tessellation already exists, it should always have a CD_POLYINDEX. */
@@ -2072,7 +2087,7 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D
if ((*final_r)->type != DM_TYPE_EDITBMESH) {
DM_ensure_tessface(*final_r);
}
- if (cage_r) {
+ if (cage_r && *cage_r) {
if ((*cage_r)->type != DM_TYPE_EDITBMESH) {
if (*cage_r != *final_r) {
DM_ensure_tessface(*cage_r);
@@ -3186,4 +3201,25 @@ void DM_debug_print(DerivedMesh *dm)
MEM_freeN(str);
}
+void DM_debug_print_cdlayers(CustomData *data)
+{
+ int i;
+ CustomDataLayer *layer;
+
+ printf("{\n");
+
+ for (i = 0, layer = data->layers; i < data->totlayer; i++, layer++) {
+
+ const char *name = CustomData_layertype_name(layer->type);
+ const int size = CustomData_sizeof(layer->type);
+ const char *structname;
+ int structnum;
+ CustomData_file_write_info(layer->type, &structname, &structnum);
+ printf(" dict(name='%s', struct='%s', type=%d, ptr='%p', elem=%d, length=%d),\n",
+ name, structname, layer->type, (void *)layer->data, size, (int)(MEM_allocN_len(layer->data) / size));
+ }
+
+ printf("}\n");
+}
+
#endif /* NDEBUG */
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 6a8ddd8e00a..66df7eccbd0 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -526,18 +526,12 @@ void BKE_pose_copy_data(bPose **dst, bPose *src, int copycon)
bPose *outPose;
bPoseChannel *pchan;
ListBase listb;
-
+
if (!src) {
*dst = NULL;
return;
}
- if (*dst == src) {
- printf("BKE_pose_copy_data source and target are the same\n");
- *dst = NULL;
- return;
- }
-
outPose = MEM_callocN(sizeof(bPose), "pose");
BLI_duplicatelist(&outPose->chanbase, &src->chanbase);
@@ -545,6 +539,7 @@ void BKE_pose_copy_data(bPose **dst, bPose *src, int copycon)
outPose->iksolver = src->iksolver;
outPose->ikdata = NULL;
outPose->ikparam = MEM_dupallocN(src->ikparam);
+ outPose->avs = src->avs;
for (pchan = outPose->chanbase.first; pchan; pchan = pchan->next) {
/* TODO: rename this argument... */
@@ -810,7 +805,7 @@ void framechange_poses_clear_unkeyed(void)
/* TODO: proxies may/may not be correctly handled here... (this needs checking) */
for (ob = G.main->object.first; ob; ob = ob->id.next) {
/* we only need to do this on objects with a pose */
- if ( (pose = ob->pose) ) {
+ if ((pose = ob->pose)) {
for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
if (pchan->bone)
pchan->bone->flag &= ~BONE_UNKEYED;
@@ -1220,475 +1215,3 @@ void what_does_obaction(Object *ob, Object *workob, bPose *pose, bAction *act, c
}
}
-/* ********** NLA with non-poses works with ipo channels ********** */
-
-#if 0 // XXX OLD ANIMATION SYSTEM (TO BE REMOVED)
-
-/* ************************ Blending with NLA *************** */
-
-static void blend_pose_strides(bPose *dst, bPose *src, float srcweight, short mode)
-{
- float dstweight;
-
- switch (mode) {
- case ACTSTRIPMODE_BLEND:
- dstweight = 1.0F - srcweight;
- break;
- case ACTSTRIPMODE_ADD:
- dstweight = 1.0F;
- break;
- default:
- dstweight = 1.0F;
- }
-
- interp_v3_v3v3(dst->stride_offset, dst->stride_offset, src->stride_offset, srcweight);
-}
-
-
-/*
- * bone matching diagram, strips A and B
- *
- * .------------------------.
- * | A |
- * '------------------------'
- * . . b2
- * . .-------------v----------.
- * . | B . |
- * . '------------------------'
- * . . .
- * . . .
- * offset: . 0 . A-B . A-b2+B
- * . . .
- *
- * */
-
-
-static void blend_pose_offset_bone(bActionStrip *strip, bPose *dst, bPose *src, float srcweight, short mode)
-{
- /* matching offset bones */
- /* take dst offset, and put src on on that location */
-
- if (strip->offs_bone[0] == 0)
- return;
-
- /* are we also blending with matching bones? */
- if (strip->prev && strip->start >= strip->prev->start) {
- bPoseChannel *dpchan = BKE_pose_channel_find_name(dst, strip->offs_bone);
- if (dpchan) {
- bPoseChannel *spchan = BKE_pose_channel_find_name(src, strip->offs_bone);
- if (spchan) {
- float vec[3];
-
- /* dst->ctime has the internal strip->prev action time */
- /* map this time to nla time */
-
- float ctime = get_actionstrip_frame(strip, src->ctime, 1);
-
- if (ctime > strip->prev->end) {
- bActionChannel *achan;
-
- /* add src to dest, minus the position of src on strip->prev->end */
-
- ctime = get_actionstrip_frame(strip, strip->prev->end, 0);
-
- achan = get_action_channel(strip->act, strip->offs_bone);
- if (achan && achan->ipo) {
- bPoseChannel pchan;
- /* Evaluates and sets the internal ipo value */
- calc_ipo(achan->ipo, ctime);
- /* This call also sets the pchan flags */
- execute_action_ipo(achan, &pchan);
-
- /* store offset that moves src to location of pchan */
- sub_v3_v3v3(vec, dpchan->loc, pchan.loc);
-
- mul_mat3_m4_v3(dpchan->bone->arm_mat, vec);
- }
- }
- else {
- /* store offset that moves src to location of dst */
-
- sub_v3_v3v3(vec, dpchan->loc, spchan->loc);
- mul_mat3_m4_v3(dpchan->bone->arm_mat, vec);
- }
-
- /* if blending, we only add with factor scrweight */
- mul_v3_fl(vec, srcweight);
-
- add_v3_v3(dst->cyclic_offset, vec);
- }
- }
- }
-
- add_v3_v3(dst->cyclic_offset, src->cyclic_offset);
-}
-
-/* added "sizecorr" here, to allow armatures to be scaled and still have striding.
- * Only works for uniform scaling. In general I'd advise against scaling armatures ever though! (ton)
- */
-static float stridechannel_frame(Object *ob, float sizecorr, bActionStrip *strip, Path *path, float pathdist, float *stride_offset)
-{
- bAction *act = strip->act;
- const char *name = strip->stridechannel;
- bActionChannel *achan = get_action_channel(act, name);
- int stride_axis = strip->stride_axis;
-
- if (achan && achan->ipo) {
- IpoCurve *icu = NULL;
- float minx = 0.0f, maxx = 0.0f, miny = 0.0f, maxy = 0.0f;
- int foundvert = 0;
-
- if (stride_axis == 0) stride_axis = AC_LOC_X;
- else if (stride_axis == 1) stride_axis = AC_LOC_Y;
- else stride_axis = AC_LOC_Z;
-
- /* calculate the min/max */
- for (icu = achan->ipo->curve.first; icu; icu = icu->next) {
- if (icu->adrcode == stride_axis) {
- if (icu->totvert > 1) {
- foundvert = 1;
- minx = icu->bezt[0].vec[1][0];
- maxx = icu->bezt[icu->totvert - 1].vec[1][0];
-
- miny = icu->bezt[0].vec[1][1];
- maxy = icu->bezt[icu->totvert - 1].vec[1][1];
- }
- break;
- }
- }
-
- if (foundvert && miny != maxy) {
- float stridelen = sizecorr * fabs(maxy - miny), striptime;
- float actiondist, pdist, pdistNewNormalized, offs;
- float vec1[4], vec2[4], dir[3];
-
- /* internal cycling, actoffs is in frames */
- offs = stridelen * strip->actoffs / (maxx - minx);
-
- /* amount path moves object */
- pdist = (float)fmod(pathdist + offs, stridelen);
- striptime = pdist / stridelen;
-
- /* amount stride bone moves */
- actiondist = sizecorr * eval_icu(icu, minx + striptime * (maxx - minx)) - miny;
-
- pdist = fabs(actiondist) - pdist;
- pdistNewNormalized = (pathdist + pdist) / path->totdist;
-
- /* now we need to go pdist further (or less) on cu path */
- where_on_path(ob, (pathdist) / path->totdist, vec1, dir); /* vec needs size 4 */
- if (pdistNewNormalized <= 1) {
- /* search for correction in positive path-direction */
- where_on_path(ob, pdistNewNormalized, vec2, dir); /* vec needs size 4 */
- sub_v3_v3v3(stride_offset, vec2, vec1);
- }
- else {
- /* we reached the end of the path, search backwards instead */
- where_on_path(ob, (pathdist - pdist) / path->totdist, vec2, dir); /* vec needs size 4 */
- sub_v3_v3v3(stride_offset, vec1, vec2);
- }
- mul_mat3_m4_v3(ob->obmat, stride_offset);
- return striptime;
- }
- }
- return 0.0f;
-}
-
-static void cyclic_offs_bone(Object *ob, bPose *pose, bActionStrip *strip, float time)
-{
- /* only called when strip has cyclic, so >= 1.0f works... */
- if (time >= 1.0f) {
- bActionChannel *achan = get_action_channel(strip->act, strip->offs_bone);
-
- if (achan && achan->ipo) {
- IpoCurve *icu = NULL;
- Bone *bone;
- float min[3] = {0.0f, 0.0f, 0.0f}, max[3] = {0.0f, 0.0f, 0.0f};
- int index = 0, foundvert = 0;
-
- /* calculate the min/max */
- for (icu = achan->ipo->curve.first; icu; icu = icu->next) {
- if (icu->totvert > 1) {
-
- if (icu->adrcode == AC_LOC_X)
- index = 0;
- else if (icu->adrcode == AC_LOC_Y)
- index = 1;
- else if (icu->adrcode == AC_LOC_Z)
- index = 2;
- else
- continue;
-
- foundvert = 1;
- min[index] = icu->bezt[0].vec[1][1];
- max[index] = icu->bezt[icu->totvert - 1].vec[1][1];
- }
- }
- if (foundvert) {
- /* bring it into armature space */
- sub_v3_v3v3(min, max, min);
- bone = BKE_armature_find_bone_name(ob->data, strip->offs_bone); /* weak */
- if (bone) {
- mul_mat3_m4_v3(bone->arm_mat, min);
-
- /* dominant motion, cyclic_offset was cleared in BKE_pose_rest */
- if (strip->flag & (ACTSTRIP_CYCLIC_USEX | ACTSTRIP_CYCLIC_USEY | ACTSTRIP_CYCLIC_USEZ)) {
- if (strip->flag & ACTSTRIP_CYCLIC_USEX) pose->cyclic_offset[0] = time * min[0];
- if (strip->flag & ACTSTRIP_CYCLIC_USEY) pose->cyclic_offset[1] = time * min[1];
- if (strip->flag & ACTSTRIP_CYCLIC_USEZ) pose->cyclic_offset[2] = time * min[2];
- }
- else {
- if (fabsf(min[0]) >= fabsf(min[1]) && fabsf(min[0]) >= fabsf(min[2]))
- pose->cyclic_offset[0] = time * min[0];
- else if (fabsf(min[1]) >= fabsf(min[0]) && fabsf(min[1]) >= fabsf(min[2]))
- pose->cyclic_offset[1] = time * min[1];
- else
- pose->cyclic_offset[2] = time * min[2];
- }
- }
- }
- }
- }
-}
-
-/* simple case for now; only the curve path with constraint value > 0.5 */
-/* blending we might do later... */
-static Object *get_parent_path(Object *ob)
-{
- bConstraint *con;
-
- if (ob->parent && ob->parent->type == OB_CURVE)
- return ob->parent;
-
- for (con = ob->constraints.first; con; con = con->next) {
- if (con->type == CONSTRAINT_TYPE_FOLLOWPATH) {
- if (con->enforce > 0.5f) {
- bFollowPathConstraint *data = con->data;
- return data->tar;
- }
- }
- }
- return NULL;
-}
-
-/* ************** do the action ************ */
-
-/* ----- nla, etc. --------- */
-
-static void do_nla(Scene *scene, Object *ob, int blocktype)
-{
- bPose *tpose = NULL;
- Key *key = NULL;
- ListBase tchanbase = {NULL, NULL}, chanbase = {NULL, NULL};
- bActionStrip *strip, *striplast = NULL, *stripfirst = NULL;
- float striptime, frametime, length, actlength;
- float blendfac, stripframe;
- float scene_cfra = BKE_scene_frame_get(scene);
- int doit, dostride;
-
- if (blocktype == ID_AR) {
- BKE_pose_copy_data(&tpose, ob->pose, 1);
- BKE_pose_rest(ob->pose); // potentially destroying current not-keyed pose
- }
- else {
- key = ob_get_key(ob);
- }
-
- /* check on extend to left or right, when no strip is hit by 'cfra' */
- for (strip = ob->nlastrips.first; strip; strip = strip->next) {
- /* escape loop on a hit */
- if (scene_cfra >= strip->start && scene_cfra <= strip->end + 0.1f) /* note 0.1 comes back below */
- break;
- if (scene_cfra < strip->start) {
- if (stripfirst == NULL)
- stripfirst = strip;
- else if (stripfirst->start > strip->start)
- stripfirst = strip;
- }
- else if (scene_cfra > strip->end) {
- if (striplast == NULL)
- striplast = strip;
- else if (striplast->end < strip->end)
- striplast = strip;
- }
- }
- if (strip == NULL) { /* extend */
- if (striplast)
- scene_cfra = striplast->end;
- else if (stripfirst)
- scene_cfra = stripfirst->start;
- }
-
- /* and now go over all strips */
- for (strip = ob->nlastrips.first; strip; strip = strip->next) {
- doit = dostride = 0;
-
- if (strip->act && !(strip->flag & ACTSTRIP_MUTE)) { /* so theres an action */
-
- /* Determine if the current frame is within the strip's range */
- length = strip->end - strip->start;
- actlength = strip->actend - strip->actstart;
- striptime = (scene_cfra - strip->start) / length;
- stripframe = (scene_cfra - strip->start);
-
- if (striptime >= 0.0) {
-
- if (blocktype == ID_AR)
- BKE_pose_rest(tpose);
-
- /* To handle repeat, we add 0.1 frame extra to make sure the last frame is included */
- if (striptime < 1.0f + 0.1f / length) {
-
- /* Handle path */
- if ((strip->flag & ACTSTRIP_USESTRIDE) && (blocktype == ID_AR) && (ob->ipoflag & OB_DISABLE_PATH) == 0) {
- Object *parent = get_parent_path(ob);
-
- if (parent) {
- Curve *cu = parent->data;
- float ctime, pdist;
-
- if (cu->flag & CU_PATH) {
- /* Ensure we have a valid path */
- if (cu->path == NULL || cu->path->data == NULL) makeDispListCurveTypes(scene, parent, 0);
- if (cu->path) {
-
- /* Find the position on the path */
- ctime = bsystem_time(scene, ob, scene_cfra, 0.0);
-
- if (calc_ipo_spec(cu->ipo, CU_SPEED, &ctime) == 0) {
- /* correct for actions not starting on zero */
- ctime = (ctime - strip->actstart) / cu->pathlen;
- CLAMP(ctime, 0.0, 1.0);
- }
- pdist = ctime * cu->path->totdist;
-
- if (tpose && strip->stridechannel[0]) {
- striptime = stridechannel_frame(parent, ob->size[0], strip, cu->path, pdist, tpose->stride_offset);
- }
- else {
- if (strip->stridelen) {
- striptime = pdist / strip->stridelen;
- striptime = (float)fmod(striptime + strip->actoffs, 1.0);
- }
- else
- striptime = 0;
- }
-
- frametime = (striptime * actlength) + strip->actstart;
- frametime = bsystem_time(scene, ob, frametime, 0.0);
-
- if (blocktype == ID_AR) {
- extract_pose_from_action(tpose, strip->act, frametime);
- }
- else if (blocktype == ID_OB) {
- extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", frametime);
- if (key)
- extract_ipochannels_from_action(&tchanbase, &key->id, strip->act, "Shape", frametime);
- }
- doit = dostride = 1;
- }
- }
- }
- }
- /* To handle repeat, we add 0.1 frame extra to make sure the last frame is included */
- else {
-
- /* Mod to repeat */
- if (strip->repeat != 1.0f) {
- float cycle = striptime * strip->repeat;
-
- striptime = (float)fmod(cycle, 1.0f + 0.1f / length);
- cycle -= striptime;
-
- if (blocktype == ID_AR)
- cyclic_offs_bone(ob, tpose, strip, cycle);
- }
-
- frametime = (striptime * actlength) + strip->actstart;
- frametime = nla_time(scene, frametime, (float)strip->repeat);
-
- if (blocktype == ID_AR) {
- extract_pose_from_action(tpose, strip->act, frametime);
- }
- else if (blocktype == ID_OB) {
- extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", frametime);
- if (key)
- extract_ipochannels_from_action(&tchanbase, &key->id, strip->act, "Shape", frametime);
- }
-
- doit = 1;
- }
- }
- /* Handle extend */
- else {
- if (strip->flag & ACTSTRIP_HOLDLASTFRAME) {
- /* we want the strip to hold on the exact fraction of the repeat value */
-
- frametime = actlength * (strip->repeat - (int)strip->repeat);
- if (frametime <= 0.000001f) frametime = actlength; /* rounding errors... */
- frametime = bsystem_time(scene, ob, frametime + strip->actstart, 0.0);
-
- if (blocktype == ID_AR)
- extract_pose_from_action(tpose, strip->act, frametime);
- else if (blocktype == ID_OB) {
- extract_ipochannels_from_action(&tchanbase, &ob->id, strip->act, "Object", frametime);
- if (key)
- extract_ipochannels_from_action(&tchanbase, &key->id, strip->act, "Shape", frametime);
- }
-
- /* handle cycle hold */
- if (strip->repeat != 1.0f) {
- if (blocktype == ID_AR)
- cyclic_offs_bone(ob, tpose, strip, strip->repeat - 1.0f);
- }
-
- doit = 1;
- }
- }
-
- /* Handle blendin & blendout */
- if (doit) {
- /* Handle blendin */
-
- if (strip->blendin > 0.0 && stripframe <= strip->blendin && scene_cfra >= strip->start) {
- blendfac = stripframe / strip->blendin;
- }
- else if (strip->blendout > 0.0 && stripframe >= (length - strip->blendout) && scene_cfra <= strip->end) {
- blendfac = (length - stripframe) / (strip->blendout);
- }
- else
- blendfac = 1;
-
- if (blocktype == ID_AR) { /* Blend this pose with the accumulated pose */
- /* offset bone, for matching cycles */
- blend_pose_offset_bone(strip, ob->pose, tpose, blendfac, strip->mode);
-
- blend_poses(ob->pose, tpose, blendfac, strip->mode);
- if (dostride)
- blend_pose_strides(ob->pose, tpose, blendfac, strip->mode);
- }
- else {
- blend_ipochannels(&chanbase, &tchanbase, blendfac, strip->mode);
- BLI_freelistN(&tchanbase);
- }
- }
- }
- }
- }
-
- if (blocktype == ID_OB) {
- execute_ipochannels(&chanbase);
- }
- else if (blocktype == ID_AR) {
- /* apply stride offset to object */
- add_v3_v3(ob->obmat[3], ob->pose->stride_offset);
- }
-
- /* free */
- if (tpose)
- BKE_pose_free(tpose);
- if (chanbase.first)
- BLI_freelistN(&chanbase);
-}
-
-#endif // XXX OLD ANIMATION SYSTEM (TO BE REMOVED)
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index 33cdede6fce..58d20fff2bc 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -63,7 +63,6 @@
#include "BKE_object.h"
#include "BKE_particle.h"
#include "BKE_scene.h"
-#include "BKE_utildefines.h"
#include "BKE_tessmesh.h"
#include "BKE_depsgraph.h"
#include "BKE_anim.h"
@@ -75,7 +74,8 @@
/* --------------------- */
/* forward declarations */
-static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], int par_index, int level, int animated);
+static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], int par_index,
+ int level, short flag);
/* ******************************************************************** */
/* Animation Visualization */
@@ -282,7 +282,7 @@ void animviz_get_object_motionpaths(Object *ob, ListBase *targets)
/* ........ */
-/* Note on evaluation optimisations:
+/* Note on evaluation optimizations:
* Optimisations currently used here play tricks with the depsgraph in order to try and
* evaluate as few objects as strictly necessary to get nicer performance under standard
* production conditions. For those people who really need the accurate version,
@@ -323,7 +323,7 @@ static void motionpaths_calc_optimise_depsgraph(Scene *scene, ListBase *targets)
/* update scene for current frame */
static void motionpaths_calc_update_scene(Scene *scene)
{
-#if 1 // 'production' optimisations always on
+#if 1 // 'production' optimizations always on
Base *base, *last = NULL;
/* only stuff that moves or needs display still */
@@ -431,7 +431,7 @@ void animviz_calc_motionpaths(Scene *scene, ListBase *targets)
if (efra <= sfra) return;
/* optimize the depsgraph for faster updates */
- /* TODO: whether this is used should depend on some setting for the level of optimisations used */
+ /* TODO: whether this is used should depend on some setting for the level of optimizations used */
motionpaths_calc_optimise_depsgraph(scene, targets);
/* calculate path over requested range */
@@ -494,36 +494,42 @@ void calc_curvepath(Object *ob)
/* in a path vertices are with equal differences: path->len = number of verts */
/* NOW WITH BEVELCURVE!!! */
- if (ob == NULL || ob->type != OB_CURVE) return;
+ if (ob == NULL || ob->type != OB_CURVE) {
+ return;
+ }
cu = ob->data;
- nurbs = BKE_curve_nurbs_get(cu);
- nu = nurbs->first;
-
if (cu->path) free_path(cu->path);
cu->path = NULL;
+ /* weak! can only use first curve */
bl = cu->bev.first;
- if (bl == NULL || !bl->nr) return;
+ if (bl == NULL || !bl->nr) {
+ return;
+ }
+
+ nurbs = BKE_curve_nurbs_get(cu);
+ nu = nurbs->first;
cu->path = path = MEM_callocN(sizeof(Path), "calc_curvepath");
/* if POLY: last vertice != first vertice */
cycl = (bl->poly != -1);
- if (cycl) tot = bl->nr;
- else tot = bl->nr - 1;
+ tot = cycl ? bl->nr : bl->nr - 1;
path->len = tot + 1;
/* exception: vector handle paths and polygon paths should be subdivided at least a factor resolu */
- if (path->len < nu->resolu * SEGMENTSU(nu)) path->len = nu->resolu * SEGMENTSU(nu);
+ if (path->len < nu->resolu * SEGMENTSU(nu)) {
+ path->len = nu->resolu * SEGMENTSU(nu);
+ }
dist = (float *)MEM_mallocN((tot + 1) * 4, "calcpathdist");
/* all lengths in *dist */
bevp = bevpfirst = (BevPoint *)(bl + 1);
fp = dist;
- *fp = 0;
+ *fp = 0.0f;
for (a = 0; a < tot; a++) {
fp++;
if (cycl && a == tot - 1)
@@ -558,19 +564,16 @@ void calc_curvepath(Object *ob)
fp++;
if (bevp < bevplast) bevp++;
bevpn = bevp + 1;
- if (bevpn > bevplast) {
- if (cycl) bevpn = bevpfirst;
- else bevpn = bevplast;
+ if (UNLIKELY(bevpn > bevplast)) {
+ bevpn = cycl ? bevpfirst : bevplast;
}
}
- fac1 = *(fp) - *(fp - 1);
- fac2 = *(fp) - d;
- fac1 = fac2 / fac1;
+ fac1 = (*(fp) - d) / (*(fp) - *(fp - 1));
fac2 = 1.0f - fac1;
-
+
interp_v3_v3v3(pp->vec, bevp->vec, bevpn->vec, fac2);
- pp->vec[3] = fac1 * bevp->alfa + fac2 * bevpn->alfa;
+ pp->vec[3] = fac1 * bevp->alfa + fac2 * bevpn->alfa;
pp->radius = fac1 * bevp->radius + fac2 * bevpn->radius;
pp->weight = fac1 * bevp->weight + fac2 * bevpn->weight;
interp_qt_qtqt(pp->quat, bevp->quat, bevpn->quat, fac2);
@@ -582,18 +585,14 @@ void calc_curvepath(Object *ob)
MEM_freeN(dist);
}
-
-/* is this only used internally?*/
-int interval_test(int min, int max, int p1, int cycl)
+static int interval_test(const int min, const int max, int p1, const int cycl)
{
if (cycl) {
- if (p1 < min)
- p1 = ((p1 - min) % (max - min + 1)) + max + 1;
- else if (p1 > max)
- p1 = ((p1 - min) % (max - min + 1)) + min;
+ if (p1 < min) p1 = ((p1 - min) % (max - min + 1)) + max + 1;
+ else if (p1 > max) p1 = ((p1 - min) % (max - min + 1)) + min;
}
else {
- if (p1 < min) p1 = min;
+ if (p1 < min) p1 = min;
else if (p1 > max) p1 = max;
}
return p1;
@@ -701,7 +700,11 @@ int where_on_path(Object *ob, float ctime, float vec[4], float dir[3], float qua
/* ******************************************************************** */
/* Dupli-Geometry */
-static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], int lay, int index, int par_index, int type, int animated)
+#define DUPLILIST_DO_UPDATE 1
+#define DUPLILIST_FOR_RENDER 2
+#define DUPLILIST_ANIMATED 4
+
+static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], int lay, int index, int par_index, int type, short flag)
{
DupliObject *dob = MEM_callocN(sizeof(DupliObject), "dupliobject");
@@ -713,13 +716,14 @@ static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], i
dob->index = index;
dob->particle_index = par_index;
dob->type = type;
- dob->animated = (type == OB_DUPLIGROUP) && animated;
+ dob->animated = (type == OB_DUPLIGROUP) && (flag & DUPLILIST_ANIMATED);
ob->lay = lay;
return dob;
}
-static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_index, int level, int animated)
+static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_index,
+ int level, short flag)
{
DupliObject *dob;
Group *group;
@@ -733,9 +737,16 @@ static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_inde
if (level > MAX_DUPLI_RECUR) return;
/* handles animated groups, and */
+
/* we need to check update for objects that are not in scene... */
- group_handle_recalc_and_update(scene, ob, group);
- animated = animated || group_is_animated(ob, group);
+ if (flag & DUPLILIST_DO_UPDATE) {
+ /* note: update is optional because we don't always need object
+ * transformations to be correct. Also fixes bug [#29616]. */
+ group_handle_recalc_and_update(scene, ob, group);
+ }
+
+ if (group_is_animated(ob, group))
+ flag |= DUPLILIST_ANIMATED;
for (go = group->gobject.first; go; go = go->next) {
/* note, if you check on layer here, render goes wrong... it still deforms verts and uses parent imat */
@@ -751,7 +762,7 @@ static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_inde
mult_m4_m4m4(mat, ob->obmat, go->ob->obmat);
}
- dob = new_dupli_object(lb, go->ob, mat, ob->lay, 0, par_index, OB_DUPLIGROUP, animated);
+ dob = new_dupli_object(lb, go->ob, mat, ob->lay, 0, par_index, OB_DUPLIGROUP, flag);
/* check the group instance and object layers match, also that the object visible flags are ok. */
if ((dob->origlay & group->layer) == 0 ||
@@ -766,14 +777,14 @@ static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_inde
if (go->ob->transflag & OB_DUPLI) {
copy_m4_m4(dob->ob->obmat, dob->mat);
- object_duplilist_recursive(&group->id, scene, go->ob, lb, ob->obmat, par_index, level + 1, animated);
+ object_duplilist_recursive(&group->id, scene, go->ob, lb, ob->obmat, par_index, level + 1, flag);
copy_m4_m4(dob->ob->obmat, dob->omat);
}
}
}
}
-static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_index, int level, int animated)
+static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_index, int level, short flag)
{
extern int enable_cu_speed; /* object.c */
Object copyob;
@@ -821,7 +832,7 @@ static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_ind
BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, (float)scene->r.cfra, ADT_RECALC_ANIM); /* ob-eval will do drivers, so we don't need to do them */
BKE_object_where_is_calc_time(scene, ob, (float)scene->r.cfra);
- dob = new_dupli_object(lb, ob, ob->obmat, ob->lay, scene->r.cfra, par_index, OB_DUPLIFRAMES, animated);
+ dob = new_dupli_object(lb, ob, ob->obmat, ob->lay, scene->r.cfra, par_index, OB_DUPLIFRAMES, flag);
copy_m4_m4(dob->omat, copyob.obmat);
}
}
@@ -845,7 +856,7 @@ static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int par_ind
typedef struct VertexDupliData {
ID *id; /* scene or group, for recursive loops */
int level;
- int animated;
+ short flag;
ListBase *lb;
float pmat[4][4];
float obmat[4][4]; /* Only used for dupliverts inside dupligroups, where the ob->obmat is modified */
@@ -889,7 +900,7 @@ static void vertex_dupli__mapFunc(void *userData, int index, const float co[3],
origlay = vdd->ob->lay;
- dob = new_dupli_object(vdd->lb, vdd->ob, obmat, vdd->par->lay, index, vdd->par_index, OB_DUPLIVERTS, vdd->animated);
+ dob = new_dupli_object(vdd->lb, vdd->ob, obmat, vdd->par->lay, index, vdd->par_index, OB_DUPLIVERTS, vdd->flag);
/* restore the original layer so that each dupli will have proper dob->origlay */
vdd->ob->lay = origlay;
@@ -901,12 +912,13 @@ static void vertex_dupli__mapFunc(void *userData, int index, const float co[3],
float tmpmat[4][4];
copy_m4_m4(tmpmat, vdd->ob->obmat);
copy_m4_m4(vdd->ob->obmat, obmat); /* pretend we are really this mat */
- object_duplilist_recursive((ID *)vdd->id, vdd->scene, vdd->ob, vdd->lb, obmat, vdd->par_index, vdd->level + 1, vdd->animated);
+ object_duplilist_recursive((ID *)vdd->id, vdd->scene, vdd->ob, vdd->lb, obmat, vdd->par_index, vdd->level + 1, vdd->flag);
copy_m4_m4(vdd->ob->obmat, tmpmat);
}
}
-static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int par_index, int level, int animated)
+static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int par_index,
+ int level, short flag)
{
Object *ob, *ob_iter;
Mesh *me = par->data;
@@ -926,7 +938,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl
/* simple preventing of too deep nested groups */
if (level > MAX_DUPLI_RECUR) return;
- em = me->edit_btmesh;
+ em = BMEdit_FromObject(par);
if (em) {
dm = editbmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH);
@@ -934,7 +946,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl
else
dm = mesh_get_derived_deform(scene, par, CD_MASK_BAREMESH);
- if (G.is_rendering) {
+ if (flag & DUPLILIST_FOR_RENDER) {
vdd.orco = (float(*)[3])BKE_mesh_orco_verts_get(par);
BKE_mesh_orco_verts_transform(me, vdd.orco, me->totvert, 0);
}
@@ -984,7 +996,7 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl
vdd.id = id;
vdd.level = level;
- vdd.animated = animated;
+ vdd.flag = flag;
vdd.lb = lb;
vdd.ob = ob;
vdd.scene = scene;
@@ -1029,7 +1041,8 @@ static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, fl
dm->release(dm);
}
-static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int par_index, int level, int animated)
+static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int par_index,
+ int level, short flag)
{
Object *ob, *ob_iter;
Base *base = NULL;
@@ -1052,7 +1065,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
if (level > MAX_DUPLI_RECUR) return;
copy_m4_m4(pmat, par->obmat);
- em = me->edit_btmesh;
+ em = BMEdit_FromObject(par);
if (em) {
dm = editbmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH);
@@ -1066,8 +1079,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
mloop = dm->getLoopArray(dm);
mvert = dm->getVertArray(dm);
- if (G.is_rendering) {
-
+ if (flag & DUPLILIST_FOR_RENDER) {
orco = (float(*)[3])BKE_mesh_orco_verts_get(par);
BKE_mesh_orco_verts_transform(me, orco, me->totvert, 0);
mloopuv = me->mloopuv;
@@ -1130,21 +1142,17 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
float *v3;
/* float *v4; */ /* UNUSED */
float cent[3], quat[4], mat[3][3], mat3[3][3], tmat[4][4], obmat[4][4];
+ float f_no[3];
MLoop *loopstart = mloop + mp->loopstart;
- if (mp->totloop < 3) {
- /* highly unlikely but to be safe */
+ if (UNLIKELY(mp->totloop < 3)) {
continue;
}
else {
+ BKE_mesh_calc_poly_normal(mp, mloop + mp->loopstart, mvert, f_no);
v1 = mvert[(mv1 = loopstart[0].v)].co;
v2 = mvert[(mv2 = loopstart[1].v)].co;
v3 = mvert[(mv3 = loopstart[2].v)].co;
-#if 0
- if (mp->totloop > 3) {
- v4 = mvert[(mv4 = loopstart[3].v)].co;
- }
-#endif
}
/* translation */
@@ -1160,12 +1168,12 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
copy_v3_v3(obmat[3], cent);
/* rotation */
- tri_to_quat(quat, v1, v2, v3);
+ tri_to_quat_ex(quat, v1, v2, v3, f_no);
quat_to_mat3(mat, quat);
/* scale */
if (par->transflag & OB_DUPLIFACES_SCALE) {
- float size = BKE_mesh_calc_poly_area(mp, loopstart, mvert, NULL);
+ float size = BKE_mesh_calc_poly_area(mp, loopstart, mvert, f_no);
size = sqrtf(size) * par->dupfacesca;
mul_m3_fl(mat, size);
}
@@ -1176,8 +1184,8 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
copy_m4_m4(tmat, obmat);
mul_m4_m4m3(obmat, tmat, mat);
- dob = new_dupli_object(lb, ob, obmat, par->lay, a, par_index, OB_DUPLIFACES, animated);
- if (G.is_rendering) {
+ dob = new_dupli_object(lb, ob, obmat, par->lay, a, par_index, OB_DUPLIFACES, (flag & DUPLILIST_ANIMATED));
+ if (flag & DUPLILIST_FOR_RENDER) {
w = 1.0f / (float)mp->totloop;
if (orco) {
@@ -1199,7 +1207,7 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
float tmpmat[4][4];
copy_m4_m4(tmpmat, ob->obmat);
copy_m4_m4(ob->obmat, obmat); /* pretend we are really this mat */
- object_duplilist_recursive((ID *)id, scene, ob, lb, ob->obmat, par_index, level + 1, animated);
+ object_duplilist_recursive((ID *)id, scene, ob, lb, ob->obmat, par_index, level + 1, flag);
copy_m4_m4(ob->obmat, tmpmat);
}
}
@@ -1219,7 +1227,8 @@ static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, floa
dm->release(dm);
}
-static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int UNUSED(par_index), ParticleSystem *psys, int level, int animated)
+static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[][4], int UNUSED(par_index), ParticleSystem *psys,
+ int level, short flag)
{
GroupObject *go;
Object *ob = NULL, **oblist = NULL, obcopy, *obcopylist = NULL;
@@ -1302,7 +1311,9 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
/* gather list of objects or single object */
if (part->ren_as == PART_DRAW_GR) {
- group_handle_recalc_and_update(scene, par, part->dup_group);
+ if (flag & DUPLILIST_DO_UPDATE) {
+ group_handle_recalc_and_update(scene, par, part->dup_group);
+ }
if (part->draw & PART_DRAW_COUNT_GR) {
for (dw = part->dupliweights.first; dw; dw = dw->next)
@@ -1443,9 +1454,9 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
else
copy_m4_m4(mat, tmat);
- dob = new_dupli_object(lb, go->ob, mat, par->lay, counter, index, OB_DUPLIPARTS, animated);
+ dob = new_dupli_object(lb, go->ob, mat, par->lay, counter, index, OB_DUPLIPARTS, (flag & DUPLILIST_ANIMATED));
copy_m4_m4(dob->omat, obcopylist[b].obmat);
- if (G.is_rendering)
+ if (flag & DUPLILIST_FOR_RENDER)
psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco);
}
}
@@ -1469,6 +1480,18 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
quat_to_mat4(obmat, q);
obmat[3][3] = 1.0f;
+ /* add scaling if requested */
+ if ((part->draw & PART_DRAW_NO_SCALE_OB) == 0)
+ mult_m4_m4m4(obmat, obmat, size_mat);
+ }
+ else if (part->draw & PART_DRAW_NO_SCALE_OB) {
+ /* remove scaling */
+ float size_mat[4][4], original_size[3];
+
+ mat4_to_size(original_size, obmat);
+ size_to_mat4(size_mat, original_size);
+ invert_m4(size_mat);
+
mult_m4_m4m4(obmat, obmat, size_mat);
}
@@ -1491,9 +1514,9 @@ static void new_particle_duplilist(ListBase *lb, ID *id, Scene *scene, Object *p
if (part->draw & PART_DRAW_GLOBAL_OB)
add_v3_v3v3(mat[3], mat[3], vec);
- dob = new_dupli_object(lb, ob, mat, ob->lay, counter, index, GS(id->name) == ID_GR ? OB_DUPLIGROUP : OB_DUPLIPARTS, animated);
+ dob = new_dupli_object(lb, ob, mat, ob->lay, counter, index, GS(id->name) == ID_GR ? OB_DUPLIGROUP : OB_DUPLIPARTS, (flag & DUPLILIST_ANIMATED));
copy_m4_m4(dob->omat, oldobmat);
- if (G.is_rendering)
+ if (flag & DUPLILIST_FOR_RENDER)
psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco);
}
@@ -1545,7 +1568,7 @@ static Object *find_family_object(Object **obar, char *family, char ch)
}
-static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int par_index, int level, int animated)
+static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int par_index, int level, short flag)
{
Object *ob, *obar[256] = {NULL};
Curve *cu;
@@ -1584,7 +1607,7 @@ static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int par_inde
copy_m4_m4(obmat, par->obmat);
copy_v3_v3(obmat[3], vec);
- new_dupli_object(lb, ob, obmat, par->lay, a, par_index, OB_DUPLIVERTS, animated);
+ new_dupli_object(lb, ob, obmat, par->lay, a, par_index, OB_DUPLIVERTS, flag);
}
}
@@ -1593,7 +1616,8 @@ static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int par_inde
/* ------------- */
-static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], int par_index, int level, int animated)
+static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBase *duplilist, float par_space_mat[][4], int par_index,
+ int level, short flag)
{
if ((ob->transflag & OB_DUPLI) == 0)
return;
@@ -1613,31 +1637,31 @@ static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBas
if (ob->transflag & OB_DUPLIPARTS) {
ParticleSystem *psys = ob->particlesystem.first;
for (; psys; psys = psys->next)
- new_particle_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, psys, level + 1, animated);
+ new_particle_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, psys, level + 1, flag);
}
else if (ob->transflag & OB_DUPLIVERTS) {
if (ob->type == OB_MESH) {
- vertex_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, level + 1, animated);
+ vertex_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, level + 1, flag);
}
else if (ob->type == OB_FONT) {
if (GS(id->name) == ID_SCE) { /* TODO - support dupligroups */
- font_duplilist(duplilist, scene, ob, par_index, level + 1, animated);
+ font_duplilist(duplilist, scene, ob, par_index, level + 1, flag);
}
}
}
else if (ob->transflag & OB_DUPLIFACES) {
if (ob->type == OB_MESH)
- face_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, level + 1, animated);
+ face_duplilist(duplilist, id, scene, ob, par_space_mat, par_index, level + 1, flag);
}
else if (ob->transflag & OB_DUPLIFRAMES) {
if (GS(id->name) == ID_SCE) { /* TODO - support dupligroups */
- frames_duplilist(duplilist, scene, ob, par_index, level + 1, animated);
+ frames_duplilist(duplilist, scene, ob, par_index, level + 1, flag);
}
}
else if (ob->transflag & OB_DUPLIGROUP) {
DupliObject *dob;
- group_duplilist(duplilist, scene, ob, par_index, level + 1, animated); /* now recursive */
+ group_duplilist(duplilist, scene, ob, par_index, level + 1, flag); /* now recursive */
if (level == 0) {
for (dob = duplilist->first; dob; dob = dob->next)
@@ -1649,14 +1673,27 @@ static void object_duplilist_recursive(ID *id, Scene *scene, Object *ob, ListBas
/* Returns a list of DupliObject
* note; group dupli's already set transform matrix. see note in group_duplilist() */
-ListBase *object_duplilist(Scene *sce, Object *ob)
+ListBase *object_duplilist_ex(Scene *sce, Object *ob, int update, int for_render)
{
ListBase *duplilist = MEM_mallocN(sizeof(ListBase), "duplilist");
+ int flag = 0;
+
+ if(update) flag |= DUPLILIST_DO_UPDATE;
+ if(for_render) flag |= DUPLILIST_FOR_RENDER;
+
duplilist->first = duplilist->last = NULL;
- object_duplilist_recursive((ID *)sce, sce, ob, duplilist, NULL, 0, 0, 0);
+ object_duplilist_recursive((ID *)sce, sce, ob, duplilist, NULL, 0, 0, flag);
return duplilist;
}
+/* note: previously updating was always done, this is why it defaults to be on
+ * but there are likely places it can be called without updating */
+ListBase *object_duplilist(Scene *sce, Object *ob, int for_render)
+{
+ return object_duplilist_ex(sce, ob, TRUE, for_render);
+}
+
+
void free_object_duplilist(ListBase *lb)
{
DupliObject *dob;
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 8e8c98a38e4..5dae2035ab0 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -59,7 +59,6 @@
#include "BKE_main.h"
#include "BKE_library.h"
#include "BKE_report.h"
-#include "BKE_utildefines.h"
#include "RNA_access.h"
@@ -621,15 +620,30 @@ static char *rna_path_rename_fix(ID *owner_id, const char *prefix, const char *o
}
/* Check RNA-Paths for a list of F-Curves */
-static void fcurves_path_rename_fix(ID *owner_id, const char *prefix, char *oldName, char *newName, ListBase *curves, int verify_paths)
+static void fcurves_path_rename_fix(ID *owner_id, const char *prefix, const char *oldName, const char *newName,
+ const char *oldKey, const char *newKey, ListBase *curves, int verify_paths)
{
FCurve *fcu;
/* we need to check every curve... */
for (fcu = curves->first; fcu; fcu = fcu->next) {
- /* firstly, handle the F-Curve's own path */
- if (fcu->rna_path)
- fcu->rna_path = rna_path_rename_fix(owner_id, prefix, oldName, newName, fcu->rna_path, verify_paths);
+ if (fcu->rna_path) {
+ char *old_path = fcu->rna_path;
+
+ /* firstly, handle the F-Curve's own path */
+ fcu->rna_path = rna_path_rename_fix(owner_id, prefix, oldKey, newKey, fcu->rna_path, verify_paths);
+
+ /* if path changed and the F-Curve is grouped, check if its group also needs renaming
+ * (i.e. F-Curve is first of a bone's F-Curves; hence renaming this should also trigger rename)
+ */
+ if (fcu->rna_path != old_path) {
+ bActionGroup *agrp = fcu->grp;
+
+ if ((agrp) && strcmp(oldName, agrp->name) == 0) {
+ BLI_strncpy(agrp->name, newName, sizeof(agrp->name));
+ }
+ }
+ }
}
}
@@ -675,7 +689,8 @@ static void drivers_path_rename_fix(ID *owner_id, ID *ref_id, const char *prefix
}
/* Fix all RNA-Paths for Actions linked to NLA Strips */
-static void nlastrips_path_rename_fix(ID *owner_id, const char *prefix, char *oldName, char *newName, ListBase *strips, int verify_paths)
+static void nlastrips_path_rename_fix(ID *owner_id, const char *prefix, const char *oldName, const char *newName,
+ const char *oldKey, const char *newKey, ListBase *strips, int verify_paths)
{
NlaStrip *strip;
@@ -683,11 +698,11 @@ static void nlastrips_path_rename_fix(ID *owner_id, const char *prefix, char *ol
for (strip = strips->first; strip; strip = strip->next) {
/* fix strip's action */
if (strip->act)
- fcurves_path_rename_fix(owner_id, prefix, oldName, newName, &strip->act->curves, verify_paths);
+ fcurves_path_rename_fix(owner_id, prefix, oldName, newName, oldKey, newKey, &strip->act->curves, verify_paths);
/* ignore own F-Curves, since those are local... */
/* check sub-strips (if metas) */
- nlastrips_path_rename_fix(owner_id, prefix, oldName, newName, &strip->strips, verify_paths);
+ nlastrips_path_rename_fix(owner_id, prefix, oldName, newName, oldKey, newKey, &strip->strips, verify_paths);
}
}
@@ -717,16 +732,16 @@ void BKE_animdata_fix_paths_rename(ID *owner_id, AnimData *adt, ID *ref_id, cons
/* Active action and temp action */
if (adt->action)
- fcurves_path_rename_fix(owner_id, prefix, oldN, newN, &adt->action->curves, verify_paths);
+ fcurves_path_rename_fix(owner_id, prefix, oldName, newName, oldN, newN, &adt->action->curves, verify_paths);
if (adt->tmpact)
- fcurves_path_rename_fix(owner_id, prefix, oldN, newN, &adt->tmpact->curves, verify_paths);
+ fcurves_path_rename_fix(owner_id, prefix, oldName, newName, oldN, newN, &adt->tmpact->curves, verify_paths);
/* Drivers - Drivers are really F-Curves */
drivers_path_rename_fix(owner_id, ref_id, prefix, oldName, newName, oldN, newN, &adt->drivers, verify_paths);
/* NLA Data - Animation Data for Strips */
for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next)
- nlastrips_path_rename_fix(owner_id, prefix, oldN, newN, &nlt->strips, verify_paths);
+ nlastrips_path_rename_fix(owner_id, prefix, oldName, newName, oldN, newN, &nlt->strips, verify_paths);
/* free the temp names */
MEM_freeN(oldN);
@@ -1145,6 +1160,7 @@ static short animsys_write_rna_setting(PointerRNA *ptr, char *path, int array_in
/* set value - only for animatable numerical values */
if (RNA_property_animateable(&new_ptr, prop)) {
int array_len = RNA_property_array_length(&new_ptr, prop);
+ int written = FALSE;
if (array_len && array_index >= array_len) {
if (G.debug & G_DEBUG) {
@@ -1158,25 +1174,52 @@ static short animsys_write_rna_setting(PointerRNA *ptr, char *path, int array_in
switch (RNA_property_type(prop)) {
case PROP_BOOLEAN:
- if (array_len)
- RNA_property_boolean_set_index(&new_ptr, prop, array_index, ANIMSYS_FLOAT_AS_BOOL(value));
- else
- RNA_property_boolean_set(&new_ptr, prop, ANIMSYS_FLOAT_AS_BOOL(value));
+ if (array_len) {
+ if (RNA_property_boolean_get_index(&new_ptr, prop, array_index) != ANIMSYS_FLOAT_AS_BOOL(value)) {
+ RNA_property_boolean_set_index(&new_ptr, prop, array_index, ANIMSYS_FLOAT_AS_BOOL(value));
+ written = TRUE;
+ }
+ }
+ else {
+ if (RNA_property_boolean_get(&new_ptr, prop) != ANIMSYS_FLOAT_AS_BOOL(value)) {
+ RNA_property_boolean_set(&new_ptr, prop, ANIMSYS_FLOAT_AS_BOOL(value));
+ written = TRUE;
+ }
+ }
break;
case PROP_INT:
- if (array_len)
- RNA_property_int_set_index(&new_ptr, prop, array_index, (int)value);
- else
- RNA_property_int_set(&new_ptr, prop, (int)value);
+ if (array_len) {
+ if (RNA_property_int_get_index(&new_ptr, prop, array_index) != (int)value) {
+ RNA_property_int_set_index(&new_ptr, prop, array_index, (int)value);
+ written = TRUE;
+ }
+ }
+ else {
+ if (RNA_property_int_get(&new_ptr, prop) != (int)value) {
+ RNA_property_int_set(&new_ptr, prop, (int)value);
+ written = TRUE;
+ }
+ }
break;
case PROP_FLOAT:
- if (array_len)
- RNA_property_float_set_index(&new_ptr, prop, array_index, value);
- else
- RNA_property_float_set(&new_ptr, prop, value);
+ if (array_len) {
+ if (RNA_property_float_get_index(&new_ptr, prop, array_index) != value) {
+ RNA_property_float_set_index(&new_ptr, prop, array_index, value);
+ written = TRUE;
+ }
+ }
+ else {
+ if (RNA_property_float_get(&new_ptr, prop) != value) {
+ RNA_property_float_set(&new_ptr, prop, value);
+ written = TRUE;
+ }
+ }
break;
case PROP_ENUM:
- RNA_property_enum_set(&new_ptr, prop, (int)value);
+ if (RNA_property_enum_get(&new_ptr, prop) != (int)value) {
+ RNA_property_enum_set(&new_ptr, prop, (int)value);
+ written = TRUE;
+ }
break;
default:
/* nothing can be done here... so it is unsuccessful? */
@@ -1186,7 +1229,7 @@ static short animsys_write_rna_setting(PointerRNA *ptr, char *path, int array_in
/* RNA property update disabled for now - [#28525] [#28690] [#28774] [#28777] */
#if 0
/* buffer property update for later flushing */
- if (RNA_property_update_check(prop)) {
+ if (written && RNA_property_update_check(prop)) {
short skip_updates_hack = 0;
/* optimization hacks: skip property updates for those properties
@@ -1206,7 +1249,7 @@ static short animsys_write_rna_setting(PointerRNA *ptr, char *path, int array_in
/* as long as we don't do property update, we still tag datablock
* as having been updated. this flag does not cause any updates to
* be run, it's for e.g. render engines to synchronize data */
- if (new_ptr.id.data) {
+ if (written && new_ptr.id.data) {
ID *id = new_ptr.id.data;
id->flag |= LIB_ID_RECALC;
DAG_id_type_tag(G.main, GS(id->name));
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 79ee0e96450..b87342f85fa 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -1463,7 +1463,7 @@ void vec_roll_to_mat3(const float vec[3], const float roll, float mat[][3])
*
* was 0.0000000000001, caused bug [#31333], smaller values give unstable
* roll when toggling editmode again...
- * No good value here, trying 0.000000001 as best compromize. :/
+ * No good value here, trying 0.000000001 as best compromise. :/
*/
if (dot_v3v3(axis, axis) > 1.0e-9f) {
/* if nor is *not* a multiple of target ... */
@@ -1551,7 +1551,7 @@ void BKE_armature_where_is(bArmature *arm)
static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected)
{
bPose *pose = ob->pose, *frompose = from->pose;
- bPoseChannel *pchan, *pchanp, pchanw;
+ bPoseChannel *pchan, *pchanp;
bConstraint *con;
int error = 0;
@@ -1587,31 +1587,32 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected
for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) {
pchanp = BKE_pose_channel_find_name(frompose, pchan->name);
-
+
if (UNLIKELY(pchanp == NULL)) {
/* happens for proxies that become invalid because of a missing link
* for regulat cases it shouldn't happen at all */
}
else if (pchan->bone->layer & layer_protected) {
ListBase proxylocal_constraints = {NULL, NULL};
-
+ bPoseChannel pchanw = {NULL};
+
/* copy posechannel to temp, but restore important pointers */
pchanw = *pchanp;
pchanw.prev = pchan->prev;
pchanw.next = pchan->next;
pchanw.parent = pchan->parent;
pchanw.child = pchan->child;
-
+
/* this is freed so copy a copy, else undo crashes */
if (pchanw.prop) {
pchanw.prop = IDP_CopyProperty(pchanw.prop);
-
+
/* use the values from the the existing props */
if (pchan->prop) {
IDP_SyncGroupValues(pchanw.prop, pchan->prop);
}
}
-
+
/* constraints - proxy constraints are flushed... local ones are added after
* 1. extract constraints not from proxy (CONSTRAINT_PROXY_LOCAL) from pchan's constraints
* 2. copy proxy-pchan's constraints on-to new
@@ -1622,30 +1623,30 @@ static void pose_proxy_synchronize(Object *ob, Object *from, int layer_protected
extract_proxylocal_constraints(&proxylocal_constraints, &pchan->constraints);
copy_constraints(&pchanw.constraints, &pchanp->constraints, FALSE);
BLI_movelisttolist(&pchanw.constraints, &proxylocal_constraints);
-
+
/* constraints - set target ob pointer to own object */
for (con = pchanw.constraints.first; con; con = con->next) {
bConstraintTypeInfo *cti = constraint_get_typeinfo(con);
ListBase targets = {NULL, NULL};
bConstraintTarget *ct;
-
+
if (cti && cti->get_constraint_targets) {
cti->get_constraint_targets(con, &targets);
-
+
for (ct = targets.first; ct; ct = ct->next) {
if (ct->tar == from)
ct->tar = ob;
}
-
+
if (cti->flush_constraint_targets)
cti->flush_constraint_targets(con, &targets, 0);
}
}
-
+
/* free stuff from current channel */
BKE_pose_channel_free(pchan);
-
- /* the final copy */
+
+ /* copy data in temp back over to the cleaned-out (but still allocated) original channel */
*pchan = pchanw;
}
else {
@@ -2516,36 +2517,6 @@ void BKE_pose_where_is(Scene *scene, Object *ob)
}
}
-
-/* Returns total selected vgroups,
- * wpi.defbase_sel is assumed malloc'd, all values are set */
-int get_selected_defgroups(Object *ob, char *dg_selection, int defbase_tot)
-{
- bDeformGroup *defgroup;
- unsigned int i;
- Object *armob = BKE_object_pose_armature_get(ob);
- int dg_flags_sel_tot = 0;
-
- if (armob) {
- bPose *pose = armob->pose;
- for (i = 0, defgroup = ob->defbase.first; i < defbase_tot && defgroup; defgroup = defgroup->next, i++) {
- bPoseChannel *pchan = BKE_pose_channel_find_name(pose, defgroup->name);
- if (pchan && (pchan->bone->flag & BONE_SELECTED)) {
- dg_selection[i] = TRUE;
- dg_flags_sel_tot++;
- }
- else {
- dg_selection[i] = FALSE;
- }
- }
- }
- else {
- memset(dg_selection, FALSE, sizeof(char) * defbase_tot);
- }
-
- return dg_flags_sel_tot;
-}
-
/************** Bounding box ********************/
static int minmax_armature(Object *ob, float r_min[3], float r_max[3])
{
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index 0b5d0d90c67..99b788e80ce 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -44,7 +44,8 @@
#include <stdio.h>
#include <stddef.h>
#include <string.h>
-#include <fcntl.h> // for open
+#include <fcntl.h> /* for open */
+#include <errno.h>
#include "MEM_guardedalloc.h"
@@ -80,19 +81,18 @@
#include "BKE_sound.h"
#include "RE_pipeline.h"
-
#include "BLO_undofile.h"
#include "BLO_readfile.h"
#include "BLO_writefile.h"
-#include "BKE_utildefines.h"
-
#include "RNA_access.h"
#include "WM_api.h" // XXXXX BAD, very BAD dependency (bad level call) - remove asap, elubie
+#include "IMB_colormanagement.h"
+
#ifdef WITH_PYTHON
-#include "BPY_extern.h"
+# include "BPY_extern.h"
#endif
Global G;
@@ -219,8 +219,6 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath
/* no load screens? */
if (mode) {
/* comes from readfile.c */
- extern void lib_link_screen_restore(Main *, bScreen *, Scene *);
-
SWAP(ListBase, G.main->wm, bfd->main->wm);
SWAP(ListBase, G.main->screen, bfd->main->screen);
SWAP(ListBase, G.main->script, bfd->main->script);
@@ -234,7 +232,7 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath
if (curscreen) curscreen->scene = curscene; /* can run in bgmode */
/* clear_global will free G.main, here we can still restore pointers */
- lib_link_screen_restore(bfd->main, curscreen, curscene);
+ blo_lib_link_screen_restore(bfd->main, curscreen, curscene);
}
/* free G.main Main database */
@@ -324,7 +322,11 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath
/* baseflags, groups, make depsgraph, etc */
BKE_scene_set_background(G.main, CTX_data_scene(C));
-
+
+ if (mode != 'u') {
+ IMB_colormanagement_check_file_config(G.main);
+ }
+
MEM_freeN(bfd);
(void)curscene; /* quiet warning */
@@ -465,11 +467,10 @@ int blender_test_break(void)
#define UNDO_DISK 0
-#define MAXUNDONAME 64
typedef struct UndoElem {
struct UndoElem *next, *prev;
char str[FILE_MAX];
- char name[MAXUNDONAME];
+ char name[BKE_UNDO_STR_MAX];
MemFile memfile;
uintptr_t undosize;
} UndoElem;
@@ -515,8 +516,13 @@ void BKE_write_undo(bContext *C, const char *name)
int nr /*, success */ /* UNUSED */;
UndoElem *uel;
- if ( (U.uiflag & USER_GLOBALUNDO) == 0) return;
- if (U.undosteps == 0) return;
+ if ((U.uiflag & USER_GLOBALUNDO) == 0) {
+ return;
+ }
+
+ if (U.undosteps == 0) {
+ return;
+ }
/* remove all undos after (also when curundo == NULL) */
while (undobase.last != curundo) {
@@ -717,38 +723,60 @@ void BKE_undo_save_quit(void)
{
UndoElem *uel;
MemFileChunk *chunk;
- int file;
char str[FILE_MAX];
-
- if ( (U.uiflag & USER_GLOBALUNDO) == 0) return;
-
+ const int flag = O_BINARY + O_WRONLY + O_CREAT + O_TRUNC + O_EXCL;
+ int file;
+
+ if ((U.uiflag & USER_GLOBALUNDO) == 0) {
+ return;
+ }
+
uel = curundo;
if (uel == NULL) {
- printf("No undo buffer to save recovery file\n");
+ fprintf(stderr, "No undo buffer to save recovery file\n");
return;
}
-
+
/* no undo state to save */
- if (undobase.first == undobase.last) return;
-
+ if (undobase.first == undobase.last) {
+ return;
+ }
+
+ /* save the undo state as quit.blend */
BLI_make_file_string("/", str, BLI_temporary_dir(), "quit.blend");
- file = BLI_open(str, O_BINARY + O_WRONLY + O_CREAT + O_TRUNC, 0666);
+ /* first try create the file, if it exists call without 'O_CREAT',
+ * to avoid writing to a symlink - use 'O_EXCL' (CVE-2008-1103) */
+ errno = 0;
+ file = BLI_open(str, flag, 0666);
if (file == -1) {
- //XXX error("Unable to save %s, check you have permissions", str);
+ if (errno == EEXIST) {
+ errno = 0;
+ file = BLI_open(str, flag & ~O_CREAT, 0666);
+ }
+ }
+
+ if (file == -1) {
+ fprintf(stderr, "Unable to save '%s': %s\n",
+ str, errno ? strerror(errno) : "Unknown error opening file");
return;
}
- chunk = uel->memfile.chunks.first;
- while (chunk) {
- if (write(file, chunk->buf, chunk->size) != chunk->size) break;
- chunk = chunk->next;
+ for (chunk = uel->memfile.chunks.first; chunk; chunk = chunk->next) {
+ if (write(file, chunk->buf, chunk->size) != chunk->size) {
+ break;
+ }
}
-
+
close(file);
- if (chunk) ; //XXX error("Unable to save %s, internal error", str);
- else printf("Saved session recovery to %s\n", str);
+ if (chunk) {
+ fprintf(stderr, "Unable to save '%s': %s\n",
+ str, errno ? strerror(errno) : "Unknown error writing file");
+ }
+ else {
+ printf("Saved session recovery to '%s'\n", str);
+ }
}
/* sets curscene */
diff --git a/source/blender/blenkernel/intern/bmfont.c b/source/blender/blenkernel/intern/bmfont.c
index 18161bc6fcb..a7d90f09160 100644
--- a/source/blender/blenkernel/intern/bmfont.c
+++ b/source/blender/blenkernel/intern/bmfont.c
@@ -96,7 +96,7 @@ void readBitmapFontVersion0(ImBuf * ibuf, unsigned char * rect, int step)
ysize = (bytes + (ibuf->x - 1)) / ibuf->x;
if (ysize < ibuf->y) {
- /* we're first going to copy all data into a liniar buffer.
+ /* we're first going to copy all data into a linear buffer.
* step can be 4 or 1 bytes, and the data is not sequential because
* the bitmap was flipped vertically. */
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index fde95e0767e..ce39eea5ceb 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -529,7 +529,7 @@ void BKE_brush_imbuf_new(const Scene *scene, Brush *brush, short flt, short texf
unsigned char *dst, crgb[3];
const float alpha = BKE_brush_alpha_get(scene, brush);
float brush_rgb[3];
-
+
imbflag = (flt) ? IB_rectfloat : IB_rect;
xoff = -bufsize / 2.0f + 0.5f;
yoff = -bufsize / 2.0f + 0.5f;
@@ -563,7 +563,7 @@ void BKE_brush_imbuf_new(const Scene *scene, Brush *brush, short flt, short texf
else {
BKE_brush_sample_tex(scene, brush, xy, rgba, 0);
mul_v3_v3v3(dstf, rgba, brush_rgb);
- dstf[3] = rgba[3] *alpha *BKE_brush_curve_strength_clamp(brush, len_v2(xy), radius);
+ dstf[3] = rgba[3] * alpha * BKE_brush_curve_strength_clamp(brush, len_v2(xy), radius);
}
}
}
@@ -594,7 +594,7 @@ void BKE_brush_imbuf_new(const Scene *scene, Brush *brush, short flt, short texf
else if (texfall == 2) {
BKE_brush_sample_tex(scene, brush, xy, rgba, 0);
mul_v3_v3(rgba, brush->rgb);
- alpha_f = rgba[3] *alpha *BKE_brush_curve_strength_clamp(brush, len_v2(xy), radius);
+ alpha_f = rgba[3] * alpha * BKE_brush_curve_strength_clamp(brush, len_v2(xy), radius);
rgb_float_to_uchar(dst, rgba);
@@ -602,7 +602,7 @@ void BKE_brush_imbuf_new(const Scene *scene, Brush *brush, short flt, short texf
}
else {
BKE_brush_sample_tex(scene, brush, xy, rgba, 0);
- alpha_f = rgba[3] *alpha *BKE_brush_curve_strength_clamp(brush, len_v2(xy), radius);
+ alpha_f = rgba[3] * alpha * BKE_brush_curve_strength_clamp(brush, len_v2(xy), radius);
dst[0] = crgb[0];
dst[1] = crgb[1];
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 12f4a17b9f1..e93c9373107 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -48,7 +48,6 @@
#include "BKE_global.h"
#include "BKE_mesh.h"
#include "BKE_paint.h"
-#include "BKE_utildefines.h"
#include "BKE_tessmesh.h"
#include "BKE_curve.h"
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index b0de7a5ea6c..4241756a109 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -50,36 +50,7 @@
#include "BKE_modifier.h"
#include "BKE_pointcache.h"
-#ifdef _WIN32
-void tstart( void )
-{}
-void tend( void )
-{
-}
-double tval( void )
-{
- return 0;
-}
-#else
-#include <sys/time.h>
-static struct timeval _tstart, _tend;
-static struct timezone tz;
-void tstart( void )
-{
- gettimeofday(&_tstart, &tz);
-}
-void tend(void)
-{
- gettimeofday(&_tend, &tz);
-}
-double tval(void)
-{
- double t1, t2;
- t1 = ( double ) _tstart.tv_sec + ( double ) _tstart.tv_usec/ ( 1000*1000 );
- t2 = ( double ) _tend.tv_sec + ( double ) _tend.tv_usec/ ( 1000*1000 );
- return t2-t1;
-}
-#endif
+// #include "PIL_time.h" /* timing for debug prints */
/* Our available solvers. */
// 255 is the magic reserved number, so NEVER try to put 255 solvers in here!
@@ -410,13 +381,13 @@ static int do_step_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *resul
cloth_apply_vgroup ( clmd, result );
cloth_update_springs( clmd );
- tstart();
+ // TIMEIT_START(cloth_step)
/* call the solver. */
if (solvers [clmd->sim_parms->solver_type].solver)
ret = solvers[clmd->sim_parms->solver_type].solver(ob, framenr, clmd, effectors);
- tend();
+ // TIMEIT_END(cloth_step)
pdEndEffectors(&effectors);
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index af9bb971d05..6631afcddaf 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -161,8 +161,6 @@ void bvhtree_update_from_mvert(BVHTree * bvhtree, MFace *faces, int numfaces, MV
/***********************************
Collision modifier code end
***********************************/
-#define mySWAP(a, b) do { double tmp = b ; b = a ; a = tmp ; } while (0)
-
// w3 is not perfect
static void collision_compute_barycentric ( float pv[3], float p1[3], float p2[3], float p3[3], float *w1, float *w2, float *w3 )
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index 85d28f68034..1bd5786debd 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -49,6 +49,7 @@
#include "BKE_fcurve.h"
+#include "IMB_colormanagement.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
@@ -105,9 +106,18 @@ void curvemapping_free_data(CurveMapping *cumap)
int a;
for (a = 0; a < CM_TOT; a++) {
- if (cumap->cm[a].curve) MEM_freeN(cumap->cm[a].curve);
- if (cumap->cm[a].table) MEM_freeN(cumap->cm[a].table);
- if (cumap->cm[a].premultable) MEM_freeN(cumap->cm[a].premultable);
+ if (cumap->cm[a].curve) {
+ MEM_freeN(cumap->cm[a].curve);
+ cumap->cm[a].curve = NULL;
+ }
+ if (cumap->cm[a].table) {
+ MEM_freeN(cumap->cm[a].table);
+ cumap->cm[a].table = NULL;
+ }
+ if (cumap->cm[a].premultable) {
+ MEM_freeN(cumap->cm[a].premultable);
+ cumap->cm[a].premultable = NULL;
+ }
}
}
@@ -165,6 +175,7 @@ void curvemapping_set_black_white(CurveMapping *cumap, const float black[3], con
}
curvemapping_set_black_white_ex(cumap->black, cumap->white, cumap->bwmul);
+ cumap->changed_timestamp++;
}
/* ***************** operations on single curve ************* */
@@ -251,7 +262,7 @@ CurveMapPoint *curvemap_insert(CurveMap *cuma, float x, float y)
return newcmp;
}
-void curvemap_reset(CurveMap *cuma, rctf *clipr, int preset, int slope)
+void curvemap_reset(CurveMap *cuma, const rctf *clipr, int preset, int slope)
{
if (cuma->curve)
MEM_freeN(cuma->curve);
@@ -470,7 +481,7 @@ static float curvemap_calc_extend(const CurveMap *cuma, float x, const float fir
}
/* only creates a table for a single channel in CurveMapping */
-static void curvemap_make_table(CurveMap *cuma, rctf *clipr)
+static void curvemap_make_table(CurveMap *cuma, const rctf *clipr)
{
CurveMapPoint *cmp = cuma->curve;
BezTriple *bezt;
@@ -668,7 +679,7 @@ void curvemapping_changed(CurveMapping *cumap, int rem_doubles)
CurveMap *cuma = cumap->cm + cumap->cur;
CurveMapPoint *cmp = cuma->curve;
rctf *clipr = &cumap->clipr;
- float thresh = 0.01f * (clipr->xmax - clipr->xmin);
+ float thresh = 0.01f * BLI_rctf_size_x(clipr);
float dx = 0.0f, dy = 0.0f;
int a;
@@ -987,7 +998,8 @@ static void save_sample_line(Scopes *scopes, const int idx, const float fx, cons
}
}
-void BKE_histogram_update_sample_line(Histogram *hist, ImBuf *ibuf, const short use_color_management)
+void BKE_histogram_update_sample_line(Histogram *hist, ImBuf *ibuf, const ColorManagedViewSettings *view_settings,
+ const ColorManagedDisplaySettings *display_settings)
{
int i, x, y;
float *fp;
@@ -999,6 +1011,8 @@ void BKE_histogram_update_sample_line(Histogram *hist, ImBuf *ibuf, const short
int y1 = 0.5f + hist->co[0][1] * ibuf->y;
int y2 = 0.5f + hist->co[1][1] * ibuf->y;
+ struct ColormanageProcessor *cm_processor = NULL;
+
hist->channels = 3;
hist->x_resolution = 256;
hist->xmax = 1.0f;
@@ -1006,6 +1020,9 @@ void BKE_histogram_update_sample_line(Histogram *hist, ImBuf *ibuf, const short
if (ibuf->rect == NULL && ibuf->rect_float == NULL) return;
+ if (ibuf->rect_float)
+ cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings);
+
/* persistent draw */
hist->flag |= HISTO_FLAG_SAMPLELINE; /* keep drawing the flag after */
@@ -1020,10 +1037,8 @@ void BKE_histogram_update_sample_line(Histogram *hist, ImBuf *ibuf, const short
if (ibuf->rect_float) {
fp = (ibuf->rect_float + (ibuf->channels) * (y * ibuf->x + x));
- if (use_color_management)
- linearrgb_to_srgb_v3_v3(rgb, fp);
- else
- copy_v3_v3(rgb, fp);
+ copy_v3_v3(rgb, fp);
+ IMB_colormanagement_processor_apply_v3(cm_processor, rgb);
hist->data_luma[i] = rgb_to_luma(rgb);
hist->data_r[i] = rgb[0];
@@ -1041,9 +1056,13 @@ void BKE_histogram_update_sample_line(Histogram *hist, ImBuf *ibuf, const short
}
}
}
+
+ if (cm_processor)
+ IMB_colormanagement_processor_free(cm_processor);
}
-void scopes_update(Scopes *scopes, ImBuf *ibuf, int use_color_management)
+void scopes_update(Scopes *scopes, ImBuf *ibuf, const ColorManagedViewSettings *view_settings,
+ const ColorManagedDisplaySettings *display_settings)
{
int x, y, c;
unsigned int n, nl;
@@ -1056,6 +1075,8 @@ void scopes_update(Scopes *scopes, ImBuf *ibuf, int use_color_management)
int ycc_mode = -1;
const short is_float = (ibuf->rect_float != NULL);
+ struct ColormanageProcessor *cm_processor = NULL;
+
if (ibuf->rect == NULL && ibuf->rect_float == NULL) return;
if (scopes->ok == 1) return;
@@ -1125,6 +1146,9 @@ void scopes_update(Scopes *scopes, ImBuf *ibuf, int use_color_management)
else
rc = (unsigned char *)ibuf->rect;
+ if (ibuf->rect_float)
+ cm_processor = IMB_colormanagement_display_processor_new(view_settings, display_settings);
+
for (y = 0; y < ibuf->y; y++) {
if (savedlines < scopes->sample_lines && y >= ((savedlines) * ibuf->y) / (scopes->sample_lines + 1)) {
saveline = 1;
@@ -1135,11 +1159,8 @@ void scopes_update(Scopes *scopes, ImBuf *ibuf, int use_color_management)
for (x = 0; x < ibuf->x; x++) {
if (is_float) {
- if (use_color_management)
- linearrgb_to_srgb_v3_v3(rgba, rf);
- else
- copy_v3_v3(rgba, rf);
- rgba[3] = rf[3];
+ copy_v4_v4(rgba, rf);
+ IMB_colormanagement_processor_apply_v4(cm_processor, rgba);
}
else {
for (c = 0; c < 4; c++)
@@ -1210,6 +1231,9 @@ void scopes_update(Scopes *scopes, ImBuf *ibuf, int use_color_management)
MEM_freeN(bin_b);
MEM_freeN(bin_a);
+ if (cm_processor)
+ IMB_colormanagement_processor_free(cm_processor);
+
scopes->ok = 1;
}
@@ -1248,3 +1272,58 @@ void scopes_new(Scopes *scopes)
scopes->waveform_3 = NULL;
scopes->vecscope = NULL;
}
+
+void BKE_color_managed_display_settings_init(ColorManagedDisplaySettings *settings)
+{
+ const char *display_name = IMB_colormanagement_display_get_default_name();
+
+ BLI_strncpy(settings->display_device, display_name, sizeof(settings->display_device));
+}
+
+void BKE_color_managed_display_settings_copy(ColorManagedDisplaySettings *new_settings,
+ const ColorManagedDisplaySettings *settings)
+{
+ BLI_strncpy(new_settings->display_device, settings->display_device, sizeof(new_settings->display_device));
+}
+
+void BKE_color_managed_view_settings_init(ColorManagedViewSettings *settings)
+{
+ /* OCIO_TODO: use default view transform here when OCIO is completely integrated
+ * and proper versioning stuff is added.
+ * for now use NONE to be compatible with all current files
+ */
+ BLI_strncpy(settings->view_transform, "Default", sizeof(settings->view_transform));
+
+ settings->gamma = 1.0f;
+ settings->exposure = 0.0f;
+}
+
+void BKE_color_managed_view_settings_copy(ColorManagedViewSettings *new_settings,
+ const ColorManagedViewSettings *settings)
+{
+ BLI_strncpy(new_settings->view_transform, settings->view_transform, sizeof(new_settings->view_transform));
+
+ new_settings->flag = settings->flag;
+ new_settings->exposure = settings->exposure;
+ new_settings->gamma = settings->gamma;
+
+ if (settings->curve_mapping)
+ new_settings->curve_mapping = curvemapping_copy(settings->curve_mapping);
+}
+
+void BKE_color_managed_view_settings_free(ColorManagedViewSettings *settings)
+{
+ if (settings->curve_mapping)
+ curvemapping_free(settings->curve_mapping);
+}
+
+void BKE_color_managed_colorspace_settings_init(ColorManagedColorspaceSettings *colorspace_settings)
+{
+ BLI_strncpy(colorspace_settings->name, "", sizeof(colorspace_settings->name));
+}
+
+void BKE_color_managed_colorspace_settings_copy(ColorManagedColorspaceSettings *colorspace_settings,
+ const ColorManagedColorspaceSettings *settings)
+{
+ BLI_strncpy(colorspace_settings->name, settings->name, sizeof(colorspace_settings->name));
+}
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 00130dd3583..e3f7ae1b1c7 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -416,8 +416,7 @@ void constraint_mat_convertspace(Object *ob, bPoseChannel *pchan, float mat[][4]
static void contarget_get_mesh_mat(Object *ob, const char *substring, float mat[][4])
{
DerivedMesh *dm = NULL;
- Mesh *me = ob->data;
- BMEditMesh *em = me->edit_btmesh;
+ BMEditMesh *em = BMEdit_FromObject(ob);
float vec[3] = {0.0f, 0.0f, 0.0f};
float normal[3] = {0.0f, 0.0f, 0.0f}, plane[3];
float imat[3][3], tmat[3][3];
@@ -1031,7 +1030,6 @@ static void trackto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar
if (VALID_CONS_TARGET(ct)) {
float size[3], vec[3];
float totmat[3][3];
- float tmat[4][4];
/* Get size property, since ob->size is only the object's own relative size, not its global one */
mat4_to_size(size, cob->matrix);
@@ -1054,9 +1052,8 @@ static void trackto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *tar
vectomat(vec, ct->matrix[2],
(short)data->reserved1, (short)data->reserved2,
data->flags, totmat);
-
- copy_m4_m4(tmat, cob->matrix);
- mul_m4_m3m4(cob->matrix, totmat, tmat);
+
+ mul_m4_m3m4(cob->matrix, totmat, cob->matrix);
}
}
@@ -2282,7 +2279,6 @@ static void locktrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
float totmat[3][3];
float tmpmat[3][3];
float invmat[3][3];
- float tmat[4][4];
float mdet;
/* Vector object -> target */
@@ -2510,8 +2506,6 @@ static void locktrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
totmat[1][0] = tmpmat[1][0]; totmat[1][1] = tmpmat[1][1]; totmat[1][2] = tmpmat[1][2];
totmat[2][0] = tmpmat[2][0]; totmat[2][1] = tmpmat[2][1]; totmat[2][2] = tmpmat[2][2];
- copy_m4_m4(tmat, cob->matrix);
-
mdet = determinant_m3(totmat[0][0], totmat[0][1], totmat[0][2],
totmat[1][0], totmat[1][1], totmat[1][2],
totmat[2][0], totmat[2][1], totmat[2][2]);
@@ -2520,7 +2514,7 @@ static void locktrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
}
/* apply out transformaton to the object */
- mul_m4_m3m4(cob->matrix, totmat, tmat);
+ mul_m4_m3m4(cob->matrix, totmat, cob->matrix);
}
}
@@ -2718,7 +2712,6 @@ static void stretchto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
if (VALID_CONS_TARGET(ct)) {
float size[3], scale[3], vec[3], xx[3], zz[3], orth[3];
float totmat[3][3];
- float tmat[4][4];
float dist;
/* store scaling before destroying obmat */
@@ -2816,9 +2809,8 @@ static void stretchto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
normalize_v3_v3(totmat[2], zz);
break;
} /* switch (data->plane) */
-
- copy_m4_m4(tmat, cob->matrix);
- mul_m4_m3m4(cob->matrix, totmat, tmat);
+
+ mul_m4_m3m4(cob->matrix, totmat, cob->matrix);
}
}
@@ -4062,32 +4054,36 @@ static void followtrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase
copy_v3_v3(cob->matrix[3], disp);
}
- if (data->depth_ob && data->depth_ob->derivedFinal) {
+ if (data->depth_ob) {
Object *depth_ob = data->depth_ob;
- BVHTreeFromMesh treeData = NULL_BVHTreeFromMesh;
- BVHTreeRayHit hit;
- float ray_start[3], ray_end[3], ray_nor[3], imat[4][4];
- int result;
+ DerivedMesh *target = object_get_derived_final(depth_ob);
+ if (target) {
+ BVHTreeFromMesh treeData = NULL_BVHTreeFromMesh;
+ BVHTreeRayHit hit;
+ float ray_start[3], ray_end[3], ray_nor[3], imat[4][4];
+ int result;
- invert_m4_m4(imat, depth_ob->obmat);
+ invert_m4_m4(imat, depth_ob->obmat);
- mul_v3_m4v3(ray_start, imat, camob->obmat[3]);
- mul_v3_m4v3(ray_end, imat, cob->matrix[3]);
+ mul_v3_m4v3(ray_start, imat, camob->obmat[3]);
+ mul_v3_m4v3(ray_end, imat, cob->matrix[3]);
- sub_v3_v3v3(ray_nor, ray_end, ray_start);
+ sub_v3_v3v3(ray_nor, ray_end, ray_start);
- bvhtree_from_mesh_faces(&treeData, depth_ob->derivedFinal, 0.0f, 4, 6);
+ bvhtree_from_mesh_faces(&treeData, target, 0.0f, 4, 6);
- hit.dist = FLT_MAX;
- hit.index = -1;
+ hit.dist = FLT_MAX;
+ hit.index = -1;
- result = BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_nor, 0.0f, &hit, treeData.raycast_callback, &treeData);
+ result = BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_nor, 0.0f, &hit, treeData.raycast_callback, &treeData);
- if (result != -1) {
- mul_v3_m4v3(cob->matrix[3], depth_ob->obmat, hit.co);
- }
+ if (result != -1) {
+ mul_v3_m4v3(cob->matrix[3], depth_ob->obmat, hit.co);
+ }
- free_bvhtree_from_mesh(&treeData);
+ free_bvhtree_from_mesh(&treeData);
+ target->release(target);
+ }
}
}
}
@@ -4292,8 +4288,8 @@ bConstraintTypeInfo *get_constraint_typeinfo(int type)
}
/* only return for valid types */
- if ( (type >= CONSTRAINT_TYPE_NULL) &&
- (type < NUM_CONSTRAINT_TYPES) )
+ if ((type >= CONSTRAINT_TYPE_NULL) &&
+ (type < NUM_CONSTRAINT_TYPES))
{
/* there shouldn't be any segfaults here... */
return constraintsTypeInfo[type];
@@ -4514,7 +4510,7 @@ static void con_relink_id_cb(bConstraint *UNUSED(con), ID **idpoin, short UNUSED
* since we've got the actual ID block, let's just inline this
* code.
*
- * See ID_NEW(a) in BKE_utildefines.h
+ * See ID_NEW(a) in DNA_ID.h
*/
if ((*idpoin) && (*idpoin)->newid)
(*idpoin) = (void *)(*idpoin)->newid;
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index e2bb1aaa2c7..0bda3b266b8 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -429,6 +429,33 @@ void BKE_curve_texspace_calc(Curve *cu)
}
}
+int BKE_nurbList_index_get_co(ListBase *nurb, const int index, float r_co[3])
+{
+ Nurb *nu;
+ int tot = 0;
+
+ for (nu = nurb->first; nu; nu = nu->next) {
+ int tot_nu;
+ if (nu->type == CU_BEZIER) {
+ tot_nu = nu->pntsu;
+ if (index - tot < tot_nu) {
+ copy_v3_v3(r_co, nu->bezt[index - tot].vec[1]);
+ return TRUE;
+ }
+ }
+ else {
+ tot_nu = nu->pntsu * nu->pntsv;
+ if (index - tot < tot_nu) {
+ copy_v3_v3(r_co, nu->bp[index - tot].vec);
+ return TRUE;
+ }
+ }
+ tot += tot_nu;
+ }
+
+ return FALSE;
+}
+
int BKE_nurbList_verts_count(ListBase *nurb)
{
Nurb *nu;
@@ -1165,7 +1192,7 @@ void BKE_curve_forward_diff_bezier(float q0, float q1, float q2, float q3, float
static void forward_diff_bezier_cotangent(const float p0[3], const float p1[3], const float p2[3], const float p3[3],
float p[3], int it, int stride)
{
- /* note that these are not purpendicular to the curve
+ /* note that these are not perpendicular to the curve
* they need to be rotated for this,
*
* This could also be optimized like BKE_curve_forward_diff_bezier */
@@ -2741,7 +2768,7 @@ static void calchandleNurb_intern(BezTriple *bezt, BezTriple *prev, BezTriple *n
if (skip_align) {
/* handles need to be updated during animation and applying stuff like hooks,
- * but in such situatios it's quite difficult to distinguish in which order
+ * but in such situations it's quite difficult to distinguish in which order
* align handles should be aligned so skip them for now */
return;
}
@@ -3047,29 +3074,6 @@ void BKE_nurbList_handles_set(ListBase *editnurb, short code)
}
}
-static void swapdata(void *adr1, void *adr2, int len)
-{
-
- if (len <= 0) return;
-
- if (len < 65) {
- char adr[64];
-
- memcpy(adr, adr1, len);
- memcpy(adr1, adr2, len);
- memcpy(adr2, adr, len);
- }
- else {
- char *adr;
-
- adr = (char *)MEM_mallocN(len, "curve swap");
- memcpy(adr, adr1, len);
- memcpy(adr1, adr2, len);
- memcpy(adr2, adr, len);
- MEM_freeN(adr);
- }
-}
-
void BKE_nurb_direction_switch(Nurb *nu)
{
BezTriple *bezt1, *bezt2;
@@ -3077,7 +3081,9 @@ void BKE_nurb_direction_switch(Nurb *nu)
float *fp1, *fp2, *tempf;
int a, b;
- if (nu->pntsu == 1 && nu->pntsv == 1) return;
+ if (nu->pntsu == 1 && nu->pntsv == 1) {
+ return;
+ }
if (nu->type == CU_BEZIER) {
a = nu->pntsu;
@@ -3086,19 +3092,22 @@ void BKE_nurb_direction_switch(Nurb *nu)
if (a & 1) a += 1; /* if odd, also swap middle content */
a /= 2;
while (a > 0) {
- if (bezt1 != bezt2)
+ if (bezt1 != bezt2) {
SWAP(BezTriple, *bezt1, *bezt2);
+ }
- swapdata(bezt1->vec[0], bezt1->vec[2], 12);
- if (bezt1 != bezt2)
- swapdata(bezt2->vec[0], bezt2->vec[2], 12);
+ swap_v3_v3(bezt1->vec[0], bezt1->vec[2]);
+
+ if (bezt1 != bezt2) {
+ swap_v3_v3(bezt2->vec[0], bezt2->vec[2]);
+ }
SWAP(char, bezt1->h1, bezt1->h2);
- SWAP(short, bezt1->f1, bezt1->f3);
+ SWAP(char, bezt1->f1, bezt1->f3);
if (bezt1 != bezt2) {
SWAP(char, bezt2->h1, bezt2->h2);
- SWAP(short, bezt2->f1, bezt2->f3);
+ SWAP(char, bezt2->f1, bezt2->f3);
bezt1->alfa = -bezt1->alfa;
bezt2->alfa = -bezt2->alfa;
}
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index b04bd5bc47f..de55751f2ec 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -51,7 +51,6 @@
#include "BLI_mempool.h"
#include "BLI_utildefines.h"
-#include "BKE_utildefines.h"
#include "BKE_customdata.h"
#include "BKE_customdata_file.h"
#include "BKE_global.h"
@@ -72,25 +71,29 @@ typedef struct LayerTypeInfo {
const char *structname; /* name of the struct used, for file writing */
int structnum; /* number of structs per element, for file writing */
- /* default layer name.
+ /**
+ * default layer name.
* note! when NULL this is a way to ensure there is only ever one item
* see: CustomData_layertype_is_singleton() */
const char *defaultname;
- /* a function to copy count elements of this layer's data
+ /**
+ * a function to copy count elements of this layer's data
* (deep copy if appropriate)
* if NULL, memcpy is used
*/
void (*copy)(const void *source, void *dest, int count);
- /* a function to free any dynamically allocated components of this
+ /**
+ * a function to free any dynamically allocated components of this
* layer's data (note the data pointer itself should not be freed)
* size should be the size of one element of this layer's data (e.g.
* LayerTypeInfo.size)
*/
void (*free)(void *data, int count, int size);
- /* a function to interpolate between count source elements of this
+ /**
+ * a function to interpolate between count source elements of this
* layer's data and store the result in dest
* if weights == NULL or sub_weights == NULL, they should default to 1
*
@@ -98,18 +101,24 @@ typedef struct LayerTypeInfo {
* sub_weights gives the sub-element weights for each element in sources
* (there should be (sub element count)^2 weights per element)
* count gives the number of elements in sources
+ *
+ * \note in some cases \a dest pointer is in \a sources
+ * so all functions have to take this into account and delay
+ * applying changes while reading from sources.
+ * See bug [#32395] - Campbell.
*/
- void (*interp)(void **sources, float *weights, float *sub_weights,
+ void (*interp)(void **sources, const float *weights, const float *sub_weights,
int count, void *dest);
- /* a function to swap the data in corners of the element */
+ /** a function to swap the data in corners of the element */
void (*swap)(void *data, const int *corner_indices);
- /* a function to set a layer's data to default values. if NULL, the
+ /**
+ * a function to set a layer's data to default values. if NULL, the
* default is assumed to be all zeros */
void (*set_default)(void *data, int count);
- /* functions necessary for geometry collapse*/
+ /** functions necessary for geometry collapse */
int (*equal)(void *data1, void *data2);
void (*multiply)(void *data, float fac);
void (*initminmax)(void *min, void *max);
@@ -117,13 +126,13 @@ typedef struct LayerTypeInfo {
void (*dominmax)(void *data1, void *min, void *max);
void (*copyvalue)(void *source, void *dest);
- /* a function to read data from a cdf file */
+ /** a function to read data from a cdf file */
int (*read)(CDataFile *cdf, void *data, int count);
- /* a function to write data to a cdf file */
+ /** a function to write data to a cdf file */
int (*write)(CDataFile *cdf, void *data, int count);
- /* a function to determine file size */
+ /** a function to determine file size */
size_t (*filesize)(CDataFile *cdf, void *data, int count);
} LayerTypeInfo;
@@ -203,8 +212,8 @@ static void linklist_free_simple(void *link)
MEM_freeN(link);
}
-static void layerInterp_mdeformvert(void **sources, float *weights,
- float *UNUSED(sub_weights), int count, void *dest)
+static void layerInterp_mdeformvert(void **sources, const float *weights,
+ const float *UNUSED(sub_weights), int count, void *dest)
{
MDeformVert *dvert = dest;
LinkNode *dest_dw = NULL; /* a list of lists of MDeformWeight pointers */
@@ -243,6 +252,8 @@ static void layerInterp_mdeformvert(void **sources, float *weights,
}
}
+ /* delay writing to the destination incase dest is in sources */
+
/* now we know how many unique deform weights there are, so realloc */
if (dvert->dw) MEM_freeN(dvert->dw);
@@ -260,27 +271,6 @@ static void layerInterp_mdeformvert(void **sources, float *weights,
BLI_linklist_free(dest_dw, linklist_free_simple);
}
-
-static void layerInterp_msticky(void **sources, float *weights,
- float *UNUSED(sub_weights), int count, void *dest)
-{
- float co[2], w;
- MSticky *mst;
- int i;
-
- co[0] = co[1] = 0.0f;
- for (i = 0; i < count; i++) {
- w = weights ? weights[i] : 1.0f;
- mst = (MSticky *)sources[i];
-
- madd_v2_v2fl(co, mst->co, w);
- }
-
- mst = (MSticky *)dest;
- copy_v2_v2(mst->co, co);
-}
-
-
static void layerCopy_tface(const void *source, void *dest, int count)
{
const MTFace *source_tf = (const MTFace *)source;
@@ -291,13 +281,13 @@ static void layerCopy_tface(const void *source, void *dest, int count)
dest_tf[i] = source_tf[i];
}
-static void layerInterp_tface(void **sources, float *weights,
- float *sub_weights, int count, void *dest)
+static void layerInterp_tface(void **sources, const float *weights,
+ const float *sub_weights, int count, void *dest)
{
MTFace *tf = dest;
int i, j, k;
float uv[4][2] = {{0.0f}};
- float *sub_weight;
+ const float *sub_weight;
if (count <= 0) return;
@@ -318,6 +308,7 @@ static void layerInterp_tface(void **sources, float *weights,
}
}
+ /* delay writing to the destination incase dest is in sources */
*tf = *(MTFace *)(*sources);
memcpy(tf->uv, uv, sizeof(tf->uv));
}
@@ -392,13 +383,13 @@ static void layerCopy_origspace_face(const void *source, void *dest, int count)
dest_tf[i] = source_tf[i];
}
-static void layerInterp_origspace_face(void **sources, float *weights,
- float *sub_weights, int count, void *dest)
+static void layerInterp_origspace_face(void **sources, const float *weights,
+ const float *sub_weights, int count, void *dest)
{
OrigSpaceFace *osf = dest;
int i, j, k;
float uv[4][2] = {{0.0f}};
- float *sub_weight;
+ const float *sub_weight;
if (count <= 0) return;
@@ -419,6 +410,8 @@ static void layerInterp_origspace_face(void **sources, float *weights,
}
}
+ /* delay writing to the destination incase dest is in sources */
+
#if 0 /* no need, this ONLY contains UV's */
*osf = *(OrigSpaceFace *)(*sources);
#endif
@@ -680,12 +673,12 @@ static void layerDefault_mloopcol(void *data, int count)
}
-static void layerInterp_mloopcol(void **sources, float *weights,
- float *sub_weights, int count, void *dest)
+static void layerInterp_mloopcol(void **sources, const float *weights,
+ const float *sub_weights, int count, void *dest)
{
MLoopCol *mc = dest;
int i;
- float *sub_weight;
+ const float *sub_weight;
struct {
float a;
float r;
@@ -719,7 +712,8 @@ static void layerInterp_mloopcol(void **sources, float *weights,
CLAMP(col.r, 0.0f, 255.0f);
CLAMP(col.g, 0.0f, 255.0f);
CLAMP(col.b, 0.0f, 255.0f);
-
+
+ /* delay writing to the destination incase dest is in sources */
mc->r = (int)col.r;
mc->g = (int)col.g;
mc->b = (int)col.b;
@@ -768,11 +762,10 @@ static void layerAdd_mloopuv(void *data1, void *data2)
add_v2_v2(l1->uv, l2->uv);
}
-static void layerInterp_mloopuv(void **sources, float *weights,
- float *sub_weights, int count, void *dest)
+static void layerInterp_mloopuv(void **sources, const float *weights,
+ const float *sub_weights, int count, void *dest)
{
- MLoopUV *mluv = dest;
- float *uv = mluv->uv;
+ float uv[2];
int i;
zero_v2(uv);
@@ -793,6 +786,9 @@ static void layerInterp_mloopuv(void **sources, float *weights,
madd_v2_v2fl(uv, src->uv, weight);
}
}
+
+ /* delay writing to the destination incase dest is in sources */
+ copy_v2_v2(((MLoopUV *)dest)->uv, uv);
}
/* origspace is almost exact copy of mloopuv's, keep in sync */
@@ -838,11 +834,10 @@ static void layerAdd_mloop_origspace(void *data1, void *data2)
add_v2_v2(l1->uv, l2->uv);
}
-static void layerInterp_mloop_origspace(void **sources, float *weights,
- float *sub_weights, int count, void *dest)
+static void layerInterp_mloop_origspace(void **sources, const float *weights,
+ const float *sub_weights, int count, void *dest)
{
- OrigSpaceLoop *mluv = dest;
- float *uv = mluv->uv;
+ float uv[2];
int i;
zero_v2(uv);
@@ -858,16 +853,19 @@ static void layerInterp_mloop_origspace(void **sources, float *weights,
}
else {
for (i = 0; i < count; i++) {
- float weight = weights ? weights[i] : 1;
+ float weight = weights ? weights[i] : 1.0f;
OrigSpaceLoop *src = sources[i];
madd_v2_v2fl(uv, src->uv, weight);
}
}
+
+ /* delay writing to the destination incase dest is in sources */
+ copy_v2_v2(((OrigSpaceLoop *)dest)->uv, uv);
}
/* --- end copy */
-static void layerInterp_mcol(void **sources, float *weights,
- float *sub_weights, int count, void *dest)
+static void layerInterp_mcol(void **sources, const float *weights,
+ const float *sub_weights, int count, void *dest)
{
MCol *mc = dest;
int i, j, k;
@@ -878,7 +876,7 @@ static void layerInterp_mcol(void **sources, float *weights,
float b;
} col[4] = {{0.0f}};
- float *sub_weight;
+ const float *sub_weight;
if (count <= 0) return;
@@ -907,6 +905,7 @@ static void layerInterp_mcol(void **sources, float *weights,
}
}
+ /* delay writing to the destination incase dest is in sources */
for (j = 0; j < 4; ++j) {
/* Subdivide smooth or fractal can cause problems without clamping
@@ -946,33 +945,36 @@ static void layerDefault_mcol(void *data, int count)
}
}
-static void layerInterp_bweight(void **sources, float *weights,
- float *UNUSED(sub_weights), int count, void *dest)
+static void layerInterp_bweight(void **sources, const float *weights,
+ const float *UNUSED(sub_weights), int count, void *dest)
{
- float *f = dest;
+ float f;
float **in = (float **)sources;
int i;
if (count <= 0) return;
- *f = 0.0f;
+ f = 0.0f;
if (weights) {
for (i = 0; i < count; ++i) {
- *f += *in[i] * weights[i];
+ f += *in[i] * weights[i];
}
}
else {
for (i = 0; i < count; ++i) {
- *f += *in[i];
+ f += *in[i];
}
}
+
+ /* delay writing to the destination incase dest is in sources */
+ *((float *)dest) = f;
}
-static void layerInterp_shapekey(void **sources, float *weights,
- float *UNUSED(sub_weights), int count, void *dest)
+static void layerInterp_shapekey(void **sources, const float *weights,
+ const float *UNUSED(sub_weights), int count, void *dest)
{
- float *co = dest;
+ float co[3];
float **in = (float **)sources;
int i;
@@ -990,6 +992,9 @@ static void layerInterp_shapekey(void **sources, float *weights,
add_v3_v3(co, in[i]);
}
}
+
+ /* delay writing to the destination incase dest is in sources */
+ copy_v3_v3((float *)dest, co);
}
static void layerDefault_mvert_skin(void *data, int count)
@@ -1003,8 +1008,8 @@ static void layerDefault_mvert_skin(void *data, int count)
}
}
-static void layerInterp_mvert_skin(void **sources, float *weights,
- float *UNUSED(sub_weights),
+static void layerInterp_mvert_skin(void **sources, const float *weights,
+ const float *UNUSED(sub_weights),
int count, void *dest)
{
float radius[3], w;
@@ -1019,6 +1024,7 @@ static void layerInterp_mvert_skin(void **sources, float *weights,
madd_v3_v3fl(radius, vs->radius, w);
}
+ /* delay writing to the destination incase dest is in sources */
vs = dest;
copy_v3_v3(vs->radius, radius);
vs->flag &= ~MVERT_SKIN_ROOT;
@@ -1027,8 +1033,8 @@ static void layerInterp_mvert_skin(void **sources, float *weights,
static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
/* 0: CD_MVERT */
{sizeof(MVert), "MVert", 1, NULL, NULL, NULL, NULL, NULL, NULL},
- /* 1: CD_MSTICKY */
- {sizeof(MSticky), "MSticky", 1, NULL, NULL, NULL, layerInterp_msticky, NULL,
+ /* 1: CD_MSTICKY */ /* DEPRECATED */
+ {sizeof(float) * 2, "", 1, NULL, NULL, NULL, NULL, NULL,
NULL},
/* 2: CD_MDEFORMVERT */
{sizeof(MDeformVert), "MDeformVert", 1, NULL, layerCopy_mdeformvert,
@@ -1127,7 +1133,7 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
{sizeof(GridPaintMask), "GridPaintMask", 1, NULL, layerCopy_grid_paint_mask,
layerFree_grid_paint_mask, NULL, NULL, NULL},
/* 36: CD_SKIN_NODE */
- {sizeof(MVertSkin), "MVertSkin", 1, "Skin", NULL, NULL,
+ {sizeof(MVertSkin), "MVertSkin", 1, NULL, NULL, NULL,
layerInterp_mvert_skin, NULL, layerDefault_mvert_skin}
};
@@ -1993,14 +1999,15 @@ void CustomData_interp(const CustomData *source, CustomData *dest,
}
/* if there are no more dest layers, we're done */
- if (dest_i >= dest->totlayer) return;
+ if (dest_i >= dest->totlayer) break;
/* if we found a matching layer, copy the data */
if (dest->layers[dest_i].type == source->layers[src_i].type) {
void *src_data = source->layers[src_i].data;
- for (j = 0; j < count; ++j)
+ for (j = 0; j < count; ++j) {
sources[j] = (char *)src_data + typeInfo->size * src_indices[j];
+ }
dest_offset = dest_index * typeInfo->size;
@@ -2590,8 +2597,9 @@ void CustomData_bmesh_interp(CustomData *data, void **src_blocks, float *weights
CustomDataLayer *layer = &data->layers[i];
const LayerTypeInfo *typeInfo = layerType_getInfo(layer->type);
if (typeInfo->interp) {
- for (j = 0; j < count; ++j)
+ for (j = 0; j < count; ++j) {
sources[j] = (char *)src_blocks[j] + layer->offset;
+ }
typeInfo->interp(sources, weights, sub_weights, count,
(char *)dest_block + layer->offset);
diff --git a/source/blender/blenkernel/intern/customdata_file.c b/source/blender/blenkernel/intern/customdata_file.c
index 71801c4729f..78449879f72 100644
--- a/source/blender/blenkernel/intern/customdata_file.c
+++ b/source/blender/blenkernel/intern/customdata_file.c
@@ -32,6 +32,7 @@
#include "BLI_fileops.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
+#include "BLI_endian_switch.h"
#include "BKE_customdata_file.h"
#include "BKE_global.h"
@@ -165,9 +166,9 @@ static int cdf_read_header(CDataFile *cdf)
header->endian = cdf_endian();
if (cdf->switchendian) {
- SWITCH_INT(header->type);
- SWITCH_INT(header->totlayer);
- SWITCH_INT(header->structbytes);
+ BLI_endian_switch_int32(&header->type);
+ BLI_endian_switch_int32(&header->totlayer);
+ BLI_endian_switch_int32(&header->structbytes);
}
if (!ELEM(header->type, CDF_TYPE_IMAGE, CDF_TYPE_MESH))
@@ -185,10 +186,10 @@ static int cdf_read_header(CDataFile *cdf)
return 0;
if (cdf->switchendian) {
- SWITCH_INT(image->width);
- SWITCH_INT(image->height);
- SWITCH_INT(image->tile_size);
- SWITCH_INT(image->structbytes);
+ BLI_endian_switch_int32(&image->width);
+ BLI_endian_switch_int32(&image->height);
+ BLI_endian_switch_int32(&image->tile_size);
+ BLI_endian_switch_int32(&image->structbytes);
}
offset += image->structbytes;
@@ -200,7 +201,7 @@ static int cdf_read_header(CDataFile *cdf)
return 0;
if (cdf->switchendian)
- SWITCH_INT(mesh->structbytes);
+ BLI_endian_switch_int32(&mesh->structbytes);
offset += mesh->structbytes;
mesh->structbytes = sizeof(CDataFileMeshHeader);
@@ -219,10 +220,10 @@ static int cdf_read_header(CDataFile *cdf)
return 0;
if (cdf->switchendian) {
- SWITCH_INT(layer->type);
- SWITCH_INT(layer->datatype);
- SWITCH_INT64(layer->datasize);
- SWITCH_INT(layer->structbytes);
+ BLI_endian_switch_int32(&layer->type);
+ BLI_endian_switch_int32(&layer->datatype);
+ BLI_endian_switch_uint64(&layer->datasize);
+ BLI_endian_switch_int32(&layer->structbytes);
}
if (layer->datatype != CDF_DATA_FLOAT)
@@ -317,20 +318,13 @@ int cdf_read_layer(CDataFile *cdf, CDataFileLayer *blay)
int cdf_read_data(CDataFile *cdf, unsigned int size, void *data)
{
- float *fdata;
- unsigned int a;
-
/* read data */
if (!fread(data, size, 1, cdf->readf))
return 0;
/* switch endian if necessary */
if (cdf->switchendian) {
- fdata = data;
-
- for (a = 0; a < size / sizeof(float); a++) {
- SWITCH_INT(fdata[a]);
- }
+ BLI_endian_switch_float_array(data, size / sizeof(float));
}
return 1;
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index 547a64a70d4..4110d4565b2 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -33,6 +33,7 @@
#include <string.h>
#include <math.h>
#include <ctype.h>
+#include <stdlib.h>
#include "MEM_guardedalloc.h"
@@ -41,7 +42,10 @@
#include "BKE_deform.h"
-#include "BLI_blenlib.h"
+#include "BLI_listbase.h"
+#include "BLI_math.h"
+#include "BLI_path_util.h"
+#include "BLI_string.h"
#include "BLI_utildefines.h"
@@ -204,13 +208,15 @@ void defvert_normalize(MDeformVert *dvert)
}
}
-void defvert_normalize_lock(MDeformVert *dvert, const int def_nr_lock)
+void defvert_normalize_lock_single(MDeformVert *dvert, const int def_nr_lock)
{
if (dvert->totweight <= 0) {
/* nothing */
}
else if (dvert->totweight == 1) {
- dvert->dw[0].weight = 1.0f;
+ if (def_nr_lock != 0) {
+ dvert->dw[0].weight = 1.0f;
+ }
}
else {
MDeformWeight *dw_lock = NULL;
@@ -246,6 +252,50 @@ void defvert_normalize_lock(MDeformVert *dvert, const int def_nr_lock)
}
}
+void defvert_normalize_lock_map(MDeformVert *dvert, const char *lock_flags, const int defbase_tot)
+{
+ if (dvert->totweight <= 0) {
+ /* nothing */
+ }
+ else if (dvert->totweight == 1) {
+ if (LIKELY(defbase_tot >= 1) && lock_flags[0]) {
+ dvert->dw[0].weight = 1.0f;
+ }
+ }
+ else {
+ MDeformWeight *dw;
+ unsigned int i;
+ float tot_weight = 0.0f;
+ float lock_iweight = 0.0f;
+
+ for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
+ if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == FALSE)) {
+ tot_weight += dw->weight;
+ }
+ else {
+ /* invert after */
+ lock_iweight += dw->weight;
+ }
+ }
+
+ lock_iweight = maxf(0.0f, 1.0f - lock_iweight);
+
+ if (tot_weight > 0.0f) {
+ /* paranoid, should be 1.0 but in case of float error clamp anyway */
+
+ float scalar = (1.0f / tot_weight) * lock_iweight;
+ for (i = dvert->totweight, dw = dvert->dw; i != 0; i--, dw++) {
+ if ((dw->def_nr < defbase_tot) && (lock_flags[dw->def_nr] == FALSE)) {
+ dw->weight *= scalar;
+
+ /* in case of division errors with very low weights */
+ CLAMP(dw->weight, 0.0f, 1.0f);
+ }
+ }
+ }
+ }
+}
+
void defvert_flip(MDeformVert *dvert, const int *flip_map, const int flip_map_len)
{
MDeformWeight *dw;
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 53981cb39cb..48040867ad4 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -75,7 +75,6 @@
#include "BKE_scene.h"
#include "BKE_screen.h"
#include "BKE_tracking.h"
-#include "BKE_utildefines.h"
#include "depsgraph_private.h"
@@ -502,7 +501,7 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
if (ob->adt)
dag_add_driver_relation(ob->adt, dag, node, (ob->type == OB_ARMATURE)); // XXX isdata arg here doesn't give an accurate picture of situation
- key = ob_get_key(ob);
+ key = BKE_key_from_object(ob);
if (key && key->adt)
dag_add_driver_relation(key->adt, dag, node, 1);
@@ -2651,7 +2650,7 @@ static void dag_id_flush_update(Scene *sce, ID *id)
/* set flags based on ShapeKey */
if (idtype == ID_KE) {
for (obt = bmain->object.first; obt; obt = obt->id.next) {
- Key *key = ob_get_key(obt);
+ Key *key = BKE_key_from_object(obt);
if (!(ob && obt == ob) && ((ID *)key == id)) {
obt->flag |= (OB_RECALC_OB | OB_RECALC_DATA);
lib_id_recalc_tag(bmain, &obt->id);
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 8db93f8b44a..d55848514cc 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -669,7 +669,7 @@ static void boundInsert(Bounds3D *b, float point[3])
}
}
-float getSurfaceDimension(PaintSurfaceData *sData)
+static float getSurfaceDimension(PaintSurfaceData *sData)
{
Bounds3D *mb = &sData->bData->mesh_bounds;
return MAX3((mb->max[0] - mb->min[0]), (mb->max[1] - mb->min[1]), (mb->max[2] - mb->min[2]));
@@ -910,7 +910,7 @@ static void free_bakeData(PaintSurfaceData *data)
}
/* free surface data if it's not used anymore */
-void surface_freeUnusedData(DynamicPaintSurface *surface)
+static void surface_freeUnusedData(DynamicPaintSurface *surface)
{
if (!surface->data) return;
@@ -1368,7 +1368,7 @@ static void dynamicPaint_initAdjacencyData(DynamicPaintSurface *surface, int for
MEM_freeN(temp_data);
}
-void dynamicPaint_setInitialColor(DynamicPaintSurface *surface)
+static void dynamicPaint_setInitialColor(DynamicPaintSurface *surface)
{
PaintSurfaceData *sData = surface->data;
PaintPoint *pPoint = (PaintPoint *)sData->type_data;
@@ -1605,7 +1605,7 @@ static void dynamicPaint_applySurfaceDisplace(DynamicPaintSurface *surface, Deri
/*
* Apply canvas data to the object derived mesh
*/
-struct DerivedMesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd,
+static DerivedMesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd,
Object *ob,
DerivedMesh *dm)
{
@@ -1830,9 +1830,12 @@ void dynamicPaint_cacheUpdateFrames(DynamicPaintSurface *surface)
}
}
-void canvas_copyDerivedMesh(DynamicPaintCanvasSettings *canvas, DerivedMesh *dm)
+static void canvas_copyDerivedMesh(DynamicPaintCanvasSettings *canvas, DerivedMesh *dm)
{
- if (canvas->dm) canvas->dm->release(canvas->dm);
+ if (canvas->dm) {
+ canvas->dm->release(canvas->dm);
+ }
+
canvas->dm = CDDM_copy(dm);
}
@@ -1941,7 +1944,7 @@ static int dynamicPaint_findNeighbourPixel(PaintUVPoint *tempPoints, DerivedMesh
{
/* Note: Current method only uses polygon edges to detect neighboring pixels.
* -> It doesn't always lead to the optimum pixel but is accurate enough
- * and faster/simplier than including possible face tip point links)
+ * and faster/simpler than including possible face tip point links)
*/
int x, y;
@@ -2595,7 +2598,7 @@ void dynamicPaint_outputSurfaceImage(DynamicPaintSurface *surface, char *filenam
int format = (surface->image_fileformat & MOD_DPAINT_IMGFORMAT_OPENEXR) ? R_IMF_IMTYPE_OPENEXR : R_IMF_IMTYPE_PNG;
char output_file[FILE_MAX];
- if (!sData || !sData->type_data) { setError(surface->canvas, "Image save failed: Invalid surface."); return; }
+ if (!sData->type_data) { setError(surface->canvas, "Image save failed: Invalid surface."); return; }
/* if selected format is openexr, but current build doesnt support one */
#ifndef WITH_OPENEXR
if (format == R_IMF_IMTYPE_OPENEXR) format = R_IMF_IMTYPE_PNG;
@@ -2748,7 +2751,7 @@ static void dynamicPaint_freeBrushMaterials(BrushMaterials *bMats)
/*
* Get material diffuse color and alpha (including linked textures) in given coordinates
*/
-void dynamicPaint_doMaterialTex(BrushMaterials *bMats, float color[3], float *alpha, Object *brushOb, const float volume_co[3], const float surface_co[3], int faceIndex, short isQuad, DerivedMesh *orcoDm)
+static void dynamicPaint_doMaterialTex(BrushMaterials *bMats, float color[3], float *alpha, Object *brushOb, const float volume_co[3], const float surface_co[3], int faceIndex, short isQuad, DerivedMesh *orcoDm)
{
Material *mat = bMats->mat;
MFace *mface = orcoDm->getTessFaceArray(orcoDm);
@@ -2849,15 +2852,15 @@ static void mesh_faces_nearest_point_dp(void *userdata, int index, const float c
/***************************** Brush Painting Calls ******************************/
-/*
- * Mix color values to canvas point.
+/**
+ * Mix color values to canvas point.
*
- * surface : canvas surface
- * index : surface point index
- * paintFlags : paint object flags
- * paintColor,Alpha,Wetness : to be mixed paint values
- * timescale : value used to adjust time dependand
- * operations when using substeps
+ * \param surface canvas surface
+ * \param index surface point index
+ * \param paintFlags paint object flags
+ * \param paintColor,Alpha,Wetness to be mixed paint values
+ * \param timescale value used to adjust time dependent
+ * operations when using substeps
*/
static void dynamicPaint_mixPaintColors(DynamicPaintSurface *surface, int index, int paintFlags,
const float paintColor[3], float *paintAlpha, float *paintWetness, float *timescale)
@@ -3953,7 +3956,7 @@ static void dynamicPaint_prepareAdjacencyData(DynamicPaintSurface *surface, int
}
/* find two adjacency points (closest_id) and influence (closest_d) to move paint towards when affected by a force */
-void surface_determineForceTargetPoints(PaintSurfaceData *sData, int index, float force[3], float closest_d[2], int closest_id[2])
+static void surface_determineForceTargetPoints(PaintSurfaceData *sData, int index, float force[3], float closest_d[2], int closest_id[2])
{
BakeAdjPoint *bNeighs = sData->bData->bNeighs;
int numOfNeighs = sData->adj_data->n_num[index];
@@ -3996,7 +3999,7 @@ void surface_determineForceTargetPoints(PaintSurfaceData *sData, int index, floa
float force_intersect;
float temp;
- /* project force vector on the plane determined by these two neightbour points
+ /* project force vector on the plane determined by these two neighbor points
* and calculate relative force angle from it*/
cross_v3_v3v3(tangent, bNeighs[closest_id[0]].dir, bNeighs[closest_id[1]].dir);
normalize_v3(tangent);
@@ -4158,7 +4161,7 @@ static int dynamicPaint_prepareEffectStep(DynamicPaintSurface *surface, Scene *s
pdEndEffectors(&effectors);
}
- /* Get number of required steps using averate point distance
+ /* Get number of required steps using average point distance
* so that just a few ultra close pixels wont up substeps to max */
/* adjust number of required substep by fastest active effect */
@@ -4221,7 +4224,7 @@ static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface, float *force
/* Only continue if surrounding point has higher wetness */
if (ePoint->wetness < pPoint->wetness || ePoint->wetness < MIN_WETNESS) continue;
- w_factor = 1.0f / numOfNeighs *MIN2(ePoint->wetness, 1.0f) * speed_scale;
+ w_factor = 1.0f / numOfNeighs * MIN2(ePoint->wetness, 1.0f) * speed_scale;
CLAMP(w_factor, 0.0f, 1.0f);
/* mix new wetness and color */
@@ -4342,7 +4345,7 @@ static void dynamicPaint_doEffectStep(DynamicPaintSurface *surface, float *force
}
}
-void dynamicPaint_doWaveStep(DynamicPaintSurface *surface, float timescale)
+static void dynamicPaint_doWaveStep(DynamicPaintSurface *surface, float timescale)
{
PaintSurfaceData *sData = surface->data;
BakeAdjPoint *bNeighs = sData->bData->bNeighs;
@@ -4800,7 +4803,7 @@ static int dynamicPaint_doStep(Scene *scene, Object *ob, DynamicPaintSurface *su
PaintBakeData *bData = sData->bData;
DynamicPaintCanvasSettings *canvas = surface->canvas;
int ret = 1;
- if (!sData || sData->total_points < 1) return 0;
+ if (sData->total_points < 1) return 0;
dynamicPaint_surfacePreStep(surface, timescale);
/*
@@ -4875,7 +4878,7 @@ static int dynamicPaint_doStep(Scene *scene, Object *ob, DynamicPaintSurface *su
/* Apply brush on the surface depending on it's collision type */
/* Particle brush: */
if (brush->collision == MOD_DPAINT_COL_PSYS) {
- if (brush && brush->psys && brush->psys->part && brush->psys->part->type == PART_EMITTER &&
+ if (brush->psys && brush->psys->part && brush->psys->part->type == PART_EMITTER &&
psys_check_enabled(brushObj, brush->psys))
{
diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c
index 925497a4929..d2f2e3f01d2 100644
--- a/source/blender/blenkernel/intern/editderivedmesh.c
+++ b/source/blender/blenkernel/intern/editderivedmesh.c
@@ -151,7 +151,7 @@ static void BMEdit_RecalcTessellation_intern(BMEditMesh *tm)
BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
/* don't consider two-edged faces */
- if (efa->len < 3) {
+ if (UNLIKELY(efa->len < 3)) {
/* do nothing */
}
@@ -1834,5 +1834,11 @@ DerivedMesh *getEditDerivedBMesh(BMEditMesh *em,
BMEditMesh *BMEdit_FromObject(Object *ob)
{
BLI_assert(ob->type == OB_MESH);
+ /* sanity check */
+#ifndef NDEBUG
+ if (((Mesh *)ob->data)->edit_btmesh) {
+ BLI_assert(((Mesh *)ob->data)->edit_btmesh->ob == ob);
+ }
+#endif
return ((Mesh *)ob->data)->edit_btmesh;
}
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index 67e7743c8a4..2dbc63e6944 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -55,7 +55,6 @@
#include "BKE_curve.h"
#include "BKE_global.h"
#include "BKE_object.h"
-#include "BKE_utildefines.h"
#include "RNA_access.h"
@@ -75,12 +74,10 @@ void free_fcurve(FCurve *fcu)
{
if (fcu == NULL)
return;
-
+
/* free curve data */
- if (fcu) {
- if (fcu->bezt) MEM_freeN(fcu->bezt);
- if (fcu->fpt) MEM_freeN(fcu->fpt);
- }
+ if (fcu->bezt) MEM_freeN(fcu->bezt);
+ if (fcu->fpt) MEM_freeN(fcu->fpt);
/* free RNA-path, as this were allocated when getting the path string */
if (fcu->rna_path)
@@ -365,7 +362,7 @@ int binarysearch_bezt_index(BezTriple array[], float frame, int arraylen, short
/* initialize replace-flag first */
*replace = 0;
- /* sneaky optimisations (don't go through searching process if...):
+ /* sneaky optimizations (don't go through searching process if...):
* - keyframe to be added is to be added out of current bounds
* - keyframe to be added would replace one of the existing ones on bounds
*/
@@ -507,8 +504,8 @@ short calc_fcurve_bounds(FCurve *fcu, float *xmin, float *xmax, float *ymin, flo
xmaxv = MAX3(xmaxv, bezt_last->vec[1][0], bezt_last->vec[2][0]);
}
else {
- xminv = MIN2(xminv, bezt_first->vec[1][0]);
- xmaxv = MAX2(xmaxv, bezt_last->vec[1][0]);
+ xminv = minf(xminv, bezt_first->vec[1][0]);
+ xmaxv = maxf(xmaxv, bezt_last->vec[1][0]);
}
}
}
@@ -524,8 +521,8 @@ short calc_fcurve_bounds(FCurve *fcu, float *xmin, float *xmax, float *ymin, flo
ymaxv = MAX4(ymaxv, bezt->vec[1][1], bezt->vec[0][1], bezt->vec[2][1]);
}
else {
- yminv = MIN2(yminv, bezt->vec[1][1]);
- ymaxv = MAX2(ymaxv, bezt->vec[1][1]);
+ yminv = minf(yminv, bezt->vec[1][1]);
+ ymaxv = maxf(ymaxv, bezt->vec[1][1]);
}
foundvert = TRUE;
@@ -536,8 +533,8 @@ short calc_fcurve_bounds(FCurve *fcu, float *xmin, float *xmax, float *ymin, flo
else if (fcu->fpt) {
/* frame range can be directly calculated from end verts */
if (xmin || xmax) {
- xminv = MIN2(xminv, fcu->fpt[0].vec[0]);
- xmaxv = MAX2(xmaxv, fcu->fpt[fcu->totvert - 1].vec[0]);
+ xminv = minf(xminv, fcu->fpt[0].vec[0]);
+ xmaxv = maxf(xmaxv, fcu->fpt[fcu->totvert - 1].vec[0]);
}
/* only loop over keyframes to find extents for values if needed */
@@ -594,15 +591,15 @@ void calc_fcurve_range(FCurve *fcu, float *start, float *end,
if (bezt_first) {
BLI_assert(bezt_last != NULL);
- min = MIN2(min, bezt_first->vec[1][0]);
- max = MAX2(max, bezt_last->vec[1][0]);
+ min = minf(min, bezt_first->vec[1][0]);
+ max = maxf(max, bezt_last->vec[1][0]);
foundvert = TRUE;
}
}
else if (fcu->fpt) {
- min = MIN2(min, fcu->fpt[0].vec[0]);
- max = MAX2(max, fcu->fpt[fcu->totvert - 1].vec[0]);
+ min = minf(min, fcu->fpt[0].vec[0]);
+ max = maxf(max, fcu->fpt[fcu->totvert - 1].vec[0]);
foundvert = TRUE;
}
diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c
index 438188b1e2a..68321076398 100644
--- a/source/blender/blenkernel/intern/fmodifier.c
+++ b/source/blender/blenkernel/intern/fmodifier.c
@@ -48,10 +48,6 @@
#include "BKE_fcurve.h"
#include "BKE_idprop.h"
-
-#define SMALL -1.0e-10
-#define SELECT 1
-
/* ******************************** F-Modifiers ********************************* */
/* Info ------------------------------- */
@@ -965,8 +961,8 @@ FModifierTypeInfo *get_fmodifier_typeinfo(int type)
}
/* only return for valid types */
- if ( (type >= FMODIFIER_TYPE_NULL) &&
- (type <= FMODIFIER_NUM_TYPES) )
+ if ((type >= FMODIFIER_TYPE_NULL) &&
+ (type < FMODIFIER_NUM_TYPES))
{
/* there shouldn't be any segfaults here... */
return fmodifiersTypeInfo[type];
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index 0ffd68c9079..8b35974ea62 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -50,7 +50,6 @@
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
-#include "BKE_utildefines.h"
#include "BKE_packedFile.h"
#include "BKE_library.h"
#include "BKE_font.h"
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index 2ec5801746c..84871375788 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -163,7 +163,7 @@ bGPDframe *gpencil_frame_addnew(bGPDlayer *gpl, int cframe)
}
/* add a new gp-layer and make it the active layer */
-bGPDlayer *gpencil_layer_addnew(bGPdata *gpd)
+bGPDlayer *gpencil_layer_addnew(bGPdata *gpd, const char *name, int setactive)
{
bGPDlayer *gpl;
@@ -182,11 +182,12 @@ bGPDlayer *gpencil_layer_addnew(bGPdata *gpd)
gpl->thickness = 3;
/* auto-name */
- strcpy(gpl->info, "GP_Layer");
+ strcpy(gpl->info, name);
BLI_uniquename(&gpd->layers, gpl, "GP_Layer", '.', offsetof(bGPDlayer, info), sizeof(gpl->info));
/* make this one the active one */
- gpencil_layer_setactive(gpd, gpl);
+ if (setactive)
+ gpencil_layer_setactive(gpd, gpl);
/* return layer */
return gpl;
@@ -509,10 +510,8 @@ void gpencil_layer_setactive(bGPdata *gpd, bGPDlayer *active)
}
/* delete the active gp-layer */
-void gpencil_layer_delactive(bGPdata *gpd)
+void gpencil_layer_delete(bGPdata *gpd, bGPDlayer *gpl)
{
- bGPDlayer *gpl = gpencil_layer_getactive(gpd);
-
/* error checking */
if (ELEM(NULL, gpd, gpl))
return;
diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c
index 500df1b7b75..634428d9194 100644
--- a/source/blender/blenkernel/intern/group.c
+++ b/source/blender/blenkernel/intern/group.c
@@ -110,16 +110,6 @@ void BKE_group_unlink(Group *group)
if (ob->dup_group == group) {
ob->dup_group = NULL;
-#if 0 /* XXX OLD ANIMSYS, NLASTRIPS ARE NO LONGER USED */
- {
- bActionStrip *strip;
- /* duplicator strips use a group object, we remove it */
- for (strip = ob->nlastrips.first; strip; strip = strip->next) {
- if (strip->object)
- strip->object = NULL;
- }
- }
-#endif
}
for (psys = ob->particlesystem.first; psys; psys = psys->next) {
@@ -383,57 +373,3 @@ void group_handle_recalc_and_update(Scene *scene, Object *UNUSED(parent), Group
}
}
}
-
-#if 0
-Object *group_get_member_with_action(Group *group, bAction *act)
-{
- GroupObject *go;
-
- if (group == NULL || act == NULL) return NULL;
-
- for (go = group->gobject.first; go; go = go->next) {
- if (go->ob) {
- if (go->ob->action == act)
- return go->ob;
- if (go->ob->nlastrips.first) {
- bActionStrip *strip;
-
- for (strip = go->ob->nlastrips.first; strip; strip = strip->next) {
- if (strip->act == act)
- return go->ob;
- }
- }
- }
- }
- return NULL;
-}
-
-/* if group has NLA, we try to map the used objects in NLA to group members */
-/* this assuming that object has received a new group link */
-void group_relink_nla_objects(Object *ob)
-{
- Group *group;
- GroupObject *go;
- bActionStrip *strip;
-
- if (ob == NULL || ob->dup_group == NULL) return;
- group = ob->dup_group;
-
- for (strip = ob->nlastrips.first; strip; strip = strip->next) {
- if (strip->object) {
- for (go = group->gobject.first; go; go = go->next) {
- if (go->ob) {
- if (strcmp(go->ob->id.name, strip->object->id.name) == 0)
- break;
- }
- }
- if (go)
- strip->object = go->ob;
- else
- strip->object = NULL;
- }
-
- }
-}
-
-#endif
diff --git a/source/blender/blenkernel/intern/icons.c b/source/blender/blenkernel/intern/icons.c
index 8a49cba7649..d8c3e260399 100644
--- a/source/blender/blenkernel/intern/icons.c
+++ b/source/blender/blenkernel/intern/icons.c
@@ -65,7 +65,7 @@ static void icon_free(void *val)
Icon *icon = val;
if (icon) {
- if (icon->drawinfo_free) {
+ if (icon->drawinfo_free) {
icon->drawinfo_free(icon->drawinfo);
}
else if (icon->drawinfo) {
@@ -255,7 +255,7 @@ void BKE_icon_changed(int id)
prv->changed_timestamp[i]++;
}
}
- }
+ }
}
int BKE_icon_getid(struct ID *id)
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index 7456f9aab8b..8ceaab56f83 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -293,18 +293,6 @@ static IDProperty *IDP_CopyArray(IDProperty *prop)
return newp;
}
-/*taken from readfile.c*/
-#define SWITCH_LONGINT(a) { \
- char s_i, *p_i; \
- p_i = (char *)& (a); \
- s_i = p_i[0]; p_i[0] = p_i[7]; p_i[7] = s_i; \
- s_i = p_i[1]; p_i[1] = p_i[6]; p_i[6] = s_i; \
- s_i = p_i[2]; p_i[2] = p_i[5]; p_i[5] = s_i; \
- s_i = p_i[3]; p_i[3] = p_i[4]; p_i[4] = s_i; \
- } (void)0
-
-
-
/* ---------- String Type ------------ */
IDProperty *IDP_NewString(const char *st, const char *name, int maxlen)
{
@@ -496,7 +484,7 @@ void IDP_ReplaceInGroup(IDProperty *group, IDProperty *prop)
BLI_remlink(&group->data.group, loop);
IDP_FreeProperty(loop);
- MEM_freeN(loop);
+ MEM_freeN(loop);
}
else {
group->len++;
@@ -691,7 +679,7 @@ IDProperty *IDP_New(const int type, const IDPropertyTemplate *val, const char *n
case IDP_DOUBLE:
prop = MEM_callocN(sizeof(IDProperty), "IDProperty float");
*(double *)&prop->data.val = val->d;
- break;
+ break;
case IDP_ARRAY:
{
/* for now, we only support float and int and double arrays */
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 2b2128439c7..c003a86a0b7 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -47,6 +47,7 @@
#include "MEM_guardedalloc.h"
+#include "IMB_colormanagement.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
@@ -70,6 +71,7 @@
#include "BLI_bpath.h"
#include "BKE_bmfont.h"
+#include "BKE_colortools.h"
#include "BKE_global.h"
#include "BKE_icons.h"
#include "BKE_image.h"
@@ -79,7 +81,6 @@
#include "BKE_scene.h"
#include "BKE_node.h"
#include "BKE_sequencer.h" /* seq_foreground_frame_get() */
-#include "BKE_utildefines.h"
#include "BLF_api.h"
@@ -244,6 +245,11 @@ static Image *image_alloc(const char *name, short source, short type)
ima->source = source;
ima->type = type;
+
+ if (source == IMA_SRC_VIEWER)
+ ima->flag |= IMA_VIEW_AS_RENDER;
+
+ BKE_color_managed_colorspace_settings_init(&ima->colorspace_settings);
}
return ima;
}
@@ -326,6 +332,8 @@ Image *BKE_image_copy(Image *ima)
nima->aspx = ima->aspx;
nima->aspy = ima->aspy;
+ BKE_color_managed_colorspace_settings_copy(&nima->colorspace_settings, &ima->colorspace_settings);
+
return nima;
}
@@ -595,7 +603,8 @@ Image *BKE_image_load_exists(const char *filepath)
return BKE_image_load(filepath);
}
-static ImBuf *add_ibuf_size(unsigned int width, unsigned int height, const char *name, int depth, int floatbuf, short uvtestgrid, float color[4])
+static ImBuf *add_ibuf_size(unsigned int width, unsigned int height, const char *name, int depth, int floatbuf, short gen_type,
+ float color[4], ColorManagedColorspaceSettings *colorspace_settings)
{
ImBuf *ibuf;
unsigned char *rect = NULL;
@@ -604,22 +613,36 @@ static ImBuf *add_ibuf_size(unsigned int width, unsigned int height, const char
if (floatbuf) {
ibuf = IMB_allocImBuf(width, height, depth, IB_rectfloat);
rect_float = ibuf->rect_float;
- ibuf->profile = IB_PROFILE_LINEAR_RGB;
+
+ if (colorspace_settings->name[0] == '\0') {
+ const char *colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DEFAULT_FLOAT);
+
+ BLI_strncpy(colorspace_settings->name, colorspace, sizeof(colorspace_settings->name));
+ }
+
+ IMB_colormanagement_check_is_data(ibuf, colorspace_settings->name);
}
else {
ibuf = IMB_allocImBuf(width, height, depth, IB_rect);
rect = (unsigned char *)ibuf->rect;
- ibuf->profile = IB_PROFILE_SRGB;
+
+ if (colorspace_settings->name[0] == '\0') {
+ const char *colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DEFAULT_BYTE);
+
+ BLI_strncpy(colorspace_settings->name, colorspace, sizeof(colorspace_settings->name));
+ }
+
+ IMB_colormanagement_assign_rect_colorspace(ibuf, colorspace_settings->name);
}
BLI_strncpy(ibuf->name, name, sizeof(ibuf->name));
ibuf->userflags |= IB_BITMAPDIRTY;
- switch (uvtestgrid) {
- case 1:
+ switch (gen_type) {
+ case IMA_GENTYPE_GRID:
BKE_image_buf_fill_checker(rect, rect_float, width, height);
break;
- case 2:
+ case IMA_GENTYPE_GRID_COLOR:
BKE_image_buf_fill_checker_color(rect, rect_float, width, height);
break;
default:
@@ -630,7 +653,7 @@ static ImBuf *add_ibuf_size(unsigned int width, unsigned int height, const char
}
/* adds new image block, creates ImBuf and initializes color */
-Image *BKE_image_add_generated(unsigned int width, unsigned int height, const char *name, int depth, int floatbuf, short uvtestgrid, float color[4])
+Image *BKE_image_add_generated(unsigned int width, unsigned int height, const char *name, int depth, int floatbuf, short gen_type, float color[4])
{
/* on save, type is changed to FILE in editsima.c */
Image *ima = image_alloc(name, IMA_SRC_GENERATED, IMA_TYPE_UV_TEST);
@@ -641,10 +664,10 @@ Image *BKE_image_add_generated(unsigned int width, unsigned int height, const ch
/* BLI_strncpy(ima->name, name, FILE_MAX); */ /* don't do this, this writes in ain invalid filepath! */
ima->gen_x = width;
ima->gen_y = height;
- ima->gen_type = uvtestgrid;
+ ima->gen_type = gen_type;
ima->gen_flag |= (floatbuf ? IMA_GEN_FLOAT : 0);
- ibuf = add_ibuf_size(width, height, ima->name, depth, floatbuf, uvtestgrid, color);
+ ibuf = add_ibuf_size(width, height, ima->name, depth, floatbuf, gen_type, color, &ima->colorspace_settings);
image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
ima->ok = IMA_OK_LOADED;
@@ -1010,6 +1033,19 @@ int BKE_imtype_supports_quality(const char imtype)
return 0;
}
+int BKE_imtype_requires_linear_float(const char imtype)
+{
+ switch (imtype) {
+ case R_IMF_IMTYPE_CINEON:
+ case R_IMF_IMTYPE_DPX:
+ case R_IMF_IMTYPE_RADHDR:
+ case R_IMF_IMTYPE_OPENEXR:
+ case R_IMF_IMTYPE_MULTILAYER:
+ return TRUE;
+ }
+ return 0;
+}
+
char BKE_imtype_valid_channels(const char imtype)
{
char chan_flag = IMA_CHAN_FLAG_RGB; /* assume all support rgb */
@@ -1208,6 +1244,9 @@ void BKE_imformat_defaults(ImageFormatData *im_format)
im_format->imtype = R_IMF_IMTYPE_PNG;
im_format->quality = 90;
im_format->compress = 90;
+
+ BKE_color_managed_display_settings_init(&im_format->display_settings);
+ BKE_color_managed_view_settings_init(&im_format->view_settings);
}
void BKE_imbuf_to_image_format(struct ImageFormatData *im_format, const ImBuf *imbuf)
@@ -1478,10 +1517,11 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec
int x, y, y_ofs;
float h_fixed;
const int mono = blf_mono_font_render; // XXX
+ struct ColorManagedDisplay *display;
+ const char *display_device;
/* this could be an argument if we want to operate on non linear float imbuf's
* for now though this is only used for renders which use scene settings */
- const int do_color_management = (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) != 0;
#define BUFF_MARGIN_X 2
#define BUFF_MARGIN_Y 1
@@ -1489,6 +1529,9 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec
if (!rect && !rectf)
return;
+ display_device = scene->display_settings.display_device;
+ display = IMB_colormanagement_display_get_named(display_device);
+
stampdata(scene, camera, &stamp_data, 1);
/* TODO, do_versions */
@@ -1498,7 +1541,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec
/* set before return */
BLF_size(mono, scene->r.stamp_font_id, 72);
- BLF_buffer(mono, rectf, rect, width, height, channels, do_color_management);
+ BLF_buffer(mono, rectf, rect, width, height, channels, display);
BLF_buffer_col(mono, scene->r.fg_stamp[0], scene->r.fg_stamp[1], scene->r.fg_stamp[2], 1.0);
pad = BLF_width_max(mono);
@@ -1515,7 +1558,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec
y -= h;
/* also a little of space to the background. */
- buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, do_color_management,
+ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, display,
x - BUFF_MARGIN_X, y - BUFF_MARGIN_Y, w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y);
/* and draw the text. */
@@ -1532,7 +1575,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec
y -= h;
/* and space for background. */
- buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, do_color_management,
+ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, display,
0, y - BUFF_MARGIN_Y, w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y);
BLF_position(mono, x, y + y_ofs, 0.0);
@@ -1548,7 +1591,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec
y -= h;
/* and space for background. */
- buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, do_color_management,
+ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, display,
0, y - BUFF_MARGIN_Y, w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y);
BLF_position(mono, x, y + y_ofs, 0.0);
@@ -1564,7 +1607,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec
y -= h;
/* and space for background. */
- buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, do_color_management,
+ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, display,
0, y - BUFF_MARGIN_Y, w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y);
BLF_position(mono, x, y + y_ofs, 0.0);
@@ -1579,7 +1622,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec
BLF_width_and_height(mono, stamp_data.marker, &w, &h); h = h_fixed;
/* extra space for background. */
- buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, do_color_management,
+ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, display,
x - BUFF_MARGIN_X, y - BUFF_MARGIN_Y, w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y);
/* and pad the text. */
@@ -1595,7 +1638,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec
BLF_width_and_height(mono, stamp_data.time, &w, &h); h = h_fixed;
/* extra space for background */
- buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, do_color_management,
+ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, display,
x - BUFF_MARGIN_X, y, x + w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y);
/* and pad the text. */
@@ -1610,7 +1653,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec
BLF_width_and_height(mono, stamp_data.frame, &w, &h); h = h_fixed;
/* extra space for background. */
- buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, do_color_management,
+ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, display,
x - BUFF_MARGIN_X, y - BUFF_MARGIN_Y, x + w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y);
/* and pad the text. */
@@ -1625,7 +1668,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec
BLF_width_and_height(mono, stamp_data.camera, &w, &h); h = h_fixed;
/* extra space for background. */
- buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, do_color_management,
+ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, display,
x - BUFF_MARGIN_X, y - BUFF_MARGIN_Y, x + w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y);
BLF_position(mono, x, y + y_ofs, 0.0);
BLF_draw_buffer(mono, stamp_data.camera);
@@ -1638,7 +1681,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec
BLF_width_and_height(mono, stamp_data.cameralens, &w, &h); h = h_fixed;
/* extra space for background. */
- buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, do_color_management,
+ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, display,
x - BUFF_MARGIN_X, y - BUFF_MARGIN_Y, x + w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y);
BLF_position(mono, x, y + y_ofs, 0.0);
BLF_draw_buffer(mono, stamp_data.cameralens);
@@ -1651,7 +1694,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec
x = width - w - 2;
/* extra space for background. */
- buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, do_color_management,
+ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, display,
x - BUFF_MARGIN_X, y - BUFF_MARGIN_Y, x + w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y);
/* and pad the text. */
@@ -1667,7 +1710,7 @@ void BKE_stamp_buf(Scene *scene, Object *camera, unsigned char *rect, float *rec
y = height - h;
/* extra space for background. */
- buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, do_color_management,
+ buf_rectfill_area(rect, rectf, width, height, scene->r.bg_stamp, display,
x - BUFF_MARGIN_X, y - BUFF_MARGIN_Y, x + w + BUFF_MARGIN_X, y + h + BUFF_MARGIN_Y);
BLF_position(mono, x, y + y_ofs, 0.0);
@@ -1879,12 +1922,12 @@ void BKE_makepicstring(char *string, const char *base, const char *relbase, int
}
/* used by sequencer too */
-struct anim *openanim(const char *name, int flags, int streamindex)
+struct anim *openanim(const char *name, int flags, int streamindex, char colorspace[IMA_MAX_SPACE])
{
struct anim *anim;
struct ImBuf *ibuf;
- anim = IMB_open_anim(name, flags, streamindex);
+ anim = IMB_open_anim(name, flags, streamindex, colorspace);
if (anim == NULL) return NULL;
ibuf = IMB_anim_absolute(anim, 0, IMB_TC_NONE, IMB_PROXY_NONE);
@@ -2178,8 +2221,10 @@ void BKE_image_backup_render(Scene *scene, Image *ima)
/* in that case we have to build a render-result */
static void image_create_multilayer(Image *ima, ImBuf *ibuf, int framenr)
{
+ const char *colorspace = ima->colorspace_settings.name;
+ int predivide = ima->flag & IMA_CM_PREDIVIDE;
- ima->rr = RE_MultilayerConvert(ibuf->userdata, ibuf->x, ibuf->y);
+ ima->rr = RE_MultilayerConvert(ibuf->userdata, colorspace, predivide, ibuf->x, ibuf->y);
#ifdef WITH_OPENEXR
IMB_exr_close(ibuf->userdata);
@@ -2227,7 +2272,7 @@ static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int frame)
flag |= IB_premul;
/* read ibuf */
- ibuf = IMB_loadiffname(name, flag);
+ ibuf = IMB_loadiffname(name, flag, ima->colorspace_settings.name);
#if 0
if (ibuf) {
@@ -2305,7 +2350,6 @@ static ImBuf *image_load_sequence_multilayer(Image *ima, ImageUser *iuser, int f
ibuf->flags |= IB_rectfloat;
ibuf->mall = IB_rectfloat;
ibuf->channels = rpass->channels;
- ibuf->profile = IB_PROFILE_LINEAR_RGB;
image_initialize_after_load(ima, ibuf);
image_assign_ibuf(ima, ibuf, iuser ? iuser->multi_index : 0, frame);
@@ -2335,7 +2379,7 @@ static ImBuf *image_load_movie_file(Image *ima, ImageUser *iuser, int frame)
BKE_image_user_file_path(iuser, ima, str);
/* FIXME: make several stream accessible in image editor, too*/
- ima->anim = openanim(str, IB_rect, 0);
+ ima->anim = openanim(str, IB_rect, 0, ima->colorspace_settings.name);
/* let's initialize this user */
if (ima->anim && iuser && iuser->frames == 0)
@@ -2386,8 +2430,8 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra)
flag = IB_rect | IB_multilayer;
if (ima->flag & IMA_DO_PREMUL) flag |= IB_premul;
- ibuf = IMB_ibImageFromMemory((unsigned char *)ima->packedfile->data,
- ima->packedfile->size, flag, "<packed data>");
+ ibuf = IMB_ibImageFromMemory((unsigned char *)ima->packedfile->data, ima->packedfile->size, flag,
+ ima->colorspace_settings.name, "<packed data>");
}
else {
flag = IB_rect | IB_multilayer | IB_metadata;
@@ -2399,7 +2443,7 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra)
BKE_image_user_file_path(iuser, ima, str);
/* read ibuf */
- ibuf = IMB_loadiffname(str, flag);
+ ibuf = IMB_loadiffname(str, flag, ima->colorspace_settings.name);
}
if (ibuf) {
@@ -2456,7 +2500,6 @@ static ImBuf *image_get_ibuf_multilayer(Image *ima, ImageUser *iuser)
ibuf->rect_float = rpass->rect;
ibuf->flags |= IB_rectfloat;
ibuf->channels = rpass->channels;
- ibuf->profile = IB_PROFILE_LINEAR_RGB;
image_assign_ibuf(ima, ibuf, iuser ? iuser->multi_index : IMA_NO_INDEX, 0);
}
@@ -2520,14 +2563,16 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_
*lock_r = re;
}
- /* this gives active layer, composite or seqence result */
+ /* this gives active layer, composite or sequence result */
rect = (unsigned int *)rres.rect32;
rectf = rres.rectf;
rectz = rres.rectz;
dither = iuser->scene->r.dither_intensity;
/* combined layer gets added as first layer */
- if (rres.have_combined && layer == 0) ;
+ if (rres.have_combined && layer == 0) {
+ /* pass */
+ }
else if (rres.layers.first) {
RenderLayer *rl = BLI_findlink(&rres.layers, layer - (rres.have_combined ? 1 : 0));
if (rl) {
@@ -2560,6 +2605,12 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_
image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
}
+ /* invalidate color managed buffers if render result changed */
+ BLI_lock_thread(LOCK_COLORMANAGE);
+ if (ibuf->x != rres.rectx || ibuf->y != rres.recty || ibuf->rect_float != rectf) {
+ ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID;
+ }
+
ibuf->x = rres.rectx;
ibuf->y = rres.recty;
@@ -2591,8 +2642,8 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_
ibuf->flags &= ~IB_zbuffloat;
}
- /* since its possible to access the buffer from the image directly, set the profile [#25073] */
- ibuf->profile = (iuser->scene->r.color_mgt_flag & R_COLOR_MANAGEMENT) ? IB_PROFILE_LINEAR_RGB : IB_PROFILE_NONE;
+ BLI_unlock_thread(LOCK_COLORMANAGE);
+
ibuf->dither = dither;
if (iuser->scene->r.color_mgt_flag & R_COLOR_MANAGEMENT_PREDIVIDE) {
@@ -2749,7 +2800,8 @@ ImBuf *BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
/* UV testgrid or black or solid etc */
if (ima->gen_x == 0) ima->gen_x = 1024;
if (ima->gen_y == 0) ima->gen_y = 1024;
- ibuf = add_ibuf_size(ima->gen_x, ima->gen_y, ima->name, 24, (ima->gen_flag & IMA_GEN_FLOAT) != 0, ima->gen_type, color);
+ ibuf = add_ibuf_size(ima->gen_x, ima->gen_y, ima->name, 24, (ima->gen_flag & IMA_GEN_FLOAT) != 0, ima->gen_type,
+ color, &ima->colorspace_settings);
image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
ima->ok = IMA_OK_LOADED;
}
@@ -2930,3 +2982,43 @@ int BKE_image_has_alpha(struct Image *image)
else
return 0;
}
+
+void BKE_image_get_size(Image *image, ImageUser *iuser, int *width, int *height)
+{
+ ImBuf *ibuf = NULL;
+ void *lock;
+
+ ibuf = BKE_image_acquire_ibuf(image, iuser, &lock);
+
+ if (ibuf && ibuf->x > 0 && ibuf->y > 0) {
+ *width = ibuf->x;
+ *height = ibuf->y;
+ }
+ else {
+ *width = IMG_SIZE_FALLBACK;
+ *height = IMG_SIZE_FALLBACK;
+ }
+
+ BKE_image_release_ibuf(image, lock);
+}
+
+void BKE_image_get_size_fl(Image *image, ImageUser *iuser, float size[2])
+{
+ int width, height;
+ BKE_image_get_size(image, iuser, &width, &height);
+
+ size[0] = (float)width;
+ size[1] = (float)height;
+
+}
+
+void BKE_image_get_aspect(Image *image, float *aspx, float *aspy)
+{
+ *aspx = 1.0;
+
+ /* x is always 1 */
+ if (image)
+ *aspy = image->aspy / image->aspx;
+ else
+ *aspy = 1.0f;
+}
diff --git a/source/blender/blenkernel/intern/image_gen.c b/source/blender/blenkernel/intern/image_gen.c
index 4d7013b9f73..37572eebed6 100644
--- a/source/blender/blenkernel/intern/image_gen.c
+++ b/source/blender/blenkernel/intern/image_gen.c
@@ -289,7 +289,11 @@ static void checker_board_text(unsigned char *rect, float *rect_float, int width
BLF_size(mono, 54, 72); /* hard coded size! */
- BLF_buffer(mono, rect_float, rect, width, height, 4, TRUE);
+ /* OCIO_TODO: using NULL as display will assume using sRGB display
+ * this is correct since currently generated images are assumed to be in sRGB space,
+ * but this would probably needed to be fixed in some way
+ */
+ BLF_buffer(mono, rect_float, rect, width, height, 4, NULL);
for (y = 0; y < height; y += step) {
text[1] = '1';
diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c
index 616214c21ff..ebb95a6561e 100644
--- a/source/blender/blenkernel/intern/implicit.c
+++ b/source/blender/blenkernel/intern/implicit.c
@@ -48,8 +48,11 @@
#include "BKE_global.h"
-#define CLOTH_OPENMP_LIMIT 512
+#ifdef _OPENMP
+# define CLOTH_OPENMP_LIMIT 512
+#endif
+#if 0 /* debug timing */
#ifdef _WIN32
#include <windows.h>
static LARGE_INTEGER _itstart, _itend;
@@ -81,7 +84,7 @@ double itval(void)
static struct timeval _itstart, _itend;
static struct timezone itz;
-void itstart(void)
+static void itstart(void)
{
gettimeofday(&_itstart, &itz);
}
@@ -89,7 +92,7 @@ static void itend(void)
{
gettimeofday(&_itend, &itz);
}
-double itval(void)
+static double itval(void)
{
double t1, t2;
t1 = (double)_itstart.tv_sec + (double)_itstart.tv_usec/(1000*1000);
@@ -97,6 +100,7 @@ double itval(void)
return t2-t1;
}
#endif
+#endif /* debug timing */
static float I[3][3] = {{1, 0, 0}, {0, 1, 0}, {0, 0, 1}};
static float ZERO[3][3] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}};
@@ -193,7 +197,7 @@ DO_INLINE lfVector *create_lfvector(unsigned int verts)
DO_INLINE void del_lfvector(float (*fLongVector)[3])
{
if (fLongVector != NULL) {
- MEM_freeN (fLongVector);
+ MEM_freeN(fLongVector);
// cloth_aligned_free(&MEMORY_BASE, fLongVector);
}
}
@@ -523,7 +527,7 @@ DO_INLINE fmatrix3x3 *create_bfmatrix(unsigned int verts, unsigned int springs)
DO_INLINE void del_bfmatrix(fmatrix3x3 *matrix)
{
if (matrix != NULL) {
- MEM_freeN (matrix);
+ MEM_freeN(matrix);
}
}
@@ -1691,13 +1695,13 @@ static void simulate_implicit_euler(lfVector *Vnew, lfVector *UNUSED(lX), lfVect
mul_bfmatrix_lfvector(dFdXmV, dFdX, lV);
add_lfvectorS_lfvectorS(B, lF, dt, dFdXmV, (dt*dt), numverts);
-
- itstart();
-
+
+ // itstart();
+
cg_filtered(dV, A, B, z, S); /* conjugate gradient algorithm to solve Ax=b */
// cg_filtered_pre(dV, A, B, z, S, P, Pinv, bigI);
-
- itend();
+
+ // itend();
// printf("cg_filtered calc time: %f\n", (float)itval());
cp_lfvector(olddV, dV, numverts);
@@ -1713,7 +1717,7 @@ static void simulate_implicit_euler(lfVector *Vnew, lfVector *UNUSED(lX), lfVect
* (edge distance constraints) in a lagrangian solver. then add forces to help
* guide the implicit solver to that state. this function is called after
* collisions*/
-int cloth_calc_helper_forces(Object *UNUSED(ob), ClothModifierData * clmd, float (*initial_cos)[3], float UNUSED(step), float dt)
+static int UNUSED_FUNCTION(cloth_calc_helper_forces)(Object *UNUSED(ob), ClothModifierData * clmd, float (*initial_cos)[3], float UNUSED(step), float dt)
{
Cloth *cloth= clmd->clothObject;
float (*cos)[3] = MEM_callocN(sizeof(float)*3*cloth->numverts, "cos cloth_calc_helper_forces");
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index b2a9e229be9..5216aefab58 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -32,7 +32,7 @@
/* NOTE:
*
- * This file is no longer used to provide tools for the depreceated IPO system. Instead, it
+ * This file is no longer used to provide tools for the deprecated IPO system. Instead, it
* is only used to house the conversion code to the new system.
*
* -- Joshua Leung, Jan 2009
@@ -1757,15 +1757,15 @@ void do_versions_ipos_to_animato(Main *main)
{
/* If we have any empty action actuators, assume they were
- converted IPO Actuators using the object IPO */
+ * converted IPO Actuators using the object IPO */
bActuator *act;
bActionActuator *aa;
for (act = ob->actuators.first; act; act = act->next) {
/* Any actuators set to ACT_IPO at this point are actually Action Actuators that
- need this converted IPO to finish converting the actuator. */
+ * need this converted IPO to finish converting the actuator. */
if (act->type == ACT_IPO) {
- aa = (bActionActuator*)act->data;
+ aa = (bActionActuator *)act->data;
aa->act = ob->adt->action;
act->type = ACT_ACTION;
}
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index 17a3c595ea7..b9bf2fd01a3 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -94,7 +94,7 @@ void BKE_key_free(Key *key)
}
-void free_key_nolib(Key *key)
+void BKE_key_free_nolib(Key *key)
{
KeyBlock *kb;
@@ -121,7 +121,7 @@ void free_key_nolib(Key *key)
/* from misc_util: flip the bytes from x */
/* #define GS(x) (((unsigned char *)(x))[0] << 8 | ((unsigned char *)(x))[1]) */
-Key *add_key(ID *id) /* common function */
+Key *BKE_key_add(ID *id) /* common function */
{
Key *key;
char *el;
@@ -133,7 +133,7 @@ Key *add_key(ID *id) /* common function */
key->uidgen = 1;
- /* XXX the code here uses some defines which will soon be depreceated... */
+ /* XXX the code here uses some defines which will soon be deprecated... */
switch (GS(id->name)) {
case ID_ME:
el = key->elemstr;
@@ -196,7 +196,7 @@ Key *BKE_key_copy(Key *key)
}
-Key *copy_key_nolib(Key *key)
+Key *BKE_key_copy_nolib(Key *key)
{
Key *keyn;
KeyBlock *kbn, *kb;
@@ -241,7 +241,7 @@ void BKE_key_make_local(Key *key)
* currently being called.
*/
-void sort_keys(Key *key)
+void BKE_key_sort(Key *key)
{
KeyBlock *kb;
KeyBlock *kb2;
@@ -691,8 +691,8 @@ static void cp_cu_key(Curve *cu, Key *key, KeyBlock *actkb, KeyBlock *kb, const
if (nu->bp) {
step = nu->pntsu * nu->pntsv;
- a1 = MAX2(a, start);
- a2 = MIN2(a + step, end);
+ a1 = maxi(a, start);
+ a2 = mini(a + step, end);
if (a1 < a2) cp_key(a1, a2, tot, out, key, actkb, kb, NULL, KEY_MODE_BPOINT);
}
@@ -700,8 +700,8 @@ static void cp_cu_key(Curve *cu, Key *key, KeyBlock *actkb, KeyBlock *kb, const
step = 3 * nu->pntsu;
/* exception because keys prefer to work with complete blocks */
- a1 = MAX2(a, start);
- a2 = MIN2(a + step, end);
+ a1 = maxi(a, start);
+ a2 = mini(a + step, end);
if (a1 < a2) cp_key(a1, a2, tot, out, key, actkb, kb, NULL, KEY_MODE_BEZTRIPLE);
}
@@ -711,7 +711,7 @@ static void cp_cu_key(Curve *cu, Key *key, KeyBlock *actkb, KeyBlock *kb, const
}
}
-void do_rel_key(const int start, int end, const int tot, char *basispoin, Key *key, KeyBlock *actkb, const int mode)
+void BKE_key_evaluate_relative(const int start, int end, const int tot, char *basispoin, Key *key, KeyBlock *actkb, const int mode)
{
KeyBlock *kb;
int *ofsp, ofs[3], elemsize, b;
@@ -1071,7 +1071,7 @@ static float *get_weights_array(Object *ob, char *vgroup)
static void do_mesh_key(Scene *scene, Object *ob, Key *key, char *out, const int tot)
{
- KeyBlock *k[4], *actkb = ob_get_keyblock(ob);
+ KeyBlock *k[4], *actkb = BKE_keyblock_from_object(ob);
float t[4];
int flag = 0;
@@ -1106,7 +1106,7 @@ static void do_mesh_key(Scene *scene, Object *ob, Key *key, char *out, const int
kb->weights = get_weights_array(ob, kb->vgroup);
}
- do_rel_key(0, tot, tot, (char *)out, key, actkb, KEY_MODE_DUMMY);
+ BKE_key_evaluate_relative(0, tot, tot, (char *)out, key, actkb, KEY_MODE_DUMMY);
for (kb = key->block.first; kb; kb = kb->next) {
if (kb->weights) MEM_freeN(kb->weights);
@@ -1154,11 +1154,11 @@ static void do_rel_cu_key(Curve *cu, Key *key, KeyBlock *actkb, char *out, const
for (a = 0, nu = cu->nurb.first; nu; nu = nu->next, a += step) {
if (nu->bp) {
step = nu->pntsu * nu->pntsv;
- do_rel_key(a, a + step, tot, out, key, actkb, KEY_MODE_BPOINT);
+ BKE_key_evaluate_relative(a, a + step, tot, out, key, actkb, KEY_MODE_BPOINT);
}
else if (nu->bezt) {
step = 3 * nu->pntsu;
- do_rel_key(a, a + step, tot, out, key, actkb, KEY_MODE_BEZTRIPLE);
+ BKE_key_evaluate_relative(a, a + step, tot, out, key, actkb, KEY_MODE_BEZTRIPLE);
}
else {
step = 0;
@@ -1169,7 +1169,7 @@ static void do_rel_cu_key(Curve *cu, Key *key, KeyBlock *actkb, char *out, const
static void do_curve_key(Scene *scene, Object *ob, Key *key, char *out, const int tot)
{
Curve *cu = ob->data;
- KeyBlock *k[4], *actkb = ob_get_keyblock(ob);
+ KeyBlock *k[4], *actkb = BKE_keyblock_from_object(ob);
float t[4];
int flag = 0;
@@ -1217,7 +1217,7 @@ static void do_curve_key(Scene *scene, Object *ob, Key *key, char *out, const in
remain = step;
}
- count = MIN2(remain, estep);
+ count = mini(remain, estep);
if (mode == KEY_MODE_BEZTRIPLE) {
count += 3 - count % 3;
}
@@ -1251,7 +1251,7 @@ static void do_curve_key(Scene *scene, Object *ob, Key *key, char *out, const in
static void do_latt_key(Scene *scene, Object *ob, Key *key, char *out, const int tot)
{
Lattice *lt = ob->data;
- KeyBlock *k[4], *actkb = ob_get_keyblock(ob);
+ KeyBlock *k[4], *actkb = BKE_keyblock_from_object(ob);
float t[4];
int flag;
@@ -1277,7 +1277,7 @@ static void do_latt_key(Scene *scene, Object *ob, Key *key, char *out, const int
for (kb = key->block.first; kb; kb = kb->next)
kb->weights = get_weights_array(ob, kb->vgroup);
- do_rel_key(0, tot, tot, out, key, actkb, KEY_MODE_DUMMY);
+ BKE_key_evaluate_relative(0, tot, tot, out, key, actkb, KEY_MODE_DUMMY);
for (kb = key->block.first; kb; kb = kb->next) {
if (kb->weights) MEM_freeN(kb->weights);
@@ -1302,8 +1302,8 @@ static void do_latt_key(Scene *scene, Object *ob, Key *key, char *out, const int
/* returns key coordinates (+ tilt) when key applied, NULL otherwise */
float *do_ob_key(Scene *scene, Object *ob)
{
- Key *key = ob_get_key(ob);
- KeyBlock *actkb = ob_get_keyblock(ob);
+ Key *key = BKE_key_from_object(ob);
+ KeyBlock *actkb = BKE_keyblock_from_object(ob);
char *out;
int tot = 0, size = 0;
@@ -1386,7 +1386,7 @@ float *do_ob_key(Scene *scene, Object *ob)
return (float *)out;
}
-Key *ob_get_key(Object *ob)
+Key *BKE_key_from_object(Object *ob)
{
if (ob == NULL) return NULL;
@@ -1405,7 +1405,7 @@ Key *ob_get_key(Object *ob)
return NULL;
}
-KeyBlock *add_keyblock(Key *key, const char *name)
+KeyBlock *BKE_keyblock_add(Key *key, const char *name)
{
KeyBlock *kb;
float curpos = -0.1;
@@ -1439,7 +1439,7 @@ KeyBlock *add_keyblock(Key *key, const char *name)
/**
* \note caller may want to set this to current time, but don't do it here since we need to sort
- * which could cause problems in some cases, see #add_keyblock_ctime */
+ * which could cause problems in some cases, see #BKE_keyblock_add_ctime */
kb->pos = curpos + 0.1f; /* only used for absolute shape keys */
return kb;
@@ -1453,22 +1453,22 @@ KeyBlock *add_keyblock(Key *key, const char *name)
* \param name Optional name for the new keyblock.
* \param do_force always use ctime even for relative keys.
*/
-KeyBlock *add_keyblock_ctime(Key *key, const char *name, const short do_force)
+KeyBlock *BKE_keyblock_add_ctime(Key *key, const char *name, const short do_force)
{
- KeyBlock *kb = add_keyblock(key, name);
+ KeyBlock *kb = BKE_keyblock_add(key, name);
if (do_force || (key->type != KEY_RELATIVE)) {
kb->pos = key->ctime / 100.0f;
- sort_keys(key);
+ BKE_key_sort(key);
}
return kb;
}
/* only the active keyblock */
-KeyBlock *ob_get_keyblock(Object *ob)
+KeyBlock *BKE_keyblock_from_object(Object *ob)
{
- Key *key = ob_get_key(ob);
+ Key *key = BKE_key_from_object(ob);
if (key) {
KeyBlock *kb = BLI_findlink(&key->block, ob->shapenr - 1);
@@ -1478,9 +1478,9 @@ KeyBlock *ob_get_keyblock(Object *ob)
return NULL;
}
-KeyBlock *ob_get_reference_keyblock(Object *ob)
+KeyBlock *BKE_keyblock_from_object_reference(Object *ob)
{
- Key *key = ob_get_key(ob);
+ Key *key = BKE_key_from_object(ob);
if (key)
return key->refkey;
@@ -1489,7 +1489,7 @@ KeyBlock *ob_get_reference_keyblock(Object *ob)
}
/* get the appropriate KeyBlock given an index */
-KeyBlock *key_get_keyblock(Key *key, int index)
+KeyBlock *BKE_keyblock_from_key(Key *key, int index)
{
KeyBlock *kb;
int i;
@@ -1509,18 +1509,29 @@ KeyBlock *key_get_keyblock(Key *key, int index)
}
/* get the appropriate KeyBlock given a name to search for */
-KeyBlock *key_get_named_keyblock(Key *key, const char name[])
+KeyBlock *BKE_keyblock_find_name(Key *key, const char name[])
{
- if (key && name)
- return BLI_findstring(&key->block, name, offsetof(KeyBlock, name));
-
- return NULL;
+ return BLI_findstring(&key->block, name, offsetof(KeyBlock, name));
+}
+
+/**
+ * \brief copy shape-key attributes, but not key data.or name/uid
+ */
+void BKE_keyblock_copy_settings(KeyBlock *kb_dst, const KeyBlock *kb_src)
+{
+ kb_dst->pos = kb_src->pos;
+ kb_dst->curval = kb_src->curval;
+ kb_dst->type = kb_src->type;
+ kb_dst->relative = kb_src->relative;
+ BLI_strncpy(kb_dst->vgroup, kb_src->vgroup, sizeof(kb_dst->vgroup));
+ kb_dst->slidermin = kb_src->slidermin;
+ kb_dst->slidermax = kb_src->slidermax;
}
/* Get RNA-Path for 'value' setting of the given ShapeKey
* NOTE: the user needs to free the returned string once they're finish with it
*/
-char *key_get_curValue_rnaPath(Key *key, KeyBlock *kb)
+char *BKE_keyblock_curval_rnapath_get(Key *key, KeyBlock *kb)
{
PointerRNA ptr;
PropertyRNA *prop;
@@ -1542,7 +1553,7 @@ char *key_get_curValue_rnaPath(Key *key, KeyBlock *kb)
/* conversion functions */
/************************* Lattice ************************/
-void latt_to_key(Lattice *lt, KeyBlock *kb)
+void BKE_key_convert_from_lattice(Lattice *lt, KeyBlock *kb)
{
BPoint *bp;
float *fp;
@@ -1563,7 +1574,7 @@ void latt_to_key(Lattice *lt, KeyBlock *kb)
}
}
-void key_to_latt(KeyBlock *kb, Lattice *lt)
+void BKE_key_convert_to_lattice(KeyBlock *kb, Lattice *lt)
{
BPoint *bp;
float *fp;
@@ -1573,7 +1584,7 @@ void key_to_latt(KeyBlock *kb, Lattice *lt)
fp = kb->data;
tot = lt->pntsu * lt->pntsv * lt->pntsw;
- tot = MIN2(kb->totelem, tot);
+ tot = mini(kb->totelem, tot);
for (a = 0; a < tot; a++, fp += 3, bp++) {
copy_v3_v3(bp->vec, fp);
@@ -1581,7 +1592,7 @@ void key_to_latt(KeyBlock *kb, Lattice *lt)
}
/************************* Curve ************************/
-void curve_to_key(Curve *cu, KeyBlock *kb, ListBase *nurb)
+void BKE_key_convert_from_curve(Curve *cu, KeyBlock *kb, ListBase *nurb)
{
Nurb *nu;
BezTriple *bezt;
@@ -1632,7 +1643,7 @@ void curve_to_key(Curve *cu, KeyBlock *kb, ListBase *nurb)
}
}
-void key_to_curve(KeyBlock *kb, Curve *UNUSED(cu), ListBase *nurb)
+void BKE_key_convert_to_curve(KeyBlock *kb, Curve *UNUSED(cu), ListBase *nurb)
{
Nurb *nu;
BezTriple *bezt;
@@ -1645,7 +1656,7 @@ void key_to_curve(KeyBlock *kb, Curve *UNUSED(cu), ListBase *nurb)
tot = BKE_nurbList_verts_count(nurb);
- tot = MIN2(kb->totelem, tot);
+ tot = mini(kb->totelem, tot);
while (nu && tot > 0) {
@@ -1683,7 +1694,7 @@ void key_to_curve(KeyBlock *kb, Curve *UNUSED(cu), ListBase *nurb)
}
/************************* Mesh ************************/
-void mesh_to_key(Mesh *me, KeyBlock *kb)
+void BKE_key_convert_from_mesh(Mesh *me, KeyBlock *kb)
{
MVert *mvert;
float *fp;
@@ -1704,7 +1715,7 @@ void mesh_to_key(Mesh *me, KeyBlock *kb)
}
}
-void key_to_mesh(KeyBlock *kb, Mesh *me)
+void BKE_key_convert_to_mesh(KeyBlock *kb, Mesh *me)
{
MVert *mvert;
float *fp;
@@ -1713,7 +1724,7 @@ void key_to_mesh(KeyBlock *kb, Mesh *me)
mvert = me->mvert;
fp = kb->data;
- tot = MIN2(kb->totelem, me->totvert);
+ tot = mini(kb->totelem, me->totvert);
for (a = 0; a < tot; a++, fp += 3, mvert++) {
copy_v3_v3(mvert->co, fp);
@@ -1721,7 +1732,7 @@ void key_to_mesh(KeyBlock *kb, Mesh *me)
}
/************************* vert coords ************************/
-float (*key_to_vertcos(Object * ob, KeyBlock * kb))[3]
+float (*BKE_key_convert_to_vertcos(Object * ob, KeyBlock * kb))[3]
{
float (*vertCos)[3], *co;
float *fp = kb->data;
@@ -1743,7 +1754,7 @@ float (*key_to_vertcos(Object * ob, KeyBlock * kb))[3]
if (tot == 0) return NULL;
- vertCos = MEM_callocN(tot * sizeof(*vertCos), "key_to_vertcos vertCos");
+ vertCos = MEM_callocN(tot * sizeof(*vertCos), "BKE_key_convert_to_vertcos vertCos");
/* Copy coords to array */
co = (float *)vertCos;
@@ -1797,7 +1808,7 @@ float (*key_to_vertcos(Object * ob, KeyBlock * kb))[3]
return vertCos;
}
-void vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3])
+void BKE_key_convert_from_vertcos(Object *ob, KeyBlock *kb, float (*vertCos)[3])
{
float *co = (float *)vertCos, *fp;
int tot = 0, a, elemsize;
@@ -1826,7 +1837,7 @@ void vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3])
return;
}
- fp = kb->data = MEM_callocN(tot * elemsize, "key_to_vertcos vertCos");
+ fp = kb->data = MEM_callocN(tot * elemsize, "BKE_key_convert_to_vertcos vertCos");
/* Copy coords to keyblock */
@@ -1877,7 +1888,7 @@ void vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3])
}
}
-void offset_to_key(Object *ob, KeyBlock *kb, float (*ofs)[3])
+void BKE_key_convert_from_offset(Object *ob, KeyBlock *kb, float (*ofs)[3])
{
int a;
float *co = (float *)ofs, *fp = kb->data;
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index 0e73d10fa5f..17e4103c7d3 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -488,7 +488,7 @@ static int where_on_path_deform(Object *ob, float ctime, float vec[4], float dir
/* test for cyclic */
bl = cu->bev.first;
if (!bl->nr) return 0;
- if (bl && bl->poly > -1) cycl = 1;
+ if (bl->poly > -1) cycl = 1;
if (cycl == 0) {
ctime1 = CLAMPIS(ctime, 0.0f, 1.0f);
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index e073cfdf76d..45364f5aafa 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -107,7 +107,6 @@
#include "BKE_gpencil.h"
#include "BKE_fcurve.h"
#include "BKE_speaker.h"
-#include "BKE_utildefines.h"
#include "BKE_movieclip.h"
#include "BKE_mask.h"
@@ -801,6 +800,7 @@ static void animdata_dtar_clear_cb(ID *UNUSED(id), AnimData *adt, void *userdata
/* used in headerbuttons.c image.c mesh.c screen.c sound.c and library.c */
void BKE_libblock_free(ListBase *lb, void *idv)
{
+ Main *bmain = G.main; /* should eventually be an arg */
ID *id = idv;
#ifdef WITH_PYTHON
@@ -863,7 +863,7 @@ void BKE_libblock_free(ListBase *lb, void *idv)
BKE_text_free((Text *)id);
break;
case ID_SCRIPT:
- //XXX free_script((Script *)id);
+ /* deprecated */
break;
case ID_SPK:
BKE_speaker_free((Speaker *)id);
@@ -900,7 +900,7 @@ void BKE_libblock_free(ListBase *lb, void *idv)
BKE_movieclip_free((MovieClip *)id);
break;
case ID_MSK:
- BKE_mask_free((Mask *)id);
+ BKE_mask_free(bmain, (Mask *)id);
break;
}
@@ -912,7 +912,7 @@ void BKE_libblock_free(ListBase *lb, void *idv)
BLI_remlink(lb, id);
/* this ID may be a driver target! */
- BKE_animdata_main_cb(G.main, animdata_dtar_clear_cb, (void *)id);
+ BKE_animdata_main_cb(bmain, animdata_dtar_clear_cb, (void *)id);
MEM_freeN(id);
}
@@ -947,9 +947,52 @@ void free_main(Main *mainvar)
ID *id;
while ( (id = lb->first) ) {
+#if 1
BKE_libblock_free(lb, id);
+#else
+ /* errors freeing ID's can be hard to track down,
+ * enable this so valgrind will give the line number in its error log */
+ switch (a) {
+ case 0: BKE_libblock_free(lb, id); break;
+ case 1: BKE_libblock_free(lb, id); break;
+ case 2: BKE_libblock_free(lb, id); break;
+ case 3: BKE_libblock_free(lb, id); break;
+ case 4: BKE_libblock_free(lb, id); break;
+ case 5: BKE_libblock_free(lb, id); break;
+ case 6: BKE_libblock_free(lb, id); break;
+ case 7: BKE_libblock_free(lb, id); break;
+ case 8: BKE_libblock_free(lb, id); break;
+ case 9: BKE_libblock_free(lb, id); break;
+ case 10: BKE_libblock_free(lb, id); break;
+ case 11: BKE_libblock_free(lb, id); break;
+ case 12: BKE_libblock_free(lb, id); break;
+ case 13: BKE_libblock_free(lb, id); break;
+ case 14: BKE_libblock_free(lb, id); break;
+ case 15: BKE_libblock_free(lb, id); break;
+ case 16: BKE_libblock_free(lb, id); break;
+ case 17: BKE_libblock_free(lb, id); break;
+ case 18: BKE_libblock_free(lb, id); break;
+ case 19: BKE_libblock_free(lb, id); break;
+ case 20: BKE_libblock_free(lb, id); break;
+ case 21: BKE_libblock_free(lb, id); break;
+ case 22: BKE_libblock_free(lb, id); break;
+ case 23: BKE_libblock_free(lb, id); break;
+ case 24: BKE_libblock_free(lb, id); break;
+ case 25: BKE_libblock_free(lb, id); break;
+ case 26: BKE_libblock_free(lb, id); break;
+ case 27: BKE_libblock_free(lb, id); break;
+ case 28: BKE_libblock_free(lb, id); break;
+ case 29: BKE_libblock_free(lb, id); break;
+ case 30: BKE_libblock_free(lb, id); break;
+ case 31: BKE_libblock_free(lb, id); break;
+ case 32: BKE_libblock_free(lb, id); break;
+ default:
+ BLI_assert(0);
+ }
+#endif
}
}
+ a = set_listbasepointers(mainvar, lbarray);
MEM_freeN(mainvar);
}
@@ -1528,7 +1571,7 @@ void BKE_library_filepath_set(Library *lib, const char *filepath)
/* not essential but set filepath is an absolute copy of value which
* is more useful if its kept in sync */
- if (strncmp(lib->filepath, "//", 2) == 0) {
+ if (BLI_path_is_rel(lib->filepath)) {
/* note that the file may be unsaved, in this case, setting the
* filepath on an indirectly linked path is not allowed from the
* outliner, and its not really supported but allow from here for now
diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c
index 1e1cbf8610e..aa19350c456 100644
--- a/source/blender/blenkernel/intern/mask.c
+++ b/source/blender/blenkernel/intern/mask.c
@@ -19,7 +19,8 @@
* All rights reserved.
*
* Contributor(s): Blender Foundation,
- * Sergey Sharybin
+ * Sergey Sharybin,
+ * Campbell Barton
*
* ***** END GPL LICENSE BLOCK *****
*/
@@ -41,12 +42,8 @@
#include "DNA_mask_types.h"
#include "DNA_node_types.h"
-#include "DNA_scene_types.h"
-#include "DNA_object_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
-#include "DNA_movieclip_types.h"
-#include "DNA_tracking_types.h"
#include "DNA_sequence_types.h"
#include "BKE_curve.h"
@@ -58,7 +55,7 @@
#include "BKE_sequencer.h"
#include "BKE_tracking.h"
#include "BKE_movieclip.h"
-#include "BKE_utildefines.h"
+#include "BKE_image.h"
static MaskSplinePoint *mask_spline_point_next(MaskSpline *spline, MaskSplinePoint *points_array, MaskSplinePoint *point)
{
@@ -90,7 +87,7 @@ static MaskSplinePoint *mask_spline_point_prev(MaskSpline *spline, MaskSplinePoi
}
}
-static BezTriple *mask_spline_point_next_bezt(MaskSpline *spline, MaskSplinePoint *points_array, MaskSplinePoint *point)
+BezTriple *BKE_mask_spline_point_next_bezt(MaskSpline *spline, MaskSplinePoint *points_array, MaskSplinePoint *point)
{
if (point == &points_array[spline->tot_point - 1]) {
if (spline->flag & MASK_SPLINE_CYCLIC) {
@@ -158,7 +155,7 @@ MaskLayer *BKE_mask_layer_new(Mask *mask, const char *name)
mask->masklay_tot++;
- masklay->blend = MASK_BLEND_MERGE;
+ masklay->blend = MASK_BLEND_MERGE_ADD;
masklay->alpha = 1.0f;
return masklay;
@@ -269,588 +266,6 @@ MaskSpline *BKE_mask_spline_add(MaskLayer *masklay)
return spline;
}
-unsigned int BKE_mask_spline_resolution(MaskSpline *spline, int width, int height)
-{
- float max_segment = 0.01f;
- unsigned int i, resol = 1;
-
- if (width != 0 && height != 0) {
- if (width >= height)
- max_segment = 1.0f / (float) width;
- else
- max_segment = 1.0f / (float) height;
- }
-
- for (i = 0; i < spline->tot_point; i++) {
- MaskSplinePoint *point = &spline->points[i];
- BezTriple *bezt, *bezt_next;
- float a, b, c, len;
- unsigned int cur_resol;
-
- bezt = &point->bezt;
- bezt_next = mask_spline_point_next_bezt(spline, spline->points, point);
-
- if (bezt_next == NULL) {
- break;
- }
-
- a = len_v3v3(bezt->vec[1], bezt->vec[2]);
- b = len_v3v3(bezt->vec[2], bezt_next->vec[0]);
- c = len_v3v3(bezt_next->vec[0], bezt_next->vec[1]);
-
- len = a + b + c;
- cur_resol = len / max_segment;
-
- resol = MAX2(resol, cur_resol);
-
- if (resol >= MASK_RESOL_MAX) {
- break;
- }
- }
-
- return CLAMPIS(resol, 1, MASK_RESOL_MAX);
-}
-
-unsigned int BKE_mask_spline_feather_resolution(MaskSpline *spline, int width, int height)
-{
- const float max_segment = 0.005;
- unsigned int resol = BKE_mask_spline_resolution(spline, width, height);
- float max_jump = 0.0f;
- int i;
-
- /* avoid checking the featrher if we already hit the maximum value */
- if (resol >= MASK_RESOL_MAX) {
- return MASK_RESOL_MAX;
- }
-
- for (i = 0; i < spline->tot_point; i++) {
- MaskSplinePoint *point = &spline->points[i];
- float prev_u, prev_w;
- int j;
-
- prev_u = 0.0f;
- prev_w = point->bezt.weight;
-
- for (j = 0; j < point->tot_uw; j++) {
- const float w_diff = (point->uw[j].w - prev_w);
- const float u_diff = (point->uw[j].u - prev_u);
-
- /* avoid divide by zero and very high values,
- * though these get clamped eventually */
- if (u_diff > FLT_EPSILON) {
- float jump = fabsf(w_diff / u_diff);
-
- max_jump = MAX2(max_jump, jump);
- }
-
- prev_u = point->uw[j].u;
- prev_w = point->uw[j].w;
- }
- }
-
- resol += max_jump / max_segment;
-
- return CLAMPIS(resol, 1, MASK_RESOL_MAX);
-}
-
-int BKE_mask_spline_differentiate_calc_total(const MaskSpline *spline, const unsigned int resol)
-{
- if (spline->flag & MASK_SPLINE_CYCLIC) {
- return spline->tot_point * resol;
- }
- else {
- return ((spline->tot_point - 1) * resol) + 1;
- }
-}
-
-float (*BKE_mask_spline_differentiate_with_resolution_ex(MaskSpline *spline,
- int *tot_diff_point,
- const unsigned int resol
- ))[2]
-{
- MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
-
- MaskSplinePoint *point, *prev;
- float (*diff_points)[2], (*fp)[2];
- const int tot = BKE_mask_spline_differentiate_calc_total(spline, resol);
- int a;
-
- if (spline->tot_point <= 1) {
- /* nothing to differentiate */
- *tot_diff_point = 0;
- return NULL;
- }
-
- /* len+1 because of 'forward_diff_bezier' function */
- *tot_diff_point = tot;
- diff_points = fp = MEM_mallocN((tot + 1) * sizeof(*diff_points), "mask spline vets");
-
- a = spline->tot_point - 1;
- if (spline->flag & MASK_SPLINE_CYCLIC)
- a++;
-
- prev = points_array;
- point = prev + 1;
-
- while (a--) {
- BezTriple *prevbezt;
- BezTriple *bezt;
- int j;
-
- if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC))
- point = points_array;
-
- prevbezt = &prev->bezt;
- bezt = &point->bezt;
-
- for (j = 0; j < 2; j++) {
- BKE_curve_forward_diff_bezier(prevbezt->vec[1][j], prevbezt->vec[2][j],
- bezt->vec[0][j], bezt->vec[1][j],
- &(*fp)[j], resol, 2 * sizeof(float));
- }
-
- fp += resol;
-
- if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC) == 0) {
- copy_v2_v2(*fp, bezt->vec[1]);
- }
-
- prev = point;
- point++;
- }
-
- return diff_points;
-}
-
-float (*BKE_mask_spline_differentiate_with_resolution(MaskSpline *spline, int width, int height,
- int *tot_diff_point
- ))[2]
-{
- int unsigned resol = BKE_mask_spline_resolution(spline, width, height);
-
- return BKE_mask_spline_differentiate_with_resolution_ex(spline, tot_diff_point, resol);
-}
-
-float (*BKE_mask_spline_differentiate(MaskSpline *spline, int *tot_diff_point))[2]
-{
- return BKE_mask_spline_differentiate_with_resolution(spline, 0, 0, tot_diff_point);
-}
-
-/* ** feather points self-intersection collapse routine ** */
-
-typedef struct FeatherEdgesBucket {
- int tot_segment;
- int (*segments)[2];
- int alloc_segment;
-} FeatherEdgesBucket;
-
-static void feather_bucket_add_edge(FeatherEdgesBucket *bucket, int start, int end)
-{
- const int alloc_delta = 256;
-
- if (bucket->tot_segment >= bucket->alloc_segment) {
- if (!bucket->segments) {
- bucket->segments = MEM_callocN(alloc_delta * sizeof(*bucket->segments), "feather bucket segments");
- }
- else {
- bucket->segments = MEM_reallocN(bucket->segments,
- (alloc_delta + bucket->tot_segment) * sizeof(*bucket->segments));
- }
-
- bucket->alloc_segment += alloc_delta;
- }
-
- bucket->segments[bucket->tot_segment][0] = start;
- bucket->segments[bucket->tot_segment][1] = end;
-
- bucket->tot_segment++;
-}
-
-static void feather_bucket_check_intersect(float (*feather_points)[2], int tot_feather_point, FeatherEdgesBucket *bucket,
- int cur_a, int cur_b)
-{
- int i;
-
- float *v1 = (float *) feather_points[cur_a];
- float *v2 = (float *) feather_points[cur_b];
-
- for (i = 0; i < bucket->tot_segment; i++) {
- int check_a = bucket->segments[i][0];
- int check_b = bucket->segments[i][1];
-
- float *v3 = (float *) feather_points[check_a];
- float *v4 = (float *) feather_points[check_b];
-
- if (check_a >= cur_a - 1 || cur_b == check_a)
- continue;
-
- if (isect_seg_seg_v2(v1, v2, v3, v4)) {
- int k;
- float p[2];
- float min_a[2], max_a[2];
- float min_b[2], max_b[2];
-
- isect_seg_seg_v2_point(v1, v2, v3, v4, p);
-
- INIT_MINMAX2(min_a, max_a);
- INIT_MINMAX2(min_b, max_b);
-
- /* collapse loop with smaller AABB */
- for (k = 0; k < tot_feather_point; k++) {
- if (k >= check_b && k <= cur_a) {
- DO_MINMAX2(feather_points[k], min_a, max_a);
- }
- else {
- DO_MINMAX2(feather_points[k], min_b, max_b);
- }
- }
-
- if (max_a[0] - min_a[0] < max_b[0] - min_b[0] ||
- max_a[1] - min_a[1] < max_b[1] - min_b[1])
- {
- for (k = check_b; k <= cur_a; k++) {
- copy_v2_v2(feather_points[k], p);
- }
- }
- else {
- for (k = 0; k <= check_a; k++) {
- copy_v2_v2(feather_points[k], p);
- }
-
- if (cur_b != 0) {
- for (k = cur_b; k < tot_feather_point; k++) {
- copy_v2_v2(feather_points[k], p);
- }
- }
- }
- }
- }
-}
-
-static int feather_bucket_index_from_coord(float co[2], const float min[2], const float bucket_scale[2],
- const int buckets_per_side)
-{
- int x = (int) ((co[0] - min[0]) * bucket_scale[0]);
- int y = (int) ((co[1] - min[1]) * bucket_scale[1]);
-
- if (x == buckets_per_side)
- x--;
-
- if (y == buckets_per_side)
- y--;
-
- return y * buckets_per_side + x;
-}
-
-static void feather_bucket_get_diagonal(FeatherEdgesBucket *buckets, int start_bucket_index, int end_bucket_index,
- int buckets_per_side, FeatherEdgesBucket **diagonal_bucket_a_r,
- FeatherEdgesBucket **diagonal_bucket_b_r)
-{
- int start_bucket_x = start_bucket_index % buckets_per_side;
- int start_bucket_y = start_bucket_index / buckets_per_side;
-
- int end_bucket_x = end_bucket_index % buckets_per_side;
- int end_bucket_y = end_bucket_index / buckets_per_side;
-
- int diagonal_bucket_a_index = start_bucket_y * buckets_per_side + end_bucket_x;
- int diagonal_bucket_b_index = end_bucket_y * buckets_per_side + start_bucket_x;
-
- *diagonal_bucket_a_r = &buckets[diagonal_bucket_a_index];
- *diagonal_bucket_b_r = &buckets[diagonal_bucket_b_index];
-}
-
-void BKE_mask_spline_feather_collapse_inner_loops(MaskSpline *spline, float (*feather_points)[2], const int tot_feather_point)
-{
-#define BUCKET_INDEX(co) \
- feather_bucket_index_from_coord(co, min, bucket_scale, buckets_per_side)
-
- int buckets_per_side, tot_bucket;
- float bucket_size, bucket_scale[2];
-
- FeatherEdgesBucket *buckets;
-
- int i;
- float min[2], max[2];
- float max_delta_x = -1.0f, max_delta_y = -1.0f, max_delta;
-
- if (tot_feather_point < 4) {
- /* self-intersection works only for quads at least,
- * in other cases polygon can't be self-intersecting anyway
- */
-
- return;
- }
-
- /* find min/max corners of mask to build buckets in that space */
- INIT_MINMAX2(min, max);
-
- for (i = 0; i < tot_feather_point; i++) {
- int next = i + 1;
- float delta;
-
- DO_MINMAX2(feather_points[i], min, max);
-
- if (next == tot_feather_point) {
- if (spline->flag & MASK_SPLINE_CYCLIC)
- next = 0;
- else
- break;
- }
-
- delta = fabsf(feather_points[i][0] - feather_points[next][0]);
- if (delta > max_delta_x)
- max_delta_x = delta;
-
- delta = fabsf(feather_points[i][1] - feather_points[next][1]);
- if (delta > max_delta_y)
- max_delta_y = delta;
- }
-
- /* prevent divisionsby zero by ensuring bounding box is not collapsed */
- if (max[0] - min[0] < FLT_EPSILON) {
- max[0] += 0.01f;
- min[0] -= 0.01f;
- }
-
- if (max[1] - min[1] < FLT_EPSILON) {
- max[1] += 0.01f;
- min[1] -= 0.01f;
- }
-
- /* use dynamically calculated buckets per side, so we likely wouldn't
- * run into a situation when segment doesn't fit two buckets which is
- * pain collecting candidates for intersection
- */
-
- max_delta_x /= max[0] - min[0];
- max_delta_y /= max[1] - min[1];
-
- max_delta = MAX2(max_delta_x, max_delta_y);
-
- buckets_per_side = MIN2(512, 0.9f / max_delta);
-
- if (buckets_per_side == 0) {
- /* happens when some segment fills the whole bounding box across some of dimension */
-
- buckets_per_side = 1;
- }
-
- tot_bucket = buckets_per_side * buckets_per_side;
- bucket_size = 1.0f / buckets_per_side;
-
- /* pre-compute multipliers, to save mathematical operations in loops */
- bucket_scale[0] = 1.0f / ((max[0] - min[0]) * bucket_size);
- bucket_scale[1] = 1.0f / ((max[1] - min[1]) * bucket_size);
-
- /* fill in buckets' edges */
- buckets = MEM_callocN(sizeof(FeatherEdgesBucket) * tot_bucket, "feather buckets");
-
- for (i = 0; i < tot_feather_point; i++) {
- int start = i, end = i + 1;
- int start_bucket_index, end_bucket_index;
-
- if (end == tot_feather_point) {
- if (spline->flag & MASK_SPLINE_CYCLIC)
- end = 0;
- else
- break;
- }
-
- start_bucket_index = BUCKET_INDEX(feather_points[start]);
- end_bucket_index = BUCKET_INDEX(feather_points[end]);
-
- feather_bucket_add_edge(&buckets[start_bucket_index], start, end);
-
- if (start_bucket_index != end_bucket_index) {
- FeatherEdgesBucket *end_bucket = &buckets[end_bucket_index];
- FeatherEdgesBucket *diagonal_bucket_a, *diagonal_bucket_b;
-
- feather_bucket_get_diagonal(buckets, start_bucket_index, end_bucket_index, buckets_per_side,
- &diagonal_bucket_a, &diagonal_bucket_b);
-
- feather_bucket_add_edge(end_bucket, start, end);
- feather_bucket_add_edge(diagonal_bucket_a, start, end);
- feather_bucket_add_edge(diagonal_bucket_a, start, end);
- }
- }
-
- /* check all edges for intersection with edges from their buckets */
- for (i = 0; i < tot_feather_point; i++) {
- int cur_a = i, cur_b = i + 1;
- int start_bucket_index, end_bucket_index;
-
- FeatherEdgesBucket *start_bucket;
-
- if (cur_b == tot_feather_point)
- cur_b = 0;
-
- start_bucket_index = BUCKET_INDEX(feather_points[cur_a]);
- end_bucket_index = BUCKET_INDEX(feather_points[cur_b]);
-
- start_bucket = &buckets[start_bucket_index];
-
- feather_bucket_check_intersect(feather_points, tot_feather_point, start_bucket, cur_a, cur_b);
-
- if (start_bucket_index != end_bucket_index) {
- FeatherEdgesBucket *end_bucket = &buckets[end_bucket_index];
- FeatherEdgesBucket *diagonal_bucket_a, *diagonal_bucket_b;
-
- feather_bucket_get_diagonal(buckets, start_bucket_index, end_bucket_index, buckets_per_side,
- &diagonal_bucket_a, &diagonal_bucket_b);
-
- feather_bucket_check_intersect(feather_points, tot_feather_point, end_bucket, cur_a, cur_b);
- feather_bucket_check_intersect(feather_points, tot_feather_point, diagonal_bucket_a, cur_a, cur_b);
- feather_bucket_check_intersect(feather_points, tot_feather_point, diagonal_bucket_b, cur_a, cur_b);
- }
- }
-
- /* free buckets */
- for (i = 0; i < tot_bucket; i++) {
- if (buckets[i].segments)
- MEM_freeN(buckets[i].segments);
- }
-
- MEM_freeN(buckets);
-
-#undef BUCKET_INDEX
-}
-
-/**
- * values align with #BKE_mask_spline_differentiate_with_resolution_ex
- * when \a resol arguments match.
- */
-float (*BKE_mask_spline_feather_differentiated_points_with_resolution_ex(MaskSpline *spline,
- int *tot_feather_point,
- const unsigned int resol,
- const int do_feather_isect
- ))[2]
-{
- MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
- MaskSplinePoint *point, *prev;
- float (*feather)[2], (*fp)[2];
-
- const int tot = BKE_mask_spline_differentiate_calc_total(spline, resol);
- int a;
-
- /* tot+1 because of 'forward_diff_bezier' function */
- feather = fp = MEM_mallocN((tot + 1) * sizeof(*feather), "mask spline feather diff points");
-
- a = spline->tot_point - 1;
- if (spline->flag & MASK_SPLINE_CYCLIC)
- a++;
-
- prev = points_array;
- point = prev + 1;
-
- while (a--) {
- /* BezTriple *prevbezt; */ /* UNUSED */
- /* BezTriple *bezt; */ /* UNUSED */
- int j;
-
- if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC))
- point = points_array;
-
-
- /* prevbezt = &prev->bezt; */
- /* bezt = &point->bezt; */
-
- for (j = 0; j < resol; j++, fp++) {
- float u = (float) j / resol, weight;
- float co[2], n[2];
-
- /* TODO - these calls all calculate similar things
- * could be unified for some speed */
- BKE_mask_point_segment_co(spline, prev, u, co);
- BKE_mask_point_normal(spline, prev, u, n);
- weight = BKE_mask_point_weight(spline, prev, u);
-
- madd_v2_v2v2fl(*fp, co, n, weight);
- }
-
- if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC) == 0) {
- float u = 1.0f, weight;
- float co[2], n[2];
-
- BKE_mask_point_segment_co(spline, prev, u, co);
- BKE_mask_point_normal(spline, prev, u, n);
- weight = BKE_mask_point_weight(spline, prev, u);
-
- madd_v2_v2v2fl(*fp, co, n, weight);
- }
-
- prev = point;
- point++;
- }
-
- *tot_feather_point = tot;
-
- if ((spline->flag & MASK_SPLINE_NOINTERSECT) && do_feather_isect) {
- BKE_mask_spline_feather_collapse_inner_loops(spline, feather, tot);
- }
-
- return feather;
-}
-
-float (*BKE_mask_spline_feather_differentiated_points_with_resolution(MaskSpline *spline, int width, int height,
- int *tot_feather_point, const int do_feather_isect))[2]
-{
- unsigned int resol = BKE_mask_spline_feather_resolution(spline, width, height);
-
- return BKE_mask_spline_feather_differentiated_points_with_resolution_ex(spline, tot_feather_point, resol, do_feather_isect);
-}
-
-float (*BKE_mask_spline_feather_differentiated_points(MaskSpline *spline, int *tot_feather_point))[2]
-{
- return BKE_mask_spline_feather_differentiated_points_with_resolution(spline, 0, 0, tot_feather_point, TRUE);
-}
-
-float (*BKE_mask_spline_feather_points(MaskSpline *spline, int *tot_feather_point))[2]
-{
- MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
-
- int i, tot = 0;
- float (*feather)[2], (*fp)[2];
-
- /* count */
- for (i = 0; i < spline->tot_point; i++) {
- MaskSplinePoint *point = &points_array[i];
-
- tot += point->tot_uw + 1;
- }
-
- /* create data */
- feather = fp = MEM_mallocN(tot * sizeof(*feather), "mask spline feather points");
-
- for (i = 0; i < spline->tot_point; i++) {
- MaskSplinePoint *point = &points_array[i];
- BezTriple *bezt = &point->bezt;
- float weight, n[2];
- int j;
-
- BKE_mask_point_normal(spline, point, 0.0f, n);
- weight = BKE_mask_point_weight(spline, point, 0.0f);
-
- madd_v2_v2v2fl(*fp, bezt->vec[1], n, weight);
- fp++;
-
- for (j = 0; j < point->tot_uw; j++) {
- float u = point->uw[j].u;
- float co[2];
-
- BKE_mask_point_segment_co(spline, point, u, co);
- BKE_mask_point_normal(spline, point, u, n);
- weight = BKE_mask_point_weight(spline, point, u);
-
- madd_v2_v2v2fl(*fp, co, n, weight);
- fp++;
- }
- }
-
- *tot_feather_point = tot;
-
- return feather;
-}
-
void BKE_mask_point_direction_switch(MaskSplinePoint *point)
{
const int tot_uw = point->tot_uw;
@@ -1069,73 +484,6 @@ void BKE_mask_point_set_handle(MaskSplinePoint *point, float loc[2], int keep_di
}
}
-float *BKE_mask_point_segment_feather_diff_with_resolution(MaskSpline *spline, MaskSplinePoint *point,
- int width, int height,
- unsigned int *tot_feather_point)
-{
- float *feather, *fp;
- unsigned int resol = BKE_mask_spline_feather_resolution(spline, width, height);
- unsigned int i;
-
- feather = fp = MEM_callocN(2 * resol * sizeof(float), "mask point spline feather diff points");
-
- for (i = 0; i < resol; i++, fp += 2) {
- float u = (float)(i % resol) / resol, weight;
- float co[2], n[2];
-
- BKE_mask_point_segment_co(spline, point, u, co);
- BKE_mask_point_normal(spline, point, u, n);
- weight = BKE_mask_point_weight(spline, point, u);
-
- fp[0] = co[0] + n[0] * weight;
- fp[1] = co[1] + n[1] * weight;
- }
-
- *tot_feather_point = resol;
-
- return feather;
-}
-
-float *BKE_mask_point_segment_feather_diff(MaskSpline *spline, MaskSplinePoint *point, unsigned int *tot_feather_point)
-{
- return BKE_mask_point_segment_feather_diff_with_resolution(spline, point, 0, 0, tot_feather_point);
-}
-
-float *BKE_mask_point_segment_diff_with_resolution(MaskSpline *spline, MaskSplinePoint *point,
- int width, int height, unsigned int *tot_diff_point)
-{
- MaskSplinePoint *points_array = BKE_mask_spline_point_array_from_point(spline, point);
-
- BezTriple *bezt, *bezt_next;
- float *diff_points, *fp;
- int j, resol = BKE_mask_spline_resolution(spline, width, height);
-
- bezt = &point->bezt;
- bezt_next = mask_spline_point_next_bezt(spline, points_array, point);
-
- if (!bezt_next)
- return NULL;
-
- /* resol+1 because of 'forward_diff_bezier' function */
- *tot_diff_point = resol + 1;
- diff_points = fp = MEM_callocN((resol + 1) * 2 * sizeof(float), "mask segment vets");
-
- for (j = 0; j < 2; j++) {
- BKE_curve_forward_diff_bezier(bezt->vec[1][j], bezt->vec[2][j],
- bezt_next->vec[0][j], bezt_next->vec[1][j],
- fp + j, resol, 2 * sizeof(float));
- }
-
- copy_v2_v2(fp + 2 * resol, bezt_next->vec[1]);
-
- return diff_points;
-}
-
-float *BKE_mask_point_segment_diff(MaskSpline *spline, MaskSplinePoint *point, unsigned int *tot_diff_point)
-{
- return BKE_mask_point_segment_diff_with_resolution(spline, point, 0, 0, tot_diff_point);
-}
-
void BKE_mask_point_segment_co(MaskSpline *spline, MaskSplinePoint *point, float u, float co[2])
{
MaskSplinePoint *points_array = BKE_mask_spline_point_array_from_point(spline, point);
@@ -1143,7 +491,7 @@ void BKE_mask_point_segment_co(MaskSpline *spline, MaskSplinePoint *point, float
BezTriple *bezt = &point->bezt, *bezt_next;
float q0[2], q1[2], q2[2], r0[2], r1[2];
- bezt_next = mask_spline_point_next_bezt(spline, points_array, point);
+ bezt_next = BKE_mask_spline_point_next_bezt(spline, points_array, point);
if (!bezt_next) {
copy_v2_v2(co, bezt->vec[1]);
@@ -1167,7 +515,7 @@ void BKE_mask_point_normal(MaskSpline *spline, MaskSplinePoint *point, float u,
BezTriple *bezt = &point->bezt, *bezt_next;
float q0[2], q1[2], q2[2], r0[2], r1[2], vec[2];
- bezt_next = mask_spline_point_next_bezt(spline, points_array, point);
+ bezt_next = BKE_mask_spline_point_next_bezt(spline, points_array, point);
if (!bezt_next) {
BKE_mask_point_handle(point, vec);
@@ -1202,7 +550,7 @@ float BKE_mask_point_weight_scalar(MaskSpline *spline, MaskSplinePoint *point, c
MaskSplinePoint *points_array = BKE_mask_spline_point_array_from_point(spline, point);
BezTriple *bezt = &point->bezt, *bezt_next;
- bezt_next = mask_spline_point_next_bezt(spline, points_array, point);
+ bezt_next = BKE_mask_spline_point_next_bezt(spline, points_array, point);
if (!bezt_next) {
return bezt->weight;
@@ -1223,7 +571,7 @@ float BKE_mask_point_weight(MaskSpline *spline, MaskSplinePoint *point, const fl
MaskSplinePoint *points_array = BKE_mask_spline_point_array_from_point(spline, point);
BezTriple *bezt = &point->bezt, *bezt_next;
- bezt_next = mask_spline_point_next_bezt(spline, points_array, point);
+ bezt_next = BKE_mask_spline_point_next_bezt(spline, points_array, point);
if (!bezt_next) {
return bezt->weight;
@@ -1562,25 +910,13 @@ void BKE_mask_layer_free_list(ListBase *masklayers)
}
}
-void BKE_mask_free(Mask *mask)
+/** free for temp copy, but don't manage unlinking from other pointers */
+void BKE_mask_free_nolib(Mask *mask)
{
BKE_mask_layer_free_list(&mask->masklayers);
}
-
-static void ntree_unlink_mask_cb(void *calldata, struct ID *UNUSED(owner_id), struct bNodeTree *ntree)
-{
- ID *id = (ID *)calldata;
- bNode *node;
-
- for (node = ntree->nodes.first; node; node = node->next) {
- if (node->id == id) {
- node->id = NULL;
- }
- }
-}
-
-void BKE_mask_unlink(Main *bmain, Mask *mask)
+void BKE_mask_free(Main *bmain, Mask *mask)
{
bScreen *scr;
ScrArea *area;
@@ -1626,24 +962,15 @@ void BKE_mask_unlink(Main *bmain, Mask *mask)
}
SEQ_END
}
-
-
- if (scene->nodetree) {
- bNode *node;
- for (node = scene->nodetree->nodes.first; node; node = node->next) {
- if (node->id == &mask->id) {
- node->id = NULL;
- }
- }
- }
}
{
bNodeTreeType *treetype = ntreeGetType(NTREE_COMPOSIT);
- treetype->foreach_nodetree(bmain, (void *)mask, &ntree_unlink_mask_cb);
+ treetype->foreach_nodetree(bmain, (void *)mask, &BKE_node_tree_unlink_id_cb);
}
- BKE_libblock_free(&bmain->mask, mask);
+ /* free mask data */
+ BKE_mask_layer_free_list(&mask->masklayers);
}
void BKE_mask_coord_from_frame(float r_co[2], const float co[2], const float frame_size[2])
@@ -1663,14 +990,26 @@ void BKE_mask_coord_from_frame(float r_co[2], const float co[2], const float fra
}
void BKE_mask_coord_from_movieclip(MovieClip *clip, MovieClipUser *user, float r_co[2], const float co[2])
{
- int width, height;
+ float aspx, aspy;
float frame_size[2];
/* scaling for the clip */
- BKE_movieclip_get_size(clip, user, &width, &height);
+ BKE_movieclip_get_size_fl(clip, user, frame_size);
+ BKE_movieclip_get_aspect(clip, &aspx, &aspy);
- frame_size[0] = (float)width;
- frame_size[1] = (float)height;
+ frame_size[1] *= (aspy / aspx);
+
+ BKE_mask_coord_from_frame(r_co, co, frame_size);
+}
+void BKE_mask_coord_from_image(Image *image, ImageUser *iuser, float r_co[2], const float co[2])
+{
+ float aspx, aspy;
+ float frame_size[2];
+
+ BKE_image_get_size_fl(image, iuser, frame_size);
+ BKE_image_get_aspect(image, &aspx, &aspy);
+
+ frame_size[1] *= (aspy / aspx);
BKE_mask_coord_from_frame(r_co, co, frame_size);
}
@@ -1693,14 +1032,27 @@ void BKE_mask_coord_to_frame(float r_co[2], const float co[2], const float frame
}
void BKE_mask_coord_to_movieclip(MovieClip *clip, MovieClipUser *user, float r_co[2], const float co[2])
{
- int width, height;
+ float aspx, aspy;
+ float frame_size[2];
+
+ /* scaling for the clip */
+ BKE_movieclip_get_size_fl(clip, user, frame_size);
+ BKE_movieclip_get_aspect(clip, &aspx, &aspy);
+
+ frame_size[1] /= (aspy / aspx);
+
+ BKE_mask_coord_to_frame(r_co, co, frame_size);
+}
+void BKE_mask_coord_to_image(Image *image, ImageUser *iuser, float r_co[2], const float co[2])
+{
+ float aspx, aspy;
float frame_size[2];
/* scaling for the clip */
- BKE_movieclip_get_size(clip, user, &width, &height);
+ BKE_image_get_size_fl(image, iuser, frame_size);
+ BKE_image_get_aspect(image, &aspx, &aspy);
- frame_size[0] = (float)width;
- frame_size[1] = (float)height;
+ frame_size[1] /= (aspy / aspx);
BKE_mask_coord_to_frame(r_co, co, frame_size);
}
@@ -1737,7 +1089,8 @@ static int BKE_mask_evaluate_parent(MaskParent *parent, float ctime, float r_co[
return FALSE;
}
-int BKE_mask_evaluate_parent_delta(MaskParent *parent, float ctime, float r_delta[2])
+/* could make external but for now its only used internally */
+static int mask_evaluate_parent_delta(MaskParent *parent, float ctime, float r_delta[2])
{
float parent_co[2];
@@ -1847,17 +1200,6 @@ void BKE_mask_calc_handle_point(MaskSpline *spline, MaskSplinePoint *point)
mask_calc_point_handle(point, point_prev, point_next);
}
-static void enforce_dist_v2_v2fl(float v1[2], const float v2[2], const float dist)
-{
- if (!equals_v2v2(v2, v1)) {
- float nor[2];
-
- sub_v2_v2v2(nor, v1, v2);
- normalize_v2(nor);
- madd_v2_v2v2fl(v1, v2, nor, dist);
- }
-}
-
void BKE_mask_calc_handle_adjacent_interp(MaskSpline *spline, MaskSplinePoint *point, const float u)
{
/* TODO! - make this interpolate between siblings - not always midpoint! */
@@ -1899,8 +1241,8 @@ void BKE_mask_calc_handle_adjacent_interp(MaskSpline *spline, MaskSplinePoint *p
length_average /= (float)length_tot;
weight_average /= (float)length_tot;
- enforce_dist_v2_v2fl(point->bezt.vec[0], point->bezt.vec[1], length_average);
- enforce_dist_v2_v2fl(point->bezt.vec[2], point->bezt.vec[1], length_average);
+ dist_ensure_v2_v2fl(point->bezt.vec[0], point->bezt.vec[1], length_average);
+ dist_ensure_v2_v2fl(point->bezt.vec[2], point->bezt.vec[1], length_average);
point->bezt.weight = weight_average;
}
}
@@ -1932,8 +1274,8 @@ void BKE_mask_calc_handle_point_auto(MaskSpline *spline, MaskSplinePoint *point,
/* preserve length by applying it back */
if (do_recalc_length == FALSE) {
- enforce_dist_v2_v2fl(point->bezt.vec[0], point->bezt.vec[1], length_average);
- enforce_dist_v2_v2fl(point->bezt.vec[2], point->bezt.vec[1], length_average);
+ dist_ensure_v2_v2fl(point->bezt.vec[0], point->bezt.vec[1], length_average);
+ dist_ensure_v2_v2fl(point->bezt.vec[2], point->bezt.vec[1], length_average);
}
}
@@ -2088,7 +1430,7 @@ void BKE_mask_layer_evaluate(MaskLayer *masklay, const float ctime, const int do
*point_deform = *point;
point_deform->uw = point->uw ? MEM_dupallocN(point->uw) : NULL;
- if (BKE_mask_evaluate_parent_delta(&point->parent, ctime, delta)) {
+ if (mask_evaluate_parent_delta(&point->parent, ctime, delta)) {
add_v2_v2(point_deform->bezt.vec[0], delta);
add_v2_v2(point_deform->bezt.vec[1], delta);
add_v2_v2(point_deform->bezt.vec[2], delta);
@@ -2183,7 +1525,7 @@ void BKE_mask_parent_init(MaskParent *parent)
}
-/* *** own animation/shapekey implimentation ***
+/* *** own animation/shapekey implementation ***
* BKE_mask_layer_shape_XXX */
int BKE_mask_layer_shape_totvert(MaskLayer *masklay)
diff --git a/source/blender/blenkernel/intern/mask_evaluate.c b/source/blender/blenkernel/intern/mask_evaluate.c
new file mode 100644
index 00000000000..4a8601df0b8
--- /dev/null
+++ b/source/blender/blenkernel/intern/mask_evaluate.c
@@ -0,0 +1,863 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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) 2012 Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Blender Foundation,
+ * Sergey Sharybin,
+ * Campbell Barton
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/mask_evaluate.c
+ * \ingroup bke
+ *
+ * Functions for evaluating the mask beziers into points for the outline and feather.
+ */
+
+#include <stddef.h>
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_path_util.h"
+#include "BLI_string.h"
+#include "BLI_listbase.h"
+#include "BLI_math.h"
+
+#include "DNA_mask_types.h"
+#include "DNA_node_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_object_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_space_types.h"
+#include "DNA_movieclip_types.h"
+#include "DNA_tracking_types.h"
+#include "DNA_sequence_types.h"
+
+#include "BKE_curve.h"
+#include "BKE_global.h"
+#include "BKE_library.h"
+#include "BKE_main.h"
+#include "BKE_mask.h"
+#include "BKE_node.h"
+#include "BKE_sequencer.h"
+#include "BKE_tracking.h"
+#include "BKE_movieclip.h"
+
+
+unsigned int BKE_mask_spline_resolution(MaskSpline *spline, int width, int height)
+{
+ float max_segment = 0.01f;
+ unsigned int i, resol = 1;
+
+ if (width != 0 && height != 0) {
+ max_segment = 1.0f / (float)maxi(width, height);
+ }
+
+ for (i = 0; i < spline->tot_point; i++) {
+ MaskSplinePoint *point = &spline->points[i];
+ BezTriple *bezt_curr, *bezt_next;
+ float a, b, c, len;
+ unsigned int cur_resol;
+
+ bezt_curr = &point->bezt;
+ bezt_next = BKE_mask_spline_point_next_bezt(spline, spline->points, point);
+
+ if (bezt_next == NULL) {
+ break;
+ }
+
+ a = len_v3v3(bezt_curr->vec[1], bezt_curr->vec[2]);
+ b = len_v3v3(bezt_curr->vec[2], bezt_next->vec[0]);
+ c = len_v3v3(bezt_next->vec[0], bezt_next->vec[1]);
+
+ len = a + b + c;
+ cur_resol = len / max_segment;
+
+ resol = MAX2(resol, cur_resol);
+
+ if (resol >= MASK_RESOL_MAX) {
+ break;
+ }
+ }
+
+ return CLAMPIS(resol, 1, MASK_RESOL_MAX);
+}
+
+unsigned int BKE_mask_spline_feather_resolution(MaskSpline *spline, int width, int height)
+{
+ const float max_segment = 0.005;
+ unsigned int resol = BKE_mask_spline_resolution(spline, width, height);
+ float max_jump = 0.0f;
+ int i;
+
+ /* avoid checking the featrher if we already hit the maximum value */
+ if (resol >= MASK_RESOL_MAX) {
+ return MASK_RESOL_MAX;
+ }
+
+ for (i = 0; i < spline->tot_point; i++) {
+ MaskSplinePoint *point = &spline->points[i];
+ float prev_u, prev_w;
+ int j;
+
+ prev_u = 0.0f;
+ prev_w = point->bezt.weight;
+
+ for (j = 0; j < point->tot_uw; j++) {
+ const float w_diff = (point->uw[j].w - prev_w);
+ const float u_diff = (point->uw[j].u - prev_u);
+
+ /* avoid divide by zero and very high values,
+ * though these get clamped eventually */
+ if (u_diff > FLT_EPSILON) {
+ float jump = fabsf(w_diff / u_diff);
+
+ max_jump = MAX2(max_jump, jump);
+ }
+
+ prev_u = point->uw[j].u;
+ prev_w = point->uw[j].w;
+ }
+ }
+
+ resol += max_jump / max_segment;
+
+ return CLAMPIS(resol, 1, MASK_RESOL_MAX);
+}
+
+int BKE_mask_spline_differentiate_calc_total(const MaskSpline *spline, const unsigned int resol)
+{
+ if (spline->flag & MASK_SPLINE_CYCLIC) {
+ return spline->tot_point * resol;
+ }
+ else {
+ return ((spline->tot_point - 1) * resol) + 1;
+ }
+}
+
+float (*BKE_mask_spline_differentiate_with_resolution_ex(MaskSpline *spline,
+ int *tot_diff_point,
+ const unsigned int resol
+ ))[2]
+{
+ MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
+
+ MaskSplinePoint *point_curr, *point_prev;
+ float (*diff_points)[2], (*fp)[2];
+ const int tot = BKE_mask_spline_differentiate_calc_total(spline, resol);
+ int a;
+
+ if (spline->tot_point <= 1) {
+ /* nothing to differentiate */
+ *tot_diff_point = 0;
+ return NULL;
+ }
+
+ /* len+1 because of 'forward_diff_bezier' function */
+ *tot_diff_point = tot;
+ diff_points = fp = MEM_mallocN((tot + 1) * sizeof(*diff_points), "mask spline vets");
+
+ a = spline->tot_point - 1;
+ if (spline->flag & MASK_SPLINE_CYCLIC)
+ a++;
+
+ point_prev = points_array;
+ point_curr = point_prev + 1;
+
+ while (a--) {
+ BezTriple *bezt_prev;
+ BezTriple *bezt_curr;
+ int j;
+
+ if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC))
+ point_curr = points_array;
+
+ bezt_prev = &point_prev->bezt;
+ bezt_curr = &point_curr->bezt;
+
+ for (j = 0; j < 2; j++) {
+ BKE_curve_forward_diff_bezier(bezt_prev->vec[1][j], bezt_prev->vec[2][j],
+ bezt_curr->vec[0][j], bezt_curr->vec[1][j],
+ &(*fp)[j], resol, 2 * sizeof(float));
+ }
+
+ fp += resol;
+
+ if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC) == 0) {
+ copy_v2_v2(*fp, bezt_curr->vec[1]);
+ }
+
+ point_prev = point_curr;
+ point_curr++;
+ }
+
+ return diff_points;
+}
+
+float (*BKE_mask_spline_differentiate_with_resolution(MaskSpline *spline, int width, int height,
+ int *tot_diff_point
+ ))[2]
+{
+ int unsigned resol = BKE_mask_spline_resolution(spline, width, height);
+
+ return BKE_mask_spline_differentiate_with_resolution_ex(spline, tot_diff_point, resol);
+}
+
+float (*BKE_mask_spline_differentiate(MaskSpline *spline, int *tot_diff_point))[2]
+{
+ return BKE_mask_spline_differentiate_with_resolution(spline, 0, 0, tot_diff_point);
+}
+
+/* ** feather points self-intersection collapse routine ** */
+
+typedef struct FeatherEdgesBucket {
+ int tot_segment;
+ int (*segments)[2];
+ int alloc_segment;
+} FeatherEdgesBucket;
+
+static void feather_bucket_add_edge(FeatherEdgesBucket *bucket, int start, int end)
+{
+ const int alloc_delta = 256;
+
+ if (bucket->tot_segment >= bucket->alloc_segment) {
+ if (!bucket->segments) {
+ bucket->segments = MEM_callocN(alloc_delta * sizeof(*bucket->segments), "feather bucket segments");
+ }
+ else {
+ bucket->segments = MEM_reallocN(bucket->segments,
+ (alloc_delta + bucket->tot_segment) * sizeof(*bucket->segments));
+ }
+
+ bucket->alloc_segment += alloc_delta;
+ }
+
+ bucket->segments[bucket->tot_segment][0] = start;
+ bucket->segments[bucket->tot_segment][1] = end;
+
+ bucket->tot_segment++;
+}
+
+static void feather_bucket_check_intersect(float (*feather_points)[2], int tot_feather_point, FeatherEdgesBucket *bucket,
+ int cur_a, int cur_b)
+{
+ int i;
+
+ float *v1 = (float *) feather_points[cur_a];
+ float *v2 = (float *) feather_points[cur_b];
+
+ for (i = 0; i < bucket->tot_segment; i++) {
+ int check_a = bucket->segments[i][0];
+ int check_b = bucket->segments[i][1];
+
+ float *v3 = (float *) feather_points[check_a];
+ float *v4 = (float *) feather_points[check_b];
+
+ if (check_a >= cur_a - 1 || cur_b == check_a)
+ continue;
+
+ if (isect_seg_seg_v2(v1, v2, v3, v4)) {
+ int k;
+ float p[2];
+ float min_a[2], max_a[2];
+ float min_b[2], max_b[2];
+
+ isect_seg_seg_v2_point(v1, v2, v3, v4, p);
+
+ INIT_MINMAX2(min_a, max_a);
+ INIT_MINMAX2(min_b, max_b);
+
+ /* collapse loop with smaller AABB */
+ for (k = 0; k < tot_feather_point; k++) {
+ if (k >= check_b && k <= cur_a) {
+ DO_MINMAX2(feather_points[k], min_a, max_a);
+ }
+ else {
+ DO_MINMAX2(feather_points[k], min_b, max_b);
+ }
+ }
+
+ if (max_a[0] - min_a[0] < max_b[0] - min_b[0] ||
+ max_a[1] - min_a[1] < max_b[1] - min_b[1])
+ {
+ for (k = check_b; k <= cur_a; k++) {
+ copy_v2_v2(feather_points[k], p);
+ }
+ }
+ else {
+ for (k = 0; k <= check_a; k++) {
+ copy_v2_v2(feather_points[k], p);
+ }
+
+ if (cur_b != 0) {
+ for (k = cur_b; k < tot_feather_point; k++) {
+ copy_v2_v2(feather_points[k], p);
+ }
+ }
+ }
+ }
+ }
+}
+
+static int feather_bucket_index_from_coord(float co[2], const float min[2], const float bucket_scale[2],
+ const int buckets_per_side)
+{
+ int x = (int) ((co[0] - min[0]) * bucket_scale[0]);
+ int y = (int) ((co[1] - min[1]) * bucket_scale[1]);
+
+ if (x == buckets_per_side)
+ x--;
+
+ if (y == buckets_per_side)
+ y--;
+
+ return y * buckets_per_side + x;
+}
+
+static void feather_bucket_get_diagonal(FeatherEdgesBucket *buckets, int start_bucket_index, int end_bucket_index,
+ int buckets_per_side, FeatherEdgesBucket **diagonal_bucket_a_r,
+ FeatherEdgesBucket **diagonal_bucket_b_r)
+{
+ int start_bucket_x = start_bucket_index % buckets_per_side;
+ int start_bucket_y = start_bucket_index / buckets_per_side;
+
+ int end_bucket_x = end_bucket_index % buckets_per_side;
+ int end_bucket_y = end_bucket_index / buckets_per_side;
+
+ int diagonal_bucket_a_index = start_bucket_y * buckets_per_side + end_bucket_x;
+ int diagonal_bucket_b_index = end_bucket_y * buckets_per_side + start_bucket_x;
+
+ *diagonal_bucket_a_r = &buckets[diagonal_bucket_a_index];
+ *diagonal_bucket_b_r = &buckets[diagonal_bucket_b_index];
+}
+
+void BKE_mask_spline_feather_collapse_inner_loops(MaskSpline *spline, float (*feather_points)[2], const int tot_feather_point)
+{
+#define BUCKET_INDEX(co) \
+ feather_bucket_index_from_coord(co, min, bucket_scale, buckets_per_side)
+
+ int buckets_per_side, tot_bucket;
+ float bucket_size, bucket_scale[2];
+
+ FeatherEdgesBucket *buckets;
+
+ int i;
+ float min[2], max[2];
+ float max_delta_x = -1.0f, max_delta_y = -1.0f, max_delta;
+
+ if (tot_feather_point < 4) {
+ /* self-intersection works only for quads at least,
+ * in other cases polygon can't be self-intersecting anyway
+ */
+
+ return;
+ }
+
+ /* find min/max corners of mask to build buckets in that space */
+ INIT_MINMAX2(min, max);
+
+ for (i = 0; i < tot_feather_point; i++) {
+ int next = i + 1;
+ float delta;
+
+ DO_MINMAX2(feather_points[i], min, max);
+
+ if (next == tot_feather_point) {
+ if (spline->flag & MASK_SPLINE_CYCLIC)
+ next = 0;
+ else
+ break;
+ }
+
+ delta = fabsf(feather_points[i][0] - feather_points[next][0]);
+ if (delta > max_delta_x)
+ max_delta_x = delta;
+
+ delta = fabsf(feather_points[i][1] - feather_points[next][1]);
+ if (delta > max_delta_y)
+ max_delta_y = delta;
+ }
+
+ /* prevent divisionsby zero by ensuring bounding box is not collapsed */
+ if (max[0] - min[0] < FLT_EPSILON) {
+ max[0] += 0.01f;
+ min[0] -= 0.01f;
+ }
+
+ if (max[1] - min[1] < FLT_EPSILON) {
+ max[1] += 0.01f;
+ min[1] -= 0.01f;
+ }
+
+ /* use dynamically calculated buckets per side, so we likely wouldn't
+ * run into a situation when segment doesn't fit two buckets which is
+ * pain collecting candidates for intersection
+ */
+
+ max_delta_x /= max[0] - min[0];
+ max_delta_y /= max[1] - min[1];
+
+ max_delta = MAX2(max_delta_x, max_delta_y);
+
+ buckets_per_side = MIN2(512, 0.9f / max_delta);
+
+ if (buckets_per_side == 0) {
+ /* happens when some segment fills the whole bounding box across some of dimension */
+
+ buckets_per_side = 1;
+ }
+
+ tot_bucket = buckets_per_side * buckets_per_side;
+ bucket_size = 1.0f / buckets_per_side;
+
+ /* pre-compute multipliers, to save mathematical operations in loops */
+ bucket_scale[0] = 1.0f / ((max[0] - min[0]) * bucket_size);
+ bucket_scale[1] = 1.0f / ((max[1] - min[1]) * bucket_size);
+
+ /* fill in buckets' edges */
+ buckets = MEM_callocN(sizeof(FeatherEdgesBucket) * tot_bucket, "feather buckets");
+
+ for (i = 0; i < tot_feather_point; i++) {
+ int start = i, end = i + 1;
+ int start_bucket_index, end_bucket_index;
+
+ if (end == tot_feather_point) {
+ if (spline->flag & MASK_SPLINE_CYCLIC)
+ end = 0;
+ else
+ break;
+ }
+
+ start_bucket_index = BUCKET_INDEX(feather_points[start]);
+ end_bucket_index = BUCKET_INDEX(feather_points[end]);
+
+ feather_bucket_add_edge(&buckets[start_bucket_index], start, end);
+
+ if (start_bucket_index != end_bucket_index) {
+ FeatherEdgesBucket *end_bucket = &buckets[end_bucket_index];
+ FeatherEdgesBucket *diagonal_bucket_a, *diagonal_bucket_b;
+
+ feather_bucket_get_diagonal(buckets, start_bucket_index, end_bucket_index, buckets_per_side,
+ &diagonal_bucket_a, &diagonal_bucket_b);
+
+ feather_bucket_add_edge(end_bucket, start, end);
+ feather_bucket_add_edge(diagonal_bucket_a, start, end);
+ feather_bucket_add_edge(diagonal_bucket_a, start, end);
+ }
+ }
+
+ /* check all edges for intersection with edges from their buckets */
+ for (i = 0; i < tot_feather_point; i++) {
+ int cur_a = i, cur_b = i + 1;
+ int start_bucket_index, end_bucket_index;
+
+ FeatherEdgesBucket *start_bucket;
+
+ if (cur_b == tot_feather_point)
+ cur_b = 0;
+
+ start_bucket_index = BUCKET_INDEX(feather_points[cur_a]);
+ end_bucket_index = BUCKET_INDEX(feather_points[cur_b]);
+
+ start_bucket = &buckets[start_bucket_index];
+
+ feather_bucket_check_intersect(feather_points, tot_feather_point, start_bucket, cur_a, cur_b);
+
+ if (start_bucket_index != end_bucket_index) {
+ FeatherEdgesBucket *end_bucket = &buckets[end_bucket_index];
+ FeatherEdgesBucket *diagonal_bucket_a, *diagonal_bucket_b;
+
+ feather_bucket_get_diagonal(buckets, start_bucket_index, end_bucket_index, buckets_per_side,
+ &diagonal_bucket_a, &diagonal_bucket_b);
+
+ feather_bucket_check_intersect(feather_points, tot_feather_point, end_bucket, cur_a, cur_b);
+ feather_bucket_check_intersect(feather_points, tot_feather_point, diagonal_bucket_a, cur_a, cur_b);
+ feather_bucket_check_intersect(feather_points, tot_feather_point, diagonal_bucket_b, cur_a, cur_b);
+ }
+ }
+
+ /* free buckets */
+ for (i = 0; i < tot_bucket; i++) {
+ if (buckets[i].segments)
+ MEM_freeN(buckets[i].segments);
+ }
+
+ MEM_freeN(buckets);
+
+#undef BUCKET_INDEX
+}
+
+/** only called from #BKE_mask_spline_feather_differentiated_points_with_resolution_ex() ! */
+static float (*mask_spline_feather_differentiated_points_with_resolution_ex__even(MaskSpline *spline,
+ int *tot_feather_point,
+ const unsigned int resol,
+ const int do_feather_isect
+ ))[2]
+{
+ MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
+ MaskSplinePoint *point_curr, *point_prev;
+ float (*feather)[2], (*fp)[2];
+
+ const int tot = BKE_mask_spline_differentiate_calc_total(spline, resol);
+ int a;
+
+ /* tot+1 because of 'forward_diff_bezier' function */
+ feather = fp = MEM_mallocN((tot + 1) * sizeof(*feather), "mask spline feather diff points");
+
+ a = spline->tot_point - 1;
+ if (spline->flag & MASK_SPLINE_CYCLIC)
+ a++;
+
+ point_prev = points_array;
+ point_curr = point_prev + 1;
+
+ while (a--) {
+ /* BezTriple *bezt_prev; */ /* UNUSED */
+ /* BezTriple *bezt_curr; */ /* UNUSED */
+ int j;
+
+ if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC))
+ point_curr = points_array;
+
+
+ /* bezt_prev = &point_prev->bezt; */
+ /* bezt_curr = &point_curr->bezt; */
+
+ for (j = 0; j < resol; j++, fp++) {
+ float u = (float) j / resol, weight;
+ float co[2], n[2];
+
+ /* TODO - these calls all calculate similar things
+ * could be unified for some speed */
+ BKE_mask_point_segment_co(spline, point_prev, u, co);
+ BKE_mask_point_normal(spline, point_prev, u, n);
+ weight = BKE_mask_point_weight(spline, point_prev, u);
+
+ madd_v2_v2v2fl(*fp, co, n, weight);
+ }
+
+ if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC) == 0) {
+ float u = 1.0f, weight;
+ float co[2], n[2];
+
+ BKE_mask_point_segment_co(spline, point_prev, u, co);
+ BKE_mask_point_normal(spline, point_prev, u, n);
+ weight = BKE_mask_point_weight(spline, point_prev, u);
+
+ madd_v2_v2v2fl(*fp, co, n, weight);
+ }
+
+ point_prev = point_curr;
+ point_curr++;
+ }
+
+ *tot_feather_point = tot;
+
+ if ((spline->flag & MASK_SPLINE_NOINTERSECT) && do_feather_isect) {
+ BKE_mask_spline_feather_collapse_inner_loops(spline, feather, tot);
+ }
+
+ return feather;
+}
+
+/** only called from #BKE_mask_spline_feather_differentiated_points_with_resolution_ex() ! */
+static float (*mask_spline_feather_differentiated_points_with_resolution_ex__double(MaskSpline *spline,
+ int *tot_feather_point,
+ const unsigned int resol,
+ const int do_feather_isect
+ ))[2]
+{
+ MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
+
+ MaskSplinePoint *point_curr, *point_prev;
+ float (*feather)[2], (*fp)[2];
+ const int tot = BKE_mask_spline_differentiate_calc_total(spline, resol);
+ int a;
+
+ if (spline->tot_point <= 1) {
+ /* nothing to differentiate */
+ *tot_feather_point = 0;
+ return NULL;
+ }
+
+ /* len+1 because of 'forward_diff_bezier' function */
+ *tot_feather_point = tot;
+ feather = fp = MEM_mallocN((tot + 1) * sizeof(*feather), "mask spline vets");
+
+ a = spline->tot_point - 1;
+ if (spline->flag & MASK_SPLINE_CYCLIC)
+ a++;
+
+ point_prev = points_array;
+ point_curr = point_prev + 1;
+
+ while (a--) {
+ BezTriple local_prevbezt;
+ BezTriple local_bezt;
+ float point_prev_n[2], point_curr_n[2], tvec[2];
+ float weight_prev, weight_curr;
+ float len_base, len_feather, len_scalar;
+
+ BezTriple *bezt_prev;
+ BezTriple *bezt_curr;
+ int j;
+
+ if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC))
+ point_curr = points_array;
+
+ bezt_prev = &point_prev->bezt;
+ bezt_curr = &point_curr->bezt;
+
+ /* modified copy for feather */
+ local_prevbezt = *bezt_prev;
+ local_bezt = *bezt_curr;
+
+ bezt_prev = &local_prevbezt;
+ bezt_curr = &local_bezt;
+
+ /* calc the normals */
+ sub_v2_v2v2(tvec, bezt_prev->vec[1], bezt_prev->vec[0]);
+ normalize_v2(tvec);
+ point_prev_n[0] = -tvec[1];
+ point_prev_n[1] = tvec[0];
+
+ sub_v2_v2v2(tvec, bezt_curr->vec[1], bezt_curr->vec[0]);
+ normalize_v2(tvec);
+ point_curr_n[0] = -tvec[1];
+ point_curr_n[1] = tvec[0];
+
+ weight_prev = bezt_prev->weight;
+ weight_curr = bezt_curr->weight;
+
+ mul_v2_fl(point_prev_n, weight_prev);
+ mul_v2_fl(point_curr_n, weight_curr);
+
+ /* before we transform verts */
+ len_base = len_v2v2(bezt_prev->vec[1], bezt_curr->vec[1]);
+
+ // add_v2_v2(bezt_prev->vec[0], point_prev_n); // not needed
+ add_v2_v2(bezt_prev->vec[1], point_prev_n);
+ add_v2_v2(bezt_prev->vec[2], point_prev_n);
+
+ add_v2_v2(bezt_curr->vec[0], point_curr_n);
+ add_v2_v2(bezt_curr->vec[1], point_curr_n);
+ // add_v2_v2(bezt_curr->vec[2], point_curr_n); // not needed
+
+ len_feather = len_v2v2(bezt_prev->vec[1], bezt_curr->vec[1]);
+
+ /* scale by chane in length */
+ len_scalar = len_feather / len_base;
+ dist_ensure_v2_v2fl(bezt_prev->vec[2], bezt_prev->vec[1], len_scalar * len_v2v2(bezt_prev->vec[2], bezt_prev->vec[1]));
+ dist_ensure_v2_v2fl(bezt_curr->vec[0], bezt_curr->vec[1], len_scalar * len_v2v2(bezt_curr->vec[0], bezt_curr->vec[1]));
+
+
+ for (j = 0; j < 2; j++) {
+ BKE_curve_forward_diff_bezier(bezt_prev->vec[1][j], bezt_prev->vec[2][j],
+ bezt_curr->vec[0][j], bezt_curr->vec[1][j],
+ &(*fp)[j], resol, 2 * sizeof(float));
+ }
+
+
+ /* scale by the uw's */
+ if (point_prev->tot_uw) {
+ for (j = 0; j < resol; j++, fp++) {
+ float u = (float) j / resol;
+ float weight_uw, weight_scalar;
+ float co[2];
+
+ /* TODO - these calls all calculate similar things
+ * could be unified for some speed */
+ BKE_mask_point_segment_co(spline, point_prev, u, co);
+
+ weight_uw = BKE_mask_point_weight(spline, point_prev, u);
+ weight_scalar = BKE_mask_point_weight_scalar(spline, point_prev, u);
+
+ dist_ensure_v2_v2fl(*fp, co, len_v2v2(*fp, co) * (weight_uw / weight_scalar));
+ }
+ }
+ else {
+ fp += resol;
+ }
+
+ if (a == 0 && (spline->flag & MASK_SPLINE_CYCLIC) == 0) {
+ copy_v2_v2(*fp, bezt_curr->vec[1]);
+ }
+
+ point_prev = point_curr;
+ point_curr++;
+ }
+
+ if ((spline->flag & MASK_SPLINE_NOINTERSECT) && do_feather_isect) {
+ BKE_mask_spline_feather_collapse_inner_loops(spline, feather, tot);
+ }
+
+ return feather;
+}
+
+/**
+ * values align with #BKE_mask_spline_differentiate_with_resolution_ex
+ * when \a resol arguments match.
+ */
+float (*BKE_mask_spline_feather_differentiated_points_with_resolution_ex(MaskSpline *spline,
+ int *tot_feather_point,
+ const unsigned int resol,
+ const int do_feather_isect
+ ))[2]
+{
+ switch (spline->offset_mode) {
+ case MASK_SPLINE_OFFSET_EVEN:
+ return mask_spline_feather_differentiated_points_with_resolution_ex__even(spline, tot_feather_point, resol, do_feather_isect);
+ break;
+ case MASK_SPLINE_OFFSET_SMOOTH:
+ default:
+ return mask_spline_feather_differentiated_points_with_resolution_ex__double(spline, tot_feather_point, resol, do_feather_isect);
+ break;
+ }
+}
+
+float (*BKE_mask_spline_feather_differentiated_points_with_resolution(MaskSpline *spline, int width, int height,
+ int *tot_feather_point, const int do_feather_isect))[2]
+{
+ unsigned int resol = BKE_mask_spline_feather_resolution(spline, width, height);
+
+ return BKE_mask_spline_feather_differentiated_points_with_resolution_ex(spline, tot_feather_point, resol, do_feather_isect);
+}
+
+float (*BKE_mask_spline_feather_differentiated_points(MaskSpline *spline, int *tot_feather_point))[2]
+{
+ return BKE_mask_spline_feather_differentiated_points_with_resolution(spline, 0, 0, tot_feather_point, TRUE);
+}
+
+float (*BKE_mask_spline_feather_points(MaskSpline *spline, int *tot_feather_point))[2]
+{
+ MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline);
+
+ int i, tot = 0;
+ float (*feather)[2], (*fp)[2];
+
+ /* count */
+ for (i = 0; i < spline->tot_point; i++) {
+ MaskSplinePoint *point = &points_array[i];
+
+ tot += point->tot_uw + 1;
+ }
+
+ /* create data */
+ feather = fp = MEM_mallocN(tot * sizeof(*feather), "mask spline feather points");
+
+ for (i = 0; i < spline->tot_point; i++) {
+ MaskSplinePoint *point = &points_array[i];
+ BezTriple *bezt = &point->bezt;
+ float weight, n[2];
+ int j;
+
+ BKE_mask_point_normal(spline, point, 0.0f, n);
+ weight = BKE_mask_point_weight(spline, point, 0.0f);
+
+ madd_v2_v2v2fl(*fp, bezt->vec[1], n, weight);
+ fp++;
+
+ for (j = 0; j < point->tot_uw; j++) {
+ float u = point->uw[j].u;
+ float co[2];
+
+ BKE_mask_point_segment_co(spline, point, u, co);
+ BKE_mask_point_normal(spline, point, u, n);
+ weight = BKE_mask_point_weight(spline, point, u);
+
+ madd_v2_v2v2fl(*fp, co, n, weight);
+ fp++;
+ }
+ }
+
+ *tot_feather_point = tot;
+
+ return feather;
+}
+
+/* *** mask point functions which involve evaluation *** */
+float *BKE_mask_point_segment_feather_diff_with_resolution(MaskSpline *spline, MaskSplinePoint *point,
+ int width, int height,
+ unsigned int *tot_feather_point)
+{
+ float *feather, *fp;
+ unsigned int resol = BKE_mask_spline_feather_resolution(spline, width, height);
+ unsigned int i;
+
+ feather = fp = MEM_callocN(2 * resol * sizeof(float), "mask point spline feather diff points");
+
+ for (i = 0; i < resol; i++, fp += 2) {
+ float u = (float)(i % resol) / resol, weight;
+ float co[2], n[2];
+
+ BKE_mask_point_segment_co(spline, point, u, co);
+ BKE_mask_point_normal(spline, point, u, n);
+ weight = BKE_mask_point_weight(spline, point, u);
+
+ fp[0] = co[0] + n[0] * weight;
+ fp[1] = co[1] + n[1] * weight;
+ }
+
+ *tot_feather_point = resol;
+
+ return feather;
+}
+
+float *BKE_mask_point_segment_feather_diff(MaskSpline *spline, MaskSplinePoint *point, unsigned int *tot_feather_point)
+{
+ return BKE_mask_point_segment_feather_diff_with_resolution(spline, point, 0, 0, tot_feather_point);
+}
+
+float *BKE_mask_point_segment_diff_with_resolution(MaskSpline *spline, MaskSplinePoint *point,
+ int width, int height, unsigned int *tot_diff_point)
+{
+ MaskSplinePoint *points_array = BKE_mask_spline_point_array_from_point(spline, point);
+
+ BezTriple *bezt, *bezt_next;
+ float *diff_points, *fp;
+ int j, resol = BKE_mask_spline_resolution(spline, width, height);
+
+ bezt = &point->bezt;
+ bezt_next = BKE_mask_spline_point_next_bezt(spline, points_array, point);
+
+ if (!bezt_next)
+ return NULL;
+
+ /* resol+1 because of 'forward_diff_bezier' function */
+ *tot_diff_point = resol + 1;
+ diff_points = fp = MEM_callocN((resol + 1) * 2 * sizeof(float), "mask segment vets");
+
+ for (j = 0; j < 2; j++) {
+ BKE_curve_forward_diff_bezier(bezt->vec[1][j], bezt->vec[2][j],
+ bezt_next->vec[0][j], bezt_next->vec[1][j],
+ fp + j, resol, 2 * sizeof(float));
+ }
+
+ copy_v2_v2(fp + 2 * resol, bezt_next->vec[1]);
+
+ return diff_points;
+}
+
+float *BKE_mask_point_segment_diff(MaskSpline *spline, MaskSplinePoint *point, unsigned int *tot_diff_point)
+{
+ return BKE_mask_point_segment_diff_with_resolution(spline, point, 0, 0, tot_diff_point);
+}
diff --git a/source/blender/blenkernel/intern/mask_rasterize.c b/source/blender/blenkernel/intern/mask_rasterize.c
index d39be3b8ed6..13ad9962aff 100644
--- a/source/blender/blenkernel/intern/mask_rasterize.c
+++ b/source/blender/blenkernel/intern/mask_rasterize.c
@@ -26,6 +26,46 @@
/** \file blender/blenkernel/intern/mask_rasterize.c
* \ingroup bke
+ *
+ * This module exposes a rasterizer that works as a black box - implementation details are confined to this file,
+ *
+ * The basic method to access is:
+ * - create & initialize a handle from a #Mask datablock.
+ * - execute pixel lookups.
+ * - free the handle.
+ *
+ * This file is admittedly a bit confusticated, in quite few areas speed was chosen over readability,
+ * though it is commented - so shouldn't be so hard to see whats going on.
+ *
+ *
+ * Implementation:
+ *
+ * To rasterize the mask its converted into geometry that use a ray-cast for each pixel lookup.
+ *
+ * Initially 'kdopbvh' was used but this ended up being too slow.
+ *
+ * To gain some extra speed we take advantage of a few shortcuts that can be made rasterizing masks specifically.
+ * - all triangles are known to be completely white - so no depth check is done on triangle intersection.
+ * - all quads are known to be feather outlines - the 1 and 0 depths are known by the vertex order in the quad,
+ * - there is no color - just a value for each mask pixel.
+ * - the mask spacial structure always maps to space 0-1 on X and Y axis.
+ * - bucketing is used to speed up lookups for geometry.
+ *
+ * Other Details:
+ * - used unsigned values all over for some extra speed on some arch's.
+ * - anti-aliasing is faked, just ensuring at least one pixel feather - avoids oversampling.
+ * - initializing the spacial structure doesn't need to be as optimized as pixel lookups are.
+ * - mask lookups need not be pixel aligned so any sub-pixel values from x/y (0 - 1), can be found.
+ * (perhaps masks can be used as a vector texture in 3D later on)
+ *
+ *
+ * Currently, to build the spacial structure we have to calculate the total number of faces ahead of time.
+ *
+ * This is getting a bit complicated with the addition of unfilled splines and end capping -
+ * If large changes are needed here we would be better off using an iterable
+ * BLI_mempool for triangles and converting to a contiguous array afterwards.
+ *
+ * - Campbell
*/
#include "MEM_guardedalloc.h"
@@ -213,9 +253,9 @@ void BKE_maskrasterize_handle_free(MaskRasterHandle *mr_handle)
}
-void maskrasterize_spline_differentiate_point_outset(float (*diff_feather_points)[2], float (*diff_points)[2],
- const unsigned int tot_diff_point, const float ofs,
- const short do_test)
+static void maskrasterize_spline_differentiate_point_outset(float (*diff_feather_points)[2], float (*diff_points)[2],
+ const unsigned int tot_diff_point, const float ofs,
+ const short do_test)
{
unsigned int k_prev = tot_diff_point - 2;
unsigned int k_curr = tot_diff_point - 1;
@@ -370,8 +410,8 @@ static void layer_bucket_init(MaskRasterLayer *layer, const float pixel_size)
{
MemArena *arena = BLI_memarena_new(1 << 16, __func__);
- const float bucket_dim_x = BLI_RCT_SIZE_X(&layer->bounds);
- const float bucket_dim_y = BLI_RCT_SIZE_Y(&layer->bounds);
+ const float bucket_dim_x = BLI_rctf_size_x(&layer->bounds);
+ const float bucket_dim_y = BLI_rctf_size_y(&layer->bounds);
layer->buckets_x = (bucket_dim_x / pixel_size) / (float)BUCKET_PIXELS_PER_CELL;
layer->buckets_y = (bucket_dim_y / pixel_size) / (float)BUCKET_PIXELS_PER_CELL;
@@ -1168,7 +1208,7 @@ static float maskrasterize_layer_isect(unsigned int *face, float (*cos)[3], cons
/* needs work */
#if 1
- /* quad check fails for bowtie, so keep using 2 tri checks */
+ /* quad check fails for bow-tie, so keep using 2 tri checks */
//if (isect_point_quad_v2(xy, cos[face[0]], cos[face[1]], cos[face[2]], cos[face[3]]))
if (isect_point_tri_v2(xy, cos[face[0]], cos[face[1]], cos[face[2]]) ||
isect_point_tri_v2(xy, cos[face[0]], cos[face[2]], cos[face[3]]))
@@ -1176,7 +1216,7 @@ static float maskrasterize_layer_isect(unsigned int *face, float (*cos)[3], cons
return maskrasterize_layer_z_depth_quad(xy, cos[face[0]], cos[face[1]], cos[face[2]], cos[face[3]]);
}
#elif 1
- /* don't use isect_point_tri_v2_cw because we could have bowtie quads */
+ /* don't use isect_point_tri_v2_cw because we could have bow-tie quads */
if (isect_point_tri_v2(xy, cos[face[0]], cos[face[1]], cos[face[2]])) {
return maskrasterize_layer_z_depth_tri(xy, cos[face[0]], cos[face[1]], cos[face[2]]);
@@ -1196,7 +1236,7 @@ static float maskrasterize_layer_isect(unsigned int *face, float (*cos)[3], cons
BLI_INLINE unsigned int layer_bucket_index_from_xy(MaskRasterLayer *layer, const float xy[2])
{
- BLI_assert(BLI_in_rctf_v(&layer->bounds, xy));
+ BLI_assert(BLI_rctf_isect_pt_v(&layer->bounds, xy));
return ( (unsigned int)((xy[0] - layer->bounds.xmin) * layer->buckets_xy_scalar[0])) +
(((unsigned int)((xy[1] - layer->bounds.ymin) * layer->buckets_xy_scalar[1])) * layer->buckets_x);
@@ -1233,7 +1273,7 @@ static float layer_bucket_depth_from_xy(MaskRasterLayer *layer, const float xy[2
float BKE_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float xy[2])
{
/* can't do this because some layers may invert */
- /* if (BLI_in_rctf_v(&mr_handle->bounds, xy)) */
+ /* if (BLI_rctf_isect_pt_v(&mr_handle->bounds, xy)) */
const unsigned int layers_tot = mr_handle->layers_tot;
unsigned int i;
@@ -1246,7 +1286,7 @@ float BKE_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float x
float value_layer;
/* also used as signal for unused layer (when render is disabled) */
- if (layer->alpha != 0.0f && BLI_in_rctf_v(&layer->bounds, xy)) {
+ if (layer->alpha != 0.0f && BLI_rctf_isect_pt_v(&layer->bounds, xy)) {
value_layer = 1.0f - layer_bucket_depth_from_xy(layer, xy);
switch (layer->falloff) {
@@ -1282,9 +1322,12 @@ float BKE_maskrasterize_handle_sample(MaskRasterHandle *mr_handle, const float x
}
switch (layer->blend) {
- case MASK_BLEND_MERGE:
+ case MASK_BLEND_MERGE_ADD:
value += value_layer * (1.0f - value);
break;
+ case MASK_BLEND_MERGE_SUBTRACT:
+ value -= value_layer * value;
+ break;
case MASK_BLEND_ADD:
value += value_layer;
break;
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index e5f392e4bce..bea0e33da9a 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -80,12 +80,18 @@ void init_def_material(void)
/* not material itself */
void BKE_material_free(Material *ma)
{
+ BKE_material_free_ex(ma, TRUE);
+}
+
+/* not material itself */
+void BKE_material_free_ex(Material *ma, int do_id_user)
+{
MTex *mtex;
int a;
for (a = 0; a < MAX_MTEX; a++) {
mtex = ma->mtex[a];
- if (mtex && mtex->tex) mtex->tex->id.us--;
+ if (do_id_user && mtex && mtex->tex) mtex->tex->id.us--;
if (mtex) MEM_freeN(mtex);
}
@@ -101,7 +107,7 @@ void BKE_material_free(Material *ma)
/* is no lib link block, but material extension */
if (ma->nodetree) {
- ntreeFreeTree(ma->nodetree);
+ ntreeFreeTree_ex(ma->nodetree, do_id_user);
MEM_freeN(ma->nodetree);
}
@@ -235,7 +241,7 @@ Material *BKE_material_copy(Material *ma)
if (ma->preview) man->preview = BKE_previewimg_copy(ma->preview);
if (ma->nodetree) {
- man->nodetree = ntreeCopyTree(ma->nodetree); /* 0 == full new tree */
+ man->nodetree = ntreeCopyTree(ma->nodetree);
}
man->gpumaterial.first = man->gpumaterial.last = NULL;
@@ -807,7 +813,7 @@ void assign_material(Object *ob, Material *ma, short act, int assign_type)
*totcolp = act;
}
- // Determine the object/mesh linking
+ /* Determine the object/mesh linking */
if (assign_type == BKE_MAT_ASSIGN_USERPREF && ob->totcol && ob->actcol) {
/* copy from previous material */
bit = ob->matbits[ob->actcol - 1];
@@ -935,7 +941,7 @@ static void do_init_render_material(Material *ma, int r_mode, float *amb)
if (ma->texco & (TEXCO_ORCO | TEXCO_REFL | TEXCO_NORM | TEXCO_STRAND | TEXCO_STRESS)) needuv = 1;
else if (ma->texco & (TEXCO_GLOB | TEXCO_UV | TEXCO_OBJECT | TEXCO_SPEED)) needuv = 1;
- else if (ma->texco & (TEXCO_LAVECTOR | TEXCO_VIEW | TEXCO_STICKY)) needuv = 1;
+ else if (ma->texco & (TEXCO_LAVECTOR | TEXCO_VIEW)) needuv = 1;
if ((ma->mapto & MAP_NORM) && (mtex->normapspace == MTEX_NSPACE_TANGENT))
needtang = 1;
@@ -1321,9 +1327,9 @@ void ramp_blend(int type, float r_col[3], const float fac, const float col[3])
r_col[2] = facm * (r_col[2]) + fac * (r_col[2]) / col[2];
break;
case MA_RAMP_DIFF:
- r_col[0] = facm * (r_col[0]) + fac *fabsf(r_col[0] - col[0]);
- r_col[1] = facm * (r_col[1]) + fac *fabsf(r_col[1] - col[1]);
- r_col[2] = facm * (r_col[2]) + fac *fabsf(r_col[2] - col[2]);
+ r_col[0] = facm * (r_col[0]) + fac * fabsf(r_col[0] - col[0]);
+ r_col[1] = facm * (r_col[1]) + fac * fabsf(r_col[1] - col[1]);
+ r_col[2] = facm * (r_col[2]) + fac * fabsf(r_col[2] - col[2]);
break;
case MA_RAMP_DARK:
tmp = col[0] + ((1 - col[0]) * facm);
@@ -1483,7 +1489,11 @@ void ramp_blend(int type, float r_col[3], const float fac, const float col[3])
}
}
-/* copy/paste buffer, if we had a propper py api that would be better */
+/**
+ * \brief copy/paste buffer, if we had a proper py api that would be better
+ * \note matcopybuf.nodetree does _NOT_ use ID's
+ * \todo matcopybuf.nodetree's node->id's are NOT validated, this will crash!
+ */
static Material matcopybuf;
static short matcopied = 0;
@@ -1511,7 +1521,7 @@ void free_matcopybuf(void)
matcopybuf.ramp_spec = NULL;
if (matcopybuf.nodetree) {
- ntreeFreeTree(matcopybuf.nodetree);
+ ntreeFreeTree_ex(matcopybuf.nodetree, FALSE);
MEM_freeN(matcopybuf.nodetree);
matcopybuf.nodetree = NULL;
}
@@ -1537,7 +1547,7 @@ void copy_matcopybuf(Material *ma)
matcopybuf.mtex[a] = MEM_dupallocN(mtex);
}
}
- matcopybuf.nodetree = ntreeCopyTree(ma->nodetree);
+ matcopybuf.nodetree = ntreeCopyTree_ex(ma->nodetree, FALSE);
matcopybuf.preview = NULL;
matcopybuf.gpumaterial.first = matcopybuf.gpumaterial.last = NULL;
matcopied = 1;
@@ -1582,7 +1592,7 @@ void paste_matcopybuf(Material *ma)
}
}
- ma->nodetree = ntreeCopyTree(matcopybuf.nodetree);
+ ma->nodetree = ntreeCopyTree_ex(matcopybuf.nodetree, FALSE);
}
@@ -1623,7 +1633,7 @@ static void decode_tfaceflag(Material *ma, int flag, int convertall)
/* flag is shifted in 1 to make 0 != no flag yet (see encode_tfaceflag) */
flag -= 1;
- alphablend = flag >> 15; //encoded in the encode_tfaceflag function
+ alphablend = flag >> 15; /* encoded in the encode_tfaceflag function */
(*game).flag = 0;
/* General Material Options */
@@ -2023,8 +2033,7 @@ int do_version_tface(Main *main, int fileload)
nowarning = 0;
}
else
- convert_tfacematerial(main, ma);
- continue;
+ convert_tfacematerial(main, ma); continue;
}
/* no conflicts in this material - 90% of cases
diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c
index 5c8ff7ad14f..9eea075c97a 100644
--- a/source/blender/blenkernel/intern/mball.c
+++ b/source/blender/blenkernel/intern/mball.c
@@ -163,11 +163,13 @@ static void converge(const float p1[3], const float p2[3], float v1, float v2,
float (*function)(float, float, float), float p[3], MetaBall *mb, int f);
/* Global variables */
+static struct {
+ float thresh;
+ int totelem;
+ MetaElem **mainb;
+ octal_tree *metaball_tree;
+} G_mb = {0};
-static float thresh = 0.6f;
-static int totelem = 0;
-static MetaElem **mainb;
-static octal_tree *metaball_tree = NULL;
/* Functions */
void BKE_mball_unlink(MetaBall *mb)
@@ -184,7 +186,7 @@ void BKE_mball_unlink(MetaBall *mb)
/* do not free mball itself */
void BKE_mball_free(MetaBall *mb)
{
- BKE_mball_unlink(mb);
+ BKE_mball_unlink(mb);
if (mb->adt) {
BKE_free_animdata((ID *)mb);
@@ -523,7 +525,7 @@ Object *BKE_mball_basis_find(Scene *scene, Object *basis)
char basisname[MAX_ID_NAME], obname[MAX_ID_NAME];
BLI_split_name_num(basisname, &basisnr, basis->id.name + 2, '.');
- totelem = 0;
+ G_mb.totelem = 0;
/* XXX recursion check, see scene.c, just too simple code this BKE_scene_base_iter_next() */
if (F_ERROR == BKE_scene_base_iter_next(&sce_iter, 0, NULL, NULL))
@@ -560,13 +562,14 @@ Object *BKE_mball_basis_find(Scene *scene, Object *basis)
basis = ob;
basisnr = obnr;
}
- }
+ }
}
}
- while (ml) {
- if (!(ml->flag & MB_HIDE)) totelem++;
- ml = ml->next;
+ for ( ; ml; ml = ml->next) {
+ if (!(ml->flag & MB_HIDE)) {
+ G_mb.totelem++;
+ }
}
}
}
@@ -633,66 +636,68 @@ static float densfunc(MetaElem *ball, float x, float y, float z)
mul_m4_v3((float (*)[4])ball->imat, dvec);
- if (ball->type == MB_BALL) {
- }
- else if (ball->type == MB_TUBEX) {
- if (dvec[0] > ball->len) dvec[0] -= ball->len;
- else if (dvec[0] < -ball->len) dvec[0] += ball->len;
- else dvec[0] = 0.0;
- }
- else if (ball->type == MB_TUBEY) {
- if (dvec[1] > ball->len) dvec[1] -= ball->len;
- else if (dvec[1] < -ball->len) dvec[1] += ball->len;
- else dvec[1] = 0.0;
- }
- else if (ball->type == MB_TUBEZ) {
- if (dvec[2] > ball->len) dvec[2] -= ball->len;
- else if (dvec[2] < -ball->len) dvec[2] += ball->len;
- else dvec[2] = 0.0;
- }
- else if (ball->type == MB_TUBE) {
- if (dvec[0] > ball->expx) dvec[0] -= ball->expx;
- else if (dvec[0] < -ball->expx) dvec[0] += ball->expx;
- else dvec[0] = 0.0;
- }
- else if (ball->type == MB_PLANE) {
- if (dvec[0] > ball->expx) dvec[0] -= ball->expx;
- else if (dvec[0] < -ball->expx) dvec[0] += ball->expx;
- else dvec[0] = 0.0;
- if (dvec[1] > ball->expy) dvec[1] -= ball->expy;
- else if (dvec[1] < -ball->expy) dvec[1] += ball->expy;
- else dvec[1] = 0.0;
- }
- else if (ball->type == MB_ELIPSOID) {
- dvec[0] *= 1 / ball->expx;
- dvec[1] *= 1 / ball->expy;
- dvec[2] *= 1 / ball->expz;
- }
- else if (ball->type == MB_CUBE) {
- if (dvec[0] > ball->expx) dvec[0] -= ball->expx;
- else if (dvec[0] < -ball->expx) dvec[0] += ball->expx;
- else dvec[0] = 0.0;
- if (dvec[1] > ball->expy) dvec[1] -= ball->expy;
- else if (dvec[1] < -ball->expy) dvec[1] += ball->expy;
- else dvec[1] = 0.0;
- if (dvec[2] > ball->expz) dvec[2] -= ball->expz;
- else if (dvec[2] < -ball->expz) dvec[2] += ball->expz;
- else dvec[2] = 0.0;
- }
-
- dist2 = len_v3(dvec);
-
- if (ball->flag & MB_NEGATIVE) {
- dist2 = 1.0f - (dist2 / ball->rad2);
- if (dist2 < 0.0f) return 0.5f;
-
- return 0.5f - ball->s * dist2 * dist2 * dist2;
+ switch (ball->type) {
+ case MB_BALL:
+ /* do nothing */
+ break;
+ case MB_TUBE:
+ if (dvec[0] > ball->expx) dvec[0] -= ball->expx;
+ else if (dvec[0] < -ball->expx) dvec[0] += ball->expx;
+ else dvec[0] = 0.0;
+ break;
+ case MB_PLANE:
+ if (dvec[0] > ball->expx) dvec[0] -= ball->expx;
+ else if (dvec[0] < -ball->expx) dvec[0] += ball->expx;
+ else dvec[0] = 0.0;
+ if (dvec[1] > ball->expy) dvec[1] -= ball->expy;
+ else if (dvec[1] < -ball->expy) dvec[1] += ball->expy;
+ else dvec[1] = 0.0;
+ break;
+ case MB_ELIPSOID:
+ dvec[0] /= ball->expx;
+ dvec[1] /= ball->expy;
+ dvec[2] /= ball->expz;
+ break;
+ case MB_CUBE:
+ if (dvec[0] > ball->expx) dvec[0] -= ball->expx;
+ else if (dvec[0] < -ball->expx) dvec[0] += ball->expx;
+ else dvec[0] = 0.0;
+
+ if (dvec[1] > ball->expy) dvec[1] -= ball->expy;
+ else if (dvec[1] < -ball->expy) dvec[1] += ball->expy;
+ else dvec[1] = 0.0;
+
+ if (dvec[2] > ball->expz) dvec[2] -= ball->expz;
+ else if (dvec[2] < -ball->expz) dvec[2] += ball->expz;
+ else dvec[2] = 0.0;
+ break;
+
+ /* *** deprecated, could be removed?, do-versioned at least *** */
+ case MB_TUBEX:
+ if (dvec[0] > ball->len) dvec[0] -= ball->len;
+ else if (dvec[0] < -ball->len) dvec[0] += ball->len;
+ else dvec[0] = 0.0;
+ break;
+ case MB_TUBEY:
+ if (dvec[1] > ball->len) dvec[1] -= ball->len;
+ else if (dvec[1] < -ball->len) dvec[1] += ball->len;
+ else dvec[1] = 0.0;
+ break;
+ case MB_TUBEZ:
+ if (dvec[2] > ball->len) dvec[2] -= ball->len;
+ else if (dvec[2] < -ball->len) dvec[2] += ball->len;
+ else dvec[2] = 0.0;
+ break;
+ /* *** end deprecated *** */
}
- else {
- dist2 = 1.0f - (dist2 / ball->rad2);
- if (dist2 < 0.0f) return -0.5f;
- return ball->s * dist2 * dist2 * dist2 - 0.5f;
+ dist2 = 1.0f - (len_squared_v3(dvec) / ball->rad2);
+
+ if ((ball->flag & MB_NEGATIVE) == 0) {
+ return (dist2 < 0.0f) ? -0.5f : (ball->s * dist2 * dist2 * dist2) - 0.5f;
+ }
+ else {
+ return (dist2 < 0.0f) ? 0.5f : 0.5f - (ball->s * dist2 * dist2 * dist2);
}
}
@@ -727,7 +732,7 @@ static octal_node *find_metaball_octal_node(octal_node *node, float x, float y,
return find_metaball_octal_node(node->nodes[2], x, y, z, depth--);
else
return node;
- }
+ }
}
}
else {
@@ -757,7 +762,7 @@ static octal_node *find_metaball_octal_node(octal_node *node, float x, float y,
return find_metaball_octal_node(node->nodes[6], x, y, z, depth--);
else
return node;
- }
+ }
}
}
@@ -772,30 +777,27 @@ static float metaball(float x, float y, float z)
float dens = 0;
int a;
- if (totelem > 1) {
- node = find_metaball_octal_node(metaball_tree->first, x, y, z, metaball_tree->depth);
+ if (G_mb.totelem > 1) {
+ node = find_metaball_octal_node(G_mb.metaball_tree->first, x, y, z, G_mb.metaball_tree->depth);
if (node) {
- ml_p = node->elems.first;
-
- while (ml_p) {
+ for (ml_p = node->elems.first; ml_p; ml_p = ml_p->next) {
dens += densfunc(ml_p->ml, x, y, z);
- ml_p = ml_p->next;
}
- dens += -0.5f * (metaball_tree->pos - node->pos);
- dens += 0.5f * (metaball_tree->neg - node->neg);
+ dens += -0.5f * (G_mb.metaball_tree->pos - node->pos);
+ dens += 0.5f * (G_mb.metaball_tree->neg - node->neg);
}
else {
- for (a = 0; a < totelem; a++) {
- dens += densfunc(mainb[a], x, y, z);
+ for (a = 0; a < G_mb.totelem; a++) {
+ dens += densfunc(G_mb.mainb[a], x, y, z);
}
}
}
else {
- dens += densfunc(mainb[0], x, y, z);
+ dens += densfunc(G_mb.mainb[0], x, y, z);
}
- return thresh - dens;
+ return G_mb.thresh - dens;
}
/* ******************************************** */
@@ -859,7 +861,7 @@ static void *new_pgn_element(int size)
}
BLI_freelistN(&lb);
- return NULL;
+ return NULL;
}
size = 4 * ( (size + 3) / 4);
@@ -1497,7 +1499,7 @@ static void find_first_points(PROCESS *mbproc, MetaBall *mb, int a)
MetaElem *ml;
float f = 0.0f;
- ml = mainb[a];
+ ml = G_mb.mainb[a];
f = 1.0 - (mb->thresh / ml->s);
/* Skip, when Stiffness of MetaElement is too small ... MetaElement can't be
@@ -1591,10 +1593,12 @@ static void find_first_points(PROCESS *mbproc, MetaBall *mb, int a)
/* add CUBE (with indexes c_i, c_j, c_k) to the stack,
* this cube includes found point of Implicit Surface */
- if (ml->flag & MB_NEGATIVE)
- add_cube(mbproc, c_i, c_j, c_k, 2);
- else
+ if ((ml->flag & MB_NEGATIVE) == 0) {
add_cube(mbproc, c_i, c_j, c_k, 1);
+ }
+ else {
+ add_cube(mbproc, c_i, c_j, c_k, 2);
+ }
}
len = len_v3v3(workp, in);
workp_v = tmp_v;
@@ -1621,10 +1625,10 @@ static void polygonize(PROCESS *mbproc, MetaBall *mb)
mbproc->edges = MEM_callocN(2 * HASHSIZE * sizeof(EDGELIST *), "mbproc->edges");
makecubetable();
- for (a = 0; a < totelem; a++) {
+ for (a = 0; a < G_mb.totelem; a++) {
/* try to find 8 points on the surface for each MetaElem */
- find_first_points(mbproc, mb, a);
+ find_first_points(mbproc, mb, a);
}
/* polygonize all MetaElems of current MetaBall */
@@ -1714,7 +1718,7 @@ static float init_meta(Scene *scene, Object *ob) /* return totsize */
ml_count++;
ml = ml->next;
}
- totelem -= ml_count;
+ G_mb.totelem -= ml_count;
}
else {
while (ml) {
@@ -1743,9 +1747,9 @@ static float init_meta(Scene *scene, Object *ob) /* return totsize */
mult_m4_m4m4(temp1, temp2, temp3);
/* make a copy because of duplicates */
- mainb[a] = new_pgn_element(sizeof(MetaElem));
- *(mainb[a]) = *ml;
- mainb[a]->bb = new_pgn_element(sizeof(BoundBox));
+ G_mb.mainb[a] = new_pgn_element(sizeof(MetaElem));
+ *(G_mb.mainb[a]) = *ml;
+ G_mb.mainb[a]->bb = new_pgn_element(sizeof(BoundBox));
mat = new_pgn_element(4 * 4 * sizeof(float));
imat = new_pgn_element(4 * 4 * sizeof(float));
@@ -1758,70 +1762,70 @@ static float init_meta(Scene *scene, Object *ob) /* return totsize */
invert_m4_m4(imat, mat);
- mainb[a]->rad2 = ml->rad * ml->rad;
+ G_mb.mainb[a]->rad2 = ml->rad * ml->rad;
- mainb[a]->mat = (float *) mat;
- mainb[a]->imat = (float *) imat;
+ G_mb.mainb[a]->mat = (float *) mat;
+ G_mb.mainb[a]->imat = (float *) imat;
/* untransformed Bounding Box of MetaElem */
/* 0 */
- mainb[a]->bb->vec[0][0] = -ml->expx;
- mainb[a]->bb->vec[0][1] = -ml->expy;
- mainb[a]->bb->vec[0][2] = -ml->expz;
+ G_mb.mainb[a]->bb->vec[0][0] = -ml->expx;
+ G_mb.mainb[a]->bb->vec[0][1] = -ml->expy;
+ G_mb.mainb[a]->bb->vec[0][2] = -ml->expz;
/* 1 */
- mainb[a]->bb->vec[1][0] = ml->expx;
- mainb[a]->bb->vec[1][1] = -ml->expy;
- mainb[a]->bb->vec[1][2] = -ml->expz;
+ G_mb.mainb[a]->bb->vec[1][0] = ml->expx;
+ G_mb.mainb[a]->bb->vec[1][1] = -ml->expy;
+ G_mb.mainb[a]->bb->vec[1][2] = -ml->expz;
/* 2 */
- mainb[a]->bb->vec[2][0] = ml->expx;
- mainb[a]->bb->vec[2][1] = ml->expy;
- mainb[a]->bb->vec[2][2] = -ml->expz;
+ G_mb.mainb[a]->bb->vec[2][0] = ml->expx;
+ G_mb.mainb[a]->bb->vec[2][1] = ml->expy;
+ G_mb.mainb[a]->bb->vec[2][2] = -ml->expz;
/* 3 */
- mainb[a]->bb->vec[3][0] = -ml->expx;
- mainb[a]->bb->vec[3][1] = ml->expy;
- mainb[a]->bb->vec[3][2] = -ml->expz;
+ G_mb.mainb[a]->bb->vec[3][0] = -ml->expx;
+ G_mb.mainb[a]->bb->vec[3][1] = ml->expy;
+ G_mb.mainb[a]->bb->vec[3][2] = -ml->expz;
/* 4 */
- mainb[a]->bb->vec[4][0] = -ml->expx;
- mainb[a]->bb->vec[4][1] = -ml->expy;
- mainb[a]->bb->vec[4][2] = ml->expz;
+ G_mb.mainb[a]->bb->vec[4][0] = -ml->expx;
+ G_mb.mainb[a]->bb->vec[4][1] = -ml->expy;
+ G_mb.mainb[a]->bb->vec[4][2] = ml->expz;
/* 5 */
- mainb[a]->bb->vec[5][0] = ml->expx;
- mainb[a]->bb->vec[5][1] = -ml->expy;
- mainb[a]->bb->vec[5][2] = ml->expz;
+ G_mb.mainb[a]->bb->vec[5][0] = ml->expx;
+ G_mb.mainb[a]->bb->vec[5][1] = -ml->expy;
+ G_mb.mainb[a]->bb->vec[5][2] = ml->expz;
/* 6 */
- mainb[a]->bb->vec[6][0] = ml->expx;
- mainb[a]->bb->vec[6][1] = ml->expy;
- mainb[a]->bb->vec[6][2] = ml->expz;
+ G_mb.mainb[a]->bb->vec[6][0] = ml->expx;
+ G_mb.mainb[a]->bb->vec[6][1] = ml->expy;
+ G_mb.mainb[a]->bb->vec[6][2] = ml->expz;
/* 7 */
- mainb[a]->bb->vec[7][0] = -ml->expx;
- mainb[a]->bb->vec[7][1] = ml->expy;
- mainb[a]->bb->vec[7][2] = ml->expz;
+ G_mb.mainb[a]->bb->vec[7][0] = -ml->expx;
+ G_mb.mainb[a]->bb->vec[7][1] = ml->expy;
+ G_mb.mainb[a]->bb->vec[7][2] = ml->expz;
/* transformation of Metalem bb */
for (i = 0; i < 8; i++)
- mul_m4_v3((float (*)[4])mat, mainb[a]->bb->vec[i]);
+ mul_m4_v3((float (*)[4])mat, G_mb.mainb[a]->bb->vec[i]);
/* find max and min of transformed bb */
for (i = 0; i < 8; i++) {
/* find maximums */
- if (mainb[a]->bb->vec[i][0] > max_x) max_x = mainb[a]->bb->vec[i][0];
- if (mainb[a]->bb->vec[i][1] > max_y) max_y = mainb[a]->bb->vec[i][1];
- if (mainb[a]->bb->vec[i][2] > max_z) max_z = mainb[a]->bb->vec[i][2];
+ if (G_mb.mainb[a]->bb->vec[i][0] > max_x) max_x = G_mb.mainb[a]->bb->vec[i][0];
+ if (G_mb.mainb[a]->bb->vec[i][1] > max_y) max_y = G_mb.mainb[a]->bb->vec[i][1];
+ if (G_mb.mainb[a]->bb->vec[i][2] > max_z) max_z = G_mb.mainb[a]->bb->vec[i][2];
/* find minimums */
- if (mainb[a]->bb->vec[i][0] < min_x) min_x = mainb[a]->bb->vec[i][0];
- if (mainb[a]->bb->vec[i][1] < min_y) min_y = mainb[a]->bb->vec[i][1];
- if (mainb[a]->bb->vec[i][2] < min_z) min_z = mainb[a]->bb->vec[i][2];
+ if (G_mb.mainb[a]->bb->vec[i][0] < min_x) min_x = G_mb.mainb[a]->bb->vec[i][0];
+ if (G_mb.mainb[a]->bb->vec[i][1] < min_y) min_y = G_mb.mainb[a]->bb->vec[i][1];
+ if (G_mb.mainb[a]->bb->vec[i][2] < min_z) min_z = G_mb.mainb[a]->bb->vec[i][2];
}
/* create "new" bb, only point 0 and 6, which are
* necessary for octal tree filling */
- mainb[a]->bb->vec[0][0] = min_x - ml->rad;
- mainb[a]->bb->vec[0][1] = min_y - ml->rad;
- mainb[a]->bb->vec[0][2] = min_z - ml->rad;
+ G_mb.mainb[a]->bb->vec[0][0] = min_x - ml->rad;
+ G_mb.mainb[a]->bb->vec[0][1] = min_y - ml->rad;
+ G_mb.mainb[a]->bb->vec[0][2] = min_z - ml->rad;
- mainb[a]->bb->vec[6][0] = max_x + ml->rad;
- mainb[a]->bb->vec[6][1] = max_y + ml->rad;
- mainb[a]->bb->vec[6][2] = max_z + ml->rad;
+ G_mb.mainb[a]->bb->vec[6][0] = max_x + ml->rad;
+ G_mb.mainb[a]->bb->vec[6][1] = max_y + ml->rad;
+ G_mb.mainb[a]->bb->vec[6][2] = max_z + ml->rad;
a++;
}
@@ -1834,13 +1838,13 @@ static float init_meta(Scene *scene, Object *ob) /* return totsize */
/* totsize (= 'manhattan' radius) */
totsize = 0.0;
- for (a = 0; a < totelem; a++) {
+ for (a = 0; a < G_mb.totelem; a++) {
- vec[0] = mainb[a]->x + mainb[a]->rad + mainb[a]->expx;
- vec[1] = mainb[a]->y + mainb[a]->rad + mainb[a]->expy;
- vec[2] = mainb[a]->z + mainb[a]->rad + mainb[a]->expz;
+ vec[0] = G_mb.mainb[a]->x + G_mb.mainb[a]->rad + G_mb.mainb[a]->expx;
+ vec[1] = G_mb.mainb[a]->y + G_mb.mainb[a]->rad + G_mb.mainb[a]->expy;
+ vec[2] = G_mb.mainb[a]->z + G_mb.mainb[a]->rad + G_mb.mainb[a]->expz;
- calc_mballco(mainb[a], vec);
+ calc_mballco(G_mb.mainb[a], vec);
size = fabsf(vec[0]);
if (size > totsize) totsize = size;
@@ -1849,11 +1853,11 @@ static float init_meta(Scene *scene, Object *ob) /* return totsize */
size = fabsf(vec[2]);
if (size > totsize) totsize = size;
- vec[0] = mainb[a]->x - mainb[a]->rad;
- vec[1] = mainb[a]->y - mainb[a]->rad;
- vec[2] = mainb[a]->z - mainb[a]->rad;
+ vec[0] = G_mb.mainb[a]->x - G_mb.mainb[a]->rad;
+ vec[1] = G_mb.mainb[a]->y - G_mb.mainb[a]->rad;
+ vec[2] = G_mb.mainb[a]->z - G_mb.mainb[a]->rad;
- calc_mballco(mainb[a], vec);
+ calc_mballco(G_mb.mainb[a], vec);
size = fabsf(vec[0]);
if (size > totsize) totsize = size;
@@ -1863,8 +1867,8 @@ static float init_meta(Scene *scene, Object *ob) /* return totsize */
if (size > totsize) totsize = size;
}
- for (a = 0; a < totelem; a++) {
- thresh += densfunc(mainb[a], 2.0f * totsize, 2.0f * totsize, 2.0f * totsize);
+ for (a = 0; a < G_mb.totelem; a++) {
+ G_mb.thresh += densfunc(G_mb.mainb[a], 2.0f * totsize, 2.0f * totsize, 2.0f * totsize);
}
return totsize;
@@ -1882,11 +1886,11 @@ static void fill_metaball_octal_node(octal_node *node, MetaElem *ml, short i)
BLI_addtail(&(node->nodes[i]->elems), ml_p);
node->count++;
- if (ml->flag & MB_NEGATIVE) {
- node->nodes[i]->neg++;
+ if ((ml->flag & MB_NEGATIVE) == 0) {
+ node->nodes[i]->pos++;
}
else {
- node->nodes[i]->pos++;
+ node->nodes[i]->neg++;
}
}
@@ -2034,7 +2038,7 @@ static void subdivide_metaball_octal_node(octal_node *node, float size_x, float
}
- /* ml belongs to the (4)5th node too */
+ /* ml belongs to the (4)5th node too */
if (ml->bb->vec[6][2] >= z) {
fill_metaball_octal_node(node, ml, 4);
}
@@ -2180,13 +2184,13 @@ static void init_metaball_octal_tree(int depth)
float size[3];
int a;
- metaball_tree = MEM_mallocN(sizeof(octal_tree), "metaball_octal_tree");
- metaball_tree->first = node = MEM_mallocN(sizeof(octal_node), "metaball_octal_node");
+ G_mb.metaball_tree = MEM_mallocN(sizeof(octal_tree), "metaball_octal_tree");
+ G_mb.metaball_tree->first = node = MEM_mallocN(sizeof(octal_node), "metaball_octal_node");
/* maximal depth of octree */
- metaball_tree->depth = depth;
+ G_mb.metaball_tree->depth = depth;
- metaball_tree->neg = node->neg = 0;
- metaball_tree->pos = node->pos = 0;
+ G_mb.metaball_tree->neg = node->neg = 0;
+ G_mb.metaball_tree->pos = node->pos = 0;
node->elems.first = NULL;
node->elems.last = NULL;
@@ -2199,36 +2203,36 @@ static void init_metaball_octal_tree(int depth)
node->x_max = node->y_max = node->z_max = -FLT_MAX;
/* size of octal tree scene */
- for (a = 0; a < totelem; a++) {
- if (mainb[a]->bb->vec[0][0] < node->x_min) node->x_min = mainb[a]->bb->vec[0][0];
- if (mainb[a]->bb->vec[0][1] < node->y_min) node->y_min = mainb[a]->bb->vec[0][1];
- if (mainb[a]->bb->vec[0][2] < node->z_min) node->z_min = mainb[a]->bb->vec[0][2];
+ for (a = 0; a < G_mb.totelem; a++) {
+ if (G_mb.mainb[a]->bb->vec[0][0] < node->x_min) node->x_min = G_mb.mainb[a]->bb->vec[0][0];
+ if (G_mb.mainb[a]->bb->vec[0][1] < node->y_min) node->y_min = G_mb.mainb[a]->bb->vec[0][1];
+ if (G_mb.mainb[a]->bb->vec[0][2] < node->z_min) node->z_min = G_mb.mainb[a]->bb->vec[0][2];
- if (mainb[a]->bb->vec[6][0] > node->x_max) node->x_max = mainb[a]->bb->vec[6][0];
- if (mainb[a]->bb->vec[6][1] > node->y_max) node->y_max = mainb[a]->bb->vec[6][1];
- if (mainb[a]->bb->vec[6][2] > node->z_max) node->z_max = mainb[a]->bb->vec[6][2];
+ if (G_mb.mainb[a]->bb->vec[6][0] > node->x_max) node->x_max = G_mb.mainb[a]->bb->vec[6][0];
+ if (G_mb.mainb[a]->bb->vec[6][1] > node->y_max) node->y_max = G_mb.mainb[a]->bb->vec[6][1];
+ if (G_mb.mainb[a]->bb->vec[6][2] > node->z_max) node->z_max = G_mb.mainb[a]->bb->vec[6][2];
ml_p = MEM_mallocN(sizeof(ml_pointer), "ml_pointer");
- ml_p->ml = mainb[a];
+ ml_p->ml = G_mb.mainb[a];
BLI_addtail(&node->elems, ml_p);
- if (mainb[a]->flag & MB_NEGATIVE) {
- /* number of negative MetaElem in scene */
- metaball_tree->neg++;
+ if ((G_mb.mainb[a]->flag & MB_NEGATIVE) == 0) {
+ /* number of positive MetaElem in scene */
+ G_mb.metaball_tree->pos++;
}
else {
- /* number of positive MetaElem in scene */
- metaball_tree->pos++;
+ /* number of negative MetaElem in scene */
+ G_mb.metaball_tree->neg++;
}
}
- /* size of first node */
+ /* size of first node */
size[0] = node->x_max - node->x_min;
size[1] = node->y_max - node->y_min;
size[2] = node->z_max - node->z_min;
/* first node is subdivided recursively */
- subdivide_metaball_octal_node(node, size[0], size[1], size[2], metaball_tree->depth);
+ subdivide_metaball_octal_node(node, size[0], size[1], size[2], G_mb.metaball_tree->depth);
}
void BKE_mball_polygonize(Scene *scene, Object *ob, ListBase *dispbase)
@@ -2241,48 +2245,48 @@ void BKE_mball_polygonize(Scene *scene, Object *ob, ListBase *dispbase)
mb = ob->data;
- if (totelem == 0) return;
+ if (G_mb.totelem == 0) return;
if ((G.is_rendering == FALSE) && (mb->flag == MB_UPDATE_NEVER)) return;
if (G.moving && mb->flag == MB_UPDATE_FAST) return;
curindex = totindex = 0;
indices = NULL;
- thresh = mb->thresh;
+ G_mb.thresh = mb->thresh;
/* total number of MetaElems (totelem) is precomputed in find_basis_mball() function */
- mainb = MEM_mallocN(sizeof(void *) * totelem, "mainb");
+ G_mb.mainb = MEM_mallocN(sizeof(void *) * G_mb.totelem, "mainb");
/* initialize all mainb (MetaElems) */
totsize = init_meta(scene, ob);
- if (metaball_tree) {
- free_metaball_octal_node(metaball_tree->first);
- MEM_freeN(metaball_tree);
- metaball_tree = NULL;
+ if (G_mb.metaball_tree) {
+ free_metaball_octal_node(G_mb.metaball_tree->first);
+ MEM_freeN(G_mb.metaball_tree);
+ G_mb.metaball_tree = NULL;
}
/* if scene includes more then one MetaElem, then octal tree optimization is used */
- if ((totelem > 1) && (totelem <= 64)) init_metaball_octal_tree(1);
- if ((totelem > 64) && (totelem <= 128)) init_metaball_octal_tree(2);
- if ((totelem > 128) && (totelem <= 512)) init_metaball_octal_tree(3);
- if ((totelem > 512) && (totelem <= 1024)) init_metaball_octal_tree(4);
- if (totelem > 1024) init_metaball_octal_tree(5);
+ if ((G_mb.totelem > 1) && (G_mb.totelem <= 64)) init_metaball_octal_tree(1);
+ if ((G_mb.totelem > 64) && (G_mb.totelem <= 128)) init_metaball_octal_tree(2);
+ if ((G_mb.totelem > 128) && (G_mb.totelem <= 512)) init_metaball_octal_tree(3);
+ if ((G_mb.totelem > 512) && (G_mb.totelem <= 1024)) init_metaball_octal_tree(4);
+ if (G_mb.totelem > 1024) init_metaball_octal_tree(5);
/* don't polygonize metaballs with too high resolution (base mball to small)
* note: Eps was 0.0001f but this was giving problems for blood animation for durian, using 0.00001f */
- if (metaball_tree) {
- if (ob->size[0] <= 0.00001f * (metaball_tree->first->x_max - metaball_tree->first->x_min) ||
- ob->size[1] <= 0.00001f * (metaball_tree->first->y_max - metaball_tree->first->y_min) ||
- ob->size[2] <= 0.00001f * (metaball_tree->first->z_max - metaball_tree->first->z_min))
+ if (G_mb.metaball_tree) {
+ if (ob->size[0] <= 0.00001f * (G_mb.metaball_tree->first->x_max - G_mb.metaball_tree->first->x_min) ||
+ ob->size[1] <= 0.00001f * (G_mb.metaball_tree->first->y_max - G_mb.metaball_tree->first->y_min) ||
+ ob->size[2] <= 0.00001f * (G_mb.metaball_tree->first->z_max - G_mb.metaball_tree->first->z_min))
{
new_pgn_element(-1); /* free values created by init_meta */
- MEM_freeN(mainb);
+ MEM_freeN(G_mb.mainb);
/* free tree */
- free_metaball_octal_node(metaball_tree->first);
- MEM_freeN(metaball_tree);
- metaball_tree = NULL;
+ free_metaball_octal_node(G_mb.metaball_tree->first);
+ MEM_freeN(G_mb.metaball_tree);
+ G_mb.metaball_tree = NULL;
return;
}
@@ -2306,13 +2310,13 @@ void BKE_mball_polygonize(Scene *scene, Object *ob, ListBase *dispbase)
polygonize(&mbproc, mb);
- MEM_freeN(mainb);
+ MEM_freeN(G_mb.mainb);
/* free octal tree */
- if (totelem > 1) {
- free_metaball_octal_node(metaball_tree->first);
- MEM_freeN(metaball_tree);
- metaball_tree = NULL;
+ if (G_mb.totelem > 1) {
+ free_metaball_octal_node(G_mb.metaball_tree->first);
+ MEM_freeN(G_mb.metaball_tree);
+ G_mb.metaball_tree = NULL;
}
if (curindex) {
@@ -2384,7 +2388,7 @@ int BKE_mball_center_bounds(MetaBall *mb, float r_cent[3])
return 0;
}
-void BKE_mball_translate(MetaBall *mb, float offset[3])
+void BKE_mball_translate(MetaBall *mb, const float offset[3])
{
MetaElem *ml;
@@ -2392,3 +2396,32 @@ void BKE_mball_translate(MetaBall *mb, float offset[3])
add_v3_v3(&ml->x, offset);
}
}
+
+/* *** select funcs *** */
+void BKE_mball_select_all(struct MetaBall *mb)
+{
+ MetaElem *ml;
+
+ for (ml = mb->editelems->first; ml; ml = ml->next) {
+ ml->flag |= SELECT;
+ }
+}
+
+void BKE_mball_deselect_all(MetaBall *mb)
+{
+ MetaElem *ml;
+
+ for (ml = mb->editelems->first; ml; ml = ml->next) {
+ ml->flag &= ~SELECT;
+ }
+}
+
+void BKE_mball_select_swap(struct MetaBall *mb)
+{
+ MetaElem *ml;
+
+ for (ml = mb->editelems->first; ml; ml = ml->next) {
+ ml->flag ^= SELECT;
+ }
+}
+
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index f5ae3c7da2b..1aaeebf5109 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -367,7 +367,6 @@ void mesh_update_customdata_pointers(Mesh *me, const short do_ensure_tess_cd)
me->mvert = CustomData_get_layer(&me->vdata, CD_MVERT);
me->dvert = CustomData_get_layer(&me->vdata, CD_MDEFORMVERT);
- me->msticky = CustomData_get_layer(&me->vdata, CD_MSTICKY);
me->medge = CustomData_get_layer(&me->edata, CD_MEDGE);
@@ -789,7 +788,7 @@ int test_index_face(MFace *mface, CustomData *fdata, int mfindex, int nr)
nr--;
}
- /* check corrupt cases, bowtie geometry, cant handle these because edge data wont exist so just return 0 */
+ /* check corrupt cases, bow-tie geometry, cant handle these because edge data wont exist so just return 0 */
if (nr == 3) {
if (
/* real edges */
@@ -1865,7 +1864,7 @@ void BKE_mesh_calc_normals_mapping_ex(MVert *mverts, int numVerts,
/* only calc poly normals */
mp = mpolys;
for (i = 0; i < numPolys; i++, mp++) {
- mesh_calc_poly_normal(mp, mloop + mp->loopstart, mverts, pnors[i]);
+ BKE_mesh_calc_poly_normal(mp, mloop + mp->loopstart, mverts, pnors[i]);
}
}
@@ -1915,7 +1914,7 @@ void BKE_mesh_calc_normals(MVert *mverts, int numVerts, MLoop *mloop, MPoly *mpo
mp = mpolys;
for (i = 0; i < numPolys; i++, mp++) {
- mesh_calc_poly_normal(mp, mloop + mp->loopstart, mverts, pnors[i]);
+ BKE_mesh_calc_poly_normal(mp, mloop + mp->loopstart, mverts, pnors[i]);
ml = mloop + mp->loopstart;
BLI_array_empty(vertcos);
@@ -1944,8 +1943,9 @@ void BKE_mesh_calc_normals(MVert *mverts, int numVerts, MLoop *mloop, MPoly *mpo
MVert *mv = &mverts[i];
float *no = tnorms[i];
- if (normalize_v3(no) == 0.0f)
+ if (UNLIKELY(normalize_v3(no) == 0.0f)) {
normalize_v3_v3(no, mv->co);
+ }
normal_float_to_short_v3(mv->no, no);
}
@@ -1981,8 +1981,9 @@ void BKE_mesh_calc_normals_tessface(MVert *mverts, int numVerts, MFace *mfaces,
MVert *mv = &mverts[i];
float *no = tnorms[i];
- if (normalize_v3(no) == 0.0f)
+ if (UNLIKELY(normalize_v3(no) == 0.0f)) {
normalize_v3_v3(no, mv->co);
+ }
normal_float_to_short_v3(mv->no, no);
}
@@ -2042,7 +2043,7 @@ static void bm_corners_to_loops_ex(ID *id, CustomData *fdata, CustomData *ldata,
int side, corners;
if (CustomData_external_test(fdata, CD_MDISPS)) {
- if (id) {
+ if (id && fdata->external) {
CustomData_external_add(ldata, id, CD_MDISPS,
totloop, fdata->external->filename);
}
@@ -2702,13 +2703,13 @@ int BKE_mesh_recalc_tessellation(CustomData *fdata,
#endif
{
/* sort loop indices to ensure winding is correct */
- if (mf->v1 > mf->v2) SWAP(int, mf->v1, mf->v2);
- if (mf->v2 > mf->v3) SWAP(int, mf->v2, mf->v3);
- if (mf->v1 > mf->v2) SWAP(int, mf->v1, mf->v2);
+ if (mf->v1 > mf->v2) SWAP(unsigned int, mf->v1, mf->v2);
+ if (mf->v2 > mf->v3) SWAP(unsigned int, mf->v2, mf->v3);
+ if (mf->v1 > mf->v2) SWAP(unsigned int, mf->v1, mf->v2);
- if (mf->v1 > mf->v2) SWAP(int, mf->v1, mf->v2);
- if (mf->v2 > mf->v3) SWAP(int, mf->v2, mf->v3);
- if (mf->v1 > mf->v2) SWAP(int, mf->v1, mf->v2);
+ if (mf->v1 > mf->v2) SWAP(unsigned int, mf->v1, mf->v2);
+ if (mf->v2 > mf->v3) SWAP(unsigned int, mf->v2, mf->v3);
+ if (mf->v1 > mf->v2) SWAP(unsigned int, mf->v1, mf->v2);
}
/* end abusing the edcode */
@@ -2899,8 +2900,8 @@ static void mesh_calc_ngon_normal(MPoly *mpoly, MLoop *loopstart,
}
}
-void mesh_calc_poly_normal(MPoly *mpoly, MLoop *loopstart,
- MVert *mvarray, float no[3])
+void BKE_mesh_calc_poly_normal(MPoly *mpoly, MLoop *loopstart,
+ MVert *mvarray, float no[3])
{
if (mpoly->totloop > 4) {
mesh_calc_ngon_normal(mpoly, loopstart, mvarray, no);
@@ -3015,7 +3016,7 @@ void BKE_mesh_calc_poly_center(MPoly *mpoly, MLoop *loopstart,
/* note, passing polynormal is only a speedup so we can skip calculating it */
float BKE_mesh_calc_poly_area(MPoly *mpoly, MLoop *loopstart,
- MVert *mvarray, float polynormal[3])
+ MVert *mvarray, const float polynormal[3])
{
if (mpoly->totloop == 3) {
return area_tri_v3(mvarray[loopstart[0].v].co,
@@ -3034,7 +3035,7 @@ float BKE_mesh_calc_poly_area(MPoly *mpoly, MLoop *loopstart,
int i;
MLoop *l_iter = loopstart;
float area, polynorm_local[3], (*vertexcos)[3];
- float *no = polynormal ? polynormal : polynorm_local;
+ const float *no = polynormal ? polynormal : polynorm_local;
BLI_array_fixedstack_declare(vertexcos, BM_NGON_STACK_SIZE, mpoly->totloop, __func__);
/* pack vertex cos into an array for area_poly_v3 */
@@ -3044,7 +3045,7 @@ float BKE_mesh_calc_poly_area(MPoly *mpoly, MLoop *loopstart,
/* need normal for area_poly_v3 as well */
if (polynormal == NULL) {
- mesh_calc_poly_normal(mpoly, loopstart, mvarray, no);
+ BKE_mesh_calc_poly_normal(mpoly, loopstart, mvarray, polynorm_local);
}
/* finally calculate the area */
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 65538e5bea2..28de80a7157 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -482,7 +482,7 @@ ModifierData *modifiers_getVirtualModifierList(Object *ob)
}
/* shape key modifier, not yet for curves */
- if (ELEM(ob->type, OB_MESH, OB_LATTICE) && ob_get_key(ob)) {
+ if (ELEM(ob->type, OB_MESH, OB_LATTICE) && BKE_key_from_object(ob)) {
if (ob->type == OB_MESH && (ob->shapeflag & OB_SHAPE_EDIT_MODE))
smd.modifier.mode |= eModifierMode_Editmode | eModifierMode_OnCage;
else
diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c
index 72c3cda9272..dc3d4a89e62 100644
--- a/source/blender/blenkernel/intern/modifiers_bmesh.c
+++ b/source/blender/blenkernel/intern/modifiers_bmesh.c
@@ -49,7 +49,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm)
MLoop *mloop, *ml;
BMVert *v, **vtable, **verts = NULL;
BMEdge *e, **etable, **edges = NULL;
- float has_face_normals;
+ float (*face_normals)[3];
BMFace *f;
BMIter liter;
BLI_array_declare(verts);
@@ -72,8 +72,8 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm)
BM_data_layer_add(bm, &bm->edata, CD_BWEIGHT);
BM_data_layer_add(bm, &bm->vdata, CD_BWEIGHT);
- vtable = MEM_callocN(sizeof(void **) * totvert, "vert table in BMDM_Copy");
- etable = MEM_callocN(sizeof(void **) * totedge, "edge table in BMDM_Copy");
+ vtable = MEM_callocN(sizeof(void **) * totvert, __func__);
+ etable = MEM_callocN(sizeof(void **) * totedge, __func__);
/*do verts*/
mv = mvert = dm->dupVertArray(dm);
@@ -110,7 +110,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm)
/*do faces*/
mp = dm->getPolyArray(dm);
mloop = dm->getLoopArray(dm);
- has_face_normals = CustomData_has_layer(&dm->polyData, CD_NORMAL);
+ face_normals = CustomData_get_layer(&dm->polyData, CD_NORMAL); /* can be NULL */
for (i = 0; i < dm->numPolyData; i++, mp++) {
BMLoop *l;
@@ -129,8 +129,9 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm)
f = BM_face_create_ngon(bm, verts[0], verts[1], edges, mp->totloop, FALSE);
- if (!f)
+ if (UNLIKELY(f == NULL)) {
continue;
+ }
f->head.hflag = BM_face_flag_from_mflag(mp->flag);
f->mat_nr = mp->mat_nr;
@@ -143,11 +144,11 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm)
CustomData_to_bmesh_block(&dm->polyData, &bm->pdata, i, &f->head.data);
- if (has_face_normals) {
- float *fno;
-
- fno = CustomData_bmesh_get(&bm->pdata, &f->head.data, CD_NORMAL);
- copy_v3_v3(f->no, fno);
+ if (face_normals) {
+ copy_v3_v3(f->no, face_normals[i]);
+ }
+ else {
+ BM_face_normal_update(f);
}
}
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
index 4c23a370a5d..0aa1f9e0822 100644
--- a/source/blender/blenkernel/intern/movieclip.c
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -52,6 +52,7 @@
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
#include "DNA_movieclip_types.h"
+#include "DNA_node_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_view3d_types.h"
@@ -66,14 +67,16 @@
#include "BKE_animsys.h"
#include "BKE_constraint.h"
+#include "BKE_colortools.h"
#include "BKE_library.h"
#include "BKE_global.h"
#include "BKE_main.h"
-#include "BKE_utildefines.h"
#include "BKE_movieclip.h"
+#include "BKE_node.h"
#include "BKE_image.h" /* openanim */
#include "BKE_tracking.h"
+#include "IMB_colormanagement.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
#include "IMB_moviecache.h"
@@ -198,19 +201,25 @@ static ImBuf *movieclip_load_sequence_file(MovieClip *clip, MovieClipUser *user,
struct ImBuf *ibuf;
char name[FILE_MAX];
int loadflag, use_proxy = FALSE;
+ char *colorspace;
use_proxy = (flag & MCLIP_USE_PROXY) && user->render_size != MCLIP_PROXY_RENDER_SIZE_FULL;
if (use_proxy) {
int undistort = user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT;
get_proxy_fname(clip, user->render_size, undistort, framenr, name);
+
+ /* proxies were built using default color space settings */
+ colorspace = NULL;
}
- else
+ else {
get_sequence_fname(clip, framenr, name);
+ colorspace = clip->colorspace_settings.name;
+ }
loadflag = IB_rect | IB_multilayer;
/* read ibuf */
- ibuf = IMB_loadiffname(name, loadflag);
+ ibuf = IMB_loadiffname(name, loadflag, colorspace);
return ibuf;
}
@@ -224,7 +233,7 @@ static void movieclip_open_anim_file(MovieClip *clip)
BLI_path_abs(str, ID_BLEND_PATH(G.main, &clip->id));
/* FIXME: make several stream accessible in image editor, too */
- clip->anim = openanim(str, IB_rect, 0);
+ clip->anim = openanim(str, IB_rect, 0, clip->colorspace_settings.name);
if (clip->anim) {
if (clip->flag & MCLIP_USE_PROXY_CUSTOM_DIR) {
@@ -285,11 +294,11 @@ static void movieclip_calc_length(MovieClip *clip)
clip->len = framenr + 1;
}
else {
- for (;; ) {
+ for (;;) {
get_sequence_fname(clip, framenr, name);
if (!BLI_exists(name)) {
- clip->len = framenr + 1;
+ clip->len = framenr;
break;
}
@@ -384,7 +393,7 @@ static int moviecache_hashcmp(const void *av, const void *bv)
return 0;
}
-void *moviecache_getprioritydata(void *key_v)
+static void *moviecache_getprioritydata(void *key_v)
{
MovieClipImBufCacheKey *key = (MovieClipImBufCacheKey *) key_v;
MovieClipCachePriorityData *priority_data;
@@ -395,7 +404,7 @@ void *moviecache_getprioritydata(void *key_v)
return priority_data;
}
-int moviecache_getitempriority(void *last_userkey_v, void *priority_data_v)
+static int moviecache_getitempriority(void *last_userkey_v, void *priority_data_v)
{
MovieClipImBufCacheKey *last_userkey = (MovieClipImBufCacheKey *) last_userkey_v;
MovieClipCachePriorityData *priority_data = (MovieClipCachePriorityData *) priority_data_v;
@@ -403,7 +412,7 @@ int moviecache_getitempriority(void *last_userkey_v, void *priority_data_v)
return -abs(last_userkey->framenr - priority_data->framenr);
}
-void moviecache_prioritydeleter(void *priority_data_v)
+static void moviecache_prioritydeleter(void *priority_data_v)
{
MovieClipCachePriorityData *priority_data = (MovieClipCachePriorityData *) priority_data_v;
@@ -479,6 +488,7 @@ static MovieClip *movieclip_alloc(const char *name)
clip->aspx = clip->aspy = 1.0f;
BKE_tracking_settings_init(&clip->tracking);
+ BKE_color_managed_colorspace_settings_init(&clip->colorspace_settings);
clip->proxy.build_size_flag = IMB_PROXY_25;
clip->proxy.build_tc_flag = IMB_TC_RECORD_RUN |
@@ -616,24 +626,22 @@ static ImBuf *get_undistorted_ibuf(MovieClip *clip, struct MovieDistortion *dist
return undistibuf;
}
-static int need_undistortion_postprocess(MovieClipUser *user, int flag)
+static int need_undistortion_postprocess(MovieClipUser *user)
{
int result = 0;
/* only full undistorted render can be used as on-fly undistorting image */
- if (flag & MCLIP_USE_PROXY) {
- result |= (user->render_size == MCLIP_PROXY_RENDER_SIZE_FULL) &&
- (user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT) != 0;
- }
+ result |= (user->render_size == MCLIP_PROXY_RENDER_SIZE_FULL) &&
+ (user->render_flag & MCLIP_PROXY_RENDER_UNDISTORT) != 0;
return result;
}
-static int need_postprocessed_frame(MovieClipUser *user, int flag, int postprocess_flag)
+static int need_postprocessed_frame(MovieClipUser *user, int postprocess_flag)
{
int result = postprocess_flag;
- result |= need_undistortion_postprocess(user, flag);
+ result |= need_undistortion_postprocess(user);
return result;
}
@@ -680,7 +688,7 @@ static ImBuf *get_postprocessed_cached_frame(MovieClip *clip, MovieClipUser *use
if (cache->postprocessed.flag != postprocess_flag)
return NULL;
- if (need_undistortion_postprocess(user, flag)) {
+ if (need_undistortion_postprocess(user)) {
if (!check_undistortion_cache_flags(clip))
return NULL;
}
@@ -711,7 +719,7 @@ static ImBuf *put_postprocessed_frame_to_cache(MovieClip *clip, MovieClipUser *u
cache->postprocessed.render_flag = 0;
}
- if (need_undistortion_postprocess(user, flag)) {
+ if (need_undistortion_postprocess(user)) {
copy_v2_v2(cache->postprocessed.principal, camera->principal);
copy_v3_v3(&cache->postprocessed.k1, &camera->k1);
cache->postprocessed.undistortion_used = TRUE;
@@ -755,7 +763,7 @@ static ImBuf *movieclip_get_postprocessed_ibuf(MovieClip *clip, MovieClipUser *u
BLI_lock_thread(LOCK_MOVIECLIP);
/* try to obtain cached postprocessed frame first */
- if (need_postprocessed_frame(user, flag, postprocess_flag)) {
+ if (need_postprocessed_frame(user, postprocess_flag)) {
ibuf = get_postprocessed_cached_frame(clip, user, flag, postprocess_flag);
if (!ibuf)
@@ -1002,6 +1010,14 @@ void BKE_movieclip_get_size(MovieClip *clip, MovieClipUser *user, int *width, in
IMB_freeImBuf(ibuf);
}
}
+void BKE_movieclip_get_size_fl(MovieClip *clip, MovieClipUser *user, float size[2])
+{
+ int width, height;
+ BKE_movieclip_get_size(clip, user, &width, &height);
+
+ size[0] = (float)width;
+ size[1] = (float)height;
+}
int BKE_movieclip_get_duration(MovieClip *clip)
{
@@ -1012,9 +1028,9 @@ int BKE_movieclip_get_duration(MovieClip *clip)
return clip->len;
}
-void BKE_movieclip_aspect(MovieClip *clip, float *aspx, float *aspy)
+void BKE_movieclip_get_aspect(MovieClip *clip, float *aspx, float *aspy)
{
- *aspx = *aspy = 1.0;
+ *aspx = 1.0;
/* x is always 1 */
*aspy = clip->aspy / clip->aspx / clip->tracking.camera.pixel_aspect;
@@ -1310,6 +1326,11 @@ void BKE_movieclip_unlink(Main *bmain, MovieClip *clip)
}
}
+ {
+ bNodeTreeType *treetype = ntreeGetType(NTREE_COMPOSIT);
+ treetype->foreach_nodetree(bmain, (void *)clip, &BKE_node_tree_unlink_id_cb);
+ }
+
clip->id.us = 0;
}
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index 1c06d95a70b..591524e5156 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -666,7 +666,9 @@ static void multires_del_higher(MultiresModifierData *mmd, Object *ob, int lvl)
mdisp->totdisp = totdisp;
mdisp->level = lvl;
- multires_grid_paint_mask_downsample(&gpm[g], lvl);
+ if (gpm) {
+ multires_grid_paint_mask_downsample(&gpm[g], lvl);
+ }
}
}
}
@@ -893,15 +895,16 @@ static void multires_subdivide(MultiresModifierData *mmd, Object *ob, int totlvl
CCGKey highGridKey, lowGridKey;
CCGSubSurf *ss;
int i, numGrids, highGridSize;
+ int has_mask = CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK);
/* create subsurf DM from original mesh at high level */
cddm = CDDM_from_mesh(me, NULL);
DM_set_only_copy(cddm, CD_MASK_BAREMESH);
- highdm = subsurf_dm_create_local(ob, cddm, totlvl, simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, TRUE);
+ highdm = subsurf_dm_create_local(ob, cddm, totlvl, simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, has_mask);
ss = ((CCGDerivedMesh *)highdm)->ss;
/* create multires DM from original mesh at low level */
- lowdm = multires_dm_create_local(ob, cddm, lvl, lvl, simple, TRUE);
+ lowdm = multires_dm_create_local(ob, cddm, lvl, lvl, simple, has_mask);
cddm->release(cddm);
/* copy subsurf grids and replace them with low displaced grids */
@@ -1164,17 +1167,18 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm)
CCGKey highGridKey, lowGridKey;
CCGSubSurf *ss;
int i, j, numGrids, highGridSize, lowGridSize;
+ int has_mask = CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK);
/* create subsurf DM from original mesh at high level */
if (ob->derivedDeform) cddm = CDDM_copy(ob->derivedDeform);
else cddm = CDDM_from_mesh(me, NULL);
DM_set_only_copy(cddm, CD_MASK_BAREMESH);
- highdm = subsurf_dm_create_local(ob, cddm, totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, TRUE);
+ highdm = subsurf_dm_create_local(ob, cddm, totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, has_mask);
ss = ((CCGDerivedMesh *)highdm)->ss;
/* create multires DM from original mesh and displacements */
- lowdm = multires_dm_create_local(ob, cddm, lvl, totlvl, mmd->simple, TRUE);
+ lowdm = multires_dm_create_local(ob, cddm, lvl, totlvl, mmd->simple, has_mask);
cddm->release(cddm);
/* gather grid data */
@@ -1226,12 +1230,13 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm)
}
else {
DerivedMesh *cddm, *subdm;
+ int has_mask = CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK);
if (ob->derivedDeform) cddm = CDDM_copy(ob->derivedDeform);
else cddm = CDDM_from_mesh(me, NULL);
DM_set_only_copy(cddm, CD_MASK_BAREMESH);
- subdm = subsurf_dm_create_local(ob, cddm, mmd->totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, TRUE);
+ subdm = subsurf_dm_create_local(ob, cddm, mmd->totlvl, mmd->simple, 0, mmd->flags & eMultiresModifierFlag_PlainUv, has_mask);
cddm->release(cddm);
multiresModifier_disp_run(dm, me, NULL, CALC_DISPLACEMENTS, subdm->getGridData(subdm), mmd->totlvl);
@@ -2107,7 +2112,7 @@ void multires_load_old(Object *ob, Mesh *me)
* reference subsurfed dm with this option, before calling multiresModifier_disp_run(),
* which implicitly expects both subsurfs from its first dm and oldGridData parameters to
* be of the same "format"! */
- dm = multires_make_derived_from_derived(orig, mmd, ob, MULTIRES_ALLOC_PAINT_MASK);
+ dm = multires_make_derived_from_derived(orig, mmd, ob, 0);
multires_load_old_dm(dm, me, mmd->totlvl + 1);
diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c
index d62b03b5060..9590160c8f3 100644
--- a/source/blender/blenkernel/intern/nla.c
+++ b/source/blender/blenkernel/intern/nla.c
@@ -764,7 +764,7 @@ void BKE_nlastrips_clear_metas(ListBase *strips, short onlySel, short onlyTemp)
}
/* Add the given NLA-Strip to the given Meta-Strip, assuming that the
- * strip isn't attached to anyy list of strips
+ * strip isn't attached to any list of strips
*/
short BKE_nlameta_add_strip(NlaStrip *mstrip, NlaStrip *strip)
{
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 62e80645a35..8cede4f51a5 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -58,8 +58,6 @@
#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_node.h"
-#include "BKE_utildefines.h"
-#include "BKE_utildefines.h"
#include "RNA_access.h"
@@ -671,7 +669,7 @@ bNodeTree *ntreeAddTree(const char *name, int type, int nodetype)
* copying for internal use (threads for eg), where you wont want it to modify the
* scene data.
*/
-static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, const short do_make_extern)
+static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, const short do_id_user, const short do_make_extern)
{
bNodeTree *newtree;
bNode *node /*, *nnode */ /* UNUSED */, *last;
@@ -702,6 +700,11 @@ static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, const short do_make_e
last = ntree->nodes.last;
for (node = ntree->nodes.first; node; node = node->next) {
+ /* ntreeUserDecrefID inline */
+ if (do_id_user) {
+ id_us_plus(node->id);
+ }
+
if (do_make_extern) {
id_lib_extern(node->id);
}
@@ -751,22 +754,56 @@ static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, const short do_make_e
return newtree;
}
+bNodeTree *ntreeCopyTree_ex(bNodeTree *ntree, const short do_id_user)
+{
+ return ntreeCopyTree_internal(ntree, do_id_user, TRUE);
+}
bNodeTree *ntreeCopyTree(bNodeTree *ntree)
{
- return ntreeCopyTree_internal(ntree, TRUE);
+ return ntreeCopyTree_ex(ntree, TRUE);
}
/* use when duplicating scenes */
-void ntreeSwitchID(bNodeTree *ntree, ID *id_from, ID *id_to)
+void ntreeSwitchID_ex(bNodeTree *ntree, ID *id_from, ID *id_to, const short do_id_user)
{
bNode *node;
+
+ if (id_from == id_to) {
+ /* should never happen but may as well skip if it does */
+ return;
+ }
+
/* for scene duplication only */
for (node = ntree->nodes.first; node; node = node->next) {
if (node->id == id_from) {
+ if (do_id_user) {
+ id_us_min(id_from);
+ id_us_plus(id_to);
+ }
+
node->id = id_to;
}
}
}
+void ntreeSwitchID(bNodeTree *ntree, ID *id_from, ID *id_to)
+{
+ ntreeSwitchID_ex(ntree, id_from, id_to, TRUE);
+}
+
+void ntreeUserIncrefID(bNodeTree *ntree)
+{
+ bNode *node;
+ for (node = ntree->nodes.first; node; node = node->next) {
+ id_us_plus(node->id);
+ }
+}
+void ntreeUserDecrefID(bNodeTree *ntree)
+{
+ bNode *node;
+ for (node = ntree->nodes.first; node; node = node->next) {
+ id_us_min(node->id);
+ }
+}
/* *************** preview *********** */
/* if node->preview, then we assume the rect to exist */
@@ -913,6 +950,7 @@ static void node_unlink_attached(bNodeTree *ntree, bNode *parent)
}
}
+/** \note caller needs to manage node->id user */
void nodeFreeNode(bNodeTree *ntree, bNode *node)
{
bNodeSocket *sock, *nextsock;
@@ -956,7 +994,7 @@ void nodeFreeNode(bNodeTree *ntree, bNode *node)
}
/* do not free ntree itself here, BKE_libblock_free calls this function too */
-void ntreeFreeTree(bNodeTree *ntree)
+void ntreeFreeTree_ex(bNodeTree *ntree, const short do_id_user)
{
bNode *node, *next;
bNodeSocket *sock;
@@ -990,6 +1028,21 @@ void ntreeFreeTree(bNodeTree *ntree)
for (node = ntree->nodes.first; node; node = next) {
next = node->next;
+
+ /* ntreeUserIncrefID inline */
+
+ /* XXX, this is correct, however when freeing the entire database
+ * this ends up accessing freed data which isn't properly unlinking
+ * its self from scene nodes, SO - for now prefer invalid usercounts
+ * on free rather then bad memory access - Campbell */
+#if 0
+ if (do_id_user) {
+ id_us_min(node->id);
+ }
+#else
+ (void)do_id_user;
+#endif
+
nodeFreeNode(ntree, node);
}
@@ -1000,6 +1053,11 @@ void ntreeFreeTree(bNodeTree *ntree)
node_socket_free_default_value(sock->type, sock->default_value);
BLI_freelistN(&ntree->outputs);
}
+/* same as ntreeFreeTree_ex but always manage users */
+void ntreeFreeTree(bNodeTree *ntree)
+{
+ ntreeFreeTree_ex(ntree, TRUE);
+}
void ntreeFreeCache(bNodeTree *ntree)
{
@@ -1188,7 +1246,7 @@ bNodeTree *ntreeLocalize(bNodeTree *ntree)
}
/* node copy func */
- ltree = ntreeCopyTree_internal(ntree, FALSE);
+ ltree = ntreeCopyTree_internal(ntree, FALSE, FALSE);
if (adt) {
AnimData *ladt = BKE_animdata_from_id(&ltree->id);
@@ -1248,7 +1306,7 @@ void ntreeLocalMerge(bNodeTree *localtree, bNodeTree *ntree)
if (ntreetype->local_merge)
ntreetype->local_merge(localtree, ntree);
- ntreeFreeTree(localtree);
+ ntreeFreeTree_ex(localtree, FALSE);
MEM_freeN(localtree);
}
@@ -1433,13 +1491,13 @@ void nodeSocketSetType(bNodeSocket *sock, int type)
* otherwise we may reference missing data.
*
* Currently its only used for ID's, but nodes may one day
- * referene other pointers which need validation.
+ * reference other pointers which need validation.
*/
typedef struct bNodeClipboardExtraInfo {
- struct bNodeClipboardExtraInfo *next, *prev;
+ struct bNodeClipboardExtraInfo *next, *prev;
ID *id;
- char id_name[MAX_ID_NAME];
- char library_name[FILE_MAX];
+ char id_name[MAX_ID_NAME];
+ char library_name[FILE_MAX];
} bNodeClipboardExtraInfo;
#endif /* USE_NODE_CB_VALIDATE */
@@ -1448,7 +1506,7 @@ typedef struct bNodeClipboard {
ListBase nodes;
#ifdef USE_NODE_CB_VALIDATE
- ListBase nodes_extra_info;
+ ListBase nodes_extra_info;
#endif
ListBase links;
@@ -1480,7 +1538,7 @@ void BKE_node_clipboard_clear(void)
node_clipboard.nodes.first = node_clipboard.nodes.last = NULL;
#ifdef USE_NODE_CB_VALIDATE
- BLI_freelistN(&node_clipboard.nodes_extra_info);
+ BLI_freelistN(&node_clipboard.nodes_extra_info);
#endif
}
@@ -1531,28 +1589,28 @@ int BKE_node_clipboard_validate(void)
void BKE_node_clipboard_add_node(bNode *node)
{
#ifdef USE_NODE_CB_VALIDATE
- /* add extra info */
- bNodeClipboardExtraInfo *node_info = MEM_mallocN(sizeof(bNodeClipboardExtraInfo), STRINGIFY(bNodeClipboardExtraInfo));
+ /* add extra info */
+ bNodeClipboardExtraInfo *node_info = MEM_mallocN(sizeof(bNodeClipboardExtraInfo), STRINGIFY(bNodeClipboardExtraInfo));
node_info->id = node->id;
- if (node->id) {
- BLI_strncpy(node_info->id_name, node->id->name, sizeof(node_info->id_name));
- if (node->id->lib) {
- BLI_strncpy(node_info->library_name, node->id->lib->filepath, sizeof(node_info->library_name));
- }
- else {
- node_info->library_name[0] = '\0';
- }
- }
- else {
- node_info->id_name[0] = '\0';
- node_info->library_name[0] = '\0';
- }
- BLI_addtail(&node_clipboard.nodes_extra_info, node_info);
+ if (node->id) {
+ BLI_strncpy(node_info->id_name, node->id->name, sizeof(node_info->id_name));
+ if (node->id->lib) {
+ BLI_strncpy(node_info->library_name, node->id->lib->filepath, sizeof(node_info->library_name));
+ }
+ else {
+ node_info->library_name[0] = '\0';
+ }
+ }
+ else {
+ node_info->id_name[0] = '\0';
+ node_info->library_name[0] = '\0';
+ }
+ BLI_addtail(&node_clipboard.nodes_extra_info, node_info);
/* end extra info */
#endif /* USE_NODE_CB_VALIDATE */
- /* add node */
+ /* add node */
BLI_addtail(&node_clipboard.nodes, node);
}
@@ -2088,6 +2146,7 @@ static void registerCompositNodes(bNodeTreeType *ttype)
register_node_type_cmp_vecblur(ttype);
register_node_type_cmp_dilateerode(ttype);
register_node_type_cmp_inpaint(ttype);
+ register_node_type_cmp_despeckle(ttype);
register_node_type_cmp_defocus(ttype);
register_node_type_cmp_valtorgb(ttype);
@@ -2213,6 +2272,7 @@ static void registerShaderNodes(bNodeTreeType *ttype)
register_node_type_sh_tex_gradient(ttype);
register_node_type_sh_tex_magic(ttype);
register_node_type_sh_tex_checker(ttype);
+ register_node_type_sh_tex_brick(ttype);
}
static void registerTextureNodes(bNodeTreeType *ttype)
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 0fd3804f63a..f72372742d0 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -305,17 +305,27 @@ void BKE_object_free(Object *ob)
ID *id = ob->data;
id->us--;
if (id->us == 0) {
- if (ob->type == OB_MESH) BKE_mesh_unlink(ob->data);
- else if (ob->type == OB_CURVE) BKE_curve_unlink(ob->data);
- else if (ob->type == OB_MBALL) BKE_mball_unlink(ob->data);
+ switch (ob->type) {
+ case OB_MESH:
+ BKE_mesh_unlink((Mesh *)id);
+ break;
+ case OB_CURVE:
+ BKE_curve_unlink((Curve *)id);
+ break;
+ case OB_MBALL:
+ BKE_mball_unlink((MetaBall *)id);
+ break;
+ }
}
ob->data = NULL;
}
-
- for (a = 0; a < ob->totcol; a++) {
- if (ob->mat[a]) ob->mat[a]->id.us--;
+
+ if (ob->mat) {
+ for (a = 0; a < ob->totcol; a++) {
+ if (ob->mat[a]) ob->mat[a]->id.us--;
+ }
+ MEM_freeN(ob->mat);
}
- if (ob->mat) MEM_freeN(ob->mat);
if (ob->matbits) MEM_freeN(ob->matbits);
ob->mat = NULL;
ob->matbits = NULL;
@@ -330,7 +340,7 @@ void BKE_object_free(Object *ob)
BKE_pose_free(ob->pose);
if (ob->mpath)
animviz_free_motionpath(ob->mpath);
- free_properties(&ob->prop);
+ BKE_bproperty_free_list(&ob->prop);
BKE_object_free_modifiers(ob);
free_sensors(&ob->sensors);
@@ -879,23 +889,44 @@ Object *BKE_object_add(struct Scene *scene, int type)
return ob;
}
-SoftBody *copy_softbody(SoftBody *sb)
+SoftBody *copy_softbody(SoftBody *sb, int copy_caches)
{
SoftBody *sbn;
if (sb == NULL) return(NULL);
sbn = MEM_dupallocN(sb);
- sbn->totspring = sbn->totpoint = 0;
- sbn->bpoint = NULL;
- sbn->bspring = NULL;
+
+ if (copy_caches == FALSE) {
+ sbn->totspring = sbn->totpoint = 0;
+ sbn->bpoint = NULL;
+ sbn->bspring = NULL;
+ }
+ else {
+ sbn->totspring = sb->totspring;
+ sbn->totpoint = sb->totpoint;
+
+ if (sbn->bpoint) {
+ int i;
+
+ sbn->bpoint = MEM_dupallocN(sbn->bpoint);
+
+ for (i = 0; i < sbn->totpoint; i++) {
+ if (sbn->bpoint[i].springs)
+ sbn->bpoint[i].springs = MEM_dupallocN(sbn->bpoint[i].springs);
+ }
+ }
+
+ if (sb->bspring)
+ sbn->bspring = MEM_dupallocN(sb->bspring);
+ }
sbn->keys = NULL;
sbn->totkey = sbn->totpointkey = 0;
sbn->scratch = NULL;
- sbn->pointcache = BKE_ptcache_copy_list(&sbn->ptcaches, &sb->ptcaches);
+ sbn->pointcache = BKE_ptcache_copy_list(&sbn->ptcaches, &sb->ptcaches, copy_caches);
if (sb->effector_weights)
sbn->effector_weights = MEM_dupallocN(sb->effector_weights);
@@ -968,7 +999,7 @@ static ParticleSystem *copy_particlesystem(ParticleSystem *psys)
psysn->childcachebufs.first = psysn->childcachebufs.last = NULL;
psysn->renderdata = NULL;
- psysn->pointcache = BKE_ptcache_copy_list(&psysn->ptcaches, &psys->ptcaches);
+ psysn->pointcache = BKE_ptcache_copy_list(&psysn->ptcaches, &psys->ptcaches, FALSE);
/* XXX - from reading existing code this seems correct but intended usage of
* pointcache should /w cloth should be added in 'ParticleSystem' - campbell */
@@ -1029,7 +1060,7 @@ void BKE_object_copy_particlesystems(Object *obn, Object *ob)
void BKE_object_copy_softbody(Object *obn, Object *ob)
{
if (ob->soft)
- obn->soft = copy_softbody(ob->soft);
+ obn->soft = copy_softbody(ob->soft, FALSE);
}
static void copy_object_pose(Object *obn, Object *ob)
@@ -1069,12 +1100,12 @@ static void copy_object_pose(Object *obn, Object *ob)
}
}
-static int object_pose_context(Object *ob)
+int BKE_object_pose_context_check(Object *ob)
{
- if ( (ob) &&
- (ob->type == OB_ARMATURE) &&
- (ob->pose) &&
- (ob->mode & OB_MODE_POSE))
+ if ((ob) &&
+ (ob->type == OB_ARMATURE) &&
+ (ob->pose) &&
+ (ob->mode & OB_MODE_POSE))
{
return 1;
}
@@ -1088,12 +1119,12 @@ Object *BKE_object_pose_armature_get(Object *ob)
if (ob == NULL)
return NULL;
- if (object_pose_context(ob))
+ if (BKE_object_pose_context_check(ob))
return ob;
ob = modifiers_isDeformedByArmature(ob);
- if (object_pose_context(ob))
+ if (BKE_object_pose_context_check(ob))
return ob;
return NULL;
@@ -1110,7 +1141,7 @@ void BKE_object_transform_copy(Object *ob_tar, const Object *ob_src)
copy_v3_v3(ob_tar->size, ob_src->size);
}
-Object *BKE_object_copy(Object *ob)
+static Object *object_copy_do(Object *ob, int copy_caches)
{
Object *obn;
ModifierData *md;
@@ -1137,7 +1168,7 @@ Object *BKE_object_copy(Object *ob)
}
obn->prop.first = obn->prop.last = NULL;
- copy_properties(&obn->prop, &ob->prop);
+ BKE_bproperty_copy_list(&obn->prop, &ob->prop);
copy_sensors(&obn->sensors, &ob->sensors);
copy_controllers(&obn->controllers, &ob->controllers);
@@ -1171,7 +1202,7 @@ Object *BKE_object_copy(Object *ob)
if (obn->pd->rng)
obn->pd->rng = MEM_dupallocN(ob->pd->rng);
}
- obn->soft = copy_softbody(ob->soft);
+ obn->soft = copy_softbody(ob->soft, copy_caches);
obn->bsoft = copy_bulletsoftbody(ob->bsoft);
BKE_object_copy_particlesystems(obn, ob);
@@ -1187,6 +1218,18 @@ Object *BKE_object_copy(Object *ob)
return obn;
}
+/* copy objects, will re-initialize cached simulation data */
+Object *BKE_object_copy(Object *ob)
+{
+ return object_copy_do(ob, FALSE);
+}
+
+/* copy objects, will duplicate cached simulation data */
+Object *BKE_object_copy_with_caches(Object *ob)
+{
+ return object_copy_do(ob, TRUE);
+}
+
static void extern_local_object(Object *ob)
{
ParticleSystem *psys;
@@ -1514,7 +1557,7 @@ void BKE_object_mat3_to_rot(Object *ob, float mat[][3], short use_compat)
/* end drot correction */
if (use_compat) mat3_to_compatible_eulO(ob->rot, ob->rot, ob->rotmode, tmat);
- else mat3_to_eulO(ob->rot, ob->rotmode, tmat);
+ else mat3_to_eulO(ob->rot, ob->rotmode, tmat);
}
}
}
@@ -1756,9 +1799,8 @@ static void ob_parbone(Object *ob, Object *par, float mat[][4])
static void give_parvert(Object *par, int nr, float vec[3])
{
BMEditMesh *em;
- int a, count;
-
- vec[0] = vec[1] = vec[2] = 0.0f;
+
+ zero_v3(vec);
if (par->type == OB_MESH) {
Mesh *me = par->data;
@@ -1785,18 +1827,28 @@ static void give_parvert(Object *par, int nr, float vec[3])
dm = (em) ? em->derivedFinal : par->derivedFinal;
if (dm) {
- MVert *mvert = dm->getVertArray(dm);
- int *index = (int *)dm->getVertDataArray(dm, CD_ORIGINDEX);
- int i, vindex, numVerts = dm->getNumVerts(dm);
-
- /* get the average of all verts with (original index == nr) */
- count = 0;
- for (i = 0; i < numVerts; i++) {
- vindex = (index) ? index[i] : i;
-
- if (vindex == nr) {
- add_v3_v3(vec, mvert[i].co);
- count++;
+ int count = 0;
+ int numVerts = dm->getNumVerts(dm);
+
+ if (nr < numVerts) {
+ MVert *mvert = dm->getVertArray(dm);
+ int *index = (int *)dm->getVertDataArray(dm, CD_ORIGINDEX);
+ int i;
+
+ /* get the average of all verts with (original index == nr) */
+ if (index) {
+ for (i = 0; i < numVerts; i++) {
+ if (index[i] == nr) {
+ add_v3_v3(vec, mvert[i].co);
+ count++;
+ }
+ }
+ }
+ else {
+ if (nr < numVerts) {
+ add_v3_v3(vec, mvert[nr].co);
+ count++;
+ }
}
}
@@ -1818,71 +1870,31 @@ static void give_parvert(Object *par, int nr, float vec[3])
}
}
else if (ELEM(par->type, OB_CURVE, OB_SURF)) {
- Nurb *nu;
- Curve *cu;
- BPoint *bp;
- BezTriple *bezt;
- int found = 0;
- ListBase *nurbs;
-
- cu = par->data;
- nurbs = BKE_curve_nurbs_get(cu);
- nu = nurbs->first;
-
- count = 0;
- while (nu && !found) {
- if (nu->type == CU_BEZIER) {
- bezt = nu->bezt;
- a = nu->pntsu;
- while (a--) {
- if (count == nr) {
- found = 1;
- copy_v3_v3(vec, bezt->vec[1]);
- break;
- }
- count++;
- bezt++;
- }
- }
- else {
- bp = nu->bp;
- a = nu->pntsu * nu->pntsv;
- while (a--) {
- if (count == nr) {
- found = 1;
- memcpy(vec, bp->vec, sizeof(float) * 3);
- break;
- }
- count++;
- bp++;
- }
- }
- nu = nu->next;
- }
+ Curve *cu = par->data;
+ ListBase *nurb = BKE_curve_nurbs_get(cu);;
+ BKE_nurbList_index_get_co(nurb, nr, vec);
}
else if (par->type == OB_LATTICE) {
- Lattice *latt = par->data;
- BPoint *bp;
- DispList *dl = BKE_displist_find(&par->disp, DL_VERTS);
- float *co = dl ? dl->verts : NULL;
-
+ Lattice *latt = par->data;
+ DispList *dl = BKE_displist_find(&par->disp, DL_VERTS);
+ float (*co)[3] = dl ? (float (*)[3])dl->verts : NULL;
+ int tot;
+
if (latt->editlatt) latt = latt->editlatt->latt;
-
- a = latt->pntsu * latt->pntsv * latt->pntsw;
- count = 0;
- bp = latt->def;
- while (a--) {
- if (count == nr) {
- if (co)
- memcpy(vec, co, 3 * sizeof(float));
- else
- memcpy(vec, bp->vec, 3 * sizeof(float));
- break;
+
+ tot = latt->pntsu * latt->pntsv * latt->pntsw;
+
+ /* ensure dl is correct size */
+ BLI_assert(dl == NULL || dl->nr == tot);
+
+ if (nr < tot) {
+ if (co) {
+ copy_v3_v3(vec, co[nr]);
+ }
+ else {
+ copy_v3_v3(vec, latt->def[nr].vec);
}
- count++;
- if (co) co += 3;
- else bp++;
}
}
}
@@ -2249,7 +2261,7 @@ void BKE_object_minmax(Object *ob, float min_r[3], float max_r[3], const short u
Curve *cu = ob->data;
/* Use the object bounding box so that modifier output
- gets taken into account */
+ * gets taken into account */
if (ob->bb)
bb = *(ob->bb);
else {
@@ -2350,7 +2362,7 @@ int BKE_object_minmax_dupli(Scene *scene, Object *ob, float r_min[3], float r_ma
ListBase *lb;
DupliObject *dob;
- lb = object_duplilist(scene, ob);
+ lb = object_duplilist(scene, ob, FALSE);
for (dob = lb->first; dob; dob = dob->next) {
if ((use_hidden == FALSE) && (dob->no_draw != 0)) {
/* pass */
@@ -2427,7 +2439,7 @@ void BKE_scene_foreach_display_point(
ListBase *lb;
DupliObject *dob;
- lb = object_duplilist(scene, ob);
+ lb = object_duplilist(scene, ob, FALSE);
for (dob = lb->first; dob; dob = dob->next) {
if (dob->no_draw == 0) {
BKE_object_foreach_display_point(dob->ob, dob->mat, func_cb, user_data);
@@ -2700,7 +2712,7 @@ void BKE_object_handle_update(Scene *scene, Object *ob)
if (pid->cache->flag & PTCACHE_OUTDATED || (pid->cache->flag & PTCACHE_SIMULATION_VALID) == 0) {
scene->physics_settings.quick_cache_step =
scene->physics_settings.quick_cache_step ?
- MIN2(scene->physics_settings.quick_cache_step, pid->cache->step) :
+ mini(scene->physics_settings.quick_cache_step, pid->cache->step) :
pid->cache->step;
}
}
@@ -2889,22 +2901,22 @@ static KeyBlock *insert_meshkey(Scene *scene, Object *ob, const char *name, int
int newkey = 0;
if (key == NULL) {
- key = me->key = add_key((ID *)me);
+ key = me->key = BKE_key_add((ID *)me);
key->type = KEY_RELATIVE;
newkey = 1;
}
if (newkey || from_mix == FALSE) {
/* create from mesh */
- kb = add_keyblock_ctime(key, name, FALSE);
- mesh_to_key(me, kb);
+ kb = BKE_keyblock_add_ctime(key, name, FALSE);
+ BKE_key_convert_from_mesh(me, kb);
}
else {
/* copy from current values */
float *data = do_ob_key(scene, ob);
/* create new block with prepared data */
- kb = add_keyblock_ctime(key, name, FALSE);
+ kb = BKE_keyblock_add_ctime(key, name, FALSE);
kb->data = data;
kb->totelem = me->totvert;
}
@@ -2920,20 +2932,20 @@ static KeyBlock *insert_lattkey(Scene *scene, Object *ob, const char *name, int
int newkey = 0;
if (key == NULL) {
- key = lt->key = add_key((ID *)lt);
+ key = lt->key = BKE_key_add((ID *)lt);
key->type = KEY_RELATIVE;
newkey = 1;
}
if (newkey || from_mix == FALSE) {
- kb = add_keyblock_ctime(key, name, FALSE);
+ kb = BKE_keyblock_add_ctime(key, name, FALSE);
if (!newkey) {
KeyBlock *basekb = (KeyBlock *)key->block.first;
kb->data = MEM_dupallocN(basekb->data);
kb->totelem = basekb->totelem;
}
else {
- latt_to_key(lt, kb);
+ BKE_key_convert_from_lattice(lt, kb);
}
}
else {
@@ -2941,7 +2953,7 @@ static KeyBlock *insert_lattkey(Scene *scene, Object *ob, const char *name, int
float *data = do_ob_key(scene, ob);
/* create new block with prepared data */
- kb = add_keyblock_ctime(key, name, FALSE);
+ kb = BKE_keyblock_add_ctime(key, name, FALSE);
kb->totelem = lt->pntsu * lt->pntsv * lt->pntsw;
kb->data = data;
}
@@ -2958,21 +2970,21 @@ static KeyBlock *insert_curvekey(Scene *scene, Object *ob, const char *name, int
int newkey = 0;
if (key == NULL) {
- key = cu->key = add_key((ID *)cu);
+ key = cu->key = BKE_key_add((ID *)cu);
key->type = KEY_RELATIVE;
newkey = 1;
}
if (newkey || from_mix == FALSE) {
/* create from curve */
- kb = add_keyblock_ctime(key, name, FALSE);
+ kb = BKE_keyblock_add_ctime(key, name, FALSE);
if (!newkey) {
KeyBlock *basekb = (KeyBlock *)key->block.first;
kb->data = MEM_dupallocN(basekb->data);
kb->totelem = basekb->totelem;
}
else {
- curve_to_key(cu, kb, lb);
+ BKE_key_convert_from_curve(cu, kb, lb);
}
}
else {
@@ -2980,7 +2992,7 @@ static KeyBlock *insert_curvekey(Scene *scene, Object *ob, const char *name, int
float *data = do_ob_key(scene, ob);
/* create new block with prepared data */
- kb = add_keyblock_ctime(key, name, FALSE);
+ kb = BKE_keyblock_add_ctime(key, name, FALSE);
kb->totelem = BKE_nurbList_verts_count(lb);
kb->data = data;
}
@@ -3010,7 +3022,7 @@ int BKE_object_is_modified(Scene *scene, Object *ob)
{
int flag = 0;
- if (ob_get_key(ob)) {
+ if (BKE_key_from_object(ob)) {
flag |= eModifierMode_Render;
}
else {
@@ -3278,7 +3290,7 @@ void BKE_object_groups_clear(Scene *scene, Base *base, Object *object)
{
Group *group = NULL;
- BLI_assert(base->object == object);
+ BLI_assert((base == NULL) || (base->object == object));
if (scene && base == NULL) {
base = BKE_scene_base_find(scene, object);
diff --git a/source/blender/blenkernel/intern/object_deform.c b/source/blender/blenkernel/intern/object_deform.c
new file mode 100644
index 00000000000..7f9578250f2
--- /dev/null
+++ b/source/blender/blenkernel/intern/object_deform.c
@@ -0,0 +1,156 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * 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.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/object_deform.c
+ * \ingroup bke
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_utildefines.h"
+#include "BLI_ghash.h"
+
+#include "BKE_action.h"
+#include "BKE_object_deform.h" /* own include */
+#include "BKE_object.h"
+#include "BKE_modifier.h"
+
+#include "DNA_armature_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_object_types.h"
+
+/* --- functions for getting vgroup aligned maps --- */
+
+/**
+ * gets the status of "flag" for each bDeformGroup
+ * in ob->defbase and returns an array containing them
+ */
+char *BKE_objdef_lock_flags_get(Object *ob, const int defbase_tot)
+{
+ char is_locked = FALSE;
+ int i;
+ //int defbase_tot = BLI_countlist(&ob->defbase);
+ char *lock_flags = MEM_mallocN(defbase_tot * sizeof(char), "defflags");
+ bDeformGroup *defgroup;
+
+ for (i = 0, defgroup = ob->defbase.first; i < defbase_tot && defgroup; defgroup = defgroup->next, i++) {
+ lock_flags[i] = ((defgroup->flag & DG_LOCK_WEIGHT) != 0);
+ is_locked |= lock_flags[i];
+ }
+ if (is_locked) {
+ return lock_flags;
+ }
+
+ MEM_freeN(lock_flags);
+ return NULL;
+}
+
+char *BKE_objdef_validmap_get(Object *ob, const int defbase_tot)
+{
+ bDeformGroup *dg;
+ ModifierData *md;
+ char *vgroup_validmap;
+ GHash *gh;
+ int i, step1 = 1;
+ //int defbase_tot = BLI_countlist(&ob->defbase);
+
+ if (ob->defbase.first == NULL) {
+ return NULL;
+ }
+
+ gh = BLI_ghash_str_new("BKE_objdef_validmap_get gh");
+
+ /* add all names to a hash table */
+ for (dg = ob->defbase.first; dg; dg = dg->next) {
+ BLI_ghash_insert(gh, dg->name, NULL);
+ }
+
+ BLI_assert(BLI_ghash_size(gh) == defbase_tot);
+
+ /* now loop through the armature modifiers and identify deform bones */
+ for (md = ob->modifiers.first; md; md = !md->next && step1 ? (step1 = 0), modifiers_getVirtualModifierList(ob) : md->next) {
+ if (!(md->mode & (eModifierMode_Realtime | eModifierMode_Virtual)))
+ continue;
+
+ if (md->type == eModifierType_Armature) {
+ ArmatureModifierData *amd = (ArmatureModifierData *) md;
+
+ if (amd->object && amd->object->pose) {
+ bPose *pose = amd->object->pose;
+ bPoseChannel *chan;
+
+ for (chan = pose->chanbase.first; chan; chan = chan->next) {
+ if (chan->bone->flag & BONE_NO_DEFORM)
+ continue;
+
+ if (BLI_ghash_remove(gh, chan->name, NULL, NULL)) {
+ BLI_ghash_insert(gh, chan->name, SET_INT_IN_POINTER(1));
+ }
+ }
+ }
+ }
+ }
+
+ vgroup_validmap = MEM_mallocN(defbase_tot, "wpaint valid map");
+
+ /* add all names to a hash table */
+ for (dg = ob->defbase.first, i = 0; dg; dg = dg->next, i++) {
+ vgroup_validmap[i] = (BLI_ghash_lookup(gh, dg->name) != NULL);
+ }
+
+ BLI_assert(i == BLI_ghash_size(gh));
+
+ BLI_ghash_free(gh, NULL, NULL);
+
+ return vgroup_validmap;
+}
+
+/* Returns total selected vgroups,
+ * wpi.defbase_sel is assumed malloc'd, all values are set */
+char *BKE_objdef_selected_get(Object *ob, int defbase_tot, int *r_dg_flags_sel_tot)
+{
+ char *dg_selection = MEM_mallocN(defbase_tot * sizeof(char), __func__);
+ bDeformGroup *defgroup;
+ unsigned int i;
+ Object *armob = BKE_object_pose_armature_get(ob);
+ (*r_dg_flags_sel_tot) = 0;
+
+ if (armob) {
+ bPose *pose = armob->pose;
+ for (i = 0, defgroup = ob->defbase.first; i < defbase_tot && defgroup; defgroup = defgroup->next, i++) {
+ bPoseChannel *pchan = BKE_pose_channel_find_name(pose, defgroup->name);
+ if (pchan && (pchan->bone->flag & BONE_SELECTED)) {
+ dg_selection[i] = TRUE;
+ (*r_dg_flags_sel_tot) += 1;
+ }
+ else {
+ dg_selection[i] = FALSE;
+ }
+ }
+ }
+ else {
+ memset(dg_selection, FALSE, sizeof(char) * defbase_tot);
+ }
+
+ return dg_selection;
+}
diff --git a/source/blender/blenkernel/intern/ocean.c b/source/blender/blenkernel/intern/ocean.c
index 66b0cff691e..4f3921936e8 100644
--- a/source/blender/blenkernel/intern/ocean.c
+++ b/source/blender/blenkernel/intern/ocean.c
@@ -37,8 +37,6 @@
#include "BKE_image.h"
#include "BKE_ocean.h"
-#include "BKE_utildefines.h"
-
#include "BKE_global.h" // XXX TESTING
#include "BLI_math_base.h"
@@ -1119,19 +1117,20 @@ void BKE_simulate_ocean_cache(struct OceanCache *och, int frame)
/* if image is already loaded in mem, return */
if (och->ibufs_disp[f] != NULL) return;
+ /* use default color spaces since we know for sure cache files were saved with default settings too */
cache_filename(string, och->bakepath, och->relbase, frame, CACHE_TYPE_DISPLACE);
- och->ibufs_disp[f] = IMB_loadiffname(string, 0);
+ och->ibufs_disp[f] = IMB_loadiffname(string, 0, NULL);
//if (och->ibufs_disp[f] == NULL) printf("error loading %s\n", string);
//else printf("loaded cache %s\n", string);
cache_filename(string, och->bakepath, och->relbase, frame, CACHE_TYPE_FOAM);
- och->ibufs_foam[f] = IMB_loadiffname(string, 0);
+ och->ibufs_foam[f] = IMB_loadiffname(string, 0, NULL);
//if (och->ibufs_foam[f] == NULL) printf("error loading %s\n", string);
//else printf("loaded cache %s\n", string);
cache_filename(string, och->bakepath, och->relbase, frame, CACHE_TYPE_NORMAL);
- och->ibufs_norm[f] = IMB_loadiffname(string, 0);
+ och->ibufs_norm[f] = IMB_loadiffname(string, 0, NULL);
//if (och->ibufs_norm[f] == NULL) printf("error loading %s\n", string);
//else printf("loaded cache %s\n", string);
}
@@ -1174,8 +1173,6 @@ void BKE_bake_ocean(struct Ocean *o, struct OceanCache *och, void (*update_cb)(v
ibuf_disp = IMB_allocImBuf(res_x, res_y, 32, IB_rectfloat);
ibuf_normal = IMB_allocImBuf(res_x, res_y, 32, IB_rectfloat);
- ibuf_disp->profile = ibuf_foam->profile = ibuf_normal->profile = IB_PROFILE_LINEAR_RGB;
-
BKE_simulate_ocean(o, och->time[i], och->wave_scale, och->chop_amount);
/* add new foam */
diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c
index 9787a5025f7..03342d0f6d1 100644
--- a/source/blender/blenkernel/intern/packedFile.c
+++ b/source/blender/blenkernel/intern/packedFile.c
@@ -57,7 +57,6 @@
#include "BKE_packedFile.h"
#include "BKE_report.h"
#include "BKE_sound.h"
-#include "BKE_utildefines.h"
#ifdef _WIN32
#define open _open
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 3267253e744..5a302cba2ab 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -190,7 +190,7 @@ void BKE_paint_free(Paint *paint)
}
/* called when copying scene settings, so even if 'src' and 'tar' are the same
- * still do a id_us_plus(), rather then if we were copying betweem 2 existing
+ * still do a id_us_plus(), rather then if we were copying between 2 existing
* scenes where a matching value should decrease the existing user count as
* with paint_brush_set() */
void BKE_paint_copy(Paint *src, Paint *tar)
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 26952db8fba..e8af794eaea 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -116,7 +116,7 @@ int count_particles_mod(ParticleSystem *psys, int totgr, int cur)
}
return tot;
}
-/* we allocate path cache memory in chunks instead of a big continguous
+/* we allocate path cache memory in chunks instead of a big contiguous
* chunk, windows' memory allocater fails to find big blocks of memory often */
#define PATH_CACHE_BUF_SIZE 1024
@@ -3776,7 +3776,7 @@ static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSetti
ptex->gravity = ptex->field = ptex->time = ptex->clump = ptex->kink =
ptex->effector = ptex->rough1 = ptex->rough2 = ptex->roughe = 1.f;
- ptex->length = 1.0f - part->randlength *PSYS_FRAND(child_index + 26);
+ ptex->length = 1.0f - part->randlength * PSYS_FRAND(child_index + 26);
ptex->length *= part->clength_thres < PSYS_FRAND(child_index + 27) ? part->clength : 1.0f;
for (m = 0; m < MAX_MTEX; m++, mtexp++) {
@@ -3968,7 +3968,7 @@ float psys_get_child_size(ParticleSystem *psys, ChildParticle *cpa, float UNUSED
size *= part->childsize;
if (part->childrandsize != 0.0f)
- size *= 1.0f - part->childrandsize *PSYS_FRAND(cpa - psys->child + 26);
+ size *= 1.0f - part->childrandsize * PSYS_FRAND(cpa - psys->child + 26);
return size;
}
@@ -4539,8 +4539,8 @@ void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3]
/* can happen with bad pointcache or physics calculation
* since this becomes geometry, nan's and inf's crash raytrace code.
* better not allow this. */
- if (!finite(bb->vec[0]) || !finite(bb->vec[1]) || !finite(bb->vec[2]) ||
- !finite(bb->vel[0]) || !finite(bb->vel[1]) || !finite(bb->vel[2]) )
+ if ((!finite(bb->vec[0])) || (!finite(bb->vec[1])) || (!finite(bb->vec[2])) ||
+ (!finite(bb->vel[0])) || (!finite(bb->vel[1])) || (!finite(bb->vel[2])) )
{
zero_v3(bb->vec);
zero_v3(bb->vel);
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index bae8efa758e..154c8cca75d 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -797,8 +797,10 @@ static void distribute_threads_exec(ParticleThread *thread, ParticleData *pa, Ch
}
else {
ctx->jitoff[i] = fmod(ctx->jitoff[i],(float)ctx->jitlevel);
- psys_uv_to_w(ctx->jit[2*(int)ctx->jitoff[i]], ctx->jit[2*(int)ctx->jitoff[i]+1], mface->v4, pa->fuv);
- ctx->jitoff[i]++;
+ if (!isnan(ctx->jitoff[i])) {
+ psys_uv_to_w(ctx->jit[2*(int)ctx->jitoff[i]], ctx->jit[2*(int)ctx->jitoff[i]+1], mface->v4, pa->fuv);
+ ctx->jitoff[i]++;
+ }
}
break;
case PART_DISTR_RAND:
@@ -3775,8 +3777,8 @@ static void save_hair(ParticleSimulationData *sim, float UNUSED(cfra))
/* Calculate the speed of the particle relative to the local scale of the
* simulation. This should be called once per particle during a simulation
* step, after the velocity has been updated. element_size defines the scale of
- * the simulation, and is typically the distance to neighbourning particles. */
-void update_courant_num(ParticleSimulationData *sim, ParticleData *pa,
+ * the simulation, and is typically the distance to neighboring particles. */
+static void update_courant_num(ParticleSimulationData *sim, ParticleData *pa,
float dtime, SPHData *sphdata)
{
float relative_vel[3];
@@ -3788,8 +3790,7 @@ void update_courant_num(ParticleSimulationData *sim, ParticleData *pa,
sim->courant_num = speed * dtime / sphdata->element_size;
}
/* Update time step size to suit current conditions. */
-float update_timestep(ParticleSystem *psys, ParticleSimulationData *sim,
- float t_frac)
+static float update_timestep(ParticleSystem *psys, ParticleSimulationData *sim, float t_frac)
{
if (sim->courant_num == 0.0f)
psys->dt_frac = 1.0f;
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index e990f461d4c..8c0d19ba1fd 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -69,7 +69,6 @@
#include "BKE_scene.h"
#include "BKE_smoke.h"
#include "BKE_softbody.h"
-#include "BKE_utildefines.h"
#include "BIK_api.h"
@@ -1030,7 +1029,8 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob, Scene *scene, int dup
if (scene && (duplis-- > 0) && (ob->transflag & OB_DUPLI)) {
ListBase *lb_dupli_ob;
- if ((lb_dupli_ob=object_duplilist(scene, ob))) {
+ /* don't update the dupli groups, we only wan't their pid's */
+ if ((lb_dupli_ob = object_duplilist_ex(scene, ob, FALSE, FALSE))) {
DupliObject *dob;
for (dob= lb_dupli_ob->first; dob; dob= dob->next) {
if (dob->ob != ob) { /* avoids recursive loops with dupliframes: bug 22988 */
@@ -1067,8 +1067,9 @@ static int ptcache_path(PTCacheID *pid, char *filename)
if (pid->cache->flag & PTCACHE_EXTERNAL) {
strcpy(filename, pid->cache->path);
- if (strncmp(filename, "//", 2)==0)
+ if (BLI_path_is_rel(filename)) {
BLI_path_abs(filename, blendfilename);
+ }
return BLI_add_slash(filename); /* new strlen() */
}
@@ -2662,32 +2663,59 @@ void BKE_ptcache_free_list(ListBase *ptcaches)
}
}
-static PointCache *ptcache_copy(PointCache *cache)
+static PointCache *ptcache_copy(PointCache *cache, int copy_data)
{
PointCache *ncache;
ncache= MEM_dupallocN(cache);
- /* hmm, should these be copied over instead? */
ncache->mem_cache.first = NULL;
ncache->mem_cache.last = NULL;
- ncache->cached_frames = NULL;
- ncache->edit = NULL;
- ncache->flag= 0;
- ncache->simframe= 0;
+ if (copy_data == FALSE) {
+ ncache->mem_cache.first = NULL;
+ ncache->mem_cache.last = NULL;
+ ncache->cached_frames = NULL;
+
+ ncache->flag= 0;
+ ncache->simframe= 0;
+ }
+ else {
+ PTCacheMem *pm;
+
+ for (pm = cache->mem_cache.first; pm; pm = pm->next) {
+ PTCacheMem *pmn = MEM_dupallocN(pm);
+ int i;
+
+ for (i = 0; i < BPHYS_TOT_DATA; i++) {
+ if (pmn->data[i])
+ pmn->data[i] = MEM_dupallocN(pm->data[i]);
+ }
+
+ BKE_ptcache_mem_pointers_init(pm);
+
+ BLI_addtail(&ncache->mem_cache, pmn);
+ }
+
+ if (ncache->cached_frames)
+ ncache->cached_frames = MEM_dupallocN(cache->cached_frames);
+ }
+
+ /* hmm, should these be copied over instead? */
+ ncache->edit = NULL;
return ncache;
}
+
/* returns first point cache */
-PointCache *BKE_ptcache_copy_list(ListBase *ptcaches_new, ListBase *ptcaches_old)
+PointCache *BKE_ptcache_copy_list(ListBase *ptcaches_new, ListBase *ptcaches_old, int copy_data)
{
PointCache *cache = ptcaches_old->first;
ptcaches_new->first = ptcaches_new->last = NULL;
for (; cache; cache=cache->next)
- BLI_addtail(ptcaches_new, ptcache_copy(cache));
+ BLI_addtail(ptcaches_new, ptcache_copy(cache, copy_data));
return ptcaches_new->first;
}
diff --git a/source/blender/blenkernel/intern/property.c b/source/blender/blenkernel/intern/property.c
index 46ddce4b51b..8da4f11fed3 100644
--- a/source/blender/blenkernel/intern/property.c
+++ b/source/blender/blenkernel/intern/property.c
@@ -27,9 +27,12 @@
/** \file blender/blenkernel/intern/property.c
* \ingroup bke
+ *
+ * This module deals with bProperty only,
+ * they are used on blender objects in the game engine
+ * (where they get converted into C++ classes - CValue and subclasses)
*/
-
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
@@ -45,7 +48,7 @@
#include "BKE_property.h"
-void free_property(bProperty *prop)
+void BKE_bproperty_free(bProperty *prop)
{
if (prop->poin && prop->poin != &prop->data) MEM_freeN(prop->poin);
@@ -53,17 +56,17 @@ void free_property(bProperty *prop)
}
-void free_properties(ListBase *lb)
+void BKE_bproperty_free_list(ListBase *lb)
{
bProperty *prop;
while ( (prop = lb->first) ) {
BLI_remlink(lb, prop);
- free_property(prop);
+ BKE_bproperty_free(prop);
}
}
-bProperty *copy_property(bProperty *prop)
+bProperty *BKE_bproperty_copy(bProperty *prop)
{
bProperty *propn;
@@ -76,13 +79,13 @@ bProperty *copy_property(bProperty *prop)
return propn;
}
-void copy_properties(ListBase *lbn, ListBase *lbo)
+void BKE_bproperty_copy_list(ListBase *lbn, ListBase *lbo)
{
bProperty *prop, *propn;
- free_properties(lbn); /* in case we are copying to an object with props */
+ BKE_bproperty_free_list(lbn); /* in case we are copying to an object with props */
prop = lbo->first;
while (prop) {
- propn = copy_property(prop);
+ propn = BKE_bproperty_copy(prop);
BLI_addtail(lbn, propn);
prop = prop->next;
}
@@ -90,7 +93,7 @@ void copy_properties(ListBase *lbn, ListBase *lbo)
}
-void init_property(bProperty *prop)
+void BKE_bproperty_init(bProperty *prop)
{
/* also use when property changes type */
@@ -113,22 +116,22 @@ void init_property(bProperty *prop)
}
-bProperty *new_property(int type)
+bProperty *BKE_bproperty_new(int type)
{
bProperty *prop;
prop = MEM_callocN(sizeof(bProperty), "property");
prop->type = type;
- init_property(prop);
+ BKE_bproperty_init(prop);
strcpy(prop->name, "prop");
return prop;
}
-/* used by unique_property() only */
-static bProperty *get_property__internal(bProperty *first, bProperty *self, const char *name)
+/* used by BKE_bproperty_unique() only */
+static bProperty *bproperty_get(bProperty *first, bProperty *self, const char *name)
{
bProperty *p;
for (p = first; p; p = p->next) {
@@ -137,7 +140,7 @@ static bProperty *get_property__internal(bProperty *first, bProperty *self, cons
}
return NULL;
}
-void unique_property(bProperty *first, bProperty *prop, int force)
+void BKE_bproperty_unique(bProperty *first, bProperty *prop, int force)
{
bProperty *p;
@@ -151,13 +154,13 @@ void unique_property(bProperty *first, bProperty *prop, int force)
if (force) {
/* change other names to make them unique */
- while ((p = get_property__internal(first, prop, prop->name))) {
- unique_property(first, p, 0);
+ while ((p = bproperty_get(first, prop, prop->name))) {
+ BKE_bproperty_unique(first, p, 0);
}
}
else {
/* change our own name until its unique */
- if (get_property__internal(first, prop, prop->name)) {
+ if (bproperty_get(first, prop, prop->name)) {
/* there is a collision */
char new_name[sizeof(prop->name)];
char base_name[sizeof(prop->name)];
@@ -175,33 +178,34 @@ void unique_property(bProperty *first, bProperty *prop, int force)
BLI_snprintf(num, sizeof(num), "%d", i++);
BLI_strncpy(new_name, base_name, sizeof(prop->name) - strlen(num));
strcat(new_name, num);
- } while (get_property__internal(first, prop, new_name));
+ } while (bproperty_get(first, prop, new_name));
BLI_strncpy(prop->name, new_name, sizeof(prop->name));
}
}
}
-bProperty *get_ob_property(Object *ob, const char *name)
+bProperty *BKE_bproperty_object_get(Object *ob, const char *name)
{
return BLI_findstring(&ob->prop, name, offsetof(bProperty, name));
}
-void set_ob_property(Object *ob, bProperty *propc)
+void BKE_bproperty_object_set(Object *ob, bProperty *propc)
{
bProperty *prop;
- prop = get_ob_property(ob, propc->name);
+ prop = BKE_bproperty_object_get(ob, propc->name);
if (prop) {
- free_property(prop);
+ BKE_bproperty_free(prop);
BLI_remlink(&ob->prop, prop);
}
- BLI_addtail(&ob->prop, copy_property(propc));
+ BLI_addtail(&ob->prop, BKE_bproperty_copy(propc));
}
/* negative: prop is smaller
* positive: prop is larger
*/
-int compare_property(bProperty *prop, const char *str)
+#if 0 /* UNUSED */
+int BKE_bproperty_cmp(bProperty *prop, const char *str)
{
// extern int Gdfra; /* sector.c */
float fvalue, ftest;
@@ -237,8 +241,9 @@ int compare_property(bProperty *prop, const char *str)
return 0;
}
+#endif
-void set_property(bProperty *prop, const char *str)
+void BKE_bproperty_set(bProperty *prop, const char *str)
{
// extern int Gdfra; /* sector.c */
@@ -262,7 +267,7 @@ void set_property(bProperty *prop, const char *str)
}
-void add_property(bProperty *prop, const char *str)
+void BKE_bproperty_add(bProperty *prop, const char *str)
{
// extern int Gdfra; /* sector.c */
@@ -282,7 +287,7 @@ void add_property(bProperty *prop, const char *str)
}
/* reads value of property, sets it in chars in str */
-void set_property_valstr(bProperty *prop, char *str)
+void BKE_bproperty_set_valstr(bProperty *prop, char *str)
{
// extern int Gdfra; /* sector.c */
@@ -303,11 +308,13 @@ void set_property_valstr(bProperty *prop, char *str)
}
}
+#if 0 /* UNUSED */
void cp_property(bProperty *prop1, bProperty *prop2)
{
char str[128];
- set_property_valstr(prop2, str);
+ BKE_bproperty_set_valstr(prop2, str);
- set_property(prop1, str);
+ BKE_bproperty_set(prop1, str);
}
+#endif
diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c
index c440d21f56d..6c1fbbfa9a0 100644
--- a/source/blender/blenkernel/intern/sca.c
+++ b/source/blender/blenkernel/intern/sca.c
@@ -44,7 +44,6 @@
#include "DNA_object_types.h"
#include "BLI_blenlib.h"
-#include "BKE_utildefines.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_library.h"
@@ -211,7 +210,7 @@ void unlink_controllers(ListBase *lb)
bController *cont;
for (cont= lb->first; cont; cont= cont->next)
- unlink_controller(cont);
+ unlink_controller(cont);
}
void free_controller(bController *cont)
@@ -537,7 +536,7 @@ void clear_sca_new_poins(void)
ob= G.main->object.first;
while (ob) {
clear_sca_new_poins_ob(ob);
- ob= ob->id.next;
+ ob= ob->id.next;
}
}
@@ -625,7 +624,7 @@ void set_sca_new_poins(void)
ob= G.main->object.first;
while (ob) {
set_sca_new_poins_ob(ob);
- ob= ob->id.next;
+ ob= ob->id.next;
}
}
@@ -697,7 +696,7 @@ void sca_remove_ob_poin(Object *obt, Object *ob)
if (sta->target == ob) sta->target = NULL;
}
act= act->next;
- }
+ }
}
/* ******************** INTERFACE ******************* */
@@ -876,3 +875,20 @@ void unlink_logicbricks(void **poin, void ***ppoin, short *tot)
return;
}
}
+
+const char *sca_state_name_get(Object *ob, short bit)
+{
+ bController *cont;
+ unsigned int mask;
+
+ mask = (1<<bit);
+ cont = ob->controllers.first;
+ while (cont) {
+ if (cont->state_mask & mask) {
+ return cont->name;
+ }
+ cont = cont->next;
+ }
+ return NULL;
+}
+
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index d476e90498c..f8777f87369 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -57,6 +57,7 @@
#include "BKE_anim.h"
#include "BKE_animsys.h"
+#include "BKE_colortools.h"
#include "BKE_depsgraph.h"
#include "BKE_global.h"
#include "BKE_group.h"
@@ -76,6 +77,8 @@
#include "RE_engine.h"
+#include "IMB_colormanagement.h"
+
//XXX #include "BIF_previewrender.h"
//XXX #include "BIF_editseq.h"
@@ -153,7 +156,8 @@ Scene *BKE_scene_copy(Scene *sce, int type)
BKE_keyingsets_copy(&(scen->keyingsets), &(sce->keyingsets));
if (sce->nodetree) {
- scen->nodetree = ntreeCopyTree(sce->nodetree); /* copies actions */
+ /* ID's are managed on both copy and switch */
+ scen->nodetree = ntreeCopyTree(sce->nodetree);
ntreeSwitchID(scen->nodetree, &sce->id, &scen->id);
}
@@ -166,6 +170,11 @@ Scene *BKE_scene_copy(Scene *sce, int type)
obase = obase->next;
base = base->next;
}
+
+ /* copy color management settings */
+ BKE_color_managed_display_settings_copy(&scen->display_settings, &sce->display_settings);
+ BKE_color_managed_view_settings_copy(&scen->view_settings, &sce->view_settings);
+ BKE_color_managed_view_settings_copy(&scen->r.im_format.view_settings, &sce->r.im_format.view_settings);
}
/* tool settings */
@@ -331,6 +340,8 @@ void BKE_scene_free(Scene *sce)
MEM_freeN(sce->fps_info);
sound_destroy_scene(sce);
+
+ BKE_color_managed_view_settings_free(&sce->view_settings);
}
Scene *BKE_scene_add(const char *name)
@@ -371,7 +382,14 @@ Scene *BKE_scene_add(const char *name)
sce->r.frs_sec_base = 1;
sce->r.edgeint = 10;
sce->r.ocres = 128;
+
+ /* OCIO_TODO: for forwards compatibility only, so if no tonecurve are used,
+ * images would look in the same way as in current blender
+ *
+ * perhaps at some point should be completely deprecated?
+ */
sce->r.color_mgt_flag |= R_COLOR_MANAGEMENT;
+
sce->r.gauss = 1.0;
/* deprecated but keep for upwards compat */
@@ -545,6 +563,9 @@ Scene *BKE_scene_add(const char *name)
sound_create_scene(sce);
+ BKE_color_managed_display_settings_init(&sce->display_settings);
+ BKE_color_managed_view_settings_init(&sce->view_settings);
+
return sce;
}
@@ -723,7 +744,7 @@ int BKE_scene_base_iter_next(Scene **scene, int val, Base **base, Object **ob)
* this enters eternal loop because of
* makeDispListMBall getting called inside of group_duplilist */
if ((*base)->object->dup_group == NULL) {
- duplilist = object_duplilist((*scene), (*base)->object);
+ duplilist = object_duplilist((*scene), (*base)->object, FALSE);
dupob = duplilist->first;
@@ -1239,3 +1260,26 @@ void BKE_scene_base_flag_from_objects(struct Scene *scene)
base = base->next;
}
}
+
+void BKE_scene_disable_color_management(Scene *scene)
+{
+ ColorManagedDisplaySettings *display_settings = &scene->display_settings;
+ ColorManagedViewSettings *view_settings = &scene->view_settings;
+ const char *view;
+ const char *none_display_name;
+
+ none_display_name = IMB_colormanagement_display_get_none_name();
+
+ BLI_strncpy(display_settings->display_device, none_display_name, sizeof(display_settings->display_device));
+
+ view = IMB_colormanagement_view_get_default_name(display_settings->display_device);
+
+ if (view) {
+ BLI_strncpy(view_settings->view_transform, view, sizeof(view_settings->view_transform));
+ }
+}
+
+int BKE_scene_check_color_management_enabled(const Scene *scene)
+{
+ return strcmp(scene->display_settings.display_device, "None") != 0;
+}
diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c
index 87906337ca2..33519483843 100644
--- a/source/blender/blenkernel/intern/seqeffects.c
+++ b/source/blender/blenkernel/intern/seqeffects.c
@@ -49,14 +49,14 @@
#include "BKE_main.h"
#include "BKE_sequencer.h"
#include "BKE_texture.h"
-#include "BKE_utildefines.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
+#include "IMB_colormanagement.h"
#include "RNA_access.h"
-static void slize_get_byte_buffers(const SeqRenderData *context, const ImBuf *ibuf1, const ImBuf *ibuf2,
+static void slice_get_byte_buffers(const SeqRenderData *context, const ImBuf *ibuf1, const ImBuf *ibuf2,
const ImBuf *ibuf3, const ImBuf *out, int start_line, unsigned char **rect1,
unsigned char **rect2, unsigned char **rect3, unsigned char **rect_out)
{
@@ -72,7 +72,7 @@ static void slize_get_byte_buffers(const SeqRenderData *context, const ImBuf *ib
*rect3 = (unsigned char*) ibuf3->rect + offset;
}
-static void slize_get_float_buffers(const SeqRenderData *context, const ImBuf *ibuf1, const ImBuf *ibuf2,
+static void slice_get_float_buffers(const SeqRenderData *context, const ImBuf *ibuf1, const ImBuf *ibuf2,
const ImBuf *ibuf3, const ImBuf *out, int start_line,
float **rect1, float **rect2, float **rect3, float **rect_out)
{
@@ -120,13 +120,13 @@ static ImBuf *prepare_effect_imbufs(SeqRenderData context, ImBuf *ibuf1, ImBuf *
}
if (ibuf1 && !ibuf1->rect_float && out->rect_float) {
- IMB_float_from_rect_simple(ibuf1);
+ BKE_sequencer_imbuf_to_sequencer_space(context.scene, ibuf1, TRUE);
}
if (ibuf2 && !ibuf2->rect_float && out->rect_float) {
- IMB_float_from_rect_simple(ibuf2);
+ BKE_sequencer_imbuf_to_sequencer_space(context.scene, ibuf2, TRUE);
}
if (ibuf3 && !ibuf3->rect_float && out->rect_float) {
- IMB_float_from_rect_simple(ibuf3);
+ BKE_sequencer_imbuf_to_sequencer_space(context.scene, ibuf3, TRUE);
}
if (ibuf1 && !ibuf1->rect && !out->rect_float) {
@@ -138,7 +138,7 @@ static ImBuf *prepare_effect_imbufs(SeqRenderData context, ImBuf *ibuf1, ImBuf *
if (ibuf3 && !ibuf3->rect && !out->rect_float) {
IMB_rect_from_float(ibuf3);
}
-
+
return out;
}
@@ -286,14 +286,14 @@ static void do_alphaover_effect(SeqRenderData context, Sequence *UNUSED(seq), fl
if (out->rect_float) {
float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
- slize_get_float_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
+ slice_get_float_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
do_alphaover_effect_float(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out);
}
else {
unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
- slize_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
+ slice_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
do_alphaover_effect_byte(facf0, facf1, context.rectx, total_lines, (char *) rect1, (char *) rect2, (char *) rect_out);
}
@@ -448,14 +448,14 @@ static void do_alphaunder_effect(SeqRenderData context, Sequence *UNUSED(seq), f
if (out->rect_float) {
float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
- slize_get_float_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
+ slice_get_float_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
do_alphaunder_effect_float(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out);
}
else {
unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
- slize_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
+ slice_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
do_alphaunder_effect_byte(facf0, facf1, context.rectx, total_lines, (char *) rect1, (char *) rect2, (char *) rect_out);
}
@@ -558,14 +558,14 @@ static void do_cross_effect(SeqRenderData context, Sequence *UNUSED(seq), float
if (out->rect_float) {
float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
- slize_get_float_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
+ slice_get_float_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
do_cross_effect_float(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out);
}
else {
unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
- slize_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
+ slice_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
do_cross_effect_byte(facf0, facf1, context.rectx, total_lines, (char *) rect1, (char *) rect2, (char *) rect_out);
}
@@ -609,9 +609,9 @@ static void makeGammaTables(float gamma)
/* The end of the table should match 1.0 carefully. In order to avoid
* rounding errors, we just set this explicitly. The last segment may
- * have a different length than the other segments, but our
- * interpolation is insensitive to that
- */
+ * have a different length than the other segments, but our
+ * interpolation is insensitive to that
+ */
color_domain_table[RE_GAMMA_TABLE_SIZE] = 1.0;
gamma_range_table[RE_GAMMA_TABLE_SIZE] = 1.0;
inv_gamma_range_table[RE_GAMMA_TABLE_SIZE] = 1.0;
@@ -807,14 +807,14 @@ static void do_gammacross_effect(SeqRenderData context, Sequence *UNUSED(seq), f
if (out->rect_float) {
float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
- slize_get_float_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
+ slice_get_float_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
do_gammacross_effect_float(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out);
}
else {
unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
- slize_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
+ slice_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
do_gammacross_effect_byte(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out);
}
@@ -913,14 +913,14 @@ static void do_add_effect(SeqRenderData context, Sequence *UNUSED(seq), float UN
if (out->rect_float) {
float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
- slize_get_float_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
+ slice_get_float_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
do_add_effect_float(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out);
}
else {
unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
- slize_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
+ slice_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
do_add_effect_byte(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out);
}
@@ -1017,14 +1017,14 @@ static void do_sub_effect(SeqRenderData context, Sequence *UNUSED(seq), float UN
if (out->rect_float) {
float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
- slize_get_float_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
+ slice_get_float_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
do_sub_effect_float(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out);
}
else {
unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
- slize_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
+ slice_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
do_sub_effect_byte(facf0, facf1, context.rectx, total_lines, (char *) rect1, (char *) rect2, (char *) rect_out);
}
@@ -1214,14 +1214,14 @@ static void do_mul_effect(SeqRenderData context, Sequence *UNUSED(seq), float UN
if (out->rect_float) {
float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
- slize_get_float_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
+ slice_get_float_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
do_mul_effect_float(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out);
}
else {
unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
- slize_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
+ slice_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
do_mul_effect_byte(facf0, facf1, context.rectx, total_lines, rect1, rect2, rect_out);
}
@@ -2748,7 +2748,7 @@ static void do_overdrop_effect(SeqRenderData context, Sequence *UNUSED(seq), flo
if (out->rect_float) {
float *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
- slize_get_float_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
+ slice_get_float_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
do_drop_effect_float(facf0, facf1, x, y, rect1, rect2, rect_out);
do_alphaover_effect_float(facf0, facf1, x, y, rect1, rect2, rect_out);
@@ -2756,7 +2756,7 @@ static void do_overdrop_effect(SeqRenderData context, Sequence *UNUSED(seq), flo
else {
unsigned char *rect1 = NULL, *rect2 = NULL, *rect_out = NULL;
- slize_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
+ slice_get_byte_buffers(&context, ibuf1, ibuf2, NULL, out, start_line, &rect1, &rect2, NULL, &rect_out);
do_drop_effect_byte(facf0, facf1, x, y, (char *) rect1, (char *) rect2, (char *) rect_out);
do_alphaover_effect_byte(facf0, facf1, x, y, (char *) rect1, (char *) rect2, (char *) rect_out);
diff --git a/source/blender/blenkernel/intern/seqmodifier.c b/source/blender/blenkernel/intern/seqmodifier.c
index 26c2fe03688..b0dcad64722 100644
--- a/source/blender/blenkernel/intern/seqmodifier.c
+++ b/source/blender/blenkernel/intern/seqmodifier.c
@@ -43,7 +43,6 @@
#include "BKE_colortools.h"
#include "BKE_sequencer.h"
-#include "BKE_utildefines.h"
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
@@ -141,7 +140,7 @@ static void modifier_apply_threaded(ImBuf *ibuf, ImBuf *mask, modifier_apply_thr
/* **** Color Balance Modifier **** */
-void colorBalance_init_data(SequenceModifierData *smd)
+static void colorBalance_init_data(SequenceModifierData *smd)
{
ColorBalanceModifierData *cbmd = (ColorBalanceModifierData *) smd;
int c;
@@ -155,14 +154,11 @@ void colorBalance_init_data(SequenceModifierData *smd)
}
}
-ImBuf *colorBalance_apply(SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
+static void colorBalance_apply(SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
{
ColorBalanceModifierData *cbmd = (ColorBalanceModifierData *) smd;
- ImBuf *ibuf_new = IMB_dupImBuf(ibuf);
- BKE_sequencer_color_balance_apply(&cbmd->color_balance, ibuf_new, cbmd->color_multiply, FALSE, mask);
-
- return ibuf_new;
+ BKE_sequencer_color_balance_apply(&cbmd->color_balance, ibuf, cbmd->color_multiply, FALSE, mask);
}
static SequenceModifierTypeInfo seqModifier_ColorBalance = {
@@ -177,21 +173,21 @@ static SequenceModifierTypeInfo seqModifier_ColorBalance = {
/* **** Curves Modifier **** */
-void curves_init_data(SequenceModifierData *smd)
+static void curves_init_data(SequenceModifierData *smd)
{
CurvesModifierData *cmd = (CurvesModifierData *) smd;
curvemapping_set_defaults(&cmd->curve_mapping, 4, 0.0f, 0.0f, 1.0f, 1.0f);
}
-void curves_free_data(SequenceModifierData *smd)
+static void curves_free_data(SequenceModifierData *smd)
{
CurvesModifierData *cmd = (CurvesModifierData *) smd;
curvemapping_free_data(&cmd->curve_mapping);
}
-void curves_copy_data(SequenceModifierData *target, SequenceModifierData *smd)
+static void curves_copy_data(SequenceModifierData *target, SequenceModifierData *smd)
{
CurvesModifierData *cmd = (CurvesModifierData *) smd;
CurvesModifierData *cmd_target = (CurvesModifierData *) target;
@@ -199,8 +195,8 @@ void curves_copy_data(SequenceModifierData *target, SequenceModifierData *smd)
curvemapping_copy_data(&cmd_target->curve_mapping, &cmd->curve_mapping);
}
-void curves_apply_threaded(int width, int height, unsigned char *rect, float *rect_float,
- unsigned char *mask_rect, float *mask_rect_float, void *data_v)
+static void curves_apply_threaded(int width, int height, unsigned char *rect, float *rect_float,
+ unsigned char *mask_rect, float *mask_rect_float, void *data_v)
{
CurveMapping *curve_mapping = (CurveMapping *) data_v;
int x, y;
@@ -253,10 +249,9 @@ void curves_apply_threaded(int width, int height, unsigned char *rect, float *re
}
}
-ImBuf *curves_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
+static void curves_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
{
CurvesModifierData *cmd = (CurvesModifierData *) smd;
- ImBuf *ibuf_new = IMB_dupImBuf(ibuf);
float black[3] = {0.0f, 0.0f, 0.0f};
float white[3] = {1.0f, 1.0f, 1.0f};
@@ -266,11 +261,9 @@ ImBuf *curves_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
curvemapping_premultiply(&cmd->curve_mapping, 0);
curvemapping_set_black_white(&cmd->curve_mapping, black, white);
- modifier_apply_threaded(ibuf_new, mask, curves_apply_threaded, &cmd->curve_mapping);
+ modifier_apply_threaded(ibuf, mask, curves_apply_threaded, &cmd->curve_mapping);
curvemapping_premultiply(&cmd->curve_mapping, 1);
-
- return ibuf_new;
}
static SequenceModifierTypeInfo seqModifier_Curves = {
@@ -285,7 +278,7 @@ static SequenceModifierTypeInfo seqModifier_Curves = {
/* **** Hue Correct Modifier **** */
-void hue_correct_init_data(SequenceModifierData *smd)
+static void hue_correct_init_data(SequenceModifierData *smd)
{
HueCorrectModifierData *hcmd = (HueCorrectModifierData *) smd;
int c;
@@ -303,14 +296,14 @@ void hue_correct_init_data(SequenceModifierData *smd)
hcmd->curve_mapping.cur = 1;
}
-void hue_correct_free_data(SequenceModifierData *smd)
+static void hue_correct_free_data(SequenceModifierData *smd)
{
HueCorrectModifierData *hcmd = (HueCorrectModifierData *) smd;
curvemapping_free_data(&hcmd->curve_mapping);
}
-void hue_correct_copy_data(SequenceModifierData *target, SequenceModifierData *smd)
+static void hue_correct_copy_data(SequenceModifierData *target, SequenceModifierData *smd)
{
HueCorrectModifierData *hcmd = (HueCorrectModifierData *) smd;
HueCorrectModifierData *hcmd_target = (HueCorrectModifierData *) target;
@@ -318,7 +311,7 @@ void hue_correct_copy_data(SequenceModifierData *target, SequenceModifierData *s
curvemapping_copy_data(&hcmd_target->curve_mapping, &hcmd->curve_mapping);
}
-void hue_correct_apply_threaded(int width, int height, unsigned char *rect, float *rect_float,
+static void hue_correct_apply_threaded(int width, int height, unsigned char *rect, float *rect_float,
unsigned char *mask_rect, float *mask_rect_float, void *data_v)
{
CurveMapping *curve_mapping = (CurveMapping *) data_v;
@@ -372,16 +365,13 @@ void hue_correct_apply_threaded(int width, int height, unsigned char *rect, floa
}
}
-ImBuf *hue_correct_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
+static void hue_correct_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
{
HueCorrectModifierData *hcmd = (HueCorrectModifierData *) smd;
- ImBuf *ibuf_new = IMB_dupImBuf(ibuf);
curvemapping_initialize(&hcmd->curve_mapping);
- modifier_apply_threaded(ibuf_new, mask, hue_correct_apply_threaded, &hcmd->curve_mapping);
-
- return ibuf_new;
+ modifier_apply_threaded(ibuf, mask, hue_correct_apply_threaded, &hcmd->curve_mapping);
}
static SequenceModifierTypeInfo seqModifier_HueCorrect = {
@@ -394,6 +384,103 @@ static SequenceModifierTypeInfo seqModifier_HueCorrect = {
hue_correct_apply /* apply */
};
+/* **** Bright/Contrast Modifier **** */
+
+typedef struct BrightContrastThreadData {
+ float bright;
+ float contrast;
+} BrightContrastThreadData;
+
+static void brightcontrast_apply_threaded(int width, int height, unsigned char *rect, float *rect_float,
+ unsigned char *mask_rect, float *mask_rect_float, void *data_v)
+{
+ BrightContrastThreadData *data = (BrightContrastThreadData *) data_v;
+ int x, y;
+
+ float i;
+ int c;
+ float a, b, v;
+ float brightness = data->bright / 100.0f;
+ float contrast = data->contrast;
+ float delta = contrast / 200.0f;
+
+ a = 1.0f - delta * 2.0f;
+ /*
+ * The algorithm is by Werner D. Streidt
+ * (http://visca.com/ffactory/archives/5-99/msg00021.html)
+ * Extracted of OpenCV demhist.c
+ */
+ if (contrast > 0) {
+ a = 1.0f / a;
+ b = a * (brightness - delta);
+ }
+ else {
+ delta *= -1;
+ b = a * (brightness + delta);
+ }
+
+ for (y = 0; y < height; y++) {
+ for (x = 0; x < width; x++) {
+ int pixel_index = (y * width + x) * 4;
+
+ if (rect) {
+ unsigned char *pixel = rect + pixel_index;
+
+ for (c = 0; c < 3; c++) {
+ i = pixel[c];
+ v = a * i + b;
+
+ if (mask_rect) {
+ unsigned char *m = mask_rect + pixel_index;
+ float t = (float) m[c] / 255.0f;
+
+ pixel[c] = pixel[c] * (1.0f - t) + v * t;
+ }
+ else
+ pixel[c] = v;
+ }
+ }
+ else if (rect_float) {
+ float *pixel = rect_float + pixel_index;
+
+ for (c = 0; c < 3; c++) {
+ i = pixel[c];
+ v = a * i + b;
+
+ if (mask_rect_float) {
+ float *m = mask_rect_float + pixel_index;
+
+ pixel[c] = pixel[c] * (1.0f - m[c]) + v * m[c];
+ }
+ else
+ pixel[c] = v;
+ }
+ }
+ }
+ }
+}
+
+static void brightcontrast_apply(struct SequenceModifierData *smd, ImBuf *ibuf, ImBuf *mask)
+{
+ BrightContrastModifierData *bcmd = (BrightContrastModifierData *) smd;
+ BrightContrastThreadData data;
+
+ data.bright = bcmd->bright;
+ data.contrast = bcmd->contrast;
+
+ modifier_apply_threaded(ibuf, mask, brightcontrast_apply_threaded, &data);
+}
+
+static SequenceModifierTypeInfo seqModifier_BrightContrast = {
+ "Bright/Contrast", /* name */
+ "BrightContrastModifierData", /* struct_name */
+ sizeof(BrightContrastModifierData), /* struct_size */
+ NULL, /* init_data */
+ NULL, /* free_data */
+ NULL, /* copy_data */
+ brightcontrast_apply /* apply */
+};
+
/*********************** Modifier functions *************************/
static void sequence_modifier_type_info_init(void)
@@ -403,6 +490,7 @@ static void sequence_modifier_type_info_init(void)
INIT_TYPE(ColorBalance);
INIT_TYPE(Curves);
INIT_TYPE(HueCorrect);
+ INIT_TYPE(BrightContrast);
#undef INIT_TYPE
}
@@ -493,9 +581,13 @@ ImBuf *BKE_sequence_modifier_apply_stack(SeqRenderData context, Sequence *seq, I
SequenceModifierData *smd;
ImBuf *processed_ibuf = ibuf;
+ if (seq->modifiers.first && (seq->flag & SEQ_USE_LINEAR_MODIFIERS)) {
+ processed_ibuf = IMB_dupImBuf(ibuf);
+ BKE_sequencer_imbuf_from_sequencer_space(context.scene, processed_ibuf);
+ }
+
for (smd = seq->modifiers.first; smd; smd = smd->next) {
SequenceModifierTypeInfo *smti = BKE_sequence_modifier_type_info_get(smd->type);
- ImBuf *ibuf_new;
/* could happen if modifier is being removed or not exists in current version of blender */
if (!smti)
@@ -511,18 +603,17 @@ ImBuf *BKE_sequence_modifier_apply_stack(SeqRenderData context, Sequence *seq, I
if (processed_ibuf == ibuf)
processed_ibuf = IMB_dupImBuf(ibuf);
- ibuf_new = smti->apply(smd, processed_ibuf, mask);
-
- if (ibuf_new != processed_ibuf) {
- IMB_freeImBuf(processed_ibuf);
- processed_ibuf = ibuf_new;
- }
+ smti->apply(smd, processed_ibuf, mask);
if (mask)
IMB_freeImBuf(mask);
}
}
+ if (seq->modifiers.first && (seq->flag & SEQ_USE_LINEAR_MODIFIERS)) {
+ BKE_sequencer_imbuf_to_sequencer_space(context.scene, processed_ibuf, FALSE);
+ }
+
return processed_ibuf;
}
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 3699f802c91..90c3347a1df 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -62,7 +62,6 @@
#include "BKE_fcurve.h"
#include "BKE_scene.h"
#include "BKE_mask.h"
-#include "BKE_utildefines.h"
#include "RNA_access.h"
@@ -72,6 +71,7 @@
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
+#include "IMB_colormanagement.h"
#include "BKE_context.h"
#include "BKE_sound.h"
@@ -166,14 +166,12 @@ static void seq_free_strip(Strip *strip)
if (strip->transform) {
MEM_freeN(strip->transform);
}
- if (strip->color_balance) {
- MEM_freeN(strip->color_balance);
- }
MEM_freeN(strip);
}
-void BKE_sequence_free(Scene *scene, Sequence *seq)
+/* only give option to skip cache locally (static func) */
+static void BKE_sequence_free_ex(Scene *scene, Sequence *seq, const int do_cache)
{
if (seq->strip)
seq_free_strip(seq->strip);
@@ -207,21 +205,39 @@ void BKE_sequence_free(Scene *scene, Sequence *seq)
/* free modifiers */
BKE_sequence_modifier_clear(seq);
- BKE_sequencer_cache_cleanup_sequence(seq);
- BKE_sequencer_preprocessed_cache_cleanup_sequence(seq);
+ /* free cached data used by this strip,
+ * also invalidate cache for all dependent sequences
+ *
+ * be _very_ careful here, invalidating cache loops over the scene sequences and
+ * assumes the listbase is valid for all strips, this may not be the case if lists are being freed.
+ * this is optional BKE_sequence_invalidate_cache
+ */
+ if (do_cache) {
+ if (scene) {
+ BKE_sequence_invalidate_cache(scene, seq);
+ }
+ }
MEM_freeN(seq);
}
+void BKE_sequence_free(Scene *scene, Sequence *seq)
+{
+ BKE_sequence_free_ex(scene, seq, TRUE);
+}
+
+/* cache must be freed before calling this function
+ * since it leaves the seqbase in an invalid state */
static void seq_free_sequence_recurse(Scene *scene, Sequence *seq)
{
- Sequence *iseq;
+ Sequence *iseq, *iseq_next;
- for (iseq = seq->seqbase.first; iseq; iseq = iseq->next) {
+ for (iseq = seq->seqbase.first; iseq; iseq = iseq_next) {
+ iseq_next = iseq->next;
seq_free_sequence_recurse(scene, iseq);
}
- BKE_sequence_free(scene, seq);
+ BKE_sequence_free_ex(scene, seq, FALSE);
}
@@ -242,7 +258,7 @@ static void seq_free_clipboard_recursive(Sequence *seq_parent)
seq_free_clipboard_recursive(seq);
}
- BKE_sequence_free(NULL, seq_parent);
+ BKE_sequence_free_ex(NULL, seq_parent, FALSE);
}
void BKE_sequencer_free_clipboard(void)
@@ -271,28 +287,103 @@ Editing *BKE_sequencer_editing_ensure(Scene *scene)
void BKE_sequencer_editing_free(Scene *scene)
{
Editing *ed = scene->ed;
- MetaStack *ms;
Sequence *seq;
if (ed == NULL)
return;
+ /* this may not be the active scene!, could be smarter about this */
+ BKE_sequencer_cache_cleanup();
+
SEQ_BEGIN (ed, seq)
{
- BKE_sequence_free(scene, seq);
+ /* handle cache freeing above */
+ BKE_sequence_free_ex(scene, seq, FALSE);
}
SEQ_END
- while ((ms = ed->metastack.first)) {
- BLI_remlink(&ed->metastack, ms);
- MEM_freeN(ms);
- }
+ BLI_freelistN(&ed->metastack);
MEM_freeN(ed);
scene->ed = NULL;
}
+/*********************** Sequencer color space functions *************************/
+
+static void sequencer_imbuf_assign_spaces(Scene *scene, ImBuf *ibuf)
+{
+ IMB_colormanagement_assign_float_colorspace(ibuf, scene->sequencer_colorspace_settings.name);
+}
+
+void BKE_sequencer_imbuf_to_sequencer_space(Scene *scene, ImBuf *ibuf, int make_float)
+{
+ const char *from_colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR);
+ const char *to_colorspace = scene->sequencer_colorspace_settings.name;
+ int predivide = ibuf->flags & IB_cm_predivide;
+
+ if (!ibuf->rect_float) {
+ if (make_float && ibuf->rect) {
+ /* when converting byte buffer to float in sequencer we need to make float
+ * buffer be in sequencer's working space, which is currently only doable
+ * from linear space.
+ *
+ */
+
+ /*
+ * OCIO_TODO: would be nice to support direct single transform from byte to sequencer's
+ */
+
+ IMB_float_from_rect(ibuf);
+ }
+ else {
+ /* if there's only byte buffer in image it's already in compositor's working space,
+ * nothing to do here
+ */
+
+ return;
+ }
+ }
+
+ if (from_colorspace && from_colorspace[0] != '\0') {
+ if (ibuf->rect)
+ imb_freerectImBuf(ibuf);
+
+ IMB_colormanagement_transform_threaded(ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels,
+ from_colorspace, to_colorspace, predivide);
+ }
+}
+
+void BKE_sequencer_imbuf_from_sequencer_space(Scene *scene, ImBuf *ibuf)
+{
+ const char *from_colorspace = scene->sequencer_colorspace_settings.name;
+ const char *to_colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR);
+
+ if (!ibuf->rect_float)
+ return;
+
+ if (to_colorspace && to_colorspace[0] != '\0') {
+ int predivide = ibuf->flags & IB_cm_predivide;
+
+ IMB_colormanagement_transform_threaded(ibuf->rect_float, ibuf->x, ibuf->y, ibuf->channels,
+ from_colorspace, to_colorspace, predivide);
+ }
+}
+
+void BKE_sequencer_pixel_from_sequencer_space_v4(struct Scene *scene, float pixel[4])
+{
+ const char *from_colorspace = scene->sequencer_colorspace_settings.name;
+ const char *to_colorspace = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_SCENE_LINEAR);
+
+ if (to_colorspace && to_colorspace[0] != '\0') {
+ IMB_colormanagement_transform_v4(pixel, from_colorspace, to_colorspace);
+ }
+ else {
+ /* if no color management enables fallback to legacy conversion */
+ srgb_to_linearrgb_v4(pixel, pixel);
+ }
+}
+
/*********************** sequencer pipeline functions *************************/
SeqRenderData BKE_sequencer_new_render_data(Main *bmain, Scene *scene, int rectx, int recty, int preview_render_size)
@@ -370,7 +461,7 @@ static void seq_array(Editing *ed, Sequence ***seqarray, int *tot, int use_point
seq_build_array(&ed->seqbase, &array, 0);
}
-void BKE_seqence_iterator_begin(Editing *ed, SeqIterator *iter, int use_pointer)
+void BKE_sequence_iterator_begin(Editing *ed, SeqIterator *iter, int use_pointer)
{
memset(iter, 0, sizeof(*iter));
seq_array(ed, &iter->array, &iter->tot, use_pointer);
@@ -382,7 +473,7 @@ void BKE_seqence_iterator_begin(Editing *ed, SeqIterator *iter, int use_pointer)
}
}
-void BKE_seqence_iterator_next(SeqIterator *iter)
+void BKE_sequence_iterator_next(SeqIterator *iter)
{
if (++iter->cur < iter->tot)
iter->seq = iter->array[iter->cur];
@@ -390,7 +481,7 @@ void BKE_seqence_iterator_next(SeqIterator *iter)
iter->valid = 0;
}
-void BKE_seqence_iterator_end(SeqIterator *iter)
+void BKE_sequence_iterator_end(SeqIterator *iter)
{
if (iter->array)
MEM_freeN(iter->array);
@@ -582,7 +673,9 @@ void BKE_sequence_reload_new_file(Scene *scene, Sequence *seq, int lock_range)
BLI_path_abs(str, G.main->name);
if (seq->anim) IMB_free_anim(seq->anim);
- seq->anim = openanim(str, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0), seq->streamindex);
+
+ /* OCIO_TODO: support configurable input space for strips */
+ seq->anim = openanim(str, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0), seq->streamindex, NULL);
if (!seq->anim) {
return;
@@ -750,7 +843,7 @@ static int seqbase_unique_name_recursive_cb(Sequence *seq, void *arg_pt)
return 1;
}
-void BKE_seqence_base_unique_name_recursive(ListBase *seqbasep, Sequence *seq)
+void BKE_sequence_base_unique_name_recursive(ListBase *seqbasep, Sequence *seq)
{
SeqUniqueInfo sui;
char *dot;
@@ -1079,7 +1172,8 @@ static void seq_open_anim_file(Sequence *seq)
seq->strip->dir, seq->strip->stripdata->name);
BLI_path_abs(name, G.main->name);
- seq->anim = openanim(name, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0), seq->streamindex);
+ /* OCIO_TODO: support configurable input space for strips */
+ seq->anim = openanim(name, IB_rect | ((seq->flag & SEQ_FILTERY) ? IB_animdeinterlace : 0), seq->streamindex, NULL);
if (seq->anim == NULL) {
return;
@@ -1185,8 +1279,9 @@ static ImBuf *seq_proxy_fetch(SeqRenderData context, Sequence *seq, int cfra)
if (seq_proxy_get_fname(seq, cfra, render_size, name) == 0) {
return NULL;
}
-
- seq->strip->proxy->anim = openanim(name, IB_rect, 0);
+
+ /* proxies are generated in default color space */
+ seq->strip->proxy->anim = openanim(name, IB_rect, 0, NULL);
}
if (seq->strip->proxy->anim == NULL) {
return NULL;
@@ -1204,7 +1299,13 @@ static ImBuf *seq_proxy_fetch(SeqRenderData context, Sequence *seq, int cfra)
}
if (BLI_exists(name)) {
- return IMB_loadiffname(name, IB_rect);
+ /* OCIO_TODO: support configurable spaces for strips */
+ ImBuf *ibuf = IMB_loadiffname(name, IB_rect, NULL);
+
+ if (ibuf)
+ sequencer_imbuf_assign_spaces(context.scene, ibuf);
+
+ return ibuf;
}
else {
return NULL;
@@ -1242,7 +1343,8 @@ static void seq_proxy_build_frame(SeqRenderData context, Sequence *seq, int cfra
ibuf->planes = 24;
BLI_make_existing_file(name);
-
+
+ /* OCIO_TODO: support per-strip color space settings */
ok = IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat);
if (ok == 0) {
perror(name);
@@ -1669,26 +1771,6 @@ void BKE_sequencer_color_balance_apply(StripColorBalance *cb, ImBuf *ibuf, float
imb_freerectImBuf(ibuf);
}
-static void sequence_color_balance(SeqRenderData context, Sequence *seq, ImBuf *ibuf, float mul, int cfra)
-{
- StripColorBalance *cb = seq->strip->color_balance;
- ImBuf *mask_input = NULL;
- short make_float = seq->flag & SEQ_MAKE_FLOAT;
-
- if (seq->mask_sequence) {
- if (seq->mask_sequence != seq && !BKE_sequence_check_depend(seq, seq->mask_sequence)) {
- int make_float = ibuf->rect_float != NULL;
-
- mask_input = BKE_sequencer_render_mask_input(context, SEQUENCE_MASK_INPUT_STRIP, seq->mask_sequence, NULL, cfra, make_float);
- }
- }
-
- BKE_sequencer_color_balance_apply(cb, ibuf, mul, make_float, mask_input);
-
- if (mask_input)
- IMB_freeImBuf(mask_input);
-}
-
/*
* input preprocessing for SEQ_TYPE_IMAGE, SEQ_TYPE_MOVIE, SEQ_TYPE_MOVIECLIP and SEQ_TYPE_SCENE
*
@@ -1711,9 +1793,7 @@ int BKE_sequencer_input_have_to_preprocess(SeqRenderData UNUSED(context), Sequen
{
float mul;
- if (seq->flag & (SEQ_FILTERY | SEQ_USE_CROP | SEQ_USE_TRANSFORM | SEQ_FLIPX |
- SEQ_FLIPY | SEQ_USE_COLOR_BALANCE | SEQ_MAKE_PREMUL))
- {
+ if (seq->flag & (SEQ_FILTERY | SEQ_USE_CROP | SEQ_USE_TRANSFORM | SEQ_FLIPX | SEQ_FLIPY | SEQ_MAKE_PREMUL | SEQ_MAKE_FLOAT)) {
return TRUE;
}
@@ -1755,8 +1835,6 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra,
StripCrop c = {0};
StripTransform t = {0};
int sx, sy, dx, dy;
- double xscale = 1.0;
- double yscale = 1.0;
if (is_proxy_image) {
double f = seq_rendersize_to_scale_factor(context.preview_render_size);
@@ -1773,14 +1851,6 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra,
t = *seq->strip->transform;
}
- xscale = context.scene->r.xsch ? ((double) context.rectx / (double) context.scene->r.xsch) : 1.0;
- yscale = context.scene->r.ysch ? ((double) context.recty / (double) context.scene->r.ysch) : 1.0;
-
- c.left *= xscale; c.right *= xscale;
- c.top *= yscale; c.bottom *= yscale;
-
- t.xofs *= xscale; t.yofs *= yscale;
-
sx = ibuf->x - c.left - c.right;
sy = ibuf->y - c.top - c.bottom;
dx = sx;
@@ -1832,14 +1902,10 @@ static ImBuf *input_preprocess(SeqRenderData context, Sequence *seq, float cfra,
mul *= seq->blend_opacity / 100.0f;
}
- if (seq->flag & SEQ_USE_COLOR_BALANCE && seq->strip->color_balance) {
- sequence_color_balance(context, seq, ibuf, mul, cfra);
- mul = 1.0;
- }
-
if (seq->flag & SEQ_MAKE_FLOAT) {
- if (!ibuf->rect_float)
- IMB_float_from_rect_simple(ibuf);
+ if (!ibuf->rect_float) {
+ BKE_sequencer_imbuf_to_sequencer_space(context.scene, ibuf, TRUE);
+ }
if (ibuf->rect) {
imb_freerectImBuf(ibuf);
@@ -1905,6 +1971,8 @@ static void copy_to_ibuf_still(SeqRenderData context, Sequence *seq, float nr, I
* changing the cached image... */
ibuf = IMB_dupImBuf(ibuf);
+ sequencer_imbuf_assign_spaces(context.scene, ibuf);
+
if (nr == 0) {
BKE_sequencer_cache_put(context, seq, seq->start, SEQ_STRIPELEM_IBUF_STARTSTILL, ibuf);
}
@@ -2108,7 +2176,7 @@ static ImBuf *seq_render_movieclip_strip(SeqRenderData context, Sequence *seq, f
memset(&user, 0, sizeof(MovieClipUser));
- BKE_movieclip_user_set_frame(&user, nr + seq->anim_startofs);
+ BKE_movieclip_user_set_frame(&user, nr + seq->anim_startofs + seq->clip->start_frame);
user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL;
@@ -2169,7 +2237,7 @@ static ImBuf *seq_render_mask(SeqRenderData context, Mask *mask, float nr, short
BKE_maskrasterize_handle_init(mr_handle, mask_temp, context.rectx, context.recty, TRUE, TRUE, TRUE);
- BKE_mask_free(mask_temp);
+ BKE_mask_free_nolib(mask_temp);
MEM_freeN(mask_temp);
BKE_maskrasterize_buffer(mr_handle, context.rectx, context.recty, maskbuf);
@@ -2319,7 +2387,7 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float
/* opengl offscreen render */
BKE_scene_update_for_newframe(context.bmain, scene, scene->lay);
ibuf = sequencer_view3d_cb(scene, camera, context.rectx, context.recty,
- IB_rect, context.scene->r.seq_prev_type, TRUE, err_out);
+ IB_rect, context.scene->r.seq_prev_type, TRUE, FALSE, err_out);
if (ibuf == NULL) {
fprintf(stderr, "seq_render_scene_strip failed to get opengl buffer: %s\n", err_out);
}
@@ -2350,11 +2418,7 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float
}
/* float buffers in the sequencer are not linear */
- if (scene->r.color_mgt_flag & R_COLOR_MANAGEMENT)
- ibuf->profile = IB_PROFILE_LINEAR_RGB;
- else
- ibuf->profile = IB_PROFILE_NONE;
- IMB_convert_profile(ibuf, IB_PROFILE_SRGB);
+ BKE_sequencer_imbuf_to_sequencer_space(context.scene, ibuf, FALSE);
}
else if (rres.rect32) {
ibuf = IMB_allocImBuf(rres.rectx, rres.recty, 32, IB_rect);
@@ -2454,14 +2518,14 @@ static ImBuf *do_render_strip_uncached(SeqRenderData context, Sequence *seq, flo
BLI_path_abs(name, G.main->name);
}
- if (s_elem && (ibuf = IMB_loadiffname(name, IB_rect))) {
+ /* OCIO_TODO: support configurable space for image strips */
+ if (s_elem && (ibuf = IMB_loadiffname(name, IB_rect, NULL))) {
/* we don't need both (speed reasons)! */
if (ibuf->rect_float && ibuf->rect)
imb_freerectImBuf(ibuf);
/* all sequencer color is done in SRGB space, linear gives odd crossfades */
- if (ibuf->profile == IB_PROFILE_LINEAR_RGB)
- IMB_convert_profile(ibuf, IB_PROFILE_NONE);
+ BKE_sequencer_imbuf_to_sequencer_space(context.scene, ibuf, FALSE);
copy_to_ibuf_still(context, seq, nr, ibuf);
@@ -2510,15 +2574,18 @@ static ImBuf *do_render_strip_uncached(SeqRenderData context, Sequence *seq, flo
{
ibuf = seq_render_movieclip_strip(context, seq, nr);
- if (ibuf && use_preprocess) {
+ if (ibuf) {
+ /* duplicate frame so movie cache wouldn't be confused by sequencer's stuff */
ImBuf *i = IMB_dupImBuf(ibuf);
-
IMB_freeImBuf(ibuf);
-
ibuf = i;
+
+ if (ibuf->rect_float)
+ BKE_sequencer_imbuf_to_sequencer_space(context.scene, ibuf, FALSE);
+
+ copy_to_ibuf_still(context, seq, nr, ibuf);
}
- copy_to_ibuf_still(context, seq, nr, ibuf);
break;
}
@@ -2532,6 +2599,9 @@ static ImBuf *do_render_strip_uncached(SeqRenderData context, Sequence *seq, flo
}
}
+ if (ibuf)
+ sequencer_imbuf_assign_spaces(context.scene, ibuf);
+
return ibuf;
}
@@ -2565,15 +2635,18 @@ static ImBuf *seq_render_strip(SeqRenderData context, Sequence *seq, float cfra)
is_proxy_image = (ibuf != NULL);
}
- ibuf = do_render_strip_uncached(context, seq, cfra);
+ if (ibuf == NULL)
+ ibuf = do_render_strip_uncached(context, seq, cfra);
if (ibuf)
BKE_sequencer_preprocessed_cache_put(context, seq, cfra, SEQ_STRIPELEM_IBUF, ibuf);
}
}
- if (ibuf == NULL)
+ if (ibuf == NULL) {
ibuf = IMB_allocImBuf(context.rectx, context.recty, 32, IB_rect);
+ sequencer_imbuf_assign_spaces(context.scene, ibuf);
+ }
if (ibuf->x != context.rectx || ibuf->y != context.recty)
use_preprocess = TRUE;
@@ -2652,12 +2725,12 @@ static ImBuf *seq_render_strip_stack(SeqRenderData context, ListBase *seqbasep,
if (count == 1) {
out = seq_render_strip(context, seq_arr[0], cfra);
+
BKE_sequencer_cache_put(context, seq_arr[0], cfra, SEQ_STRIPELEM_IBUF_COMP, out);
return out;
}
-
for (i = count - 1; i >= 0; i--) {
int early_out;
Sequence *seq = seq_arr[i];
@@ -2935,6 +3008,9 @@ static void free_anim_seq(Sequence *seq)
/* check whether sequence cur depends on seq */
int BKE_sequence_check_depend(Sequence *seq, Sequence *cur)
{
+ if (cur->seq1 == seq || cur->seq2 == seq || cur->seq3 == seq)
+ return TRUE;
+
/* sequences are not intersecting in time, assume no dependency exists between them */
if (cur->enddisp < seq->startdisp || cur->startdisp > seq->enddisp)
return FALSE;
@@ -2956,20 +3032,11 @@ int BKE_sequence_check_depend(Sequence *seq, Sequence *cur)
return TRUE;
}
-static void sequence_invalidate_cache(Scene *scene, Sequence *seq, int invalidate_preprocess)
+static void sequence_do_invalidate_dependent(Sequence *seq, ListBase *seqbase)
{
- Editing *ed = scene->ed;
Sequence *cur;
- /* invalidate cache for current sequence */
- BKE_sequencer_cache_cleanup_sequence(seq);
-
- if (invalidate_preprocess)
- BKE_sequencer_preprocessed_cache_cleanup_sequence(seq);
-
- /* invalidate cache for all dependent sequences */
- SEQ_BEGIN (ed, cur)
- {
+ for (cur = seqbase->first; cur; cur = cur->next) {
if (cur == seq)
continue;
@@ -2977,60 +3044,71 @@ static void sequence_invalidate_cache(Scene *scene, Sequence *seq, int invalidat
BKE_sequencer_cache_cleanup_sequence(cur);
BKE_sequencer_preprocessed_cache_cleanup_sequence(cur);
}
+
+ if (cur->seqbase.first)
+ sequence_do_invalidate_dependent(seq, &cur->seqbase);
}
- SEQ_END
+}
+
+static void sequence_invalidate_cache(Scene *scene, Sequence *seq, int invalidate_self, int invalidate_preprocess)
+{
+ Editing *ed = scene->ed;
+
+ /* invalidate cache for current sequence */
+ if (invalidate_self)
+ BKE_sequencer_cache_cleanup_sequence(seq);
+
+ /* if invalidation is invoked from sequence free routine, effectdata would be NULL here */
+ if (seq->effectdata && seq->type == SEQ_TYPE_SPEED)
+ BKE_sequence_effect_speed_rebuild_map(scene, seq, TRUE);
+
+ if (invalidate_preprocess)
+ BKE_sequencer_preprocessed_cache_cleanup_sequence(seq);
+
+ /* invalidate cache for all dependent sequences */
+
+ /* NOTE: can not use SEQ_BEGIN/SEQ_END here because that macro will change sequence's depth,
+ * which makes transformation routines work incorrect
+ */
+ sequence_do_invalidate_dependent(seq, &ed->seqbase);
}
void BKE_sequence_invalidate_cache(Scene *scene, Sequence *seq)
{
- sequence_invalidate_cache(scene, seq, TRUE);
+ sequence_invalidate_cache(scene, seq, TRUE, TRUE);
+}
+
+void BKE_sequence_invalidate_dependent(Scene *scene, Sequence *seq)
+{
+ sequence_invalidate_cache(scene, seq, FALSE, TRUE);
}
void BKE_sequence_invalidate_cache_for_modifier(Scene *scene, Sequence *seq)
{
- sequence_invalidate_cache(scene, seq, FALSE);
+ sequence_invalidate_cache(scene, seq, TRUE, FALSE);
}
-void BKE_sequencer_free_imbuf(Scene *scene, ListBase *seqbase, int check_mem_usage, int keep_file_handles)
+void BKE_sequencer_free_imbuf(Scene *scene, ListBase *seqbase, int for_render)
{
Sequence *seq;
- if (check_mem_usage) {
- /* Let the cache limitor take care of this (schlaile) */
- /* While render let's keep all memory available for render
- * (ton)
- * At least if free memory is tight...
- * This can make a big difference in encoding speed
- * (it is around 4 times(!) faster, if we do not waste time
- * on freeing _all_ buffers every time on long timelines...)
- * (schlaile)
- */
-
- uintptr_t mem_in_use;
- uintptr_t mmap_in_use;
- uintptr_t max;
-
- mem_in_use = MEM_get_memory_in_use();
- mmap_in_use = MEM_get_mapped_memory_in_use();
- max = MEM_CacheLimiter_get_maximum();
-
- if (max == 0 || mem_in_use + mmap_in_use <= max) {
- return;
- }
- }
-
BKE_sequencer_cache_cleanup();
-
+
for (seq = seqbase->first; seq; seq = seq->next) {
+ if (for_render && CFRA >= seq->startdisp && CFRA <= seq->enddisp) {
+ continue;
+ }
+
if (seq->strip) {
- if (seq->type == SEQ_TYPE_MOVIE && !keep_file_handles)
+ if (seq->type == SEQ_TYPE_MOVIE) {
free_anim_seq(seq);
+ }
if (seq->type == SEQ_TYPE_SPEED) {
BKE_sequence_effect_speed_rebuild_map(scene, seq, 1);
}
}
if (seq->type == SEQ_TYPE_META) {
- BKE_sequencer_free_imbuf(scene, &seq->seqbase, FALSE, keep_file_handles);
+ BKE_sequencer_free_imbuf(scene, &seq->seqbase, for_render);
}
if (seq->type == SEQ_TYPE_SCENE) {
/* FIXME: recurs downwards,
@@ -3626,8 +3704,8 @@ int BKE_sequence_swap(Sequence *seq_a, Sequence *seq_b, const char **error_str)
SWAP(float, seq_a->blend_opacity, seq_b->blend_opacity);
- SWAP(void *, seq_a->prev, seq_b->prev);
- SWAP(void *, seq_a->next, seq_b->next);
+ SWAP(Sequence *, seq_a->prev, seq_b->prev);
+ SWAP(Sequence *, seq_a->next, seq_b->next);
SWAP(int, seq_a->start, seq_b->start);
SWAP(int, seq_a->startofs, seq_b->startofs);
SWAP(int, seq_a->endofs, seq_b->endofs);
@@ -3805,7 +3883,7 @@ static void seq_load_apply(Scene *scene, Sequence *seq, SeqLoadInfo *seq_load)
{
if (seq) {
BLI_strncpy(seq->name + 2, seq_load->name, sizeof(seq->name) - 2);
- BKE_seqence_base_unique_name_recursive(&scene->ed->seqbase, seq);
+ BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq);
if (seq_load->flag & SEQ_LOAD_FRAME_ADVANCE) {
seq_load->start_frame += (seq->enddisp - seq->startdisp);
@@ -3892,10 +3970,10 @@ Sequence *BKE_sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoad
sound = sound_new_file(bmain, seq_load->path); /* handles relative paths */
if (sound == NULL || sound->playback_handle == NULL) {
- /*
+#if 0
if (op)
BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
- */
+#endif
return NULL;
}
@@ -3904,10 +3982,10 @@ Sequence *BKE_sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoad
if (info.specs.channels == AUD_CHANNELS_INVALID) {
sound_delete(bmain, sound);
- /*
+#if 0
if (op)
BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
- */
+#endif
return NULL;
}
@@ -3916,7 +3994,7 @@ Sequence *BKE_sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoad
seq->type = SEQ_TYPE_SOUND_RAM;
seq->sound = sound;
BLI_strncpy(seq->name + 2, "Sound", SEQ_NAME_MAXSTR - 2);
- BKE_seqence_base_unique_name_recursive(&scene->ed->seqbase, seq);
+ BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq);
/* basic defaults */
seq->strip = strip = MEM_callocN(sizeof(Strip), "strip");
@@ -3963,7 +4041,8 @@ Sequence *BKE_sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoad
BLI_strncpy(path, seq_load->path, sizeof(path));
BLI_path_abs(path, G.main->name);
- an = openanim(path, IB_rect, 0);
+ /* OCIO_TODO: support configurable input space for strips */
+ an = openanim(path, IB_rect, 0, NULL);
if (an == NULL)
return NULL;
@@ -3975,7 +4054,7 @@ Sequence *BKE_sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoad
seq->anim = an;
seq->anim_preseek = IMB_anim_get_preseek(an);
BLI_strncpy(seq->name + 2, "Movie", SEQ_NAME_MAXSTR - 2);
- BKE_seqence_base_unique_name_recursive(&scene->ed->seqbase, seq);
+ BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq);
/* basic defaults */
seq->strip = strip = MEM_callocN(sizeof(Strip), "strip");
@@ -4032,10 +4111,6 @@ static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dup
seqn->strip->proxy->anim = NULL;
}
- if (seq->strip->color_balance) {
- seqn->strip->color_balance = MEM_dupallocN(seq->strip->color_balance);
- }
-
if (seqn->modifiers.first) {
seqn->modifiers.first = seqn->modifiers.last = NULL;
@@ -4091,7 +4166,7 @@ static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dup
}
if (dupe_flag & SEQ_DUPE_UNIQUE_NAME)
- BKE_seqence_base_unique_name_recursive(&scene->ed->seqbase, seqn);
+ BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seqn);
if (dupe_flag & SEQ_DUPE_ANIM)
BKE_sequencer_dupe_animdata(scene, seq->name + 2, seqn->name + 2);
@@ -4146,7 +4221,7 @@ void BKE_sequence_base_dupli_recursive(Scene *scene, Scene *scene_to, ListBase *
/* called on draw, needs to be fast,
* we could cache and use a flag if we want to make checks for file paths resolving for eg. */
-int BKE_seqence_is_valid_check(Sequence *seq)
+int BKE_sequence_is_valid_check(Sequence *seq)
{
switch (seq->type) {
case SEQ_TYPE_MASK:
diff --git a/source/blender/blenkernel/intern/shrinkwrap.c b/source/blender/blenkernel/intern/shrinkwrap.c
index f9399946570..9a8bcaabe0c 100644
--- a/source/blender/blenkernel/intern/shrinkwrap.c
+++ b/source/blender/blenkernel/intern/shrinkwrap.c
@@ -313,7 +313,7 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc)
auxMesh = object_get_derived_final(calc->smd->auxTarget);
if (!auxMesh)
return;
- space_transform_setup(&local2aux, calc->ob, calc->smd->auxTarget);
+ SPACE_TRANSFORM_SETUP(&local2aux, calc->ob, calc->smd->auxTarget);
}
//After sucessufuly build the trees, start projection vertexs
@@ -500,7 +500,7 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Object *ob, DerivedM
//TODO there might be several "bugs" on non-uniform scales matrixs
//because it will no longer be nearest surface, not sphere projection
//because space has been deformed
- space_transform_setup(&calc.local2target, ob, smd->target);
+ SPACE_TRANSFORM_SETUP(&calc.local2target, ob, smd->target);
//TODO: smd->keepDist is in global units.. must change to local
calc.keepDist = smd->keepDist;
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index f194c5e9d05..1909e65d0ab 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -80,10 +80,10 @@
/* UNUSED so far, may be enabled later */
/* #define USE_SMOKE_COLLISION_DM */
-#ifdef WITH_SMOKE
-
#include "smoke_API.h"
+#ifdef WITH_SMOKE
+
#ifdef _WIN32
#include <time.h>
#include <stdio.h>
@@ -148,7 +148,7 @@ static void fill_scs_points(Object *ob, DerivedMesh *dm, SmokeCollSettings *scs)
/* Stubs to use when smoke is disabled */
struct WTURBULENCE *smoke_turbulence_init(int *UNUSED(res), int UNUSED(amplify), int UNUSED(noisetype)) { return NULL; }
-struct FLUID_3D *smoke_init(int *UNUSED(res), float *UNUSED(p0)) { return NULL; }
+// struct FLUID_3D *smoke_init(int *UNUSED(res), float *UNUSED(p0)) { return NULL; }
void smoke_free(struct FLUID_3D *UNUSED(fluid)) {}
float *smoke_get_density(struct FLUID_3D *UNUSED(fluid)) { return NULL; }
void smoke_turbulence_free(struct WTURBULENCE *UNUSED(wt)) {}
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index 008dc332710..f47c931e309 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -143,13 +143,15 @@ typedef struct SB_thread_context {
} SB_thread_context;
#define NLF_BUILD 1
-#define NLF_SOLVE 2
+#if 0
+# define NLF_SOLVE 2
+#endif
#define MID_PRESERVE 1
#define SOFTGOALSNAP 0.999f
/* if bp-> goal is above make it a *forced follow original* and skip all ODE stuff for this bp
- * removes *unnecessary* stiffnes from ODE system
+ * removes *unnecessary* stiffness from ODE system
*/
#define HEUNWARNLIMIT 1 /* 500 would be fine i think for detecting severe *stiff* stuff */
@@ -2291,7 +2293,7 @@ static int _softbody_calc_forces_slice_in_a_thread(Scene *scene, Object *ob, flo
/* done goal stuff */
/* gravitation */
- if (sb && scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) {
+ if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) {
float gravity[3];
copy_v3_v3(gravity, scene->physics_settings.gravity);
mul_v3_fl(gravity, sb_grav_force_scale(ob)*_final_mass(ob, bp)*sb->effector_weights->global_gravity); /* individual mass of node here */
@@ -3923,7 +3925,7 @@ static void softbody_step(Scene *scene, Object *ob, SoftBody *sb, float dtime)
sst=PIL_check_seconds_timer();
/* Integration back in time is possible in theory, but pretty useless here.
- * So we refuse to do so. Since we do not know anything about 'outside' canges
+ * So we refuse to do so. Since we do not know anything about 'outside' changes
* especially colliders we refuse to go more than 10 frames.
*/
if (dtime < 0 || dtime > 10.5f) return;
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index 14360297ec0..385d1bb6fc5 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -50,7 +50,6 @@
# include "AUD_C-API.h"
#endif
-#include "BKE_utildefines.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_sound.h"
@@ -774,37 +773,36 @@ void sound_force_device(int UNUSED(device)) {}
void sound_init_once(void) {}
void sound_init(struct Main *UNUSED(bmain)) {}
void sound_exit(void) {}
-void sound_cache(struct bSound* UNUSED(sound)) { }
-void sound_delete_cache(struct bSound* UNUSED(sound)) {}
-void sound_load(struct Main *UNUSED(bmain), struct bSound* UNUSED(sound)) {}
+void sound_cache(struct bSound *UNUSED(sound)) { }
+void sound_delete_cache(struct bSound *UNUSED(sound)) {}
+void sound_load(struct Main *UNUSED(bmain), struct bSound *UNUSED(sound)) {}
void sound_create_scene(struct Scene *UNUSED(scene)) {}
void sound_destroy_scene(struct Scene *UNUSED(scene)) {}
void sound_mute_scene(struct Scene *UNUSED(scene), int UNUSED(muted)) {}
-void* sound_scene_add_scene_sound(struct Scene *UNUSED(scene), struct Sequence* UNUSED(sequence), int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) { return NULL; }
-void* sound_scene_add_scene_sound_defaults(struct Scene *UNUSED(scene), struct Sequence* UNUSED(sequence)) { return NULL; }
-void* sound_add_scene_sound(struct Scene *UNUSED(scene), struct Sequence* UNUSED(sequence), int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) { return NULL; }
-void* sound_add_scene_sound_defaults(struct Scene *UNUSED(scene), struct Sequence* UNUSED(sequence)) { return NULL; }
-void sound_remove_scene_sound(struct Scene *UNUSED(scene), void* UNUSED(handle)) {}
-void sound_mute_scene_sound(void* UNUSED(handle), char UNUSED(mute)) {}
-void sound_move_scene_sound(struct Scene *UNUSED(scene), void* UNUSED(handle), int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) {}
+void *sound_scene_add_scene_sound(struct Scene *UNUSED(scene), struct Sequence *UNUSED(sequence), int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) { return NULL; }
+void *sound_scene_add_scene_sound_defaults(struct Scene *UNUSED(scene), struct Sequence *UNUSED(sequence)) { return NULL; }
+void *sound_add_scene_sound(struct Scene *UNUSED(scene), struct Sequence *UNUSED(sequence), int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) { return NULL; }
+void *sound_add_scene_sound_defaults(struct Scene *UNUSED(scene), struct Sequence *UNUSED(sequence)) { return NULL; }
+void sound_remove_scene_sound(struct Scene *UNUSED(scene), void *UNUSED(handle)) {}
+void sound_mute_scene_sound(void *UNUSED(handle), char UNUSED(mute)) {}
+void sound_move_scene_sound(struct Scene *UNUSED(scene), void *UNUSED(handle), int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) {}
void sound_move_scene_sound_defaults(struct Scene *UNUSED(scene), struct Sequence *UNUSED(sequence)) {}
void sound_play_scene(struct Scene *UNUSED(scene)) {}
void sound_stop_scene(struct Scene *UNUSED(scene)) {}
void sound_seek_scene(struct Main *UNUSED(bmain), struct Scene *UNUSED(scene)) {}
float sound_sync_scene(struct Scene *UNUSED(scene)) { return NAN_FLT; }
int sound_scene_playing(struct Scene *UNUSED(scene)) { return -1; }
-int sound_read_sound_buffer(struct bSound* UNUSED(sound), float* UNUSED(buffer), int UNUSED(length), float UNUSED(start), float UNUSED(end)) { return 0; }
-void sound_read_waveform(struct bSound* sound) { (void)sound; }
+void sound_read_waveform(struct bSound *sound) { (void)sound; }
void sound_init_main(struct Main *bmain) { (void)bmain; }
void sound_set_cfra(int cfra) { (void)cfra; }
-void sound_update_sequencer(struct Main* main, struct bSound* sound) { (void)main; (void)sound; }
-void sound_update_scene(struct Scene* scene) { (void)scene; }
-void sound_update_scene_sound(void* handle, struct bSound* sound) { (void)handle; (void)sound; }
+void sound_update_sequencer(struct Main *main, struct bSound *sound) { (void)main; (void)sound; }
+void sound_update_scene(struct Scene *scene) { (void)scene; }
+void sound_update_scene_sound(void *handle, struct bSound *sound) { (void)handle; (void)sound; }
void sound_update_scene_listener(struct Scene *scene) { (void)scene; }
void sound_update_fps(struct Scene *scene) { (void)scene; }
-void sound_set_scene_sound_volume(void* handle, float volume, char animated) { (void)handle; (void)volume; (void)animated; }
-void sound_set_scene_sound_pan(void* handle, float pan, char animated) { (void)handle; (void)pan; (void)animated; }
+void sound_set_scene_sound_volume(void *handle, float volume, char animated) { (void)handle; (void)volume; (void)animated; }
+void sound_set_scene_sound_pan(void *handle, float pan, char animated) { (void)handle; (void)pan; (void)animated; }
void sound_set_scene_volume(struct Scene *scene, float volume) { (void)scene; (void)volume; }
-void sound_set_scene_sound_pitch(void* handle, float pitch, char animated) { (void)handle; (void)pitch; (void)animated; }
-float sound_get_length(struct bSound* sound) { (void)sound; return 0; }
+void sound_set_scene_sound_pitch(void *handle, float pitch, char animated) { (void)handle; (void)pitch; (void)animated; }
+float sound_get_length(struct bSound *sound) { (void)sound; return 0; }
#endif // WITH_AUDASPACE
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 99486f47629..e1a7bb792f8 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -513,10 +513,14 @@ static float *get_ss_weights(WeightTable *wtable, int gridCuts, int faceLen)
w2 = (1.0f - fx + fac2 * fx * -fac) * (fy);
w4 = (fx) * (1.0f - fy + -fac2 * fy * fac);
- fac2 = 1.0f - (w1 + w2 + w4);
- fac2 = fac2 / (float)(faceLen - 3);
- for (j = 0; j < faceLen; j++)
- w[j] = fac2;
+ /* these values aren't used for tri's and cause divide by zero */
+ if (faceLen > 3) {
+ fac2 = 1.0f - (w1 + w2 + w4);
+ fac2 = fac2 / (float)(faceLen - 3);
+ for (j = 0; j < faceLen; j++) {
+ w[j] = fac2;
+ }
+ }
w[i] = w1;
w[(i - 1 + faceLen) % faceLen] = w2;
@@ -1468,9 +1472,9 @@ static void ccgdm_getVertCos(DerivedMesh *dm, float (*cos)[3])
}
static void ccgDM_foreachMappedVert(
- DerivedMesh *dm,
- void (*func)(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]),
- void *userData)
+ DerivedMesh *dm,
+ void (*func)(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]),
+ void *userData)
{
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
CCGVertIterator *vi;
@@ -1490,9 +1494,9 @@ static void ccgDM_foreachMappedVert(
}
static void ccgDM_foreachMappedEdge(
- DerivedMesh *dm,
- void (*func)(void *userData, int index, const float v0co[3], const float v1co[3]),
- void *userData)
+ DerivedMesh *dm,
+ void (*func)(void *userData, int index, const float v0co[3], const float v1co[3]),
+ void *userData)
{
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
CCGSubSurf *ss = ccgdm->ss;
@@ -2588,9 +2592,9 @@ static void ccgDM_drawMappedEdgesInterp(DerivedMesh *dm,
}
static void ccgDM_foreachMappedFaceCenter(
- DerivedMesh *dm,
- void (*func)(void *userData, int index, const float co[3], const float no[3]),
- void *userData)
+ DerivedMesh *dm,
+ void (*func)(void *userData, int index, const float co[3], const float no[3]),
+ void *userData)
{
CCGDerivedMesh *ccgdm = (CCGDerivedMesh *) dm;
CCGSubSurf *ss = ccgdm->ss;
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 7de5f97588b..05d0705107d 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -48,6 +48,7 @@
#include "DNA_constraint_types.h"
#include "DNA_controller_types.h"
+#include "DNA_actuator_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
@@ -528,6 +529,7 @@ void BKE_text_unlink(Main *bmain, Text *text)
SpaceLink *sl;
Object *ob;
bController *cont;
+ bActuator *act;
bConstraint *con;
short update;
@@ -541,6 +543,15 @@ void BKE_text_unlink(Main *bmain, Text *text)
if (pc->text == text) pc->text = NULL;
}
}
+ /* game actuators */
+ for (act = ob->actuators.first; act; act = act->next) {
+ if (act->type == ACT_2DFILTER) {
+ bTwoDFilterActuator *tfa;
+
+ tfa = act->data;
+ if (tfa->text == text) tfa->text = NULL;
+ }
+ }
/* pyconstraints */
update = 0;
@@ -1684,7 +1695,8 @@ void txt_print_undo(Text *text)
printf("%c%c%c", text->undo_buf[i], text->undo_buf[i + 1], text->undo_buf[i + 2]);
i += 3;
break;
- case UNDO_INSERT_4: case UNDO_BS_4: case UNDO_DEL_4: {
+ case UNDO_INSERT_4: case UNDO_BS_4: case UNDO_DEL_4:
+ {
unsigned int uc;
char c[BLI_UTF8_MAX + 1];
size_t c_len;
@@ -1918,6 +1930,7 @@ static unsigned int txt_undo_read_unicode(const char *undo_buf, int *undo_pos, s
break;
case 4: /* 32-bit unicode symbol */
unicode = txt_undo_read_uint32(undo_buf, undo_pos);
+ break;
default:
/* should never happen */
BLI_assert(0);
@@ -1969,6 +1982,7 @@ static unsigned int txt_redo_read_unicode(const char *undo_buf, int *undo_pos, s
break;
case 4: /* 32-bit unicode symbol */
unicode = txt_undo_read_uint32(undo_buf, undo_pos);
+ break;
default:
/* should never happen */
BLI_assert(0);
@@ -3030,30 +3044,6 @@ void txt_uncomment(Text *text)
}
}
-
-void txt_move_lines_up(struct Text *text)
-{
- TextLine *prev_line;
-
- if (!text || !text->curl || !text->sell) return;
-
- txt_order_cursors(text);
-
- prev_line = text->curl->prev;
-
- if (!prev_line) return;
-
- BLI_remlink(&text->lines, prev_line);
- BLI_insertlinkafter(&text->lines, text->sell, prev_line);
-
- txt_make_dirty(text);
- txt_clean_text(text);
-
- if (!undoing) {
- txt_undo_add_op(text, UNDO_MOVE_LINES_UP);
- }
-}
-
void txt_move_lines(struct Text *text, const int direction)
{
TextLine *line_other;
@@ -3093,7 +3083,6 @@ int setcurr_tab_spaces(Text *text, int space)
const char *comm = "#";
const char indent = (text->flags & TXT_TABSTOSPACES) ? ' ' : '\t';
static const char *back_words[] = {"return", "break", "continue", "pass", "yield", NULL};
- if (!text) return 0;
if (!text->curl) return 0;
while (text->curl->line[i] == indent) {
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index 2f54fe6cebd..9dd83181521 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -56,7 +56,6 @@
#include "IMB_imbuf.h"
-#include "BKE_utildefines.h"
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_ocean.h"
@@ -339,7 +338,7 @@ void colorband_table_RGBA(ColorBand *coba, float **array, int *size)
do_colorband(coba, (float)a / (float)CM_TABLE, &(*array)[a * 4]);
}
-int vergcband(const void *a1, const void *a2)
+static int vergcband(const void *a1, const void *a2)
{
const CBData *x1 = a1, *x2 = a2;
@@ -1074,19 +1073,21 @@ void set_current_material_texture(Material *ma, Tex *newtex)
{
Tex *tex = NULL;
bNode *node;
-
- if (ma && ma->use_nodes && ma->nodetree) {
- node = nodeGetActiveID(ma->nodetree, ID_TE);
- if (node) {
- tex = (Tex *)node->id;
- id_us_min(&tex->id);
+ if ((ma->use_nodes && ma->nodetree) &&
+ (node = nodeGetActiveID(ma->nodetree, ID_TE)))
+ {
+ tex = (Tex *)node->id;
+ id_us_min(&tex->id);
+ if (newtex) {
node->id = &newtex->id;
id_us_plus(&newtex->id);
- ma = NULL;
+ }
+ else {
+ node->id = NULL;
}
}
- if (ma) {
+ else {
int act = (int)ma->texact;
tex = (ma->mtex[act]) ? ma->mtex[act]->tex : NULL;
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c
index 78e7dab045f..c9d7ec3964f 100644
--- a/source/blender/blenkernel/intern/tracking.c
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -335,7 +335,7 @@ static void search_pixel_to_marker_unified(int frame_width, int frame_height,
}
/* Each marker has 5 coordinates associated with it that get warped with
- * tracking: the four corners ("pattern_corners"), and the cernter ("pos").
+ * tracking: the four corners ("pattern_corners"), and the center ("pos").
* This function puts those 5 points into the appropriate frame for tracking
* (the "search" coordinate frame).
*/
@@ -411,6 +411,8 @@ void BKE_tracking_clipboard_free(void)
track = next_track;
}
+
+ tracking_clipboard.tracks.first = tracking_clipboard.tracks.last = NULL;
}
void BKE_tracking_clipboard_copy_tracks(MovieTracking *tracking, MovieTrackingObject *object)
@@ -453,7 +455,7 @@ void BKE_tracking_clipboard_paste_tracks(MovieTracking *tracking, MovieTrackingO
/*********************** Tracks *************************/
-static void tracking_marker_insert_disabled(MovieTrackingTrack *track, MovieTrackingMarker *ref_marker,
+static void tracking_marker_insert_disabled(MovieTrackingTrack *track, const MovieTrackingMarker *ref_marker,
int before, int overwrite)
{
MovieTrackingMarker marker_new;
@@ -854,7 +856,7 @@ static void track_mask_gpencil_layer_rasterize(int frame_width, int frame_height
}
/* TODO: add an option to control whether AA is enabled or not */
- PLX_raskterize((float (*)[2])mask_points, stroke->totpoints, mask, mask_width, mask_height, FALSE);
+ PLX_raskterize((float (*)[2])mask_points, stroke->totpoints, mask, mask_width, mask_height);
MEM_freeN(mask_points);
}
@@ -1041,14 +1043,6 @@ void BKE_tracking_marker_clamp(MovieTrackingMarker *marker, int event)
}
}
}
- else if (event == CLAMP_SEARCH_DIM) {
- float dim[2];
- sub_v2_v2v2(dim, pat_max, pat_min);
- for (a = 0; a < 2; a++) {
- marker->search_min[a] = pat_min[a];
- marker->search_max[a] = pat_max[a];
- }
- }
}
MovieTrackingMarker *BKE_tracking_marker_get(MovieTrackingTrack *track, int framenr)
@@ -1625,7 +1619,6 @@ ImBuf *BKE_tracking_sample_pattern(int frame_width, int frame_height, ImBuf *sea
float *mask = NULL;
pattern_ibuf = IMB_allocImBuf(num_samples_x, num_samples_y, 32, IB_rectfloat);
- pattern_ibuf->profile = IB_PROFILE_LINEAR_RGB;
if (!search_ibuf->rect_float) {
IMB_float_from_rect(search_ibuf);
@@ -1720,7 +1713,6 @@ ImBuf *BKE_tracking_get_search_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, Mov
h = (marker->search_max[1] - marker->search_min[1]) * ibuf->y;
searchibuf = IMB_allocImBuf(w, h, 32, ibuf->rect_float ? IB_rectfloat : IB_rect);
- searchibuf->profile = ibuf->profile;
IMB_rectcpy(searchibuf, ibuf, 0, 0, x, y, w, h);
@@ -2029,7 +2021,7 @@ static void track_context_free(void *customdata)
{
TrackContext *track_context = (TrackContext *)customdata;
-#if WITH_LIBMV
+#ifdef WITH_LIBMV
if (track_context->search_area)
MEM_freeN(track_context->search_area);
@@ -2223,8 +2215,8 @@ static ImBuf *tracking_context_get_frame_ibuf(MovieTrackingContext *context, int
return ibuf;
}
-MovieTrackingMarker *tracking_context_get_keyframed_marker(MovieTrackingContext *context, MovieTrackingTrack *track,
- MovieTrackingMarker *marker)
+static MovieTrackingMarker *tracking_context_get_keyframed_marker(MovieTrackingContext *context, MovieTrackingTrack *track,
+ MovieTrackingMarker *marker)
{
int a = marker - track->markers;
MovieTrackingMarker *marker_keyed = marker;
@@ -2289,9 +2281,9 @@ static ImBuf *tracking_context_get_reference_ibuf(MovieTrackingContext *context,
return ibuf;
}
-static void track_context_update_reference(MovieTrackingContext *context, TrackContext *track_context,
- MovieTrackingTrack *track, MovieTrackingMarker *marker, int curfra,
- int frame_width, int frame_height)
+static int track_context_update_reference(MovieTrackingContext *context, TrackContext *track_context,
+ MovieTrackingTrack *track, MovieTrackingMarker *marker, int curfra,
+ int frame_width, int frame_height)
{
MovieTrackingMarker *marker_keyed = NULL;
ImBuf *reference_ibuf = NULL;
@@ -2299,6 +2291,10 @@ static void track_context_update_reference(MovieTrackingContext *context, TrackC
/* calculate patch for keyframed position */
reference_ibuf = tracking_context_get_reference_ibuf(context, track, marker, curfra, &marker_keyed);
+
+ if (!reference_ibuf)
+ return FALSE;
+
track_context->marker = *marker_keyed;
if (track_context->search_area) {
@@ -2317,6 +2313,8 @@ static void track_context_update_reference(MovieTrackingContext *context, TrackC
}
IMB_freeImBuf(reference_ibuf);
+
+ return TRUE;
}
static void tracking_configure_tracker(TrackContext *track_context, MovieTrackingTrack *track,
@@ -2402,7 +2400,7 @@ static void tracking_insert_new_marker(MovieTrackingContext *context, MovieTrack
* if so -- create disabled marker before currently tracking "segment"
*/
- tracking_marker_insert_disabled(track, &new_marker, !context->backwards, FALSE);
+ tracking_marker_insert_disabled(track, old_marker, !context->backwards, FALSE);
}
/* insert currently tracked marker */
@@ -2481,8 +2479,12 @@ int BKE_tracking_context_step(MovieTrackingContext *context)
float *patch_new;
if (need_readjust) {
- track_context_update_reference(context, track_context, track, marker,
- curfra, frame_width, frame_height);
+ if (track_context_update_reference(context, track_context, track, marker,
+ curfra, frame_width, frame_height) == FALSE)
+ {
+ /* happens when reference frame fails to be loaded */
+ continue;
+ }
}
/* for now track to the same search area dimension as marker has got for current frame
@@ -2776,7 +2778,7 @@ static int reconstruct_count_tracks_on_both_keyframes(MovieTracking *tracking, L
int BKE_tracking_reconstruction_check(MovieTracking *tracking, MovieTrackingObject *object, char *error_msg, int error_size)
{
-#if WITH_LIBMV
+#ifdef WITH_LIBMV
ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
if (tracking->settings.motion_flag & TRACKING_MOTION_MODAL) {
@@ -3315,7 +3317,6 @@ static ImBuf *stabilization_allocate_ibuf(ImBuf *cacheibuf, ImBuf *srcibuf, int
}
else {
cacheibuf = IMB_allocImBuf(srcibuf->x, srcibuf->y, srcibuf->planes, flags);
- cacheibuf->profile = srcibuf->profile;
}
return cacheibuf;
diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c
index da5e7ff3db7..46836b1f8d1 100644
--- a/source/blender/blenkernel/intern/unit.c
+++ b/source/blender/blenkernel/intern/unit.c
@@ -350,7 +350,7 @@ static int unit_as_string(char *str, int len_max, double value, int prec, bUnitC
/* Add unit prefix and strip zeros */
/* replace trailing zero's with spaces
- * so the number is less complicated but allignment in a button wont
+ * so the number is less complicated but alignment in a button wont
* jump about while dragging */
i = len - 1;
diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c
index dd71e43182e..434bfe19c1f 100644
--- a/source/blender/blenkernel/intern/world.c
+++ b/source/blender/blenkernel/intern/world.c
@@ -51,14 +51,14 @@
#include "BKE_node.h"
#include "BKE_world.h"
-void BKE_world_free(World *wrld)
+void BKE_world_free_ex(World *wrld, int do_id_user)
{
MTex *mtex;
int a;
for (a = 0; a < MAX_MTEX; a++) {
mtex = wrld->mtex[a];
- if (mtex && mtex->tex) mtex->tex->id.us--;
+ if (do_id_user && mtex && mtex->tex) mtex->tex->id.us--;
if (mtex) MEM_freeN(mtex);
}
BKE_previewimg_free(&wrld->preview);
@@ -67,7 +67,7 @@ void BKE_world_free(World *wrld)
/* is no lib link block, but world extension */
if (wrld->nodetree) {
- ntreeFreeTree(wrld->nodetree);
+ ntreeFreeTree_ex(wrld->nodetree, do_id_user);
MEM_freeN(wrld->nodetree);
}
@@ -75,6 +75,10 @@ void BKE_world_free(World *wrld)
wrld->id.icon_id = 0;
}
+void BKE_world_free(World *wrld)
+{
+ BKE_world_free_ex(wrld, TRUE);
+}
World *add_world(const char *name)
{
diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index f22fd74baf4..ff1fdebb728 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -69,8 +69,6 @@
#include "ffmpeg_compat.h"
-extern void do_init_ffmpeg(void);
-
static int ffmpeg_type = 0;
static int ffmpeg_codec = CODEC_ID_MPEG4;
static int ffmpeg_audio_codec = CODEC_ID_NONE;
@@ -101,6 +99,8 @@ static AUD_Device *audio_mixdown_device = 0;
#define FFMPEG_AUTOSPLIT_SIZE 2000000000
+#define PRINT if (G.debug & G_DEBUG_FFMPEG) printf
+
/* Delete a picture buffer */
static void delete_picture(AVFrame *f)
@@ -125,9 +125,7 @@ static int write_audio_frame(void)
AUD_readDevice(audio_mixdown_device, audio_input_buffer, audio_input_samples);
audio_time += (double) audio_input_samples / (double) c->sample_rate;
- pkt.size = avcodec_encode_audio(c, audio_output_buffer,
- audio_outbuf_size,
- (short *)audio_input_buffer);
+ pkt.size = avcodec_encode_audio(c, audio_output_buffer, audio_outbuf_size, (short *) audio_input_buffer);
if (pkt.size < 0) {
// XXX error("Error writing audio packet");
@@ -137,9 +135,8 @@ static int write_audio_frame(void)
pkt.data = audio_output_buffer;
if (c->coded_frame && c->coded_frame->pts != AV_NOPTS_VALUE) {
- pkt.pts = av_rescale_q(c->coded_frame->pts,
- c->time_base, audio_stream->time_base);
- fprintf(stderr, "Audio Frame PTS: %d\n", (int)pkt.pts);
+ pkt.pts = av_rescale_q(c->coded_frame->pts, c->time_base, audio_stream->time_base);
+ PRINT("Audio Frame PTS: %d\n", (int) pkt.pts);
}
pkt.stream_index = audio_stream->index;
@@ -180,59 +177,71 @@ static AVFrame *alloc_picture(int pix_fmt, int width, int height)
static const char **get_file_extensions(int format)
{
switch (format) {
- case FFMPEG_DV: {
+ case FFMPEG_DV:
+ {
static const char *rv[] = { ".dv", NULL };
return rv;
}
- case FFMPEG_MPEG1: {
+ case FFMPEG_MPEG1:
+ {
static const char *rv[] = { ".mpg", ".mpeg", NULL };
return rv;
}
- case FFMPEG_MPEG2: {
- static const char *rv[] = { ".dvd", ".vob", ".mpg", ".mpeg",
- NULL };
+ case FFMPEG_MPEG2:
+ {
+ static const char *rv[] = { ".dvd", ".vob", ".mpg", ".mpeg", NULL };
return rv;
}
- case FFMPEG_MPEG4: {
+ case FFMPEG_MPEG4:
+ {
static const char *rv[] = { ".mp4", ".mpg", ".mpeg", NULL };
return rv;
}
- case FFMPEG_AVI: {
+ case FFMPEG_AVI:
+ {
static const char *rv[] = { ".avi", NULL };
return rv;
}
- case FFMPEG_MOV: {
+ case FFMPEG_MOV:
+ {
static const char *rv[] = { ".mov", NULL };
return rv;
}
- case FFMPEG_H264: {
+ case FFMPEG_H264:
+ {
/* FIXME: avi for now... */
static const char *rv[] = { ".avi", NULL };
return rv;
}
- case FFMPEG_XVID: {
+ case FFMPEG_XVID:
+ {
/* FIXME: avi for now... */
static const char *rv[] = { ".avi", NULL };
return rv;
}
- case FFMPEG_FLV: {
+ case FFMPEG_FLV:
+ {
static const char *rv[] = { ".flv", NULL };
return rv;
}
- case FFMPEG_MKV: {
+ case FFMPEG_MKV:
+ {
static const char *rv[] = { ".mkv", NULL };
return rv;
}
- case FFMPEG_OGG: {
+ case FFMPEG_OGG:
+ {
static const char *rv[] = { ".ogg", ".ogv", NULL };
return rv;
}
- case FFMPEG_MP3: {
+ case FFMPEG_MP3:
+ {
static const char *rv[] = { ".mp3", NULL };
return rv;
}
- case FFMPEG_WAV: {
+ case FFMPEG_WAV:
+ {
static const char *rv[] = { ".wav", NULL };
return rv;
}
@@ -254,21 +263,18 @@ static int write_video_frame(RenderData *rd, int cfra, AVFrame *frame, ReportLis
frame->top_field_first = ((rd->mode & R_ODDFIELD) != 0);
}
- outsize = avcodec_encode_video(c, video_buffer, video_buffersize,
- frame);
+ outsize = avcodec_encode_video(c, video_buffer, video_buffersize, frame);
if (outsize > 0) {
AVPacket packet;
av_init_packet(&packet);
if (c->coded_frame->pts != AV_NOPTS_VALUE) {
- packet.pts = av_rescale_q(c->coded_frame->pts,
- c->time_base,
- video_stream->time_base);
- fprintf(stderr, "Video Frame PTS: %d\n", (int)packet.pts);
+ packet.pts = av_rescale_q(c->coded_frame->pts, c->time_base, video_stream->time_base);
+ PRINT("Video Frame PTS: %d\n", (int)packet.pts);
}
else {
- fprintf(stderr, "Video Frame PTS: not set\n");
+ PRINT("Video Frame PTS: not set\n");
}
if (c->coded_frame->key_frame)
packet.flags |= AV_PKT_FLAG_KEY;
@@ -364,7 +370,7 @@ static void set_ffmpeg_property_option(AVCodecContext *c, IDProperty *prop)
char *param;
const AVOption *rv = NULL;
- fprintf(stderr, "FFMPEG expert option: %s: ", prop->name);
+ PRINT("FFMPEG expert option: %s: ", prop->name);
BLI_strncpy(name, prop->name, sizeof(name));
@@ -376,15 +382,15 @@ static void set_ffmpeg_property_option(AVCodecContext *c, IDProperty *prop)
switch (prop->type) {
case IDP_STRING:
- fprintf(stderr, "%s.\n", IDP_String(prop));
+ PRINT("%s.\n", IDP_String(prop));
av_set_string3(c, prop->name, IDP_String(prop), 1, &rv);
break;
case IDP_FLOAT:
- fprintf(stderr, "%g.\n", IDP_Float(prop));
+ PRINT("%g.\n", IDP_Float(prop));
rv = av_set_double(c, prop->name, IDP_Float(prop));
break;
case IDP_INT:
- fprintf(stderr, "%d.\n", IDP_Int(prop));
+ PRINT("%d.\n", IDP_Int(prop));
if (param) {
if (IDP_Int(prop)) {
@@ -401,8 +407,7 @@ static void set_ffmpeg_property_option(AVCodecContext *c, IDProperty *prop)
}
if (!rv) {
- fprintf(stderr, "ffmpeg-option not supported: %s! Skipping.\n",
- prop->name);
+ PRINT("ffmpeg-option not supported: %s! Skipping.\n", prop->name);
}
}
@@ -446,11 +451,14 @@ static void set_ffmpeg_properties(RenderData *rd, AVCodecContext *c, const char
/* prepare a video stream for the output file */
static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContext *of,
- int rectx, int recty)
+ int rectx, int recty, char *error, int error_size)
{
AVStream *st;
AVCodecContext *c;
AVCodec *codec;
+
+ error[0] = '\0';
+
st = av_new_stream(of, 0);
if (!st) return NULL;
@@ -460,7 +468,6 @@ static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
c->codec_id = codec_id;
c->codec_type = AVMEDIA_TYPE_VIDEO;
-
/* Get some values from the current render settings */
c->width = rectx;
@@ -492,7 +499,8 @@ static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
c->me_method = ME_EPZS;
codec = avcodec_find_encoder(c->codec_id);
- if (!codec) return NULL;
+ if (!codec)
+ return NULL;
/* Be sure to use the correct pixel format(e.g. RGB, YUV) */
@@ -547,27 +555,25 @@ static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
// || !strcmp(of->oformat->name, "3gp")
)
{
- fprintf(stderr, "Using global header\n");
+ PRINT("Using global header\n");
c->flags |= CODEC_FLAG_GLOBAL_HEADER;
}
/* Determine whether we are encoding interlaced material or not */
if (rd->mode & R_FIELDS) {
- fprintf(stderr, "Encoding interlaced video\n");
+ PRINT("Encoding interlaced video\n");
c->flags |= CODEC_FLAG_INTERLACED_DCT;
c->flags |= CODEC_FLAG_INTERLACED_ME;
}
/* xasp & yasp got float lately... */
- st->sample_aspect_ratio = c->sample_aspect_ratio = av_d2q(
- ((double) rd->xasp / (double) rd->yasp), 255);
+ st->sample_aspect_ratio = c->sample_aspect_ratio = av_d2q(((double) rd->xasp / (double) rd->yasp), 255);
set_ffmpeg_properties(rd, c, "video");
if (avcodec_open(c, codec) < 0) {
- //
- //XXX error("Couldn't initialize codec");
+ BLI_strncpy(error, IMB_ffmpeg_last_error(), error_size);
return NULL;
}
@@ -584,16 +590,11 @@ static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
else
video_buffersize = avpicture_get_size(c->pix_fmt, c->width, c->height);
- video_buffer = (uint8_t *)MEM_mallocN(video_buffersize * sizeof(uint8_t),
- "FFMPEG video buffer");
+ video_buffer = (uint8_t *)MEM_mallocN(video_buffersize * sizeof(uint8_t), "FFMPEG video buffer");
current_frame = alloc_picture(c->pix_fmt, c->width, c->height);
- img_convert_ctx = sws_getContext(c->width, c->height,
- PIX_FMT_BGR32,
- c->width, c->height,
- c->pix_fmt,
- SWS_BICUBIC,
+ img_convert_ctx = sws_getContext(c->width, c->height, PIX_FMT_BGR32, c->width, c->height, c->pix_fmt, SWS_BICUBIC,
NULL, NULL, NULL);
return st;
}
@@ -645,11 +646,9 @@ static AVStream *alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex
audio_outbuf_size = c->frame_size * c->channels * sizeof(int16_t) * 4;
}
- audio_output_buffer = (uint8_t *)av_malloc(
- audio_outbuf_size);
+ audio_output_buffer = (uint8_t *) av_malloc(audio_outbuf_size);
- audio_input_buffer = (uint8_t *)av_malloc(
- audio_input_samples * c->channels * sizeof(int16_t));
+ audio_input_buffer = (uint8_t *) av_malloc(audio_input_samples * c->channels * sizeof(int16_t));
audio_time = 0.0f;
@@ -672,7 +671,7 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
AVFormatContext *of;
AVOutputFormat *fmt;
AVDictionary *opts = NULL;
- char name[256];
+ char name[256], error[1024];
const char **exts;
ffmpeg_type = rd->ffcodecdata.type;
@@ -681,14 +680,11 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
ffmpeg_video_bitrate = rd->ffcodecdata.video_bitrate;
ffmpeg_audio_bitrate = rd->ffcodecdata.audio_bitrate;
ffmpeg_gop_size = rd->ffcodecdata.gop_size;
- ffmpeg_autosplit = rd->ffcodecdata.flags
- & FFMPEG_AUTOSPLIT_OUTPUT;
+ ffmpeg_autosplit = rd->ffcodecdata.flags & FFMPEG_AUTOSPLIT_OUTPUT;
- do_init_ffmpeg();
-
/* Determine the correct filename */
BKE_ffmpeg_filepath_get(name, rd);
- fprintf(stderr, "Starting output to %s(ffmpeg)...\n"
+ PRINT("Starting output to %s(ffmpeg)...\n"
" Using type=%d, codec=%d, audio_codec=%d,\n"
" video_bitrate=%d, audio_bitrate=%d,\n"
" gop_size=%d, autosplit=%d\n"
@@ -793,10 +789,14 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
}
if (fmt->video_codec != CODEC_ID_NONE) {
- video_stream = alloc_video_stream(rd, fmt->video_codec, of, rectx, recty);
- printf("alloc video stream %p\n", video_stream);
+ video_stream = alloc_video_stream(rd, fmt->video_codec, of, rectx, recty, error, sizeof(error));
+ PRINT("alloc video stream %p\n", video_stream);
if (!video_stream) {
- BKE_report(reports, RPT_ERROR, "Error initializing video stream.");
+ if (error[0])
+ BKE_report(reports, RPT_ERROR, error);
+ else
+ BKE_report(reports, RPT_ERROR, "Error initializing video stream.");
+
av_dict_free(&opts);
return 0;
}
@@ -839,7 +839,7 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
* inter-frames (H.264 B-frames, for example), it can output the frames
* in a different order from the one it was given.
* For example, when sending frames 1, 2, 3, 4 to the encoder, it may write
- * them in the order 1, 4, 2, 3 - first the two frames used for predition,
+ * them in the order 1, 4, 2, 3 - first the two frames used for prediction,
* and then the bidirectionally-predicted frames. What this means in practice
* is that the encoder may not immediately produce one output frame for each
* input frame. These delayed frames must be flushed before we close the
@@ -847,7 +847,7 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
* parameter.
* </p>
*/
-void flush_ffmpeg(void)
+static void flush_ffmpeg(void)
{
int outsize = 0;
int ret = 0;
@@ -867,13 +867,11 @@ void flush_ffmpeg(void)
break;
}
if (c->coded_frame->pts != AV_NOPTS_VALUE) {
- packet.pts = av_rescale_q(c->coded_frame->pts,
- c->time_base,
- video_stream->time_base);
- fprintf(stderr, "Video Frame PTS: %d\n", (int)packet.pts);
+ packet.pts = av_rescale_q(c->coded_frame->pts, c->time_base, video_stream->time_base);
+ PRINT("Video Frame PTS: %d\n", (int) packet.pts);
}
else {
- fprintf(stderr, "Video Frame PTS: not set\n");
+ PRINT("Video Frame PTS: not set\n");
}
if (c->coded_frame->key_frame) {
packet.flags |= AV_PKT_FLAG_KEY;
@@ -916,9 +914,7 @@ void BKE_ffmpeg_filepath_get(char *string, RenderData *rd)
}
while (*fe) {
- if (BLI_strcasecmp(string + strlen(string) - strlen(*fe),
- *fe) == 0)
- {
+ if (BLI_strcasecmp(string + strlen(string) - strlen(*fe), *fe) == 0) {
break;
}
fe++;
@@ -962,6 +958,7 @@ int BKE_ffmpeg_start(struct Scene *scene, RenderData *rd, int rectx, int recty,
}
void BKE_ffmpeg_end(void);
+static void end_ffmpeg_impl(int is_autosplit);
#ifdef WITH_AUDASPACE
static void write_audio_frames(double to_pts)
@@ -983,9 +980,7 @@ int BKE_ffmpeg_append(RenderData *rd, int start_frame, int frame, int *pixels, i
AVFrame *avframe;
int success = 1;
- fprintf(stderr, "Writing frame %i, "
- "render width=%d, render height=%d\n", frame,
- rectx, recty);
+ PRINT("Writing frame %i, render width=%d, render height=%d\n", frame, rectx, recty);
// why is this done before writing the video frame and again at end_ffmpeg?
// write_audio_frames(frame / (((double)rd->frs_sec) / rd->frs_sec_base));
@@ -996,7 +991,7 @@ int BKE_ffmpeg_append(RenderData *rd, int start_frame, int frame, int *pixels, i
if (ffmpeg_autosplit) {
if (avio_tell(outfile->pb) > FFMPEG_AUTOSPLIT_SIZE) {
- BKE_ffmpeg_end();
+ end_ffmpeg_impl(TRUE);
ffmpeg_autosplit_count++;
success &= start_ffmpeg_impl(rd, rectx, recty, reports);
}
@@ -1009,11 +1004,11 @@ int BKE_ffmpeg_append(RenderData *rd, int start_frame, int frame, int *pixels, i
return success;
}
-void BKE_ffmpeg_end(void)
+static void end_ffmpeg_impl(int is_autosplit)
{
unsigned int i;
- fprintf(stderr, "Closing ffmpeg...\n");
+ PRINT("Closing ffmpeg...\n");
#if 0
if (audio_stream) { /* SEE UPPER */
@@ -1022,14 +1017,16 @@ void BKE_ffmpeg_end(void)
#endif
#ifdef WITH_AUDASPACE
- if (audio_mixdown_device) {
- AUD_closeReadDevice(audio_mixdown_device);
- audio_mixdown_device = 0;
+ if (is_autosplit == FALSE) {
+ if (audio_mixdown_device) {
+ AUD_closeReadDevice(audio_mixdown_device);
+ audio_mixdown_device = 0;
+ }
}
#endif
if (video_stream && video_stream->codec) {
- fprintf(stderr, "Flushing delayed frames...\n");
+ PRINT("Flushing delayed frames...\n");
flush_ffmpeg();
}
@@ -1041,7 +1038,7 @@ void BKE_ffmpeg_end(void)
if (video_stream && video_stream->codec) {
avcodec_close(video_stream->codec);
- printf("zero video stream %p\n", video_stream);
+ PRINT("zero video stream %p\n", video_stream);
video_stream = 0;
}
@@ -1087,6 +1084,11 @@ void BKE_ffmpeg_end(void)
}
}
+void BKE_ffmpeg_end(void)
+{
+ end_ffmpeg_impl(FALSE);
+}
+
/* properties */
void BKE_ffmpeg_property_del(RenderData *rd, void *type, void *prop_)
@@ -1142,8 +1144,7 @@ IDProperty *BKE_ffmpeg_property_add(RenderData *rd, const char *type, int opt_in
BLI_strncpy(name, o->name, sizeof(name));
}
- fprintf(stderr, "ffmpeg_property_add: %s %d %d %s\n",
- type, parent_index, opt_index, name);
+ PRINT("ffmpeg_property_add: %s %d %d %s\n", type, parent_index, opt_index, name);
prop = IDP_GetPropertyFromGroup(group, name);
if (prop) {
@@ -1181,8 +1182,7 @@ IDProperty *BKE_ffmpeg_property_add(RenderData *rd, const char *type, int opt_in
/* not all versions of ffmpeg include that, so here we go ... */
-static const AVOption *my_av_find_opt(void *v, const char *name,
- const char *unit, int mask, int flags)
+static const AVOption *my_av_find_opt(void *v, const char *name, const char *unit, int mask, int flags)
{
AVClass *c = *(AVClass **)v;
const AVOption *o = c->option;
@@ -1235,14 +1235,11 @@ int BKE_ffmpeg_property_add_string(RenderData *rd, const char *type, const char
if (param && o->type != FF_OPT_TYPE_CONST && o->unit) {
p = my_av_find_opt(&c, param, o->unit, 0, 0);
if (p) {
- prop = BKE_ffmpeg_property_add(rd,
- (char *) type, p - c.av_class->option,
- o - c.av_class->option);
+ prop = BKE_ffmpeg_property_add(rd, (char *) type, p - c.av_class->option, o - c.av_class->option);
}
}
else {
- prop = BKE_ffmpeg_property_add(rd,
- (char *) type, o - c.av_class->option, 0);
+ prop = BKE_ffmpeg_property_add(rd, (char *) type, o - c.av_class->option, 0);
}
@@ -1316,12 +1313,10 @@ static void ffmpeg_set_expert_options(RenderData *rd)
if (rd->ffcodecdata.flags & FFMPEG_LOSSLESS_OUTPUT)
BKE_ffmpeg_property_add_string(rd, "video", "cqp:0");
}
-#if 0 /* disabled for after release */
else if (codec_id == CODEC_ID_DNXHD) {
if (rd->ffcodecdata.flags & FFMPEG_LOSSLESS_OUTPUT)
- ffmpeg_property_add_string(rd, "video", "mbd:rd");
+ BKE_ffmpeg_property_add_string(rd, "video", "mbd:rd");
}
-#endif
}
void BKE_ffmpeg_preset_set(RenderData *rd, int preset)