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:
authorTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2013-02-24 07:39:20 +0400
committerTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2013-02-24 07:39:20 +0400
commitd120ec146d3c28b7243371b0de1edf4ba590470c (patch)
treea05f182978c6007bb9193f6ad0b4f2b210394ee8 /source/blender/blenkernel/intern
parent3df023ae82eef0ea105dc61c9730af87b59a07d1 (diff)
parent93c3593d825aafe30aaf051182e50bde4c6084dd (diff)
Merged changes in the trunk up to revision 54802.
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c41
-rw-r--r--source/blender/blenkernel/intern/anim.c64
-rw-r--r--source/blender/blenkernel/intern/blender.c3
-rw-r--r--source/blender/blenkernel/intern/constraint.c2
-rw-r--r--source/blender/blenkernel/intern/context.c4
-rw-r--r--source/blender/blenkernel/intern/curve.c135
-rw-r--r--source/blender/blenkernel/intern/deform.c21
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c68
-rw-r--r--source/blender/blenkernel/intern/editderivedmesh.c152
-rw-r--r--source/blender/blenkernel/intern/idprop.c6
-rw-r--r--source/blender/blenkernel/intern/image.c14
-rw-r--r--source/blender/blenkernel/intern/key.c2
-rw-r--r--source/blender/blenkernel/intern/movieclip.c2
-rw-r--r--source/blender/blenkernel/intern/node.c20
-rw-r--r--source/blender/blenkernel/intern/object.c53
-rw-r--r--source/blender/blenkernel/intern/particle.c6
-rw-r--r--source/blender/blenkernel/intern/particle_system.c52
-rw-r--r--source/blender/blenkernel/intern/pointcache.c24
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c19
-rw-r--r--source/blender/blenkernel/intern/sca.c6
-rw-r--r--source/blender/blenkernel/intern/scene.c29
-rw-r--r--source/blender/blenkernel/intern/sequencer.c18
-rw-r--r--source/blender/blenkernel/intern/text.c12
-rw-r--r--source/blender/blenkernel/intern/tracking.c149
24 files changed, 621 insertions, 281 deletions
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 8e740075bc6..6b3c95a5cd3 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -1017,8 +1017,12 @@ void weight_to_rgb(float r_rgb[3], const float weight)
/* draw_flag's for calc_weightpaint_vert_color */
enum {
- CALC_WP_MULTIPAINT = (1 << 0),
- CALC_WP_AUTO_NORMALIZE = (1 << 1)
+ /* only one of these should be set, keep first (for easy bit-shifting) */
+ CALC_WP_GROUP_USER_ACTIVE = (1 << 1),
+ CALC_WP_GROUP_USER_ALL = (1 << 2),
+
+ CALC_WP_MULTIPAINT = (1 << 3),
+ CALC_WP_AUTO_NORMALIZE = (1 << 4)
};
static void weightpaint_color(unsigned char r_col[4], ColorBand *coba, const float input)
@@ -1050,7 +1054,7 @@ static void calc_weightpaint_vert_color(
{
float input = 0.0f;
- int make_black = FALSE;
+ bool make_black = false;
if ((defbase_sel_tot > 1) && (draw_flag & CALC_WP_MULTIPAINT)) {
int was_a_nonzero = FALSE;
@@ -1072,7 +1076,7 @@ static void calc_weightpaint_vert_color(
/* make it black if the selected groups have no weight on a vertex */
if (was_a_nonzero == FALSE) {
- make_black = TRUE;
+ make_black = true;
}
else if ((draw_flag & CALC_WP_AUTO_NORMALIZE) == FALSE) {
input /= defbase_sel_tot; /* get the average */
@@ -1081,6 +1085,17 @@ static void calc_weightpaint_vert_color(
else {
/* default, non tricky behavior */
input = defvert_find_weight(dv, defbase_act);
+
+ if (draw_flag & CALC_WP_GROUP_USER_ACTIVE) {
+ if (input == 0.0f) {
+ make_black = true;
+ }
+ }
+ else if (draw_flag & CALC_WP_GROUP_USER_ALL) {
+ if (input == 0.0f) {
+ make_black = defvert_is_weight_zero(dv, defbase_tot);
+ }
+ }
}
if (make_black) { /* TODO, theme color */
@@ -1138,7 +1153,12 @@ static unsigned char *calc_weightpaint_vert_array(Object *ob, DerivedMesh *dm, i
}
else {
int col_i;
- weightpaint_color((unsigned char *)&col_i, coba, 0.0f);
+ if (draw_flag & (CALC_WP_GROUP_USER_ACTIVE | CALC_WP_GROUP_USER_ALL)) {
+ col_i = 0;
+ }
+ else {
+ weightpaint_color((unsigned char *)&col_i, coba, 0.0f);
+ }
fill_vn_i((int *)wtcol_v, numVerts, col_i);
}
@@ -1354,8 +1374,11 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
int sculpt_mode = ob->mode & OB_MODE_SCULPT && ob->sculpt;
int sculpt_dyntopo = (sculpt_mode && ob->sculpt->bm);
- const int draw_flag = ((scene->toolsettings->multipaint ? CALC_WP_MULTIPAINT : 0) |
+ const int draw_flag = ((scene->toolsettings->multipaint ? CALC_WP_MULTIPAINT :
+ /* CALC_WP_GROUP_USER_ACTIVE or CALC_WP_GROUP_USER_ALL*/
+ (1 << scene->toolsettings->weightuser)) |
(scene->toolsettings->auto_normalize ? CALC_WP_AUTO_NORMALIZE : 0));
+
/* Generic preview only in object mode! */
const int do_mod_mcol = (ob->mode == OB_MODE_OBJECT);
#if 0 /* XXX Will re-enable this when we have global mod stack options. */
@@ -2720,7 +2743,7 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs,
a = attribs->tottface++;
attribs->tface[a].array = tfdata->layers[layer].data;
- attribs->tface[a].em_offset = tfdata->layers[layer].offset;
+ attribs->tface[a].em_offset = ldata->layers[layer].offset;
attribs->tface[a].gl_index = gattribs->layer[b].glindex;
attribs->tface[a].gl_texco = gattribs->layer[b].gltexco;
}
@@ -2757,7 +2780,8 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs,
a = attribs->totmcol++;
attribs->mcol[a].array = tfdata->layers[layer].data;
- attribs->mcol[a].em_offset = tfdata->layers[layer].offset;
+ /* odd, store the offset for a different layer type here, but editmode draw code expects it */
+ attribs->mcol[a].em_offset = ldata->layers[layer].offset;
attribs->mcol[a].gl_index = gattribs->layer[b].glindex;
}
}
@@ -2773,6 +2797,7 @@ void DM_vertex_attributes_from_gpu(DerivedMesh *dm, GPUVertexAttribs *gattribs,
a = attribs->totmcol++;
attribs->mcol[a].array = tfdata->layers[layer].data;
+ /* odd, store the offset for a different layer type here, but editmode draw code expects it */
attribs->mcol[a].em_offset = tfdata->layers[layer].offset;
attribs->mcol[a].gl_index = gattribs->layer[b].glindex;
}
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index a6b3008e00a..4eb26e81ae2 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -69,7 +69,6 @@
#include "BKE_depsgraph.h"
#include "BKE_anim.h"
#include "BKE_report.h"
-#include "BKE_rigidbody.h"
// XXX bad level call...
@@ -320,46 +319,45 @@ static void motionpaths_calc_optimise_depsgraph(Scene *scene, ListBase *targets)
}
/* "brew me a list that's sorted a bit faster now depsy" */
- DAG_scene_sort(G.main, scene);
+ DAG_scene_relations_rebuild(G.main, scene);
}
/* update scene for current frame */
static void motionpaths_calc_update_scene(Scene *scene)
{
#if 1 // 'production' optimizations always on
- Base *base, *last = NULL;
- float ctime = BKE_scene_frame_get(scene);
-
- /* only stuff that moves or needs display still */
- DAG_scene_update_flags(G.main, scene, scene->lay, TRUE);
-
- /* find the last object with the tag
- * - all those afterwards are assumed to not be relevant for our calculations
- */
- /* optimize further by moving out... */
- for (base = scene->base.first; base; base = base->next) {
- if (base->object->flag & BA_TEMP_TAG)
- last = base;
+
+ /* rigid body simulation needs complete update to work correctly for now */
+ /* RB_TODO investigate if we could avoid updating everything */
+ if (BKE_scene_check_rigidbody_active(scene)) {
+ BKE_scene_update_for_newframe(G.main, scene, scene->lay);
}
-
- /* run rigidbody sim
- * NOTE: keep in sync with BKE_scene_update_for_newframe() in scene.c
- */
- // XXX: this position may still change, objects not being updated correctly before simulation is run
- // NOTE: current position is so that rigidbody sim affects other objects
- if (BKE_scene_check_rigidbody_active(scene))
- BKE_rigidbody_do_simulation(scene, ctime);
-
- /* perform updates for tagged objects */
- /* XXX: this will break if rigs depend on scene or other data that
- * is animated but not attached to/updatable from objects */
- for (base = scene->base.first; base; base = base->next) {
- /* update this object */
- BKE_object_handle_update(scene, base->object);
+ else { /* otherwise we can optimize by restricting updates */
+ Base *base, *last = NULL;
+
+ /* only stuff that moves or needs display still */
+ DAG_scene_update_flags(G.main, scene, scene->lay, TRUE);
- /* if this is the last one we need to update, let's stop to save some time */
- if (base == last)
- break;
+ /* find the last object with the tag
+ * - all those afterwards are assumed to not be relevant for our calculations
+ */
+ /* optimize further by moving out... */
+ for (base = scene->base.first; base; base = base->next) {
+ if (base->object->flag & BA_TEMP_TAG)
+ last = base;
+ }
+
+ /* perform updates for tagged objects */
+ /* XXX: this will break if rigs depend on scene or other data that
+ * is animated but not attached to/updatable from objects */
+ for (base = scene->base.first; base; base = base->next) {
+ /* update this object */
+ BKE_object_handle_update(scene, base->object);
+
+ /* if this is the last one we need to update, let's stop to save some time */
+ if (base == last)
+ break;
+ }
}
#else // original, 'always correct' version
/* do all updates
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index fb2d1a3aaf7..be316197078 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -1000,8 +1000,7 @@ int BKE_copybuffer_paste(bContext *C, char *libname, ReportList *reports)
flag_all_listbases_ids(LIB_PRE_EXISTING, 0);
/* recreate dependency graph to include new objects */
- DAG_scene_sort(bmain, scene);
- DAG_ids_flush_update(bmain, 0);
+ DAG_relations_tag_update(bmain);
BLO_blendhandle_close(bh);
/* remove library... */
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 1a25def3829..48ad3f51389 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -4261,7 +4261,7 @@ static void con_unlink_refs_cb(bConstraint *UNUSED(con), ID **idpoin, short isRe
/* Free data of a specific constraint if it has any info.
* be sure to run BIK_clear_data() when freeing an IK constraint,
- * unless DAG_scene_sort is called.
+ * unless DAG_relations_tag_update is called.
*/
void BKE_free_constraint_data(bConstraint *con)
{
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index a45afa5e69a..a9e3d52f223 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -48,6 +48,8 @@
#include "BLI_threads.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
#include "BKE_context.h"
#include "BKE_main.h"
#include "BKE_screen.h"
@@ -851,7 +853,7 @@ void CTX_wm_operator_poll_msg_set(bContext *C, const char *msg)
const char *CTX_wm_operator_poll_msg_get(bContext *C)
{
- return C->wm.operator_poll_msg;
+ return IFACE_(C->wm.operator_poll_msg);
}
/* data context */
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 7d6212f8760..2da75ec64be 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -2202,6 +2202,70 @@ static void make_bevel_list_segment_3D(BevList *bl)
copy_qt_qt(bevp2->quat, bevp1->quat);
}
+/* only for 2 points */
+static void make_bevel_list_segment_2D(BevList *bl)
+{
+ BevPoint *bevp2 = (BevPoint *)(bl + 1);
+ BevPoint *bevp1 = bevp2 + 1;
+
+ const float x1 = bevp1->vec[0] - bevp2->vec[0];
+ const float y1 = bevp1->vec[1] - bevp2->vec[1];
+
+ calc_bevel_sin_cos(x1, y1, -x1, -y1, &(bevp1->sina), &(bevp1->cosa));
+ bevp2->sina = bevp1->sina;
+ bevp2->cosa = bevp1->cosa;
+
+ /* fill in dir & quat */
+ make_bevel_list_segment_3D(bl);
+}
+
+static void make_bevel_list_2D(BevList *bl)
+{
+ /* note: bevp->dir and bevp->quat are not needed for beveling but are
+ * used when making a path from a 2D curve, therefor they need to be set - Campbell */
+
+ BevPoint *bevp2 = (BevPoint *)(bl + 1);
+ BevPoint *bevp1 = bevp2 + (bl->nr - 1);
+ BevPoint *bevp0 = bevp1 - 1;
+ int nr;
+
+ nr = bl->nr;
+ while (nr--) {
+ const float x1 = bevp1->vec[0] - bevp0->vec[0];
+ const float x2 = bevp1->vec[0] - bevp2->vec[0];
+ const float y1 = bevp1->vec[1] - bevp0->vec[1];
+ const float y2 = bevp1->vec[1] - bevp2->vec[1];
+
+ calc_bevel_sin_cos(x1, y1, x2, y2, &(bevp1->sina), &(bevp1->cosa));
+
+ /* from: make_bevel_list_3D_zup, could call but avoid a second loop.
+ * no need for tricky tilt calculation as with 3D curves */
+ bisect_v3_v3v3v3(bevp1->dir, bevp0->vec, bevp1->vec, bevp2->vec);
+ vec_to_quat(bevp1->quat, bevp1->dir, 5, 1);
+ /* done with inline make_bevel_list_3D_zup */
+
+ bevp0 = bevp1;
+ bevp1 = bevp2;
+ bevp2++;
+ }
+
+ /* correct non-cyclic cases */
+ if (bl->poly == -1) {
+ BevPoint *bevp = (BevPoint *)(bl + 1);
+ bevp1 = bevp + 1;
+ bevp->sina = bevp1->sina;
+ bevp->cosa = bevp1->cosa;
+ bevp = (BevPoint *)(bl + 1);
+ bevp += (bl->nr - 1);
+ bevp1 = bevp - 1;
+ bevp->sina = bevp1->sina;
+ bevp->cosa = bevp1->cosa;
+
+ /* correct for the dir/quat, see above why its needed */
+ bevel_list_cyclic_fix_3D(bl);
+ }
+}
+
void BKE_curve_bevelList_make(Object *ob)
{
/*
@@ -2216,7 +2280,7 @@ void BKE_curve_bevelList_make(Object *ob)
BPoint *bp;
BevList *bl, *blnew, *blnext;
BevPoint *bevp, *bevp2, *bevp1 = NULL, *bevp0;
- float min, inp, x1, x2, y1, y2;
+ float min, inp;
struct bevelsort *sortdata, *sd, *sd1;
int a, b, nr, poly, resolu = 0, len = 0;
int do_tilt, do_radius, do_weight;
@@ -2534,76 +2598,22 @@ void BKE_curve_bevelList_make(Object *ob)
/* STEP 4: 2D-COSINES or 3D ORIENTATION */
if ((cu->flag & CU_3D) == 0) {
- /* note: bevp->dir and bevp->quat are not needed for beveling but are
- * used when making a path from a 2D curve, therefor they need to be set - Campbell */
- bl = cu->bev.first;
- while (bl) {
-
+ /* 2D Curves */
+ for (bl = cu->bev.first; bl; bl = bl->next) {
if (bl->nr < 2) {
/* do nothing */
}
else if (bl->nr == 2) { /* 2 pnt, treat separate */
- bevp2 = (BevPoint *)(bl + 1);
- bevp1 = bevp2 + 1;
-
- x1 = bevp1->vec[0] - bevp2->vec[0];
- y1 = bevp1->vec[1] - bevp2->vec[1];
-
- calc_bevel_sin_cos(x1, y1, -x1, -y1, &(bevp1->sina), &(bevp1->cosa));
- bevp2->sina = bevp1->sina;
- bevp2->cosa = bevp1->cosa;
-
- /* fill in dir & quat */
- make_bevel_list_segment_3D(bl);
+ make_bevel_list_segment_2D(bl);
}
else {
- bevp2 = (BevPoint *)(bl + 1);
- bevp1 = bevp2 + (bl->nr - 1);
- bevp0 = bevp1 - 1;
-
- nr = bl->nr;
- while (nr--) {
- x1 = bevp1->vec[0] - bevp0->vec[0];
- x2 = bevp1->vec[0] - bevp2->vec[0];
- y1 = bevp1->vec[1] - bevp0->vec[1];
- y2 = bevp1->vec[1] - bevp2->vec[1];
-
- calc_bevel_sin_cos(x1, y1, x2, y2, &(bevp1->sina), &(bevp1->cosa));
-
- /* from: make_bevel_list_3D_zup, could call but avoid a second loop.
- * no need for tricky tilt calculation as with 3D curves */
- bisect_v3_v3v3v3(bevp1->dir, bevp0->vec, bevp1->vec, bevp2->vec);
- vec_to_quat(bevp1->quat, bevp1->dir, 5, 1);
- /* done with inline make_bevel_list_3D_zup */
-
- bevp0 = bevp1;
- bevp1 = bevp2;
- bevp2++;
- }
-
- /* correct non-cyclic cases */
- if (bl->poly == -1) {
- bevp = (BevPoint *)(bl + 1);
- bevp1 = bevp + 1;
- bevp->sina = bevp1->sina;
- bevp->cosa = bevp1->cosa;
- bevp = (BevPoint *)(bl + 1);
- bevp += (bl->nr - 1);
- bevp1 = bevp - 1;
- bevp->sina = bevp1->sina;
- bevp->cosa = bevp1->cosa;
-
- /* correct for the dir/quat, see above why its needed */
- bevel_list_cyclic_fix_3D(bl);
- }
+ make_bevel_list_2D(bl);
}
- bl = bl->next;
}
}
- else { /* 3D Curves */
- bl = cu->bev.first;
- while (bl) {
-
+ else {
+ /* 3D Curves */
+ for (bl = cu->bev.first; bl; bl = bl->next) {
if (bl->nr < 2) {
/* do nothing */
}
@@ -2613,7 +2623,6 @@ void BKE_curve_bevelList_make(Object *ob)
else {
make_bevel_list_3D(bl, (int)(resolu * cu->twist_smooth), cu->twist_mode);
}
- bl = bl->next;
}
}
}
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index de15100de0b..439180e8d76 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -41,14 +41,13 @@
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
-#include "BKE_deform.h"
-
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
+#include "BKE_deform.h" /* own include */
void defgroup_copy_list(ListBase *outbase, ListBase *inbase)
{
@@ -787,6 +786,24 @@ int defvert_find_shared(const MDeformVert *dvert_a, const MDeformVert *dvert_b)
return -1;
}
+/**
+ * return true if has no weights
+ */
+bool defvert_is_weight_zero(const struct MDeformVert *dvert, const int defgroup_tot)
+{
+ MDeformWeight *dw = dvert->dw;
+ unsigned int i;
+ for (i = dvert->totweight; i != 0; i--, dw++) {
+ if (dw->weight != 0.0f) {
+ /* check the group is in-range, happens on rare situations */
+ if (LIKELY(dw->def_nr < defgroup_tot)) {
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
/* -------------------------------------------------------------------- */
/* Defvert Array functions */
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 99d0c5ed964..8c55ad02dc6 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -837,7 +837,6 @@ DagForest *build_dag(Main *bmain, Scene *sce, short mask)
DagAdjList *itA;
dag = sce->theDag;
- sce->dagisvalid = 1;
if (dag)
free_forest(dag);
else {
@@ -1846,8 +1845,18 @@ static void scene_sort_groups(Main *bmain, Scene *sce)
}
}
+/* free the depency graph */
+static void dag_scene_free(Scene *sce)
+{
+ if (sce->theDag) {
+ free_forest(sce->theDag);
+ MEM_freeN(sce->theDag);
+ sce->theDag = NULL;
+ }
+}
+
/* sort the base list on dependency order */
-void DAG_scene_sort(Main *bmain, Scene *sce)
+static void dag_scene_build(Main *bmain, Scene *sce)
{
DagNode *node, *rootnode;
DagNodeQueue *nqueue;
@@ -1856,7 +1865,7 @@ void DAG_scene_sort(Main *bmain, Scene *sce)
int skip = 0;
ListBase tempbase;
Base *base;
-
+
tempbase.first = tempbase.last = NULL;
build_dag(bmain, sce, DAG_RL_ALL_BUT_DATA);
@@ -1936,10 +1945,34 @@ void DAG_scene_sort(Main *bmain, Scene *sce)
printf(" %s\n", base->object->id.name);
}
}
+
/* temporal...? */
sce->recalc |= SCE_PRV_CHANGED; /* test for 3d preview */
}
+/* clear all dependency graphs */
+void DAG_relations_tag_update(Main *bmain)
+{
+ Scene *sce;
+
+ for (sce = bmain->scene.first; sce; sce = sce->id.next)
+ dag_scene_free(sce);
+}
+
+/* rebuild dependency graph only for a given scene */
+void DAG_scene_relations_rebuild(Main *bmain, Scene *sce)
+{
+ dag_scene_free(sce);
+ DAG_scene_relations_update(bmain, sce);
+}
+
+/* create dependency graph if it was cleared or didn't exist yet */
+void DAG_scene_relations_update(Main *bmain, Scene *sce)
+{
+ if (!sce->theDag)
+ dag_scene_build(bmain, sce);
+}
+
static void lib_id_recalc_tag(Main *bmain, ID *id)
{
id->flag |= LIB_ID_RECALC;
@@ -2177,7 +2210,7 @@ void DAG_scene_flush_update(Main *bmain, Scene *sce, unsigned int lay, const sho
if (sce->theDag == NULL) {
printf("DAG zero... not allowed to happen!\n");
- DAG_scene_sort(bmain, sce);
+ DAG_scene_relations_update(bmain, sce);
}
firstnode = sce->theDag->DagNode.first; /* always scene node */
@@ -2545,20 +2578,6 @@ static void dag_current_scene_layers(Main *bmain, ListBase *lb)
}
}
-void DAG_ids_flush_update(Main *bmain, int time)
-{
- ListBase listbase;
- DagSceneLayer *dsl;
-
- /* get list of visible scenes and layers */
- dag_current_scene_layers(bmain, &listbase);
-
- for (dsl = listbase.first; dsl; dsl = dsl->next)
- DAG_scene_flush_update(bmain, dsl->scene, dsl->layer, time);
-
- BLI_freelistN(&listbase);
-}
-
void DAG_on_visible_update(Main *bmain, const short do_time)
{
ListBase listbase;
@@ -2895,12 +2914,10 @@ void DAG_ids_clear_recalc(Main *bmain)
memset(bmain->id_tag_update, 0, sizeof(bmain->id_tag_update));
}
-void DAG_id_tag_update(ID *id, short flag)
+void DAG_id_tag_update_ex(Main *bmain, ID *id, short flag)
{
- Main *bmain = G.main;
-
if (id == NULL) return;
-
+
/* tag ID for update */
if (flag) {
if (flag & OB_RECALC_OB)
@@ -2955,6 +2972,11 @@ void DAG_id_tag_update(ID *id, short flag)
}
}
+void DAG_id_tag_update(ID *id, short flag)
+{
+ DAG_id_tag_update_ex(G.main, id, flag);
+}
+
void DAG_id_type_tag(Main *bmain, short idtype)
{
if (idtype == ID_NT) {
@@ -3169,7 +3191,7 @@ void DAG_print_dependencies(Main *bmain, Scene *scene, Object *ob)
}
else {
printf("\nDEPENDENCY RELATIONS for %s\n\n", scene->id.name + 2);
- DAG_scene_sort(bmain, scene);
+ DAG_scene_relations_rebuild(bmain, scene);
}
dag_print_dependencies = 0;
diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c
index d652b97e2fa..11c05772962 100644
--- a/source/blender/blenkernel/intern/editderivedmesh.c
+++ b/source/blender/blenkernel/intern/editderivedmesh.c
@@ -997,6 +997,43 @@ static void emDM_drawMappedFacesTex(DerivedMesh *dm,
emDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData);
}
+/**
+ * \note
+ *
+ * For UV's:
+ * const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(loop, attribs->tface[i].em_offset);
+ *
+ * This is intentionally different to calling:
+ * CustomData_bmesh_get_n(&bm->ldata, loop->head.data, CD_MLOOPUV, i);
+ *
+ * ... because the material may use layer names to select different UV's
+ * see: [#34378]
+ */
+static void emdm_pass_attrib_vertex_glsl(DMVertexAttribs *attribs, BMLoop *loop, int index_in_face)
+{
+ BMVert *eve = loop->v;
+ int i;
+
+ if (attribs->totorco) {
+ const float *orco = attribs->orco.array[BM_elem_index_get(eve)];
+ glVertexAttrib3fvARB(attribs->orco.gl_index, orco);
+ }
+ for (i = 0; i < attribs->tottface; i++) {
+ const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(loop, attribs->tface[i].em_offset);
+ glVertexAttrib2fvARB(attribs->tface[i].gl_index, luv->uv);
+ }
+ for (i = 0; i < attribs->totmcol; i++) {
+ const MLoopCol *cp = BM_ELEM_CD_GET_VOID_P(loop, attribs->mcol[i].em_offset);
+ GLubyte col[4];
+ col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
+ glVertexAttrib4ubvARB(attribs->mcol[i].gl_index, col);
+ }
+ if (attribs->tottang) {
+ const float *tang = attribs->tang.array[i * 4 + index_in_face];
+ glVertexAttrib3fvARB(attribs->tang.gl_index, tang);
+ }
+}
+
static void emDM_drawMappedFacesGLSL(DerivedMesh *dm,
DMSetMaterial setMaterial,
DMSetDrawOptions setDrawOptions,
@@ -1012,7 +1049,7 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm,
DMVertexAttribs attribs;
GPUVertexAttribs gattribs;
- int i, b, matnr, new_matnr, do_draw;
+ int i, matnr, new_matnr, do_draw;
do_draw = FALSE;
matnr = -1;
@@ -1023,30 +1060,6 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm,
glShadeModel(GL_SMOOTH);
BM_mesh_elem_index_ensure(bm, BM_VERT | BM_FACE);
-#define PASSATTRIB(loop, eve, vert) { \
- if (attribs.totorco) { \
- float *orco = attribs.orco.array[BM_elem_index_get(eve)]; \
- glVertexAttrib3fvARB(attribs.orco.gl_index, orco); \
- } \
- for (b = 0; b < attribs.tottface; b++) { \
- MLoopUV *_luv = CustomData_bmesh_get_n(&bm->ldata, loop->head.data, \
- CD_MLOOPUV, b); \
- glVertexAttrib2fvARB(attribs.tface[b].gl_index, _luv->uv); \
- } \
- for (b = 0; b < attribs.totmcol; b++) { \
- MLoopCol *_cp = CustomData_bmesh_get_n(&bm->ldata, loop->head.data, \
- CD_MLOOPCOL, b); \
- GLubyte _col[4]; \
- _col[0] = _cp->b; _col[1] = _cp->g; _col[2] = _cp->r; _col[3] = _cp->a; \
- glVertexAttrib4ubvARB(attribs.mcol[b].gl_index, _col); \
- } \
- if (attribs.tottang) { \
- float *tang = attribs.tang.array[i * 4 + vert]; \
- glVertexAttrib3fvARB(attribs.tang.gl_index, tang); \
- } \
- } (void)0
-
-
for (i = 0, ltri = em->looptris[0]; i < em->tottri; i++, ltri += 3) {
int drawSmooth;
@@ -1069,20 +1082,20 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm,
if (vertexCos) glNormal3fv(bmdm->polyNos[BM_elem_index_get(efa)]);
else glNormal3fv(efa->no);
- PASSATTRIB(ltri[0], ltri[0]->v, 0);
+ emdm_pass_attrib_vertex_glsl(&attribs, ltri[0], 0);
if (vertexCos) glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
else glVertex3fv(ltri[0]->v->co);
- PASSATTRIB(ltri[1], ltri[1]->v, 1);
+ emdm_pass_attrib_vertex_glsl(&attribs, ltri[1], 1);
if (vertexCos) glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
else glVertex3fv(ltri[1]->v->co);
- PASSATTRIB(ltri[2], ltri[2]->v, 2);
+ emdm_pass_attrib_vertex_glsl(&attribs, ltri[2], 2);
if (vertexCos) glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
else glVertex3fv(ltri[2]->v->co);
}
else {
- PASSATTRIB(ltri[0], ltri[0]->v, 0);
+ emdm_pass_attrib_vertex_glsl(&attribs, ltri[0], 0);
if (vertexCos) {
glNormal3fv(vertexNos[BM_elem_index_get(ltri[0]->v)]);
glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
@@ -1092,7 +1105,7 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm,
glVertex3fv(ltri[0]->v->co);
}
- PASSATTRIB(ltri[1], ltri[1]->v, 1);
+ emdm_pass_attrib_vertex_glsl(&attribs, ltri[1], 1);
if (vertexCos) {
glNormal3fv(vertexNos[BM_elem_index_get(ltri[1]->v)]);
glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
@@ -1102,7 +1115,7 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm,
glVertex3fv(ltri[1]->v->co);
}
- PASSATTRIB(ltri[2], ltri[2]->v, 2);
+ emdm_pass_attrib_vertex_glsl(&attribs, ltri[2], 2);
if (vertexCos) {
glNormal3fv(vertexNos[BM_elem_index_get(ltri[2]->v)]);
glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
@@ -1115,7 +1128,6 @@ static void emDM_drawMappedFacesGLSL(DerivedMesh *dm,
glEnd();
}
}
-#undef PASSATTRIB
}
static void emDM_drawFacesGLSL(DerivedMesh *dm,
@@ -1124,6 +1136,38 @@ static void emDM_drawFacesGLSL(DerivedMesh *dm,
dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
}
+/* emdm_pass_attrib_vertex_glsl's note about em_offset use applies here */
+static void emdm_pass_attrib_vertex_mat(DMVertexAttribs *attribs, BMLoop *loop, int index_in_face)
+{
+ BMVert *eve = loop->v;
+ int i;
+
+ if (attribs->totorco) {
+ float *orco = attribs->orco.array[BM_elem_index_get(eve)];
+ if (attribs->orco.gl_texco)
+ glTexCoord3fv(orco);
+ else
+ glVertexAttrib3fvARB(attribs->orco.gl_index, orco);
+ }
+ for (i = 0; i < attribs->tottface; i++) {
+ const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(loop, attribs->tface[i].em_offset);
+ if (attribs->tface[i].gl_texco)
+ glTexCoord2fv(luv->uv);
+ else
+ glVertexAttrib2fvARB(attribs->tface[i].gl_index, luv->uv);
+ }
+ for (i = 0; i < attribs->totmcol; i++) {
+ const MLoopCol *cp = BM_ELEM_CD_GET_VOID_P(loop, attribs->mcol[i].em_offset);
+ GLubyte col[4];
+ col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
+ glVertexAttrib4ubvARB(attribs->mcol[i].gl_index, col);
+ }
+ if (attribs->tottang) {
+ float *tang = attribs->tang.array[i * 4 + index_in_face];
+ glVertexAttrib4fvARB(attribs->tang.gl_index, tang);
+ }
+}
+
static void emDM_drawMappedFacesMat(DerivedMesh *dm,
void (*setMaterial)(void *userData, int, void *attribs),
int (*setFace)(void *userData, int index), void *userData)
@@ -1137,7 +1181,7 @@ static void emDM_drawMappedFacesMat(DerivedMesh *dm,
BMLoop **ltri;
DMVertexAttribs attribs = {{{0}}};
GPUVertexAttribs gattribs;
- int i, b, matnr, new_matnr;
+ int i, matnr, new_matnr;
matnr = -1;
@@ -1146,35 +1190,6 @@ static void emDM_drawMappedFacesMat(DerivedMesh *dm,
BM_mesh_elem_index_ensure(bm, BM_VERT | BM_FACE);
-#define PASSATTRIB(loop, eve, vert) { \
- if (attribs.totorco) { \
- float *orco = attribs.orco.array[BM_elem_index_get(eve)]; \
- if (attribs.orco.gl_texco) \
- glTexCoord3fv(orco); \
- else \
- glVertexAttrib3fvARB(attribs.orco.gl_index, orco); \
- } \
- for (b = 0; b < attribs.tottface; b++) { \
- MLoopUV *_luv = CustomData_bmesh_get_n(&bm->ldata, loop->head.data, \
- CD_MLOOPUV, b); \
- if (attribs.tface[b].gl_texco) \
- glTexCoord2fv(_luv->uv); \
- else \
- glVertexAttrib2fvARB(attribs.tface[b].gl_index, _luv->uv); \
- } \
- for (b = 0; b < attribs.totmcol; b++) { \
- MLoopCol *_cp = CustomData_bmesh_get_n(&bm->ldata, loop->head.data, \
- CD_MLOOPCOL, b); \
- GLubyte _col[4]; \
- _col[0] = _cp->b; _col[1] = _cp->g; _col[2] = _cp->r; _col[3] = _cp->a; \
- glVertexAttrib4ubvARB(attribs.mcol[b].gl_index, _col); \
- } \
- if (attribs.tottang) { \
- float *tang = attribs.tang.array[i * 4 + vert]; \
- glVertexAttrib4fvARB(attribs.tang.gl_index, tang); \
- } \
- } (void)0
-
for (i = 0, ltri = em->looptris[0]; i < em->tottri; i++, ltri += 3) {
int drawSmooth;
@@ -1198,21 +1213,21 @@ static void emDM_drawMappedFacesMat(DerivedMesh *dm,
if (vertexCos) glNormal3fv(bmdm->polyNos[BM_elem_index_get(efa)]);
else glNormal3fv(efa->no);
- PASSATTRIB(ltri[0], ltri[0]->v, 0);
+ emdm_pass_attrib_vertex_mat(&attribs, ltri[0], 0);
if (vertexCos) glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
else glVertex3fv(ltri[0]->v->co);
- PASSATTRIB(ltri[1], ltri[1]->v, 1);
+ emdm_pass_attrib_vertex_mat(&attribs, ltri[1], 1);
if (vertexCos) glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
else glVertex3fv(ltri[1]->v->co);
- PASSATTRIB(ltri[2], ltri[2]->v, 2);
+ emdm_pass_attrib_vertex_mat(&attribs, ltri[2], 2);
if (vertexCos) glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
else glVertex3fv(ltri[2]->v->co);
}
else {
- PASSATTRIB(ltri[0], ltri[0]->v, 0);
+ emdm_pass_attrib_vertex_mat(&attribs, ltri[0], 0);
if (vertexCos) {
glNormal3fv(vertexNos[BM_elem_index_get(ltri[0]->v)]);
glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
@@ -1222,7 +1237,7 @@ static void emDM_drawMappedFacesMat(DerivedMesh *dm,
glVertex3fv(ltri[0]->v->co);
}
- PASSATTRIB(ltri[1], ltri[1]->v, 1);
+ emdm_pass_attrib_vertex_mat(&attribs, ltri[1], 1);
if (vertexCos) {
glNormal3fv(vertexNos[BM_elem_index_get(ltri[1]->v)]);
glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
@@ -1232,7 +1247,7 @@ static void emDM_drawMappedFacesMat(DerivedMesh *dm,
glVertex3fv(ltri[1]->v->co);
}
- PASSATTRIB(ltri[2], ltri[2]->v, 2);
+ emdm_pass_attrib_vertex_mat(&attribs, ltri[2], 2);
if (vertexCos) {
glNormal3fv(vertexNos[BM_elem_index_get(ltri[2]->v)]);
glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
@@ -1244,7 +1259,6 @@ static void emDM_drawMappedFacesMat(DerivedMesh *dm,
}
glEnd();
}
-#undef PASSATTRIB
}
static void emDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index 9fdf51ceba9..19ef1e3971d 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -454,7 +454,7 @@ void IDP_ReplaceGroupInGroup(IDProperty *dest, IDProperty *src)
if (strcmp(loop->name, prop->name) == 0) {
IDProperty *copy = IDP_CopyProperty(prop);
- BLI_insertlink(&dest->data.group, loop, copy);
+ BLI_insertlinkafter(&dest->data.group, loop, copy);
BLI_remlink(&dest->data.group, loop);
IDP_FreeProperty(loop);
@@ -479,7 +479,7 @@ void IDP_ReplaceInGroup(IDProperty *group, IDProperty *prop)
{
IDProperty *loop;
if ((loop = IDP_GetPropertyFromGroup(group, prop->name))) {
- BLI_insertlink(&group->data.group, loop, prop);
+ BLI_insertlinkafter(&group->data.group, loop, prop);
BLI_remlink(&group->data.group, loop);
IDP_FreeProperty(loop);
@@ -532,7 +532,7 @@ int IDP_InsertToGroup(IDProperty *group, IDProperty *previous, IDProperty *pnew)
{
if (IDP_GetPropertyFromGroup(group, pnew->name) == NULL) {
group->len++;
- BLI_insertlink(&group->data.group, previous, pnew);
+ BLI_insertlinkafter(&group->data.group, previous, pnew);
return 1;
}
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index de85cb54cfd..3655afdf088 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -571,6 +571,20 @@ static void image_init_color_management(Image *ima)
}
}
+void BKE_image_alpha_mode_from_extension(Image *image)
+{
+ if (BLI_testextensie(image->name, ".exr") ||
+ BLI_testextensie(image->name, ".cin") ||
+ BLI_testextensie(image->name, ".dpx") ||
+ BLI_testextensie(image->name, ".hdr"))
+ {
+ image->alpha_mode = IMA_ALPHA_PREMUL;
+ }
+ else {
+ image->alpha_mode = IMA_ALPHA_STRAIGHT;
+ }
+}
+
Image *BKE_image_load(Main *bmain, const char *filepath)
{
Image *ima;
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index cb0a11a16e0..f3dc391738e 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -246,7 +246,7 @@ void BKE_key_sort(Key *key)
/* find the right location and insert before */
for (kb2 = key->block.first; kb2; kb2 = kb2->next) {
if (kb2->pos > kb->pos) {
- BLI_insertlink(&key->block, kb2->prev, kb);
+ BLI_insertlinkafter(&key->block, kb2->prev, kb);
break;
}
}
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
index 943d9e9452a..eceac61ddb6 100644
--- a/source/blender/blenkernel/intern/movieclip.c
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -216,7 +216,7 @@ static ImBuf *movieclip_load_sequence_file(MovieClip *clip, MovieClipUser *user,
colorspace = clip->colorspace_settings.name;
}
- loadflag = IB_rect | IB_multilayer;
+ loadflag = IB_rect | IB_multilayer | IB_alphamode_detect;
/* read ibuf */
ibuf = IMB_loadiffname(name, loadflag, colorspace);
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 97bee320ecb..86fe47268d6 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -2028,9 +2028,8 @@ void node_type_base(bNodeTreeType *ttype, bNodeType *ntype, int type, const char
ntype->update_internal_links = ttype->update_internal_links;
/* default size values */
- ntype->width = 140;
- ntype->minwidth = 100;
- ntype->maxwidth = 320;
+ node_type_size_preset(ntype, NODE_SIZE_DEFAULT);
+
ntype->height = 100;
ntype->minheight = 30;
ntype->maxheight = FLT_MAX;
@@ -2062,6 +2061,21 @@ void node_type_size(struct bNodeType *ntype, int width, int minwidth, int maxwid
ntype->maxwidth = maxwidth;
}
+void node_type_size_preset(struct bNodeType *ntype, eNodeSizePreset size)
+{
+ switch (size) {
+ case NODE_SIZE_DEFAULT:
+ node_type_size(ntype, 140, 100, 320);
+ break;
+ case NODE_SIZE_SMALL:
+ node_type_size(ntype, 100, 80, 320);
+ break;
+ case NODE_SIZE_LARGE:
+ node_type_size(ntype, 140, 120, 500);
+ break;
+ }
+}
+
void node_type_storage(bNodeType *ntype, const char *storagename, void (*freestoragefunc)(struct bNode *), void (*copystoragefunc)(struct bNode *, struct bNode *))
{
if (storagename)
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 119dc8c7d11..5cea2c9fe0e 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -74,6 +74,7 @@
#include "BKE_bullet.h"
#include "BKE_colortools.h"
#include "BKE_deform.h"
+#include "BKE_depsgraph.h"
#include "BKE_DerivedMesh.h"
#include "BKE_animsys.h"
#include "BKE_anim.h"
@@ -410,7 +411,8 @@ static void unlink_object__unlinkModifierLinks(void *userData, Object *ob, Objec
if (*obpoin == unlinkOb) {
*obpoin = NULL;
- ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME; // XXX: should this just be OB_RECALC_DATA?
+ // XXX: should this just be OB_RECALC_DATA?
+ DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
}
}
@@ -444,14 +446,14 @@ void BKE_object_unlink(Object *ob)
obt->proxy = NULL;
if (obt->proxy_from == ob) {
obt->proxy_from = NULL;
- obt->recalc |= OB_RECALC_OB;
+ DAG_id_tag_update(&obt->id, OB_RECALC_OB);
}
if (obt->proxy_group == ob)
obt->proxy_group = NULL;
if (obt->parent == ob) {
obt->parent = NULL;
- obt->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
+ DAG_id_tag_update(&obt->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
}
modifiers_foreachObjectLink(obt, unlink_object__unlinkModifierLinks, ob);
@@ -461,15 +463,15 @@ void BKE_object_unlink(Object *ob)
if (cu->bevobj == ob) {
cu->bevobj = NULL;
- obt->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
+ DAG_id_tag_update(&obt->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
}
if (cu->taperobj == ob) {
cu->taperobj = NULL;
- obt->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
+ DAG_id_tag_update(&obt->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
}
if (cu->textoncurve == ob) {
cu->textoncurve = NULL;
- obt->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
+ DAG_id_tag_update(&obt->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
}
}
else if (obt->type == OB_ARMATURE && obt->pose) {
@@ -487,7 +489,7 @@ void BKE_object_unlink(Object *ob)
if (ct->tar == ob) {
ct->tar = NULL;
ct->subtarget[0] = '\0';
- obt->recalc |= OB_RECALC_DATA;
+ DAG_id_tag_update(&obt->id, OB_RECALC_DATA);
}
}
@@ -501,7 +503,7 @@ void BKE_object_unlink(Object *ob)
}
else if (ELEM(OB_MBALL, ob->type, obt->type)) {
if (BKE_mball_is_basis_for(obt, ob))
- obt->recalc |= OB_RECALC_DATA;
+ DAG_id_tag_update(&obt->id, OB_RECALC_DATA);
}
sca_remove_ob_poin(obt, ob);
@@ -518,7 +520,7 @@ void BKE_object_unlink(Object *ob)
if (ct->tar == ob) {
ct->tar = NULL;
ct->subtarget[0] = '\0';
- obt->recalc |= OB_RECALC_DATA;
+ DAG_id_tag_update(&obt->id, OB_RECALC_DATA);
}
}
@@ -530,12 +532,12 @@ void BKE_object_unlink(Object *ob)
/* object is deflector or field */
if (ob->pd) {
if (obt->soft)
- obt->recalc |= OB_RECALC_DATA;
+ DAG_id_tag_update(&obt->id, OB_RECALC_DATA);
/* cloth */
for (md = obt->modifiers.first; md; md = md->next)
if (md->type == eModifierType_Cloth)
- obt->recalc |= OB_RECALC_DATA;
+ DAG_id_tag_update(&obt->id, OB_RECALC_DATA);
}
/* strips */
@@ -564,14 +566,14 @@ void BKE_object_unlink(Object *ob)
for (; pt; pt = pt->next) {
if (pt->ob == ob) {
pt->ob = NULL;
- obt->recalc |= OB_RECALC_DATA;
+ DAG_id_tag_update(&obt->id, OB_RECALC_DATA);
break;
}
}
if (tpsys->target_ob == ob) {
tpsys->target_ob = NULL;
- obt->recalc |= OB_RECALC_DATA;
+ DAG_id_tag_update(&obt->id, OB_RECALC_DATA);
}
if (tpsys->part->dup_ob == ob)
@@ -606,7 +608,7 @@ void BKE_object_unlink(Object *ob)
}
}
if (ob->pd)
- obt->recalc |= OB_RECALC_DATA;
+ DAG_id_tag_update(&obt->id, OB_RECALC_DATA);
}
obt = obt->id.next;
@@ -984,7 +986,7 @@ Object *BKE_object_add(struct Scene *scene, int type)
base = BKE_scene_base_add(scene, ob);
BKE_scene_base_deselect_all(scene);
BKE_scene_base_select(scene, base);
- ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
+ DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
return ob;
}
@@ -1494,7 +1496,8 @@ void BKE_object_make_proxy(Object *ob, Object *target, Object *gob)
ob->proxy_group = gob;
id_lib_extern(&target->id);
- ob->recalc = target->recalc = OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME;
+ DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
+ DAG_id_tag_update(&target->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
/* copy transform
* - gob means this proxy comes from a group, just apply the matrix
@@ -2132,7 +2135,8 @@ static int where_is_object_parslow(Object *ob, float obmat[4][4], float slowmat[
}
/* note, scene is the active scene while actual_scene is the scene the object resides in */
-void BKE_object_where_is_calc_time_ex(Scene *scene, RigidBodyWorld *rbw, Object *ob, float ctime)
+void BKE_object_where_is_calc_time_ex(Scene *scene, Object *ob, float ctime,
+ RigidBodyWorld *rbw)
{
if (ob == NULL) return;
@@ -2158,6 +2162,8 @@ void BKE_object_where_is_calc_time_ex(Scene *scene, RigidBodyWorld *rbw, Object
BKE_object_to_mat4(ob, ob->obmat);
}
+ /* try to fall back to the scene rigid body world if none given */
+ rbw = rbw ? rbw : scene->rigidbody_world;
/* read values pushed into RBO from sim/cache... */
BKE_rigidbody_sync_transforms(rbw, ob, ctime);
@@ -2177,7 +2183,7 @@ void BKE_object_where_is_calc_time_ex(Scene *scene, RigidBodyWorld *rbw, Object
void BKE_object_where_is_calc_time(Scene *scene, Object *ob, float ctime)
{
- BKE_object_where_is_calc_time_ex(scene, NULL, ob, ctime);
+ BKE_object_where_is_calc_time_ex(scene, ob, ctime, NULL);
}
/* get object transformation matrix without recalculating dependencies and
@@ -2203,17 +2209,17 @@ void BKE_object_where_is_calc_mat4(Scene *scene, Object *ob, float obmat[4][4])
void BKE_object_where_is_calc_ex(Scene *scene, RigidBodyWorld *rbw, Object *ob)
{
- BKE_object_where_is_calc_time_ex(scene, rbw, ob, BKE_scene_frame_get(scene));
+ BKE_object_where_is_calc_time_ex(scene, ob, BKE_scene_frame_get(scene), rbw);
}
void BKE_object_where_is_calc(Scene *scene, Object *ob)
{
- BKE_object_where_is_calc_time_ex(scene, NULL, ob, BKE_scene_frame_get(scene));
+ BKE_object_where_is_calc_time_ex(scene, ob, BKE_scene_frame_get(scene), NULL);
}
-void BKE_object_where_is_calc_simul(Scene *scene, Object *ob)
/* was written for the old game engine (until 2.04) */
/* It seems that this function is only called
* for a lamp that is the child of another object */
+void BKE_object_where_is_calc_simul(Scene *scene, Object *ob)
{
Object *par;
float *fp1, *fp2;
@@ -2644,7 +2650,8 @@ int BKE_object_parent_loop_check(const Object *par, const Object *ob)
/* the main object update call, for object matrix, constraints, keys and displist (modifiers) */
/* requires flags to be set! */
/* Ideally we shouldn't have to pass the rigid body world, but need bigger restructuring to avoid id */
-void BKE_object_handle_update_ex(Scene *scene, RigidBodyWorld *rbw, Object *ob)
+void BKE_object_handle_update_ex(Scene *scene, Object *ob,
+ RigidBodyWorld *rbw)
{
if (ob->recalc & OB_RECALC_ALL) {
/* speed optimization for animation lookups */
@@ -2846,7 +2853,7 @@ void BKE_object_handle_update_ex(Scene *scene, RigidBodyWorld *rbw, Object *ob)
*/
void BKE_object_handle_update(Scene *scene, Object *ob)
{
- BKE_object_handle_update_ex(scene, NULL, ob);
+ BKE_object_handle_update_ex(scene, ob, NULL);
}
void BKE_object_sculpt_modifiers_changed(Object *ob)
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index c01ea4e518d..f90fde983aa 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -3509,12 +3509,12 @@ ModifierData *object_add_particle_system(Scene *scene, Object *ob, const char *n
psys->flag = PSYS_ENABLED | PSYS_CURRENT;
psys->cfra = BKE_scene_frame_get_from_ctime(scene, CFRA + 1);
- DAG_scene_sort(G.main, scene);
+ DAG_relations_tag_update(G.main);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
return md;
}
-void object_remove_particle_system(Scene *scene, Object *ob)
+void object_remove_particle_system(Scene *UNUSED(scene), Object *ob)
{
ParticleSystem *psys = psys_get_current(ob);
ParticleSystemModifierData *psmd;
@@ -3552,7 +3552,7 @@ void object_remove_particle_system(Scene *scene, Object *ob)
else
ob->mode &= ~OB_MODE_PARTICLE_EDIT;
- DAG_scene_sort(G.main, scene);
+ DAG_relations_tag_update(G.main);
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
static void default_particle_settings(ParticleSettings *part)
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 6e4937d11ec..3efe25794e1 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -3028,13 +3028,20 @@ static void basic_rotate(ParticleSettings *part, ParticleData *pa, float dfra, f
normalize_qt(pa->state.rot);
}
-/************************************************/
-/* Collisions */
-/************************************************/
+/************************************************
+ * Collisions
+ *
+ * The algorithm is roughly:
+ * 1. Use a BVH tree to search for faces that a particle may collide with.
+ * 2. Use Newton's method to find the exact time at which the collision occurs.
+ * http://en.wikipedia.org/wiki/Newton's_method
+ *
+ ************************************************/
#define COLLISION_MAX_COLLISIONS 10
#define COLLISION_MIN_RADIUS 0.001f
#define COLLISION_MIN_DISTANCE 0.0001f
#define COLLISION_ZERO 0.00001f
+#define COLLISION_INIT_STEP 0.00008f
typedef float (*NRDistanceFunc)(float *p, float radius, ParticleCollisionElement *pce, float *nor);
static float nr_signed_distance_to_plane(float *p, float radius, ParticleCollisionElement *pce, float *nor)
{
@@ -3189,16 +3196,20 @@ static void collision_point_on_surface(float p[3], ParticleCollisionElement *pce
/* find first root in range [0-1] starting from 0 */
static float collision_newton_rhapson(ParticleCollision *col, float radius, ParticleCollisionElement *pce, NRDistanceFunc distance_func)
{
- float t0, t1, d0, d1, dd, n[3];
+ float t0, t1, dt_init, d0, d1, dd, n[3];
int iter;
pce->inv_nor = -1;
+ /* Initial step size should be small, but not too small or floating point
+ * precision errors will appear. - z0r */
+ dt_init = COLLISION_INIT_STEP * col->inv_total_time;
+
/* start from the beginning */
t0 = 0.f;
collision_interpolate_element(pce, t0, col->f, col);
d0 = distance_func(col->co1, radius, pce, n);
- t1 = 0.001f;
+ t1 = dt_init;
d1 = 0.f;
for (iter=0; iter<10; iter++) {//, itersum++) {
@@ -3208,11 +3219,6 @@ static float collision_newton_rhapson(ParticleCollision *col, float radius, Part
d1 = distance_func(pce->p, radius, pce, n);
- /* no movement, so no collision */
- if (d1 == d0) {
- return -1.f;
- }
-
/* particle already inside face, so report collision */
if (iter == 0 && d0 < 0.f && d0 > -radius) {
copy_v3_v3(pce->p, col->co1);
@@ -3220,7 +3226,24 @@ static float collision_newton_rhapson(ParticleCollision *col, float radius, Part
pce->inside = 1;
return 0.f;
}
-
+
+ /* Zero gradient (no movement relative to element). Can't step from
+ * here. */
+ if (d1 == d0) {
+ /* If first iteration, try from other end where the gradient may be
+ * greater. Note: code duplicated below. */
+ if (iter == 0) {
+ t0 = 1.f;
+ collision_interpolate_element(pce, t0, col->f, col);
+ d0 = distance_func(col->co2, radius, pce, n);
+ t1 = 1.0f - dt_init;
+ d1 = 0.f;
+ continue;
+ }
+ else
+ return -1.f;
+ }
+
dd = (t1-t0)/(d1-d0);
t0 = t1;
@@ -3228,14 +3251,14 @@ static float collision_newton_rhapson(ParticleCollision *col, float radius, Part
t1 -= d1*dd;
- /* particle movin away from plane could also mean a strangely rotating face, so check from end */
+ /* Particle moving away from plane could also mean a strangely rotating
+ * face, so check from end. Note: code duplicated above. */
if (iter == 0 && t1 < 0.f) {
t0 = 1.f;
collision_interpolate_element(pce, t0, col->f, col);
d0 = distance_func(col->co2, radius, pce, n);
- t1 = 0.999f;
+ t1 = 1.0f - dt_init;
d1 = 0.f;
-
continue;
}
else if (iter == 1 && (t1 < -COLLISION_ZERO || t1 > 1.f))
@@ -3683,6 +3706,7 @@ static void collision_check(ParticleSimulationData *sim, int p, float dfra, floa
memset(&col, 0, sizeof(ParticleCollision));
col.total_time = timestep * dfra;
+ col.inv_total_time = 1.0f/col.total_time;
col.inv_timestep = 1.0f/timestep;
col.cfra = cfra;
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 4302032ade1..27c5e03132e 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -52,6 +52,8 @@
#include "BLI_math.h"
#include "BLI_utildefines.h"
+#include "BLF_translation.h"
+
#include "PIL_time.h"
#include "WM_api.h"
@@ -3505,11 +3507,11 @@ void BKE_ptcache_update_info(PTCacheID *pid)
/* smoke doesn't use frame 0 as info frame so can't check based on totpoint */
if (pid->type == PTCACHE_TYPE_SMOKE_DOMAIN && totframes)
- BLI_snprintf(cache->info, sizeof(cache->info), "%i frames found!", totframes);
+ BLI_snprintf(cache->info, sizeof(cache->info), IFACE_("%i frames found!"), totframes);
else if (totframes && cache->totpoint)
- BLI_snprintf(cache->info, sizeof(cache->info), "%i points found!", cache->totpoint);
+ BLI_snprintf(cache->info, sizeof(cache->info), IFACE_("%i points found!"), cache->totpoint);
else
- BLI_snprintf(cache->info, sizeof(cache->info), "No valid data to read!");
+ BLI_snprintf(cache->info, sizeof(cache->info), IFACE_("No valid data to read!"));
return;
}
@@ -3518,9 +3520,9 @@ void BKE_ptcache_update_info(PTCacheID *pid)
int totpoint = pid->totpoint(pid->calldata, 0);
if (cache->totpoint > totpoint)
- BLI_snprintf(mem_info, sizeof(mem_info), "%i cells + High Resolution cached", totpoint);
+ BLI_snprintf(mem_info, sizeof(mem_info), IFACE_("%i cells + High Resolution cached"), totpoint);
else
- BLI_snprintf(mem_info, sizeof(mem_info), "%i cells cached", totpoint);
+ BLI_snprintf(mem_info, sizeof(mem_info), IFACE_("%i cells cached"), totpoint);
}
else {
int cfra = cache->startframe;
@@ -3530,7 +3532,7 @@ void BKE_ptcache_update_info(PTCacheID *pid)
totframes++;
}
- BLI_snprintf(mem_info, sizeof(mem_info), "%i frames on disk", totframes);
+ BLI_snprintf(mem_info, sizeof(mem_info), IFACE_("%i frames on disk"), totframes);
}
}
else {
@@ -3554,17 +3556,18 @@ void BKE_ptcache_update_info(PTCacheID *pid)
mb = (bytes > 1024.0f * 1024.0f);
- BLI_snprintf(mem_info, sizeof(mem_info), "%i frames in memory (%.1f %s)",
+ BLI_snprintf(mem_info, sizeof(mem_info), IFACE_("%i frames in memory (%.1f %s)"),
totframes,
bytes / (mb ? 1024.0f * 1024.0f : 1024.0f),
- mb ? "Mb" : "kb");
+ mb ? IFACE_("Mb") : IFACE_("kb"));
}
if (cache->flag & PTCACHE_OUTDATED) {
- BLI_snprintf(cache->info, sizeof(cache->info), "%s, cache is outdated!", mem_info);
+ BLI_snprintf(cache->info, sizeof(cache->info), IFACE_("%s, cache is outdated!"), mem_info);
}
else if (cache->flag & PTCACHE_FRAMES_SKIPPED) {
- BLI_snprintf(cache->info, sizeof(cache->info), "%s, not exact since frame %i.", mem_info, cache->last_exact);
+ BLI_snprintf(cache->info, sizeof(cache->info), IFACE_("%s, not exact since frame %i."),
+ mem_info, cache->last_exact);
}
else {
BLI_snprintf(cache->info, sizeof(cache->info), "%s.", mem_info);
@@ -3586,4 +3589,3 @@ void BKE_ptcache_invalidate(PointCache *cache)
cache->last_exact = MIN2(cache->startframe, 0);
}
}
-
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index 26f0c25617f..4c6bae122cd 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -633,8 +633,18 @@ void BKE_rigidbody_validate_sim_constraint(RigidBodyWorld *rbw, Object *ob, shor
else
RB_constraint_set_limits_6dof(rbc->physics_constraint, RB_LIMIT_ANG_Z, 0.0f, -1.0f);
break;
+ case RBC_TYPE_MOTOR:
+ rbc->physics_constraint = RB_constraint_new_motor(loc, rot, rb1, rb2);
+
+ RB_constraint_set_enable_motor(rbc->physics_constraint, rbc->flag & RBC_FLAG_USE_MOTOR_LIN, rbc->flag & RBC_FLAG_USE_MOTOR_ANG);
+ RB_constraint_set_max_impulse_motor(rbc->physics_constraint, rbc->motor_lin_max_impulse, rbc->motor_ang_max_impulse);
+ RB_constraint_set_target_velocity_motor(rbc->physics_constraint, rbc->motor_lin_target_velocity, rbc->motor_ang_target_velocity);
+ break;
}
}
+ else { /* can't create constraint without both rigid bodies */
+ return;
+ }
RB_constraint_set_enabled(rbc->physics_constraint, rbc->flag & RBC_FLAG_ENABLED);
@@ -813,6 +823,11 @@ RigidBodyCon *BKE_rigidbody_create_constraint(Scene *scene, Object *ob, short ty
rbc->spring_stiffness_y = 10.0f;
rbc->spring_stiffness_z = 10.0f;
+ rbc->motor_lin_max_impulse = 1.0f;
+ rbc->motor_lin_target_velocity = 1.0f;
+ rbc->motor_ang_max_impulse = 1.0f;
+ rbc->motor_ang_target_velocity = 1.0f;
+
/* flag cache as outdated */
BKE_rigidbody_cache_reset(rbw);
@@ -1259,7 +1274,7 @@ void BKE_rigidbody_do_simulation(Scene *scene, float ctime)
}
/* advance simulation, we can only step one frame forward */
- if (ctime == rbw->ltime + 1) {
+ if (ctime == rbw->ltime + 1 && !(cache->flag & PTCACHE_BAKED)) {
/* write cache for first frame when on second frame */
if (rbw->ltime == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact == 0)) {
BKE_ptcache_write(&pid, startframe);
@@ -1308,7 +1323,7 @@ struct RigidBodyCon *BKE_rigidbody_create_constraint(Scene *scene, Object *ob, s
struct RigidBodyWorld *BKE_rigidbody_get_world(Scene *scene) { return NULL; }
void BKE_rigidbody_remove_object(Scene *scene, Object *ob) {}
void BKE_rigidbody_remove_constraint(Scene *scene, Object *ob) {}
-void BKE_rigidbody_sync_transforms(Scene *scene, Object *ob, float ctime) {}
+void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime) {}
void BKE_rigidbody_aftertrans_update(Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle) {}
void BKE_rigidbody_cache_reset(RigidBodyWorld *rbw) {}
void BKE_rigidbody_do_simulation(Scene *scene, float ctime) {}
diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c
index eb4e0d9c679..6433b73fda0 100644
--- a/source/blender/blenkernel/intern/sca.c
+++ b/source/blender/blenkernel/intern/sca.c
@@ -734,7 +734,7 @@ void sca_move_sensor(bSensor *sens_to_move, Object *ob, int move_up)
}
if (tmp) {
BLI_remlink(&ob->sensors, sens);
- BLI_insertlink(&ob->sensors, tmp, sens);
+ BLI_insertlinkafter(&ob->sensors, tmp, sens);
}
}
}
@@ -778,7 +778,7 @@ void sca_move_controller(bController *cont_to_move, Object *ob, int move_up)
tmp = tmp->next;
}
BLI_remlink(&ob->controllers, cont);
- BLI_insertlink(&ob->controllers, tmp, cont);
+ BLI_insertlinkafter(&ob->controllers, tmp, cont);
}
}
@@ -818,7 +818,7 @@ void sca_move_actuator(bActuator *act_to_move, Object *ob, int move_up)
}
if (tmp) {
BLI_remlink(&ob->actuators, act);
- BLI_insertlink(&ob->actuators, tmp, act);
+ BLI_insertlinkafter(&ob->actuators, tmp, act);
}
}
}
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 9934d9b6e9a..e1e4563e89f 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -177,6 +177,7 @@ Scene *BKE_scene_copy(Scene *sce, int type)
scen->obedit = NULL;
scen->stats = NULL;
scen->fps_info = NULL;
+ scen->rigidbody_world = NULL; /* RB_TODO figure out a way of copying the rigid body world */
BLI_duplicatelist(&(scen->markers), &(sce->markers));
BLI_duplicatelist(&(scen->transform_spaces), &(sce->transform_spaces));
@@ -404,7 +405,7 @@ void BKE_scene_free(Scene *sce)
BKE_color_managed_view_settings_free(&sce->view_settings);
}
-static Scene *scene_add(Main *bmain, const char *name)
+Scene *BKE_scene_add(Main *bmain, const char *name)
{
Scene *sce;
ParticleEditSettings *pset;
@@ -639,11 +640,6 @@ static Scene *scene_add(Main *bmain, const char *name)
return sce;
}
-Scene *BKE_scene_add(Main *bmain, const char *name)
-{
- return scene_add(bmain, name);
-}
-
Base *BKE_scene_base_find(Scene *scene, Object *ob)
{
return BLI_findptr(&scene->base, ob, offsetof(Base, object));
@@ -679,12 +675,11 @@ void BKE_scene_set_background(Main *bmain, Scene *scene)
}
/* sort baselist */
- DAG_scene_sort(bmain, scene);
+ DAG_scene_relations_rebuild(bmain, scene);
/* ensure dags are built for sets */
- for (sce = scene->set; sce; sce = sce->set)
- if (sce->theDag == NULL)
- DAG_scene_sort(bmain, sce);
+ for (sce = scene; sce; sce = sce->set)
+ DAG_scene_relations_update(bmain, sce);
/* copy layers and flags from bases to objects */
for (base = scene->base.first; base; base = base->next) {
@@ -1155,7 +1150,7 @@ static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scen
for (base = scene->base.first; base; base = base->next) {
Object *ob = base->object;
- BKE_object_handle_update_ex(scene_parent, scene->rigidbody_world, ob);
+ BKE_object_handle_update_ex(scene_parent, ob, scene->rigidbody_world);
if (ob->dup_group && (ob->transflag & OB_DUPLIGROUP))
group_handle_recalc_and_update(scene_parent, ob, ob->dup_group);
@@ -1180,9 +1175,15 @@ static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scen
/* this is called in main loop, doing tagged updates before redraw */
void BKE_scene_update_tagged(Main *bmain, Scene *scene)
{
+ Scene *sce_iter;
+
/* keep this first */
BLI_callback_exec(bmain, &scene->id, BLI_CB_EVT_SCENE_UPDATE_PRE);
+ /* (re-)build dependency graph if needed */
+ for (sce_iter = scene; sce_iter; sce_iter = sce_iter->set)
+ DAG_scene_relations_update(bmain, sce_iter);
+
/* flush recalc flags to dependencies */
DAG_ids_flush_tagged(bmain);
@@ -1233,10 +1234,8 @@ void BKE_scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay)
/* clear animation overrides */
/* XXX TODO... */
- for (sce_iter = sce; sce_iter; sce_iter = sce_iter->set) {
- if (sce_iter->theDag == NULL)
- DAG_scene_sort(bmain, sce_iter);
- }
+ for (sce_iter = sce; sce_iter; sce_iter = sce_iter->set)
+ DAG_scene_relations_update(bmain, sce_iter);
/* flush recalc flags to dependencies, if we were only changing a frame
* this would not be necessary, but if a user or a script has modified
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 45393726add..68618287546 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -3955,6 +3955,24 @@ Sequence *BKE_sequence_alloc(ListBase *lb, int cfra, int machine)
return seq;
}
+void BKE_sequence_alpha_mode_from_extension(Sequence *seq)
+{
+ if (seq->strip && seq->strip->stripdata) {
+ char *name = seq->strip->stripdata->name;
+
+ if (BLI_testextensie(name, ".exr") ||
+ BLI_testextensie(name, ".cin") ||
+ BLI_testextensie(name, ".dpx") ||
+ BLI_testextensie(name, ".hdr"))
+ {
+ seq->alpha_mode = IMA_ALPHA_PREMUL;
+ }
+ else {
+ seq->alpha_mode = IMA_ALPHA_STRAIGHT;
+ }
+ }
+}
+
void BKE_sequence_init_colorspace(Sequence *seq)
{
if (seq->strip && seq->strip->stripdata) {
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 86e7a152a4a..74c0a76f82d 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -2938,6 +2938,18 @@ int text_check_identifier_nodigit(const char ch)
return 0;
}
+#ifndef WITH_PYTHON
+int text_check_identifier_unicode(const unsigned int ch)
+{
+ return (ch < 255 && text_check_identifier((char)ch));
+}
+
+int text_check_identifier_nodigit_unicode(const unsigned int ch)
+{
+ return (ch < 255 && text_check_identifier_nodigit((char)ch));
+}
+#endif /* WITH_PYTHON */
+
int text_check_whitespace(const char ch)
{
if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n')
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c
index 8b81e474e76..1a7458f531c 100644
--- a/source/blender/blenkernel/intern/tracking.c
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -141,8 +141,10 @@ static void tracking_dopesheet_free(MovieTrackingDopesheet *dopesheet)
}
BLI_freelistN(&dopesheet->channels);
+ BLI_freelistN(&dopesheet->coverage_segments);
dopesheet->channels.first = dopesheet->channels.last = NULL;
+ dopesheet->coverage_segments.first = dopesheet->coverage_segments.last = NULL;
dopesheet->tot_channel = 0;
}
@@ -1605,6 +1607,67 @@ ImBuf *BKE_tracking_distort_frame(MovieTracking *tracking, ImBuf *ibuf, int cali
calibration_height, overscan, FALSE);
}
+void BKE_tracking_max_undistortion_delta_across_bound(MovieTracking *tracking, rcti *rect, float delta[2])
+{
+ int a;
+ float pos[2], warped_pos[2];
+ const int coord_delta = 5;
+
+ delta[0] = delta[1] = -FLT_MAX;
+
+ for (a = rect->xmin; a <= rect->xmax + coord_delta; a += coord_delta) {
+ if (a > rect->xmax)
+ a = rect->xmax;
+
+ /* bottom edge */
+ pos[0] = a;
+ pos[1] = rect->ymin;
+
+ BKE_tracking_undistort_v2(tracking, pos, warped_pos);
+
+ delta[0] = max_ff(delta[0], fabs(pos[0] - warped_pos[0]));
+ delta[1] = max_ff(delta[1], fabs(pos[1] - warped_pos[1]));
+
+ /* top edge */
+ pos[0] = a;
+ pos[1] = rect->ymax;
+
+ BKE_tracking_undistort_v2(tracking, pos, warped_pos);
+
+ delta[0] = max_ff(delta[0], fabs(pos[0] - warped_pos[0]));
+ delta[1] = max_ff(delta[1], fabs(pos[1] - warped_pos[1]));
+
+ if (a >= rect->xmax)
+ break;
+ }
+
+ for (a = rect->ymin; a <= rect->ymax + coord_delta; a += coord_delta) {
+ if (a > rect->ymax)
+ a = rect->ymax;
+
+ /* left edge */
+ pos[0] = rect->xmin;
+ pos[1] = a;
+
+ BKE_tracking_undistort_v2(tracking, pos, warped_pos);
+
+ delta[0] = max_ff(delta[0], fabs(pos[0] - warped_pos[0]));
+ delta[1] = max_ff(delta[1], fabs(pos[1] - warped_pos[1]));
+
+ /* right edge */
+ pos[0] = rect->xmax;
+ pos[1] = a;
+
+ BKE_tracking_undistort_v2(tracking, pos, warped_pos);
+
+ delta[0] = max_ff(delta[0], fabs(pos[0] - warped_pos[0]));
+ delta[1] = max_ff(delta[1], fabs(pos[1] - warped_pos[1]));
+
+ if (a >= rect->ymax)
+ break;
+ }
+}
+
/*********************** Image sampling *************************/
static void disable_imbuf_channels(ImBuf *ibuf, MovieTrackingTrack *track, int grayscale)
@@ -3723,6 +3786,88 @@ static void tracking_dopesheet_sort(MovieTracking *tracking, int sort_method, in
}
}
+static int coverage_from_count(int count)
+{
+ if (count < 8)
+ return TRACKING_COVERAGE_BAD;
+ else if (count < 16)
+ return TRACKING_COVERAGE_ACCEPTABLE;
+ return TRACKING_COVERAGE_OK;
+}
+
+static void tracking_dopesheet_calc_coverage(MovieTracking *tracking)
+{
+ MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
+ MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
+ ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
+ MovieTrackingTrack *track;
+ int frames, start_frame = INT_MAX, end_frame = -INT_MAX;
+ int *per_frame_counter;
+ int prev_coverage, last_segment_frame;
+ int i;
+
+ /* find frame boundaries */
+ for (track = tracksbase->first; track; track = track->next) {
+ start_frame = min_ii(start_frame, track->markers[0].framenr);
+ end_frame = max_ii(end_frame, track->markers[track->markersnr - 1].framenr);
+ }
+
+ frames = end_frame - start_frame + 1;
+
+ /* this is a per-frame counter of markers (how many markers belongs to the same frame) */
+ per_frame_counter = MEM_callocN(sizeof(int) * frames, "per frame track counter");
+
+ /* find per-frame markers count */
+ for (track = tracksbase->first; track; track = track->next) {
+ int i;
+
+ for (i = 0; i < track->markersnr; i++) {
+ MovieTrackingMarker *marker = &track->markers[i];
+
+ /* TODO: perhaps we need to add check for non-single-frame track here */
+ if ((marker->flag & MARKER_DISABLED) == 0)
+ per_frame_counter[marker->framenr - start_frame]++;
+ }
+ }
+
+ /* convert markers count to coverage and detect segments with the same coverage */
+ prev_coverage = coverage_from_count(per_frame_counter[0]);
+ last_segment_frame = start_frame;
+
+ /* means only disabled tracks in the beginning, could be ignored */
+ if (!per_frame_counter[0])
+ prev_coverage = TRACKING_COVERAGE_OK;
+
+ for (i = 1; i < frames; i++) {
+ int coverage = coverage_from_count(per_frame_counter[i]);
+
+ /* means only disabled tracks in the end, could be ignored */
+ if (i == frames - 1 && !per_frame_counter[i])
+ coverage = TRACKING_COVERAGE_OK;
+
+ if (coverage != prev_coverage || i == frames - 1) {
+ MovieTrackingDopesheetCoverageSegment *coverage_segment;
+ int end_segment_frame = i - 1 + start_frame;
+
+ if (end_segment_frame == last_segment_frame)
+ end_segment_frame++;
+
+ coverage_segment = MEM_callocN(sizeof(MovieTrackingDopesheetCoverageSegment), "tracking coverage segment");
+ coverage_segment->coverage = prev_coverage;
+ coverage_segment->start_frame = last_segment_frame;
+ coverage_segment->end_frame = end_segment_frame;
+
+ BLI_addtail(&dopesheet->coverage_segments, coverage_segment);
+
+ last_segment_frame = end_segment_frame;
+ }
+
+ prev_coverage = coverage;
+ }
+
+ MEM_freeN(per_frame_counter);
+}
+
void BKE_tracking_dopesheet_tag_update(MovieTracking *tracking)
{
MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
@@ -3750,6 +3895,7 @@ void BKE_tracking_dopesheet_update(MovieTracking *tracking)
reconstruction = BKE_tracking_object_get_reconstruction(tracking, object);
+ /* channels */
for (track = tracksbase->first; track; track = track->next) {
MovieTrackingDopesheetChannel *channel;
@@ -3777,5 +3923,8 @@ void BKE_tracking_dopesheet_update(MovieTracking *tracking)
tracking_dopesheet_sort(tracking, sort_method, inverse);
+ /* frame coverage */
+ tracking_dopesheet_calc_coverage(tracking);
+
dopesheet->ok = TRUE;
}