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>2010-10-03 15:33:32 +0400
committerTamito Kajiyama <rd6t-kjym@asahi-net.or.jp>2010-10-03 15:33:32 +0400
commit854ef1770075c6e1579ccbbd30eda57484527760 (patch)
tree78b799cb79a1f1c40e176ff1f51efe82d61c4896 /source/blender/blenkernel
parentdf528a92097d42e5f5d18ecb9f2981d75546b4d5 (diff)
parent05884e09beed97669fbec4d35b4e9427bfe997d3 (diff)
Merged changes in the trunk up to revision 32271.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_context.h2
-rw-r--r--source/blender/blenkernel/BKE_curve.h3
-rw-r--r--source/blender/blenkernel/BKE_image.h2
-rw-r--r--source/blender/blenkernel/BKE_modifier.h11
-rw-r--r--source/blender/blenkernel/BKE_utildefines.h7
-rw-r--r--source/blender/blenkernel/CMakeLists.txt4
-rw-r--r--source/blender/blenkernel/SConscript3
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c35
-rw-r--r--source/blender/blenkernel/intern/constraint.c3
-rw-r--r--source/blender/blenkernel/intern/context.c11
-rw-r--r--source/blender/blenkernel/intern/curve.c37
-rw-r--r--source/blender/blenkernel/intern/customdata.c29
-rw-r--r--source/blender/blenkernel/intern/image.c17
-rw-r--r--source/blender/blenkernel/intern/node.c80
-rw-r--r--source/blender/blenkernel/intern/object.c10
-rw-r--r--source/blender/blenkernel/intern/particle.c2
-rw-r--r--source/blender/blenkernel/intern/pointcache.c116
-rw-r--r--source/blender/blenkernel/intern/seqeffects.c42
-rw-r--r--source/blender/blenkernel/intern/smoke.c56
-rw-r--r--source/blender/blenkernel/intern/sound.c4
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c108
21 files changed, 457 insertions, 125 deletions
diff --git a/source/blender/blenkernel/BKE_context.h b/source/blender/blenkernel/BKE_context.h
index f6d41190c5a..9f38c5833a2 100644
--- a/source/blender/blenkernel/BKE_context.h
+++ b/source/blender/blenkernel/BKE_context.h
@@ -163,6 +163,8 @@ void CTX_wm_screen_set(bContext *C, struct bScreen *screen); /* to be removed */
void CTX_wm_area_set(bContext *C, struct ScrArea *sa);
void CTX_wm_region_set(bContext *C, struct ARegion *region);
void CTX_wm_menu_set(bContext *C, struct ARegion *menu);
+const char *CTX_wm_operator_poll_msg_get(struct bContext *C);
+void CTX_wm_operator_poll_msg_set(struct bContext *C, const char *msg);
/* Data Context
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h
index db6d995aa74..39de5517170 100644
--- a/source/blender/blenkernel/BKE_curve.h
+++ b/source/blender/blenkernel/BKE_curve.h
@@ -69,7 +69,8 @@ void duplicateNurblist( struct ListBase *lb1, struct ListBase *lb2);
void test2DNurb( struct Nurb *nu);
void minmaxNurb( struct Nurb *nu, float *min, float *max);
-void makeknots( struct Nurb *nu, short uv);
+void nurbs_knot_calc_u(struct Nurb *nu);
+void nurbs_knot_calc_v(struct Nurb *nu);
void makeNurbfaces(struct Nurb *nu, float *coord_array, int rowstride);
void makeNurbcurve(struct Nurb *nu, float *coord_array, float *tilt_array, float *radius_array, float *weight_array, int resolu, int stride);
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index e246b51af09..0a07e6d482c 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -115,7 +115,7 @@ void BKE_image_release_ibuf(struct Image *ima, void *lock);
struct Image *BKE_add_image_file(const char *name, int frame);
/* adds image, adds ibuf, generates color or pattern */
-struct Image *BKE_add_image_size(int width, int height, char *name, int depth, int floatbuf, short uvtestgrid, float color[4]);
+struct Image *BKE_add_image_size(unsigned int width, unsigned int height, char *name, int depth, int floatbuf, short uvtestgrid, float color[4]);
/* adds image from imbuf, owns imbuf */
struct Image *BKE_add_image_imbuf(struct ImBuf *ibuf);
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index 95a9394427f..51120a61e69 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -245,6 +245,17 @@ typedef struct ModifierTypeInfo {
*/
int (*dependsOnTime)(struct ModifierData *md);
+
+ /* True when a deform modifier uses normals, the requiredDataMask
+ * cant be used here because that refers to a normal layer where as
+ * in this case we need to know if the deform modifier uses normals.
+ *
+ * this is needed because applying 2 deform modifiers will give the
+ * second modifier bogus normals.
+ * */
+ int (*dependsOnNormals)(struct ModifierData *md);
+
+
/* Should call the given walk function on with a pointer to each Object
* pointer that the modifier data stores. This is used for linking on file
* load and for unlinking objects or forwarding object references.
diff --git a/source/blender/blenkernel/BKE_utildefines.h b/source/blender/blenkernel/BKE_utildefines.h
index 925b1d7171a..5a6a151afee 100644
--- a/source/blender/blenkernel/BKE_utildefines.h
+++ b/source/blender/blenkernel/BKE_utildefines.h
@@ -38,8 +38,11 @@
#define TRUE 1
#endif
-/* Macro to convert a value to string in the preprocessor */
-#define QUOTE(x) #x
+/* Macro to convert a value to string in the preprocessor
+ * STRINGIFY_ARG: gives the defined name in the string
+ * STRINGIFY: gives the defined value. */
+#define STRINGIFY_ARG(x) #x
+#define STRINGIFY(x) STRINGIFY_ARG(x)
/* these values need to be hardcoded in structs, dna does not recognize defines */
/* also defined in DNA_space_types.h */
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index b4eb1d073a6..c8645f91de8 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -116,6 +116,10 @@ IF(NOT WITH_FLUID)
ADD_DEFINITIONS(-DDISABLE_ELBEEM)
ENDIF(NOT WITH_FLUID)
+IF(WITH_JACK)
+ ADD_DEFINITIONS(-DWITH_JACK)
+ENDIF(WITH_JACK)
+
IF(WITH_LZO)
LIST(APPEND INC ../../../extern/lzo/minilzo)
ADD_DEFINITIONS(-DWITH_LZO)
diff --git a/source/blender/blenkernel/SConscript b/source/blender/blenkernel/SConscript
index 5069fddefd6..0345ef26c9a 100644
--- a/source/blender/blenkernel/SConscript
+++ b/source/blender/blenkernel/SConscript
@@ -53,6 +53,9 @@ if env['WITH_BF_CINEON']:
if env['WITH_BF_HDR']:
defs.append('WITH_HDR')
+if env['WITH_BF_JACK']:
+ defs.append('WITH_JACK')
+
if env['WITH_BF_FFMPEG']:
defs.append('WITH_FFMPEG')
incs += ' ' + env['BF_FFMPEG_INC']
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index de7b962e38a..01b02653a51 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -239,6 +239,15 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me)
if(!CustomData_has_layer(&tmp.fdata, CD_MFACE))
CustomData_add_layer(&tmp.fdata, CD_MFACE, CD_ASSIGN, dm->dupFaceArray(dm), totface);
+ /* object had got displacement layer, should copy this layer to save sculpted data */
+ /* NOTE: maybe some other layers should be copied? nazgul */
+ if(CustomData_has_layer(&me->fdata, CD_MDISPS)) {
+ if (totface == me->totface) {
+ MDisps *mdisps = CustomData_get_layer(&me->fdata, CD_MDISPS);
+ CustomData_add_layer(&tmp.fdata, CD_MDISPS, CD_DUPLICATE, mdisps, totface);
+ }
+ }
+
mesh_update_customdata_pointers(&tmp);
CustomData_free(&me->vdata, me->totvert);
@@ -1661,8 +1670,20 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
DerivedMesh *dm, *orcodm, *clothorcodm, *finaldm;
int numVerts = me->totvert;
int required_mode;
+ int isPrevDeform= FALSE;
+ int skipVirtualArmature = (useDeform < 0);
+
+ if(!skipVirtualArmature) {
+ firstmd = modifiers_getVirtualModifierList(ob);
+ }
+ else {
+ /* game engine exception */
+ firstmd = ob->modifiers.first;
+ if(firstmd && firstmd->type == eModifierType_Armature)
+ firstmd = firstmd->next;
+ }
- md = firstmd = (useDeform<0) ? ob->modifiers.first : modifiers_getVirtualModifierList(ob);
+ md = firstmd;
modifiers_clearErrors(ob);
@@ -1778,6 +1799,16 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
}
}
+ /* if this is not the last modifier in the stack then recalculate the normals
+ * to avoid giving bogus normals to the next modifier see: [#23673] */
+ if(isPrevDeform && mti->dependsOnNormals && mti->dependsOnNormals(md)) {
+ /* XXX, this covers bug #23673, but we may need normal calc for other types */
+ if(dm->type == DM_TYPE_CDDM) {
+ CDDM_apply_vert_coords(dm, deformedVerts);
+ CDDM_calc_normals(dm);
+ }
+ }
+
mti->deformVerts(md, ob, dm, deformedVerts, numVerts, useRenderParams, useDeform);
} else {
DerivedMesh *ndm;
@@ -1888,6 +1919,8 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
}
}
+ isPrevDeform= (mti->type == eModifierTypeType_OnlyDeform);
+
/* grab modifiers until index i */
if((index >= 0) && (modifiers_indexInObject(ob, md) >= index))
break;
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 59e81293c9f..fe69f13bbda 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -4358,8 +4358,7 @@ void get_constraint_target_matrix (struct Scene *scene, bConstraint *con, int n,
void solve_constraints (ListBase *conlist, bConstraintOb *cob, float ctime)
{
bConstraint *con;
- float solution[4][4], delta[4][4];
- float oldmat[4][4], imat[4][4];
+ float oldmat[4][4];
float enf;
/* check that there is a valid constraint object to evaluate */
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index 7928424e47c..a5d96baf049 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -64,6 +64,7 @@ struct bContext {
struct ARegion *region;
struct ARegion *menu;
struct bContextStore *store;
+ const char *operator_poll_msg; /* reason for poll failing */
} wm;
/* data context */
@@ -399,6 +400,16 @@ void CTX_wm_menu_set(bContext *C, ARegion *menu)
C->wm.menu= menu;
}
+void CTX_wm_operator_poll_msg_set(bContext *C, const char *msg)
+{
+ C->wm.operator_poll_msg= msg;
+}
+
+const char *CTX_wm_operator_poll_msg_get(bContext *C)
+{
+ return C->wm.operator_poll_msg;
+}
+
/* data context utility functions */
struct bContextDataResult {
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 358dd1914e7..9578b5185af 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -74,12 +74,22 @@ void unlink_curve(Curve *cu)
for(a=0; a<cu->totcol; a++) {
if(cu->mat[a]) cu->mat[a]->id.us--;
- cu->mat[a]= 0;
+ cu->mat[a]= NULL;
}
if(cu->vfont) cu->vfont->id.us--;
- cu->vfont= 0;
+ cu->vfont= NULL;
+
+ if(cu->vfontb) cu->vfontb->id.us--;
+ cu->vfontb= NULL;
+
+ if(cu->vfonti) cu->vfonti->id.us--;
+ cu->vfonti= NULL;
+
+ if(cu->vfontbi) cu->vfontbi->id.us--;
+ cu->vfontbi= NULL;
+
if(cu->key) cu->key->id.us--;
- cu->key= 0;
+ cu->key= NULL;
}
/* frees editcurve entirely */
@@ -210,9 +220,12 @@ void make_local_curve(Curve *cu)
*/
if(cu->id.lib==0) return;
-
- if(cu->vfont) cu->vfont->id.lib= 0;
-
+
+ if(cu->vfont) cu->vfont->id.lib= NULL;
+ if(cu->vfontb) cu->vfontb->id.lib= NULL;
+ if(cu->vfonti) cu->vfonti->id.lib= NULL;
+ if(cu->vfontbi) cu->vfontbi->id.lib= NULL;
+
if(cu->id.us==1) {
cu->id.lib= 0;
cu->id.flag= LIB_LOCAL;
@@ -623,7 +636,7 @@ static void makecyclicknots(float *knots, short pnts, short order)
-void makeknots(Nurb *nu, short uv)
+static void makeknots(Nurb *nu, short uv)
{
if(nu->type == CU_NURBS) {
if(uv == 1) {
@@ -655,6 +668,16 @@ void makeknots(Nurb *nu, short uv)
}
}
+void nurbs_knot_calc_u(Nurb *nu)
+{
+ makeknots(nu, 1);
+}
+
+void nurbs_knot_calc_v(Nurb *nu)
+{
+ makeknots(nu, 2);
+}
+
static void basisNurb(float t, short order, short pnts, float *knots, float *basis, int *start, int *end)
{
float d, e;
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 1f4b0f303f7..1f867a615b2 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -42,6 +42,7 @@
#include "BLI_blenlib.h"
#include "BLI_linklist.h"
+#include "BLI_math.h"
#include "BLI_mempool.h"
#include "BKE_customdata.h"
@@ -452,22 +453,27 @@ static void layerSwap_mdisps(void *data, const int *ci)
int corners, cornersize, S;
/* this function is untested .. */
- corners = mdisp_corners(s);
- cornersize = s->totdisp/corners;
+ if(s->disps) {
+ corners = mdisp_corners(s);
+ cornersize = s->totdisp/corners;
- d = MEM_callocN(sizeof(float) * 3 * s->totdisp, "mdisps swap");
+ d = MEM_callocN(sizeof(float) * 3 * s->totdisp, "mdisps swap");
- for(S = 0; S < corners; S++)
- memcpy(d + cornersize*S, s->disps + cornersize*ci[S], cornersize*3*sizeof(float));
-
- if(s->disps)
- MEM_freeN(s->disps);
- s->disps = d;
+ for(S = 0; S < corners; S++)
+ memcpy(d + cornersize*S, s->disps + cornersize*ci[S], cornersize*3*sizeof(float));
+
+ if(s->disps)
+ MEM_freeN(s->disps);
+ s->disps = d;
+ }
}
static void layerInterp_mdisps(void **sources, float *weights, float *sub_weights,
int count, void *dest)
{
+ MDisps *d = dest;
+ int i;
+
// XXX
#if 0
MDisps *d = dest;
@@ -514,6 +520,11 @@ static void layerInterp_mdisps(void **sources, float *weights, float *sub_weight
copy_v3_v3(d->disps[y * st + x], srcdisp);
}
}
+#else
+ if(d->disps) {
+ for(i = 0; i < d->totdisp; ++i)
+ zero_v3(d->disps[i]);
+ }
#endif
}
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 344f8500075..cb2261932ce 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -382,7 +382,7 @@ Image *BKE_add_image_file(const char *name, int frame)
return ima;
}
-static ImBuf *add_ibuf_size(int width, int height, char *name, int depth, int floatbuf, short uvtestgrid, float color[4])
+static ImBuf *add_ibuf_size(unsigned int width, unsigned int height, char *name, int depth, int floatbuf, short uvtestgrid, float color[4])
{
ImBuf *ibuf;
unsigned char *rect= NULL;
@@ -415,7 +415,7 @@ static ImBuf *add_ibuf_size(int width, int height, char *name, int depth, int fl
}
/* adds new image block, creates ImBuf and initializes color */
-Image *BKE_add_image_size(int width, int height, char *name, int depth, int floatbuf, short uvtestgrid, float color[4])
+Image *BKE_add_image_size(unsigned int width, unsigned int height, char *name, int depth, int floatbuf, short uvtestgrid, 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);
@@ -2139,10 +2139,15 @@ ImBuf *BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
BLI_lock_thread(LOCK_VIEWER);
*lock_r= ima;
- /* Composite Viewer, all handled in compositor */
- /* fake ibuf, will be filled in compositor */
- ibuf= IMB_allocImBuf(256, 256, 32, IB_rect, 0);
- image_assign_ibuf(ima, ibuf, 0, frame);
+ frame= iuser?iuser->framenr:0;
+ ibuf= image_get_ibuf(ima, 0, frame);
+
+ if(!ibuf) {
+ /* Composite Viewer, all handled in compositor */
+ /* fake ibuf, will be filled in compositor */
+ ibuf= IMB_allocImBuf(256, 256, 32, IB_rect, 0);
+ image_assign_ibuf(ima, ibuf, 0, frame);
+ }
}
}
}
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 135ddbab2b7..cb98c2282bc 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -1690,6 +1690,45 @@ static int node_recurs_check(bNode *node, bNode ***nsort, int level)
return 0xFFF;
}
+
+static void ntreeSetOutput(bNodeTree *ntree)
+{
+ bNode *node;
+
+ /* find the active outputs, might become tree type dependant handler */
+ for(node= ntree->nodes.first; node; node= node->next) {
+ if(node->typeinfo->nclass==NODE_CLASS_OUTPUT) {
+ bNode *tnode;
+ int output= 0;
+
+ /* we need a check for which output node should be tagged like this, below an exception */
+ if(node->type==CMP_NODE_OUTPUT_FILE)
+ continue;
+
+ /* there is more types having output class, each one is checked */
+ for(tnode= ntree->nodes.first; tnode; tnode= tnode->next) {
+ if(tnode->typeinfo->nclass==NODE_CLASS_OUTPUT) {
+ /* same type, exception for viewer */
+ if(tnode->type==node->type ||
+ (ELEM(tnode->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER) &&
+ ELEM(node->type, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))) {
+ if(tnode->flag & NODE_DO_OUTPUT) {
+ output++;
+ if(output>1)
+ tnode->flag &= ~NODE_DO_OUTPUT;
+ }
+ }
+ }
+ }
+ if(output==0)
+ node->flag |= NODE_DO_OUTPUT;
+ }
+ }
+
+ /* here we could recursively set which nodes have to be done,
+ might be different for editor or for "real" use... */
+}
+
void ntreeSolveOrder(bNodeTree *ntree)
{
bNode *node, **nodesort, **nsort;
@@ -1738,38 +1777,11 @@ void ntreeSolveOrder(bNodeTree *ntree)
}
MEM_freeN(nodesort);
-
- /* find the active outputs, might become tree type dependant handler */
- for(node= ntree->nodes.first; node; node= node->next) {
- if(node->typeinfo->nclass==NODE_CLASS_OUTPUT) {
- bNode *tnode;
- int output= 0;
-
- /* we need a check for which output node should be tagged like this, below an exception */
- if(node->type==CMP_NODE_OUTPUT_FILE)
- continue;
-
- /* there is more types having output class, each one is checked */
- for(tnode= ntree->nodes.first; tnode; tnode= tnode->next) {
- if(tnode->typeinfo->nclass==NODE_CLASS_OUTPUT) {
- if(tnode->type==node->type) {
- if(tnode->flag & NODE_DO_OUTPUT) {
- output++;
- if(output>1)
- tnode->flag &= ~NODE_DO_OUTPUT;
- }
- }
- }
- }
- if(output==0)
- node->flag |= NODE_DO_OUTPUT;
- }
- }
-
- /* here we could recursively set which nodes have to be done,
- might be different for editor or for "real" use... */
+
+ ntreeSetOutput(ntree);
}
+
/* Should be callback! */
/* Do not call execs here */
void NodeTagChanged(bNodeTree *ntree, bNode *node)
@@ -2466,6 +2478,9 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
/* fixed seed, for example noise texture */
BLI_srandom(rd->cfra);
+ /* ensures only a single output node is enabled */
+ ntreeSetOutput(ntree);
+
/* sets need_exec tags in nodes */
curnode = totnode= setExecutableNodes(ntree, &thdata);
@@ -2564,7 +2579,10 @@ bNodeTree *ntreeLocalize(bNodeTree *ntree)
}
/* end animdata uglyness */
-
+
+ /* ensures only a single output node is enabled */
+ ntreeSetOutput(ntree);
+
/* move over the compbufs */
/* right after ntreeCopyTree() oldsock pointers are valid */
for(node= ntree->nodes.first; node; node= node->next) {
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index f45c0717b26..d9ee67920eb 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -532,12 +532,10 @@ void unlink_object(Scene *scene, Object *ob)
}
/* textures */
- tex= bmain->tex.first;
- while(tex) {
- if(tex->env) {
- if(tex->env->object == ob) tex->env->object= NULL;
- }
- tex= tex->id.next;
+ for(tex= bmain->tex.first; tex; tex= tex->id.next) {
+ if(tex->env && (ob==tex->env->object)) tex->env->object= NULL;
+ if(tex->pd && (ob==tex->pd->object)) tex->pd->object= NULL;
+ if(tex->vd && (ob==tex->vd->object)) tex->vd->object= NULL;
}
/* worlds */
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 6b75f5d417c..723ff7faed3 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -272,7 +272,7 @@ int psys_check_enabled(Object *ob, ParticleSystem *psys)
}
psmd= psys_get_modifier(ob, psys);
- if(psys->renderdata) {
+ if(psys->renderdata || G.rendering) {
if(!(psmd->modifier.mode & eModifierMode_Render))
return 0;
}
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 741580048cf..784f6e40706 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -1008,11 +1008,22 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob, Scene *scene, int dup
}
for(psys=ob->particlesystem.first; psys; psys=psys->next) {
- if(psys->part) {
- pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID");
- BKE_ptcache_id_from_particles(pid, ob, psys);
- BLI_addtail(lb, pid);
- }
+ if(psys->part==NULL)
+ continue;
+
+ /* check to make sure point cache is actually used by the particles */
+ if(ELEM(psys->part->phystype, PART_PHYS_NO, PART_PHYS_KEYED))
+ continue;
+
+ if(psys->part->type == PART_HAIR && (psys->flag & PSYS_HAIR_DYNAMICS)==0)
+ continue;
+
+ if(psys->part->type == PART_FLUID)
+ continue;
+
+ pid= MEM_callocN(sizeof(PTCacheID), "PTCacheID");
+ BKE_ptcache_id_from_particles(pid, ob, psys);
+ BLI_addtail(lb, pid);
}
for(md=ob->modifiers.first; md; md=md->next) {
@@ -1876,6 +1887,9 @@ int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
else
cache->flag |= PTCACHE_FRAMES_SKIPPED;
}
+
+ if(cache->cached_frames)
+ cache->cached_frames[cfra] = 1;
if(pf) ptcache_file_close(pf);
@@ -1893,6 +1907,9 @@ int BKE_ptcache_write_cache(PTCacheID *pid, int cfra)
void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
{
int len; /* store the length of the string */
+ int i;
+ int sta = pid->cache->startframe;
+ int end = pid->cache->endframe;
/* mode is same as fopen's modes */
DIR *dir;
@@ -1936,6 +1953,8 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
pid->cache->last_exact = MIN2(pid->cache->startframe, 0);
BLI_join_dirfile(path_full, path, de->d_name);
BLI_delete(path_full, 0, 0);
+ if(pid->cache->cached_frames) for(i=0; i<end-sta+1; i++)
+ pid->cache->cached_frames[i] = 0;
} else {
/* read the number of the file */
int frame, len2 = (int)strlen(de->d_name);
@@ -1950,6 +1969,8 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
BLI_join_dirfile(path_full, path, de->d_name);
BLI_delete(path_full, 0, 0);
+ if(frame >=sta && frame <= end)
+ pid->cache->cached_frames[frame-sta] = 0;
}
}
}
@@ -1970,11 +1991,16 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
for(; pm; pm=pm->next)
ptcache_free_data(pm);
BLI_freelistN(&pid->cache->mem_cache);
+
+ if(pid->cache->cached_frames) for(i=0; i<end-sta+1; i++)
+ pid->cache->cached_frames[i] = 0;
} else {
while(pm) {
if((mode==PTCACHE_CLEAR_BEFORE && pm->frame < cfra) ||
(mode==PTCACHE_CLEAR_AFTER && pm->frame > cfra) ) {
link = pm;
+ if(pm->frame >=sta && pm->frame <= end)
+ pid->cache->cached_frames[pm->frame-sta] = 0;
ptcache_free_data(pm);
pm = pm->next;
BLI_freelinkN(&pid->cache->mem_cache, link);
@@ -2004,6 +2030,8 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, int cfra)
}
}
}
+ if(pid->cache->cached_frames && cfra>=sta && cfra<=end)
+ pid->cache->cached_frames[cfra-sta] = 0;
break;
}
@@ -2014,6 +2042,12 @@ int BKE_ptcache_id_exist(PTCacheID *pid, int cfra)
{
if(!pid->cache)
return 0;
+
+ if(cfra<pid->cache->startframe || cfra > pid->cache->endframe)
+ return 0;
+
+ if(pid->cache->cached_frames && pid->cache->cached_frames[cfra-pid->cache->startframe]==0)
+ return 0;
if(pid->cache->flag & PTCACHE_DISK_CACHE) {
char filename[MAX_PTCACHE_FILE];
@@ -2073,6 +2107,71 @@ void BKE_ptcache_id_time(PTCacheID *pid, Scene *scene, float cfra, int *startfra
*endframe += (int)(offset+0.5f);
}
}
+
+ /* verify cached_frames array is up to date */
+ if(cache->cached_frames) {
+ if(MEM_allocN_len(cache->cached_frames) != sizeof(char) * (cache->endframe-cache->startframe+1)) {
+ MEM_freeN(cache->cached_frames);
+ cache->cached_frames = NULL;
+ }
+ }
+
+ if(cache->cached_frames==NULL && cache->endframe > cache->startframe) {
+ int sta=cache->startframe;
+ int end=cache->endframe;
+
+ cache->cached_frames = MEM_callocN(sizeof(char) * (cache->endframe-cache->startframe+1), "cached frames array");
+
+ if(pid->cache->flag & PTCACHE_DISK_CACHE) {
+ /* mode is same as fopen's modes */
+ DIR *dir;
+ struct dirent *de;
+ char path[MAX_PTCACHE_PATH];
+ char filename[MAX_PTCACHE_FILE];
+ char ext[MAX_PTCACHE_PATH];
+ int len; /* store the length of the string */
+
+ ptcache_path(pid, path);
+
+ len = BKE_ptcache_id_filename(pid, filename, (int)cfra, 0, 0); /* no path */
+
+ dir = opendir(path);
+ if (dir==NULL)
+ return;
+
+ snprintf(ext, sizeof(ext), "_%02d"PTCACHE_EXT, pid->stack_index);
+
+ while ((de = readdir(dir)) != NULL) {
+ if (strstr(de->d_name, ext)) { /* do we have the right extension?*/
+ if (strncmp(filename, de->d_name, len ) == 0) { /* do we have the right prefix */
+ /* read the number of the file */
+ int frame, len2 = (int)strlen(de->d_name);
+ char num[7];
+
+ if (len2 > 15) { /* could crash if trying to copy a string out of this range*/
+ BLI_strncpy(num, de->d_name + (strlen(de->d_name) - 15), sizeof(num));
+ frame = atoi(num);
+
+ if(frame >= sta && frame <= end)
+ cache->cached_frames[frame-sta] = 1;
+ }
+ }
+ }
+ }
+ closedir(dir);
+ }
+ else {
+ PTCacheMem *pm= pid->cache->mem_cache.first;
+
+ pm= pid->cache->mem_cache.first;
+
+ while(pm) {
+ if(pm->frame >= sta && pm->frame <= end)
+ cache->cached_frames[pm->frame-sta] = 1;
+ pm = pm->next;
+ }
+ }
+ }
}
int BKE_ptcache_id_reset(Scene *scene, PTCacheID *pid, int mode)
@@ -2293,6 +2392,8 @@ void BKE_ptcache_free(PointCache *cache)
BKE_ptcache_free_mem(&cache->mem_cache);
if(cache->edit && cache->free_edit)
cache->free_edit(cache->edit);
+ if(cache->cached_frames)
+ MEM_freeN(cache->cached_frames);
MEM_freeN(cache);
}
void BKE_ptcache_free_list(ListBase *ptcaches)
@@ -2840,7 +2941,10 @@ void BKE_ptcache_update_info(PTCacheID *pid)
totframes++;
}
- if(totframes && cache->totpoint)
+ /* smoke doesn't use frame 0 as info frame so can't check based on totpoint */
+ if(pid->type == PTCACHE_TYPE_SMOKE_DOMAIN && totframes)
+ sprintf(cache->info, "%i frames found!", totframes);
+ else if(totframes && cache->totpoint)
sprintf(cache->info, "%i points found!", cache->totpoint);
else
sprintf(cache->info, "No valid data to read!");
diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c
index 461cb075bb0..7b428661c6d 100644
--- a/source/blender/blenkernel/intern/seqeffects.c
+++ b/source/blender/blenkernel/intern/seqeffects.c
@@ -2873,7 +2873,7 @@ static void init_speed_effect(Sequence *seq)
v = (SpeedControlVars *)seq->effectdata;
v->globalSpeed = 1.0;
v->frameMap = 0;
- v->flags = 0;
+ v->flags |= SEQ_SPEED_INTEGRATE; /* should be default behavior */
v->length = 0;
}
@@ -2936,9 +2936,8 @@ static void store_icu_yrange_speed(struct Sequence * seq,
}
void sequence_effect_speed_rebuild_map(Scene *scene, Sequence * seq, int force)
{
- float ctime, div;
int cfra;
- float fallback_fac;
+ float fallback_fac = 1.0f;
SpeedControlVars * v = (SpeedControlVars *)seq->effectdata;
FCurve *fcu= NULL;
@@ -2955,7 +2954,7 @@ void sequence_effect_speed_rebuild_map(Scene *scene, Sequence * seq, int force)
/* XXX - new in 2.5x. should we use the animation system this way?
* The fcurve is needed because many frames need evaluating at once - campbell */
- fcu= id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "speed_fader", 0);
+ fcu= id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "speed_factor", 0);
if (!v->frameMap || v->length != seq->len) {
@@ -2966,17 +2965,12 @@ void sequence_effect_speed_rebuild_map(Scene *scene, Sequence * seq, int force)
v->frameMap = MEM_callocN(sizeof(float) * v->length,
"speedcontrol frameMap");
}
-
- fallback_fac = 1.0;
- /* if there is no fcurve, try to make retiming easy by stretching the
- strip */
- if (!fcu && seq->seq1->enddisp != seq->seq1->start && seq->seq1->len != 0) {
- fallback_fac = (float) seq->seq1->len /
- (float) (seq->seq1->enddisp - seq->seq1->start);
- }
+ /* if there is no fcurve, use value as simple multiplier */
+ if (!fcu)
+ fallback_fac = seq->speed_fader; /* same as speed_factor in rna*/
- if ((v->flags & SEQ_SPEED_INTEGRATE) != 0) {
+ if (v->flags & SEQ_SPEED_INTEGRATE) {
float cursor = 0;
float facf;
@@ -2985,10 +2979,7 @@ void sequence_effect_speed_rebuild_map(Scene *scene, Sequence * seq, int force)
for (cfra = 1; cfra < v->length; cfra++) {
if(fcu) {
- ctime = seq->startdisp + cfra;
- div = 1.0;
-
- facf = evaluate_fcurve(fcu, ctime/div);
+ facf = evaluate_fcurve(fcu, seq->startdisp + cfra);
} else {
facf = fallback_fac;
}
@@ -3010,19 +3001,16 @@ void sequence_effect_speed_rebuild_map(Scene *scene, Sequence * seq, int force)
for (cfra = 0; cfra < v->length; cfra++) {
if(fcu) {
- ctime = seq->startdisp + cfra;
- div = 1.0;
-
- facf = evaluate_fcurve(fcu, ctime / div);
- if (v->flags & SEQ_SPEED_COMPRESS_IPO_Y) {
- facf *= v->length;
- }
+ facf = evaluate_fcurve(fcu, seq->startdisp + cfra);
+ } else {
+ facf = fallback_fac;
}
-
- if (!fcu) {
- facf = (float) cfra * fallback_fac;
+
+ if (v->flags & SEQ_SPEED_COMPRESS_IPO_Y) {
+ facf *= seq->seq1->len;
}
facf *= v->globalSpeed;
+
if (facf >= seq->seq1->len) {
facf = seq->seq1->len - 1;
} else {
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index d2d8d5a6e07..965ce9801d7 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -800,20 +800,25 @@ static float calc_voxel_transp(float *result, float *input, int res[3], int *pix
static int get_lamp(Scene *scene, float *light)
{
Base *base_tmp = NULL;
- for(base_tmp = scene->base.first; base_tmp; base_tmp= base_tmp->next)
- {
- if(base_tmp->object->type == OB_LAMP)
- {
- Lamp *la = (Lamp *)base_tmp->object->data;
-
- if(la->type == LA_LOCAL)
- {
- VECCOPY(light, base_tmp->object->obmat[3]);
- return 1;
- }
- }
- }
- return 0;
+ int found_lamp = 0;
+
+ // try to find a lamp, preferably local
+ for(base_tmp = scene->base.first; base_tmp; base_tmp= base_tmp->next) {
+ if(base_tmp->object->type == OB_LAMP) {
+ Lamp *la = base_tmp->object->data;
+
+ if(la->type == LA_LOCAL) {
+ copy_v3_v3(light, base_tmp->object->obmat[3]);
+ return 1;
+ }
+ else if(!found_lamp) {
+ copy_v3_v3(light, base_tmp->object->obmat[3]);
+ found_lamp = 1;
+ }
+ }
+ }
+
+ return found_lamp;
}
static void smoke_calc_domain(Scene *scene, Object *ob, SmokeModifierData *smd)
@@ -1338,10 +1343,17 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
cache_wt = sds->point_cache[1];
BKE_ptcache_id_from_smoke_turbulence(&pid_wt, ob, smd);
- if(!smd->domain->fluid)
+ if(!smd->domain->fluid || framenr == startframe)
{
BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
+ BKE_ptcache_validate(cache, framenr);
+ cache->flag &= ~PTCACHE_REDO_NEEDED;
+
BKE_ptcache_id_reset(scene, &pid_wt, PTCACHE_RESET_OUTDATED);
+ if(cache_wt) {
+ BKE_ptcache_validate(cache_wt, framenr);
+ cache_wt->flag &= ~PTCACHE_REDO_NEEDED;
+ }
}
if(framenr < startframe)
@@ -1368,6 +1380,7 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
if(cache_result == PTCACHE_READ_EXACT)
{
BKE_ptcache_validate(cache, framenr);
+ smd->time = framenr;
if(sds->wt)
{
@@ -1388,14 +1401,21 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM
else
return;
}
-
- /* only calculate something when we advanced a frame */
- if(framenr == smd->time)
+ /* only calculate something when we advanced a single frame */
+ else if(framenr != (int)smd->time+1)
return;
tstart();
smoke_calc_domain(scene, ob, smd);
+
+ /* if on second frame, write cache for first frame */
+ /* this needs to be done for smoke too so that pointcache works properly */
+ if((int)smd->time == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0)) {
+ BKE_ptcache_write_cache(&pid, startframe);
+ if(sds->wt)
+ BKE_ptcache_write_cache(&pid_wt, startframe);
+ }
// set new time
smd->time = scene->r.cfra;
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index 26392132038..5e95b19b64f 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -433,9 +433,11 @@ void sound_seek_scene(struct bContext *C)
if(scene->audio.flag & AUDIO_SCRUB && !CTX_wm_screen(C)->animtimer)
{
- // AUD_XXX TODO: fix scrubbing, it currently doesn't stop playing
if(scene->audio.flag & AUDIO_SYNC)
+ {
+ AUD_seek(scene->sound_scene_handle, CFRA / FPS);
AUD_seekSequencer(scene->sound_scene_handle, CFRA / FPS);
+ }
else
AUD_seek(scene->sound_scene_handle, CFRA / FPS);
AUD_resume(scene->sound_scene_handle);
diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index 6cd207f628c..473c10d6ced 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -160,7 +160,7 @@ static int write_audio_frame(void)
pkt.stream_index = audio_stream->index;
pkt.flags |= PKT_FLAG_KEY;
if (av_interleaved_write_frame(outfile, &pkt) != 0) {
- // XXX error("Error writing audio packet");
+ fprintf(stderr, "Error writing audio packet!\n");
return -1;
}
return 0;
@@ -290,7 +290,9 @@ static int write_video_frame(RenderData *rd, AVFrame* frame, ReportList *reports
packet.data = video_buffer;
packet.size = outsize;
ret = av_interleaved_write_frame(outfile, &packet);
- } else ret = 0;
+ } else {
+ ret = 0;
+ }
if (ret != 0) {
success= 0;
@@ -778,6 +780,69 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
return 1;
}
+/**
+ * Writes any delayed frames in the encoder. This function is called before
+ * closing the encoder.
+ *
+ * <p>
+ * Since an encoder may use both past and future frames to predict
+ * 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,
+ * 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
+ * stream. We do this by calling avcodec_encode_video with NULL for the last
+ * parameter.
+ * </p>
+ */
+void flush_ffmpeg(void)
+{
+ int outsize = 0;
+ int ret = 0;
+
+ AVCodecContext* c = get_codec_from_stream(video_stream);
+ /* get the delayed frames */
+ while (1) {
+ AVPacket packet;
+ av_init_packet(&packet);
+
+ outsize = avcodec_encode_video(c, video_buffer, video_buffersize, NULL);
+ if (outsize < 0) {
+ fprintf(stderr, "Error encoding delayed frame %d\n", outsize);
+ break;
+ }
+ if (outsize == 0) {
+ break;
+ }
+ if (c->coded_frame->pts != AV_NOPTS_VALUE) {
+#ifdef FFMPEG_CODEC_TIME_BASE
+ packet.pts = av_rescale_q(c->coded_frame->pts,
+ c->time_base,
+ video_stream->time_base);
+#else
+ packet.pts = c->coded_frame->pts;
+#endif
+ fprintf(stderr, "Video Frame PTS: %d\n", (int)packet.pts);
+ } else {
+ fprintf(stderr, "Video Frame PTS: not set\n");
+ }
+ if (c->coded_frame->key_frame) {
+ packet.flags |= PKT_FLAG_KEY;
+ }
+ packet.stream_index = video_stream->index;
+ packet.data = video_buffer;
+ packet.size = outsize;
+ ret = av_interleaved_write_frame(outfile, &packet);
+ if (ret != 0) {
+ fprintf(stderr, "Error writing delayed frame %d\n", ret);
+ break;
+ }
+ }
+ avcodec_flush_buffers(get_codec_from_stream(video_stream));
+}
+
/* **********************************************************************
* public interface
********************************************************************** */
@@ -888,7 +953,6 @@ int append_ffmpeg(RenderData *rd, int frame, int *pixels, int rectx, int recty,
return success;
}
-
void end_ffmpeg(void)
{
int i;
@@ -905,6 +969,11 @@ void end_ffmpeg(void)
audio_mixdown_device = 0;
}
+ if (video_stream && get_codec_from_stream(video_stream)) {
+ fprintf(stderr, "Flushing delayed frames...\n");
+ flush_ffmpeg ();
+ }
+
if (outfile) {
av_write_trailer(outfile);
}
@@ -913,8 +982,8 @@ void end_ffmpeg(void)
if (video_stream && get_codec_from_stream(video_stream)) {
avcodec_close(get_codec_from_stream(video_stream));
- video_stream = 0;
printf("zero video stream %p\n", video_stream);
+ video_stream = 0;
}
@@ -1195,20 +1264,47 @@ void ffmpeg_set_preset(RenderData *rd, int preset)
rd->ffcodecdata.mux_packet_size = 2048;
rd->ffcodecdata.mux_rate = 10080000;
+ /*
+ * All options here are for x264, but must be set via ffmpeg.
+ * The names are therefore different - Search for "x264 to FFmpeg option mapping"
+ * to get a list.
+ */
+
+ /*
+ * Use CABAC coder. Using "coder:1", which should be equivalent,
+ * crashes Blender for some reason. Either way - this is no big deal.
+ */
ffmpeg_property_add_string(rd, "video", "coder:vlc");
+
+ /*
+ * The other options were taken from the libx264-default.preset
+ * included in the ffmpeg distribution.
+ */
ffmpeg_property_add_string(rd, "video", "flags:loop");
ffmpeg_property_add_string(rd, "video", "cmp:chroma");
ffmpeg_property_add_string(rd, "video", "partitions:parti4x4");
ffmpeg_property_add_string(rd, "video", "partitions:partp8x8");
ffmpeg_property_add_string(rd, "video", "partitions:partb8x8");
ffmpeg_property_add_string(rd, "video", "me:hex");
- ffmpeg_property_add_string(rd, "video", "subq:5");
+ ffmpeg_property_add_string(rd, "video", "subq:6");
ffmpeg_property_add_string(rd, "video", "me_range:16");
+ ffmpeg_property_add_string(rd, "video", "qdiff:4");
ffmpeg_property_add_string(rd, "video", "keyint_min:25");
ffmpeg_property_add_string(rd, "video", "sc_threshold:40");
ffmpeg_property_add_string(rd, "video", "i_qfactor:0.71");
ffmpeg_property_add_string(rd, "video", "b_strategy:1");
-
+ ffmpeg_property_add_string(rd, "video", "bf:3");
+ ffmpeg_property_add_string(rd, "video", "refs:2");
+ ffmpeg_property_add_string(rd, "video", "qcomp:0.6");
+ ffmpeg_property_add_string(rd, "video", "directpred:3");
+ ffmpeg_property_add_string(rd, "video", "trellis:0");
+ ffmpeg_property_add_string(rd, "video", "flags2:wpred");
+ ffmpeg_property_add_string(rd, "video", "flags2:dct8x8");
+ ffmpeg_property_add_string(rd, "video", "flags2:fastpskip");
+ ffmpeg_property_add_string(rd, "video", "wpredp:2");
+
+ // This makes x264 output lossless. Will be a separate option later.
+ //ffmpeg_property_add_string(rd, "video", "cqp:0");
break;
case FFMPEG_PRESET_THEORA: