Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c2
-rw-r--r--source/blender/blenkernel/intern/action.c4
-rw-r--r--source/blender/blenkernel/intern/armature.c9
-rw-r--r--source/blender/blenkernel/intern/blender.c2
-rw-r--r--source/blender/blenkernel/intern/brush.c2
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c49
-rw-r--r--source/blender/blenkernel/intern/collision.c10
-rw-r--r--source/blender/blenkernel/intern/colortools.c39
-rw-r--r--source/blender/blenkernel/intern/context.c10
-rw-r--r--source/blender/blenkernel/intern/curve.c2
-rw-r--r--source/blender/blenkernel/intern/customdata.c4
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c3
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c6
-rw-r--r--source/blender/blenkernel/intern/idcode.c65
-rw-r--r--source/blender/blenkernel/intern/image.c276
-rw-r--r--source/blender/blenkernel/intern/library.c4
-rw-r--r--source/blender/blenkernel/intern/mask_evaluate.c6
-rw-r--r--source/blender/blenkernel/intern/mesh.c2
-rw-r--r--source/blender/blenkernel/intern/modifier.c4
-rw-r--r--source/blender/blenkernel/intern/node.c1
-rw-r--r--source/blender/blenkernel/intern/object.c18
-rw-r--r--source/blender/blenkernel/intern/particle.c28
-rw-r--r--source/blender/blenkernel/intern/pointcache.c6
-rw-r--r--source/blender/blenkernel/intern/scene.c2
-rw-r--r--source/blender/blenkernel/intern/seqeffects.c3
-rw-r--r--source/blender/blenkernel/intern/sequencer.c14
-rw-r--r--source/blender/blenkernel/intern/suggestions.c10
-rw-r--r--source/blender/blenkernel/intern/text.c1003
-rw-r--r--source/blender/blenkernel/intern/tracking.c10
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c35
30 files changed, 673 insertions, 956 deletions
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index b329a502c42..db8fb288d87 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -2166,6 +2166,8 @@ static void mesh_build_data(Scene *scene, Object *ob, CustomDataMask dataMask,
/* weight paint and face select need original indices because of selection buffer drawing */
int needMapping = (ob == obact) && (editing || (ob->mode & (OB_MODE_WEIGHT_PAINT | OB_MODE_VERTEX_PAINT | OB_MODE_TEXTURE_PAINT)));
+ BLI_assert(ob->type == OB_MESH);
+
clear_mesh_caches(ob);
mesh_calc_modifiers(scene, ob, NULL, &ob->derivedDeform,
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index e95451252d0..dd27cc70ba3 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -512,7 +512,7 @@ const char *BKE_pose_ikparam_get_name(bPose *pose)
{
if (pose) {
switch (pose->iksolver) {
- case IKSOLVER_LEGACY:
+ case IKSOLVER_STANDARD:
return NULL;
case IKSOLVER_ITASC:
return "bItasc";
@@ -587,7 +587,7 @@ void BKE_pose_ikparam_init(bPose *pose)
BKE_pose_itasc_init(itasc);
pose->ikparam = itasc;
break;
- case IKSOLVER_LEGACY:
+ case IKSOLVER_STANDARD:
default:
pose->ikparam = NULL;
break;
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index b3cbc1f2b16..1970df54339 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -1822,8 +1822,15 @@ static void splineik_init_tree_from_pchan(Scene *scene, Object *UNUSED(ob), bPos
*/
/* only happens on reload file, but violates depsgraph still... fix! */
- if ((cu->path == NULL) || (cu->path->data == NULL))
+ if (ELEM(NULL, cu->path, cu->path->data)) {
BKE_displist_make_curveTypes(scene, ikData->tar, 0);
+
+ /* path building may fail in EditMode after removing verts [#33268]*/
+ if (ELEM(NULL, cu->path, cu->path->data)) {
+ /* BLI_assert(cu->path != NULL); */
+ return;
+ }
+ }
}
/* find the root bone and the chain of bones from the root to the tip
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index e1e868b234e..40cd5b3d403 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -70,6 +70,7 @@
#include "BKE_displist.h"
#include "BKE_global.h"
#include "BKE_idprop.h"
+#include "BKE_image.h"
#include "BKE_ipo.h"
#include "BKE_library.h"
#include "BKE_main.h"
@@ -113,6 +114,7 @@ void free_blender(void)
BKE_spacetypes_free(); /* after free main, it uses space callbacks */
IMB_exit();
+ BKE_images_exit();
BLI_callback_global_finalize();
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 98b206712d6..f310895f590 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -1287,8 +1287,6 @@ unsigned int *BKE_brush_gen_texture_cache(Brush *br, int half_side)
texcache = MEM_callocN(sizeof(int) * side * side, "Brush texture cache");
- BKE_image_get_ibuf(mtex->tex->ima, NULL);
-
/*do normalized cannonical view coords for texture*/
for (y = -1.0, iy = 0; iy < side; iy++, y += step) {
for (x = -1.0, ix = 0; ix < side; ix++, x += step) {
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index b7ad135fa72..7ac046c092f 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -2408,6 +2408,11 @@ void CDDM_calc_normals_tessface(DerivedMesh *dm)
* this is a really horribly written function. ger. - joeedh
*
* note, CDDM_recalc_tessellation has to run on the returned DM if you want to access tessfaces.
+ *
+ * Note: This function is currently only used by the Mirror modifier, so it
+ * skips any faces that have all vertices merged (to avoid creating pairs
+ * of faces sharing the same set of vertices). If used elsewhere, it may
+ * be necessary to make this functionality optional.
*/
DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap)
{
@@ -2451,14 +2456,11 @@ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap)
newv[i] = newv[vtargetmap[i]];
}
}
-
- /* find-replace merged vertices with target vertices */
- ml = cddm->mloop;
- for (i = 0; i < totloop; i++, ml++) {
- if (vtargetmap[ml->v] != -1) {
- ml->v = vtargetmap[ml->v];
- }
- }
+
+ /* Don't remap vertices in cddm->mloop, because we need to know the original
+ * indices in order to skip faces with all vertices merged.
+ * The "update loop indices..." section further down remaps vertices in mloop.
+ */
/* now go through and fix edges and faces */
med = cddm->medge;
@@ -2492,6 +2494,24 @@ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap)
ml = cddm->mloop + mp->loopstart;
+ /* skip faces with all vertices merged */
+ {
+ int all_vertices_merged = TRUE;
+
+ for (j = 0; j < mp->totloop; j++, ml++) {
+ if (vtargetmap[ml->v] == -1) {
+ all_vertices_merged = FALSE;
+ break;
+ }
+ }
+
+ if (UNLIKELY(all_vertices_merged)) {
+ continue;
+ }
+ }
+
+ ml = cddm->mloop + mp->loopstart;
+
c = 0;
for (j = 0; j < mp->totloop; j++, ml++) {
med = cddm->medge + ml->e;
@@ -2650,7 +2670,7 @@ void CDDM_calc_edges(DerivedMesh *dm)
EdgeHashIterator *ehi;
MPoly *mp = cddm->mpoly;
MLoop *ml;
- MEdge *med;
+ MEdge *med, *origmed;
EdgeHash *eh = BLI_edgehash_new();
int v1, v2;
int *eindex;
@@ -2683,6 +2703,7 @@ void CDDM_calc_edges(DerivedMesh *dm)
CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
+ origmed = cddm->medge;
med = CustomData_get_layer(&edgeData, CD_MEDGE);
index = CustomData_get_layer(&edgeData, CD_ORIGINDEX);
@@ -2693,8 +2714,14 @@ void CDDM_calc_edges(DerivedMesh *dm)
BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2);
j = GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi));
- med->flag = ME_EDGEDRAW | ME_EDGERENDER;
- *index = j == 0 ? ORIGINDEX_NONE : eindex[j - 1];
+ if (j == 0) {
+ med->flag = ME_EDGEDRAW | ME_EDGERENDER;
+ *index = ORIGINDEX_NONE;
+ }
+ else {
+ med->flag = ME_EDGEDRAW | ME_EDGERENDER | origmed[j - 1].flag;
+ *index = eindex[j - 1];
+ }
BLI_edgehashIterator_setValue(ehi, SET_INT_IN_POINTER(i));
}
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index b488e683947..4641a02265a 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -198,8 +198,10 @@ static void collision_compute_barycentric ( float pv[3], float p1[3], float p2[3
w3[0] = 1.0f - w1[0] - w2[0];
}
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wdouble-promotion"
+#ifdef __GNUC__
+# pragma GCC diagnostic push
+# pragma GCC diagnostic ignored "-Wdouble-promotion"
+#endif
DO_INLINE void collision_interpolateOnTriangle ( float to[3], float v1[3], float v2[3], float v3[3], double w1, double w2, double w3 )
{
@@ -371,7 +373,9 @@ static int cloth_collision_response_static ( ClothModifierData *clmd, CollisionM
return result;
}
-#pragma GCC diagnostic pop
+#ifdef __GNUC__
+# pragma GCC diagnostic pop
+#endif
//Determines collisions on overlap, collisions are written to collpair[i] and collision+number_collision_found is returned
static CollPair* cloth_collision(ModifierData *md1, ModifierData *md2,
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index 75276adf518..529fe07cab3 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -1008,8 +1008,8 @@ void scopes_update(Scopes *scopes, ImBuf *ibuf, const ColorManagedViewSettings *
const ColorManagedDisplaySettings *display_settings)
{
int x, y, c;
- unsigned int n, nl;
- double div, divl;
+ unsigned int nl, na, nr, ng, nb;
+ double divl, diva, divr, divg, divb;
float *rf = NULL;
unsigned char *rc = NULL;
unsigned int *bin_lum, *bin_r, *bin_g, *bin_b, *bin_a;
@@ -1149,24 +1149,37 @@ void scopes_update(Scopes *scopes, ImBuf *ibuf, const ColorManagedViewSettings *
savedlines += 1;
}
+ /* test for nicer distribution even - non standard, leave it out for a while */
+#if 0
+ for (x = 0; x < 256; x++) {
+ bin_lum[x] = sqrt (bin_lum[x]);
+ bin_r[x] = sqrt(bin_r[x]);
+ bin_g[x] = sqrt(bin_g[x]);
+ bin_b[x] = sqrt(bin_b[x]);
+ bin_a[x] = sqrt(bin_a[x]);
+ }
+#endif
+
/* convert hist data to float (proportional to max count) */
- n = 0;
- nl = 0;
+ nl = na = nr = nb = ng = 0;
for (x = 0; x < 256; x++) {
if (bin_lum[x] > nl) nl = bin_lum[x];
- if (bin_r[x] > n) n = bin_r[x];
- if (bin_g[x] > n) n = bin_g[x];
- if (bin_b[x] > n) n = bin_b[x];
- if (bin_a[x] > n) n = bin_a[x];
+ if (bin_r[x] > nr) nr = bin_r[x];
+ if (bin_g[x] > ng) ng = bin_g[x];
+ if (bin_b[x] > nb) nb = bin_b[x];
+ if (bin_a[x] > na) na = bin_a[x];
}
- div = 1.0 / (double)n;
divl = 1.0 / (double)nl;
+ diva = 1.0 / (double)na;
+ divr = 1.0 / (double)nr;
+ divg = 1.0 / (double)ng;
+ divb = 1.0 / (double)nb;
for (x = 0; x < 256; x++) {
scopes->hist.data_luma[x] = bin_lum[x] * divl;
- scopes->hist.data_r[x] = bin_r[x] * div;
- scopes->hist.data_g[x] = bin_g[x] * div;
- scopes->hist.data_b[x] = bin_b[x] * div;
- scopes->hist.data_a[x] = bin_a[x] * div;
+ scopes->hist.data_r[x] = bin_r[x] * divr;
+ scopes->hist.data_g[x] = bin_g[x] * divg;
+ scopes->hist.data_b[x] = bin_b[x] * divb;
+ scopes->hist.data_a[x] = bin_a[x] * diva;
}
MEM_freeN(bin_lum);
MEM_freeN(bin_r);
diff --git a/source/blender/blenkernel/intern/context.c b/source/blender/blenkernel/intern/context.c
index 719ae7357b4..ffb93139358 100644
--- a/source/blender/blenkernel/intern/context.c
+++ b/source/blender/blenkernel/intern/context.c
@@ -44,6 +44,7 @@
#include "BLI_listbase.h"
#include "BLI_string.h"
+#include "BLI_threads.h"
#include "BLI_utildefines.h"
#include "BKE_context.h"
@@ -245,6 +246,10 @@ static void *ctx_wm_python_context_get(const bContext *C, const char *member, vo
(void)C, (void)member;
#endif
+ /* don't allow UI context access from non-main threads */
+ if (!BLI_thread_is_main())
+ return NULL;
+
return fall_through;
}
@@ -264,6 +269,11 @@ static int ctx_data_get(bContext *C, const char *member, bContextDataResult *res
// return 1;
}
#endif
+
+ /* don't allow UI context access from non-main threads */
+ if (!BLI_thread_is_main())
+ return done;
+
/* we check recursion to ensure that we do not get infinite
* loops requesting data from ourselfs in a context callback */
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index f2cd695d64a..754a4fbc0c8 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -1116,7 +1116,7 @@ void BKE_nurb_makeCurve(Nurb *nu, float *coord_array, float *tilt_array, float *
*fp = basisu[i] * bp->vec[3];
sumdiv += *fp;
}
- if (sumdiv != 0.0f) if (sumdiv < 0.999f || sumdiv > 1.001f) {
+ if ((sumdiv != 0.0f) && (sumdiv < 0.999f || sumdiv > 1.001f)) {
/* is normalizing needed? */
fp = sum;
for (i = istart; i <= iend; i++, fp++) {
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 93c776ae30e..b2f8db0dcce 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -761,7 +761,7 @@ static void layerDoMinMax_mloopuv(void *data, void *vmin, void *vmax)
{
MLoopUV *min = vmin, *max = vmax, *luv = data;
- DO_MINMAX2(luv->uv, min->uv, max->uv);
+ minmax_v2v2_v2(min->uv, max->uv, luv->uv);
}
static void layerAdd_mloopuv(void *data1, void *data2)
@@ -833,7 +833,7 @@ static void layerDoMinMax_mloop_origspace(void *data, void *vmin, void *vmax)
{
OrigSpaceLoop *min = vmin, *max = vmax, *luv = data;
- DO_MINMAX2(luv->uv, min->uv, max->uv);
+ minmax_v2v2_v2(min->uv, max->uv, luv->uv);
}
static void layerAdd_mloop_origspace(void *data1, void *data2)
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 9d3a7ec57cf..d23a608d31f 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -671,8 +671,9 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
}
}
}
- else if(ob->type == OB_LAMP)
+ else if (ob->type == OB_LAMP) {
dag_add_lamp_driver_relations(dag, node, ob->data);
+ }
/* particles */
psys = ob->particlesystem.first;
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 89d728c0419..bb3836e3c08 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -86,11 +86,13 @@
#include "RE_shader_ext.h"
#ifdef _OPENMP
-#include <omp.h>
+# include <omp.h>
#endif
/* could enable at some point but for now there are far too many conversions */
-#pragma GCC diagnostic ignored "-Wdouble-promotion"
+#ifdef __GNUC__
+# pragma GCC diagnostic ignored "-Wdouble-promotion"
+#endif
/* precalculated gaussian factors for 5x super sampling */
static float gaussianFactors[5] = {0.996849f,
diff --git a/source/blender/blenkernel/intern/idcode.c b/source/blender/blenkernel/intern/idcode.c
index 30427a81c4b..c3008d17bd1 100644
--- a/source/blender/blenkernel/intern/idcode.c
+++ b/source/blender/blenkernel/intern/idcode.c
@@ -47,39 +47,40 @@ typedef struct {
} IDType;
/* plural need to match rna_main.c's MainCollectionDef */
+/* WARNING! Keep it in sync with i18n contexts in BLF_translation.h */
static IDType idtypes[] = {
- { ID_AC, "Action", "actions", IDTYPE_FLAGS_ISLINKABLE},
- { ID_AR, "Armature", "armatures", IDTYPE_FLAGS_ISLINKABLE},
- { ID_BR, "Brush", "brushes", IDTYPE_FLAGS_ISLINKABLE},
- { ID_CA, "Camera", "cameras", IDTYPE_FLAGS_ISLINKABLE},
- { ID_CU, "Curve", "curves", IDTYPE_FLAGS_ISLINKABLE},
- { ID_GD, "GPencil", "grease_pencil", IDTYPE_FLAGS_ISLINKABLE}, /* rename gpencil */
- { ID_GR, "Group", "groups", IDTYPE_FLAGS_ISLINKABLE},
- { ID_ID, "ID", "ids", 0}, /* plural is fake */
- { ID_IM, "Image", "images", IDTYPE_FLAGS_ISLINKABLE},
- { ID_IP, "Ipo", "ipos", IDTYPE_FLAGS_ISLINKABLE}, /* deprecated */
- { ID_KE, "Key", "shape_keys", 0},
- { ID_LA, "Lamp", "lamps", IDTYPE_FLAGS_ISLINKABLE},
- { ID_LI, "Library", "libraries", 0},
- { ID_LT, "Lattice", "lattices", IDTYPE_FLAGS_ISLINKABLE},
- { ID_MA, "Material", "materials", IDTYPE_FLAGS_ISLINKABLE},
- { ID_MB, "Metaball", "metaballs", IDTYPE_FLAGS_ISLINKABLE},
- { ID_ME, "Mesh", "meshes", IDTYPE_FLAGS_ISLINKABLE},
- { ID_NT, "NodeTree", "node_groups", IDTYPE_FLAGS_ISLINKABLE},
- { ID_OB, "Object", "objects", IDTYPE_FLAGS_ISLINKABLE},
- { ID_PA, "ParticleSettings", "particles", 0},
- { ID_SCE, "Scene", "scenes", IDTYPE_FLAGS_ISLINKABLE},
- { ID_SCR, "Screen", "screens", 0},
- { ID_SEQ, "Sequence", "sequences", 0}, /* not actually ID data */
- { ID_SPK, "Speaker", "speakers", IDTYPE_FLAGS_ISLINKABLE},
- { ID_SO, "Sound", "sounds", IDTYPE_FLAGS_ISLINKABLE},
- { ID_TE, "Texture", "textures", IDTYPE_FLAGS_ISLINKABLE},
- { ID_TXT, "Text", "texts", IDTYPE_FLAGS_ISLINKABLE},
- { ID_VF, "VFont", "fonts", IDTYPE_FLAGS_ISLINKABLE},
- { ID_WO, "World", "worlds", IDTYPE_FLAGS_ISLINKABLE},
- { ID_WM, "WindowManager", "window_managers", 0},
- { ID_MC, "MovieClip", "movieclips", IDTYPE_FLAGS_ISLINKABLE},
- { ID_MSK, "Mask", "masks", IDTYPE_FLAGS_ISLINKABLE},
+ { ID_AC, "Action", "actions", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_AR, "Armature", "armatures", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_BR, "Brush", "brushes", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_CA, "Camera", "cameras", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_CU, "Curve", "curves", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_GD, "GPencil", "grease_pencil", IDTYPE_FLAGS_ISLINKABLE }, /* rename gpencil */
+ { ID_GR, "Group", "groups", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_ID, "ID", "ids", 0 }, /* plural is fake */
+ { ID_IM, "Image", "images", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_IP, "Ipo", "ipos", IDTYPE_FLAGS_ISLINKABLE }, /* deprecated */
+ { ID_KE, "Key", "shape_keys", 0 },
+ { ID_LA, "Lamp", "lamps", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_LI, "Library", "libraries", 0 },
+ { ID_LT, "Lattice", "lattices", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_MA, "Material", "materials", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_MB, "Metaball", "metaballs", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_MC, "MovieClip", "movieclips", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_ME, "Mesh", "meshes", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_MSK, "Mask", "masks", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_NT, "NodeTree", "node_groups", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_OB, "Object", "objects", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_PA, "ParticleSettings", "particles", 0 },
+ { ID_SCE, "Scene", "scenes", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_SCR, "Screen", "screens", 0 },
+ { ID_SEQ, "Sequence", "sequences", 0 }, /* not actually ID data */
+ { ID_SPK, "Speaker", "speakers", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_SO, "Sound", "sounds", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_TE, "Texture", "textures", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_TXT, "Text", "texts", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_VF, "VFont", "fonts", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_WO, "World", "worlds", IDTYPE_FLAGS_ISLINKABLE },
+ { ID_WM, "WindowManager", "window_managers", 0 },
};
static int nidtypes = sizeof(idtypes) / sizeof(idtypes[0]);
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 55d37c91859..e4b9edacc7e 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -100,6 +100,8 @@
#include "WM_api.h"
+static SpinLock image_spin;
+
/* max int, to indicate we don't store sequences in ibuf */
#define IMA_NO_INDEX 0x7FEFEFEF
@@ -108,6 +110,16 @@
#define IMA_INDEX_FRAME(index) (index >> 10)
#define IMA_INDEX_PASS(index) (index & ~1023)
+void BKE_images_init(void)
+{
+ BLI_spin_init(&image_spin);
+}
+
+void BKE_images_exit(void)
+{
+ BLI_spin_end(&image_spin);
+}
+
/* ******** IMAGE PROCESSING ************* */
static void de_interlace_ng(struct ImBuf *ibuf) /* neogeo fields */
@@ -168,13 +180,14 @@ static void de_interlace_st(struct ImBuf *ibuf) /* standard fields */
void BKE_image_de_interlace(Image *ima, int odd)
{
- ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, NULL);
if (ibuf) {
if (odd)
de_interlace_st(ibuf);
else
de_interlace_ng(ibuf);
}
+ BKE_image_release_ibuf(ima, ibuf, NULL);
}
/* ***************** ALLOC & FREE, DATA MANAGING *************** */
@@ -260,8 +273,9 @@ static ImBuf *image_get_ibuf(Image *ima, int index, int frame)
/* this function is intended to be thread safe. with IMA_NO_INDEX this
* should be OK, but when iterating over the list this is more tricky
* */
- if (index == IMA_NO_INDEX)
+ if (index == IMA_NO_INDEX) {
return ima->ibufs.first;
+ }
else {
ImBuf *ibuf;
@@ -269,9 +283,9 @@ static ImBuf *image_get_ibuf(Image *ima, int index, int frame)
for (ibuf = ima->ibufs.first; ibuf; ibuf = ibuf->next)
if (ibuf->index == index)
return ibuf;
-
- return NULL;
}
+
+ return NULL;
}
/* no ima->ibuf anymore, but listbase */
@@ -534,7 +548,7 @@ int BKE_image_scale(Image *image, int width, int height)
ibuf->userflags |= IB_BITMAPDIRTY;
}
- BKE_image_release_ibuf(image, lock);
+ BKE_image_release_ibuf(image, ibuf, lock);
return (ibuf != NULL);
}
@@ -2081,6 +2095,8 @@ void BKE_image_signal(Image *ima, ImageUser *iuser, int signal)
if (ima == NULL)
return;
+ BLI_spin_lock(&image_spin);
+
switch (signal) {
case IMA_SIGNAL_FREE:
image_free_buffers(ima);
@@ -2157,6 +2173,8 @@ void BKE_image_signal(Image *ima, ImageUser *iuser, int signal)
break;
}
+ BLI_spin_unlock(&image_spin);
+
/* don't use notifiers because they are not 100% sure to succeeded
* this also makes sure all scenes are accounted for. */
{
@@ -2320,7 +2338,7 @@ static ImBuf *image_load_sequence_file(Image *ima, ImageUser *iuser, int frame)
if (ibuf) {
#ifdef WITH_OPENEXR
- /* handle multilayer case, don't assign ibuf. will be handled in BKE_image_get_ibuf */
+ /* handle multilayer case, don't assign ibuf. will be handled in BKE_image_acquire_ibuf */
if (ibuf->ftype == OPENEXR && ibuf->userdata) {
image_create_multilayer(ima, ibuf, frame);
ima->type = IMA_TYPE_MULTILAYER;
@@ -2482,7 +2500,7 @@ static ImBuf *image_load_image_file(Image *ima, ImageUser *iuser, int cfra)
}
if (ibuf) {
- /* handle multilayer case, don't assign ibuf. will be handled in BKE_image_get_ibuf */
+ /* handle multilayer case, don't assign ibuf. will be handled in BKE_image_acquire_ibuf */
if (ibuf->ftype == OPENEXR && ibuf->userdata) {
image_create_multilayer(ima, ibuf, cfra);
ima->type = IMA_TYPE_MULTILAYER;
@@ -2751,38 +2769,32 @@ static ImBuf *image_get_ibuf_threadsafe(Image *ima, ImageUser *iuser, int *frame
* a big bottleneck */
}
- *frame_r = frame;
- *index_r = index;
+ if (frame_r)
+ *frame_r = frame;
+
+ if (index_r)
+ *index_r = index;
return ibuf;
}
-/* Checks optional ImageUser and verifies/creates ImBuf. */
-/* use this one if you want to get a render result in progress,
- * if not, use BKE_image_get_ibuf which doesn't require a release */
-ImBuf *BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
+/* Checks optional ImageUser and verifies/creates ImBuf.
+ *
+ * not thread-safe, so callee should worry about thread locks
+ */
+static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
{
ImBuf *ibuf = NULL;
float color[] = {0, 0, 0, 1};
int frame = 0, index = 0;
- /* This function is intended to be thread-safe. It postpones the mutex lock
- * until it needs to load the image, if the image is already there it
- * should just get the pointer and return. The reason is that a lot of mutex
- * locks appears to be very slow on certain multicore macs, causing a render
- * with image textures to actually slow down as more threads are used.
- *
- * Note that all the image loading functions should also make sure they do
- * things in a threadsafe way for image_get_ibuf_threadsafe to work correct.
- * That means, the last two steps must be, 1) add the ibuf to the list and
- * 2) set ima/iuser->ok to 0 to IMA_OK_LOADED */
-
if (lock_r)
*lock_r = NULL;
/* quick reject tests */
if (ima == NULL)
return NULL;
+
if (iuser) {
if (iuser->ok == 0)
return NULL;
@@ -2790,95 +2802,71 @@ ImBuf *BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
else if (ima->ok == 0)
return NULL;
- /* try to get the ibuf without locking */
ibuf = image_get_ibuf_threadsafe(ima, iuser, &frame, &index);
if (ibuf == NULL) {
- /* couldn't get ibuf and image is not ok, so let's lock and try to
- * load the image */
- BLI_lock_thread(LOCK_IMAGE);
-
- /* need to check ok flag and loading ibuf again, because the situation
- * might have changed in the meantime */
- if (iuser) {
- if (iuser->ok == 0) {
- BLI_unlock_thread(LOCK_IMAGE);
- return NULL;
- }
- }
- else if (ima->ok == 0) {
- BLI_unlock_thread(LOCK_IMAGE);
- return NULL;
- }
-
- ibuf = image_get_ibuf_threadsafe(ima, iuser, &frame, &index);
-
- if (ibuf == NULL) {
- /* we are sure we have to load the ibuf, using source and type */
- if (ima->source == IMA_SRC_MOVIE) {
- /* source is from single file, use flipbook to store ibuf */
- ibuf = image_load_movie_file(ima, iuser, frame);
- }
- else if (ima->source == IMA_SRC_SEQUENCE) {
- if (ima->type == IMA_TYPE_IMAGE) {
- /* regular files, ibufs in flipbook, allows saving */
- ibuf = image_load_sequence_file(ima, iuser, frame);
- }
- /* no else; on load the ima type can change */
- if (ima->type == IMA_TYPE_MULTILAYER) {
- /* only 1 layer/pass stored in imbufs, no exrhandle anim storage, no saving */
- ibuf = image_load_sequence_multilayer(ima, iuser, frame);
- }
+ /* we are sure we have to load the ibuf, using source and type */
+ if (ima->source == IMA_SRC_MOVIE) {
+ /* source is from single file, use flipbook to store ibuf */
+ ibuf = image_load_movie_file(ima, iuser, frame);
+ }
+ else if (ima->source == IMA_SRC_SEQUENCE) {
+ if (ima->type == IMA_TYPE_IMAGE) {
+ /* regular files, ibufs in flipbook, allows saving */
+ ibuf = image_load_sequence_file(ima, iuser, frame);
}
- else if (ima->source == IMA_SRC_FILE) {
-
- if (ima->type == IMA_TYPE_IMAGE)
- ibuf = image_load_image_file(ima, iuser, frame); /* cfra only for '#', this global is OK */
- /* no else; on load the ima type can change */
- if (ima->type == IMA_TYPE_MULTILAYER)
- /* keeps render result, stores ibufs in listbase, allows saving */
- ibuf = image_get_ibuf_multilayer(ima, iuser);
-
+ /* no else; on load the ima type can change */
+ if (ima->type == IMA_TYPE_MULTILAYER) {
+ /* only 1 layer/pass stored in imbufs, no exrhandle anim storage, no saving */
+ ibuf = image_load_sequence_multilayer(ima, iuser, frame);
}
- else if (ima->source == IMA_SRC_GENERATED) {
- /* generated is: ibuf is allocated dynamically */
- /* UV testgrid or black or solid etc */
- if (ima->gen_x == 0) ima->gen_x = 1024;
- if (ima->gen_y == 0) ima->gen_y = 1024;
- ibuf = add_ibuf_size(ima->gen_x, ima->gen_y, ima->name, 24, (ima->gen_flag & IMA_GEN_FLOAT) != 0, ima->gen_type,
- color, &ima->colorspace_settings);
- image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
- ima->ok = IMA_OK_LOADED;
+ }
+ else if (ima->source == IMA_SRC_FILE) {
+
+ if (ima->type == IMA_TYPE_IMAGE)
+ ibuf = image_load_image_file(ima, iuser, frame); /* cfra only for '#', this global is OK */
+ /* no else; on load the ima type can change */
+ if (ima->type == IMA_TYPE_MULTILAYER)
+ /* keeps render result, stores ibufs in listbase, allows saving */
+ ibuf = image_get_ibuf_multilayer(ima, iuser);
+
+ }
+ else if (ima->source == IMA_SRC_GENERATED) {
+ /* generated is: ibuf is allocated dynamically */
+ /* UV testgrid or black or solid etc */
+ if (ima->gen_x == 0) ima->gen_x = 1024;
+ if (ima->gen_y == 0) ima->gen_y = 1024;
+ ibuf = add_ibuf_size(ima->gen_x, ima->gen_y, ima->name, 24, (ima->gen_flag & IMA_GEN_FLOAT) != 0, ima->gen_type,
+ color, &ima->colorspace_settings);
+ image_assign_ibuf(ima, ibuf, IMA_NO_INDEX, 0);
+ ima->ok = IMA_OK_LOADED;
+ }
+ else if (ima->source == IMA_SRC_VIEWER) {
+ if (ima->type == IMA_TYPE_R_RESULT) {
+ /* always verify entirely, and potentially
+ * returns pointer to release later */
+ ibuf = image_get_render_result(ima, iuser, lock_r);
}
- else if (ima->source == IMA_SRC_VIEWER) {
- if (ima->type == IMA_TYPE_R_RESULT) {
- /* always verify entirely, and potentially
- * returns pointer to release later */
- ibuf = image_get_render_result(ima, iuser, lock_r);
- }
- else if (ima->type == IMA_TYPE_COMPOSITE) {
- /* requires lock/unlock, otherwise don't return image */
- if (lock_r) {
- /* unlock in BKE_image_release_ibuf */
- BLI_lock_thread(LOCK_VIEWER);
- *lock_r = ima;
-
- /* XXX anim play for viewer nodes not yet supported */
- frame = 0; // XXX 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);
- image_assign_ibuf(ima, ibuf, 0, frame);
- }
+ else if (ima->type == IMA_TYPE_COMPOSITE) {
+ /* requires lock/unlock, otherwise don't return image */
+ if (lock_r) {
+ /* unlock in BKE_image_release_ibuf */
+ BLI_lock_thread(LOCK_VIEWER);
+ *lock_r = ima;
+
+ /* XXX anim play for viewer nodes not yet supported */
+ frame = 0; // XXX 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);
+ image_assign_ibuf(ima, ibuf, 0, frame);
}
}
}
}
-
- BLI_unlock_thread(LOCK_IMAGE);
}
BKE_image_tag_time(ima);
@@ -2886,23 +2874,79 @@ ImBuf *BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
return ibuf;
}
-void BKE_image_release_ibuf(Image *ima, void *lock)
+/* return image buffer for given image and user
+ *
+ * - will lock render result if image type is render result and lock is not NULL
+ * - will return NULL if image type if render or composite result and lock is NULL
+ *
+ * references the result, BKE_image_release_ibuf should be used to de-reference
+ */
+ImBuf *BKE_image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r)
+{
+ ImBuf *ibuf;
+
+ BLI_spin_lock(&image_spin);
+
+ ibuf = image_acquire_ibuf(ima, iuser, lock_r);
+
+ if (ibuf)
+ IMB_refImBuf(ibuf);
+
+ BLI_spin_unlock(&image_spin);
+
+ return ibuf;
+}
+
+void BKE_image_release_ibuf(Image *ima, ImBuf *ibuf, void *lock)
{
- /* for getting image during threaded render / compositing, need to release */
- if (lock == ima) {
- BLI_unlock_thread(LOCK_VIEWER); /* viewer image */
+ if (lock) {
+ /* for getting image during threaded render / compositing, need to release */
+ if (lock == ima) {
+ BLI_unlock_thread(LOCK_VIEWER); /* viewer image */
+ }
+ else if (lock) {
+ RE_ReleaseResultImage(lock); /* render result */
+ BLI_unlock_thread(LOCK_VIEWER); /* view image imbuf */
+ }
}
- else if (lock) {
- RE_ReleaseResultImage(lock); /* render result */
- BLI_unlock_thread(LOCK_VIEWER); /* view image imbuf */
+
+ if (ibuf) {
+ BLI_spin_lock(&image_spin);
+ IMB_freeImBuf(ibuf);
+ BLI_spin_unlock(&image_spin);
}
}
-/* warning, this can allocate generated images */
-ImBuf *BKE_image_get_ibuf(Image *ima, ImageUser *iuser)
+/* checks whether there's an image buffer for given image and user */
+int BKE_image_has_ibuf(Image *ima, ImageUser *iuser)
{
- /* here (+fie_ima/2-1) makes sure that division happens correctly */
- return BKE_image_acquire_ibuf(ima, iuser, NULL);
+ ImBuf *ibuf;
+
+ /* quick reject tests */
+ if (ima == NULL)
+ return FALSE;
+
+ if (iuser) {
+ if (iuser->ok == 0)
+ return FALSE;
+ }
+ else if (ima->ok == 0)
+ return FALSE;
+
+ ibuf = image_get_ibuf_threadsafe(ima, iuser, NULL, NULL);
+
+ if (!ibuf) {
+ BLI_spin_lock(&image_spin);
+
+ ibuf = image_get_ibuf_threadsafe(ima, iuser, NULL, NULL);
+
+ if (!ibuf)
+ ibuf = image_acquire_ibuf(ima, iuser, NULL);
+
+ BLI_spin_unlock(&image_spin);
+ }
+
+ return ibuf != NULL;
}
int BKE_image_user_frame_get(const ImageUser *iuser, int cfra, int fieldnr, short *r_is_in_range)
@@ -3020,7 +3064,7 @@ int BKE_image_has_alpha(struct Image *image)
ibuf = BKE_image_acquire_ibuf(image, NULL, &lock);
planes = (ibuf ? ibuf->planes : 0);
- BKE_image_release_ibuf(image, lock);
+ BKE_image_release_ibuf(image, ibuf, lock);
if (planes == 32)
return 1;
@@ -3044,7 +3088,7 @@ void BKE_image_get_size(Image *image, ImageUser *iuser, int *width, int *height)
*height = IMG_SIZE_FALLBACK;
}
- BKE_image_release_ibuf(image, lock);
+ BKE_image_release_ibuf(image, ibuf, lock);
}
void BKE_image_get_size_fl(Image *image, ImageUser *iuser, float size[2])
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 9deff12f124..eb0612a75bd 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -1520,7 +1520,9 @@ void test_idbutton(char *name)
/* search for id */
idtest = BLI_findstring(lb, name, offsetof(ID, name) + 2);
- if (idtest) if (new_id(lb, idtest, name) == 0) id_sort_by_name(lb, idtest);
+ if (idtest && (new_id(lb, idtest, name) == 0)) {
+ id_sort_by_name(lb, idtest);
+ }
}
void text_idbutton(struct ID *id, char *text)
diff --git a/source/blender/blenkernel/intern/mask_evaluate.c b/source/blender/blenkernel/intern/mask_evaluate.c
index 7d89678d36f..a2f6b3c1929 100644
--- a/source/blender/blenkernel/intern/mask_evaluate.c
+++ b/source/blender/blenkernel/intern/mask_evaluate.c
@@ -289,10 +289,10 @@ static void feather_bucket_check_intersect(float (*feather_points)[2], int tot_f
/* collapse loop with smaller AABB */
for (k = 0; k < tot_feather_point; k++) {
if (k >= check_b && k <= cur_a) {
- DO_MINMAX2(feather_points[k], min_a, max_a);
+ minmax_v2v2_v2(min_a, max_a, feather_points[k]);
}
else {
- DO_MINMAX2(feather_points[k], min_b, max_b);
+ minmax_v2v2_v2(min_b, max_b, feather_points[k]);
}
}
@@ -379,7 +379,7 @@ void BKE_mask_spline_feather_collapse_inner_loops(MaskSpline *spline, float (*fe
int next = i + 1;
float delta;
- DO_MINMAX2(feather_points[i], min, max);
+ minmax_v2v2_v2(min, max, feather_points[i]);
if (next == tot_feather_point) {
if (spline->flag & MASK_SPLINE_CYCLIC)
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 068059dc29a..fd5af6a20bb 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -3011,7 +3011,7 @@ float BKE_mesh_calc_poly_area(MPoly *mpoly, MLoop *loopstart,
MLoop *l_iter = loopstart;
float area, polynorm_local[3], (*vertexcos)[3];
const float *no = polynormal ? polynormal : polynorm_local;
- BLI_array_fixedstack_declare(vertexcos, BM_NGON_STACK_SIZE, mpoly->totloop, __func__);
+ BLI_array_fixedstack_declare(vertexcos, BM_DEFAULT_NGON_STACK_SIZE, mpoly->totloop, __func__);
/* pack vertex cos into an array for area_poly_v3 */
for (i = 0; i < mpoly->totloop; i++, l_iter++) {
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 9c7cbc42bdd..25b70ce1793 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -249,13 +249,13 @@ int modifier_couldBeCage(struct Scene *scene, ModifierData *md)
modifier_supportsMapping(md));
}
-int modifier_sameTopology(ModifierData *md)
+int modifier_isSameTopology(ModifierData *md)
{
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
return ELEM(mti->type, eModifierTypeType_OnlyDeform, eModifierTypeType_NonGeometrical);
}
-int modifier_nonGeometrical(ModifierData *md)
+int modifier_isNonGeometrical(ModifierData *md)
{
ModifierTypeInfo *mti = modifierType_getInfo(md->type);
return (mti->type == eModifierTypeType_NonGeometrical);
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 2d76484b60a..06b846a6df9 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -2184,6 +2184,7 @@ static void registerCompositNodes(bNodeTreeType *ttype)
register_node_type_cmp_normal(ttype);
register_node_type_cmp_curve_vec(ttype);
register_node_type_cmp_map_value(ttype);
+ register_node_type_cmp_map_range(ttype);
register_node_type_cmp_normalize(ttype);
register_node_type_cmp_filter(ttype);
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 6ec173a5908..47ca502d247 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -196,18 +196,18 @@ int BKE_object_support_modifier_type_check(Object *ob, int modifier_type)
return TRUE;
}
-void BKE_object_link_modifiers(struct Object *ob, struct Object *from)
+void BKE_object_link_modifiers(struct Object *ob_dst, struct Object *ob_src)
{
ModifierData *md;
- BKE_object_free_modifiers(ob);
+ BKE_object_free_modifiers(ob_dst);
- if (!ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) {
+ if (!ELEM5(ob_dst->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) {
/* only objects listed above can have modifiers and linking them to objects
* which doesn't have modifiers stack is quite silly */
return;
}
- for (md = from->modifiers.first; md; md = md->next) {
+ for (md = ob_src->modifiers.first; md; md = md->next) {
ModifierData *nmd = NULL;
if (ELEM4(md->type,
@@ -219,16 +219,18 @@ void BKE_object_link_modifiers(struct Object *ob, struct Object *from)
continue;
}
- if (!BKE_object_support_modifier_type_check(ob, md->type))
+ if (!BKE_object_support_modifier_type_check(ob_dst, md->type))
continue;
nmd = modifier_new(md->type);
+ BLI_strncpy(nmd->name, md->name, sizeof(nmd->name));
modifier_copyData(md, nmd);
- BLI_addtail(&ob->modifiers, nmd);
+ BLI_addtail(&ob_dst->modifiers, nmd);
+ modifier_unique_name(&ob_dst->modifiers, nmd);
}
- BKE_object_copy_particlesystems(ob, from);
- BKE_object_copy_softbody(ob, from);
+ BKE_object_copy_particlesystems(ob_dst, ob_src);
+ BKE_object_copy_softbody(ob_dst, ob_src);
/* TODO: smoke?, cloth? */
}
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index d645204d29c..93bf5a5c0b4 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -3786,14 +3786,22 @@ static int get_particle_uv(DerivedMesh *dm, ParticleData *pa, int face_index, co
return 1;
}
-#define SET_PARTICLE_TEXTURE(type, pvalue, texfac) \
- if ((event & mtex->mapto) & type) { pvalue = texture_value_blend(def, pvalue, value, texfac, blend); } (void)0
-
-#define CLAMP_PARTICLE_TEXTURE_POS(type, pvalue) \
- if (event & type) { if (pvalue < 0.0f) pvalue = 1.0f + pvalue; CLAMP(pvalue, 0.0f, 1.0f); } (void)0
-
-#define CLAMP_PARTICLE_TEXTURE_POSNEG(type, pvalue) \
- if (event & type) { CLAMP(pvalue, -1.0f, 1.0f); } (void)0
+#define SET_PARTICLE_TEXTURE(type, pvalue, texfac) \
+ if ((event & mtex->mapto) & type) { \
+ pvalue = texture_value_blend(def, pvalue, value, texfac, blend); \
+ } (void)0
+
+#define CLAMP_PARTICLE_TEXTURE_POS(type, pvalue) \
+ if (event & type) { \
+ if (pvalue < 0.0f) \
+ pvalue = 1.0f + pvalue; \
+ CLAMP(pvalue, 0.0f, 1.0f); \
+ } (void)0
+
+#define CLAMP_PARTICLE_TEXTURE_POSNEG(type, pvalue) \
+ if (event & type) { \
+ CLAMP(pvalue, -1.0f, 1.0f); \
+ } (void)0
static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSettings *part, ParticleData *par, int child_index, int face_index, const float fw[4], float *orco, ParticleTexture *ptex, int event, float cfra)
{
@@ -3802,8 +3810,8 @@ static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSetti
float value, rgba[4], texvec[3];
ptex->ivel = ptex->life = ptex->exist = ptex->size = ptex->damp =
- ptex->gravity = ptex->field = ptex->time = ptex->clump = ptex->kink =
- ptex->effector = ptex->rough1 = ptex->rough2 = ptex->roughe = 1.f;
+ ptex->gravity = ptex->field = ptex->time = ptex->clump = ptex->kink =
+ ptex->effector = ptex->rough1 = ptex->rough2 = ptex->roughe = 1.0f;
ptex->length = 1.0f - part->randlength * PSYS_FRAND(child_index + 26);
ptex->length *= part->clength_thres < PSYS_FRAND(child_index + 27) ? part->clength : 1.0f;
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index f195b3d71b0..3f2eb32f61c 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -2568,10 +2568,12 @@ int BKE_ptcache_id_reset(Scene *scene, PTCacheID *pid, int mode)
sbFreeSimulation(pid->calldata);
else if (pid->type == PTCACHE_TYPE_PARTICLES)
psys_reset(pid->calldata, PSYS_RESET_DEPSGRAPH);
- /*else if (pid->type == PTCACHE_TYPE_SMOKE_DOMAIN)
+#if 0
+ else if (pid->type == PTCACHE_TYPE_SMOKE_DOMAIN)
smokeModifier_reset(pid->calldata);
else if (pid->type == PTCACHE_TYPE_SMOKE_HIGHRES)
- smokeModifier_reset_turbulence(pid->calldata);*/
+ smokeModifier_reset_turbulence(pid->calldata);
+#endif
else if (pid->type == PTCACHE_TYPE_DYNAMICPAINT)
dynamicPaint_clearSurface((DynamicPaintSurface*)pid->calldata);
}
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 4f62732f5e6..9b1425584a7 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -1045,7 +1045,7 @@ static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scen
/* always update layer, so that animating layers works (joshua july 2010) */
/* XXX commented out, this has depsgraph issues anyway - and this breaks setting scenes
- (on scene-set, the base-lay is copied to ob-lay (ton nov 2012) */
+ * (on scene-set, the base-lay is copied to ob-lay (ton nov 2012) */
// base->lay = ob->lay;
}
diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c
index 469881020c1..0b7fdaa7c1d 100644
--- a/source/blender/blenkernel/intern/seqeffects.c
+++ b/source/blender/blenkernel/intern/seqeffects.c
@@ -139,6 +139,9 @@ static ImBuf *prepare_effect_imbufs(SeqRenderData context, ImBuf *ibuf1, ImBuf *
IMB_rect_from_float(ibuf3);
}
+ if (out->rect_float)
+ IMB_colormanagement_assign_float_colorspace(out, context.scene->sequencer_colorspace_settings.name);
+
return out;
}
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index a947a48938e..e023a3e20ae 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -2338,11 +2338,13 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float
*/
const short is_rendering = G.is_rendering;
+ const short is_background = G.background;
const int do_seq_gl = G.is_rendering ?
0 /* (context.scene->r.seq_flag & R_SEQ_GL_REND) */ :
(context.scene->r.seq_flag & R_SEQ_GL_PREV);
int do_seq;
int have_seq = FALSE;
+ int have_comp = FALSE;
Scene *scene;
int is_thread_main = BLI_thread_is_main();
@@ -2355,6 +2357,7 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float
frame = scene->r.sfra + nr + seq->anim_startofs;
have_seq = (scene->r.scemode & R_DOSEQ) && scene->ed && scene->ed->seqbase.first;
+ have_comp = (scene->r.scemode & R_DOCOMP) && scene->use_nodes && scene->nodetree;
oldcfra = scene->r.cfra;
scene->r.cfra = frame;
@@ -2367,7 +2370,7 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float
camera = scene->camera;
}
- if (have_seq == FALSE && camera == NULL) {
+ if (have_comp == FALSE && camera == NULL) {
scene->r.cfra = oldcfra;
return NULL;
}
@@ -2384,8 +2387,7 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float
(void)oldmarkers;
#endif
- if ((sequencer_view3d_cb && do_seq_gl && camera) && is_thread_main)
- {
+ if ((sequencer_view3d_cb && do_seq_gl && camera) && is_thread_main) {
char err_out[256] = "unknown";
/* for old scened this can be uninitialized,
* should probably be added to do_versions at some point if the functionality stays */
@@ -2408,11 +2410,15 @@ static ImBuf *seq_render_scene_strip(SeqRenderData context, Sequence *seq, float
*
* disable rendered preview for sequencer while rendering -- it's very much possible
* that preview render will went into conflict with final render
+ *
+ * When rendering from command line renderer is called from main thread, in this
+ * case it's always safe to render scene here
*/
- if (!is_thread_main || is_rendering == FALSE) {
+ if (!is_thread_main || is_rendering == FALSE || is_background) {
if (re == NULL)
re = RE_NewRender(scene->id.name);
+ BKE_scene_update_for_newframe(context.bmain, scene, scene->lay);
RE_BlenderFrame(re, context.bmain, scene, NULL, camera, scene->lay, frame, FALSE);
/* restore previous state after it was toggled on & off by RE_BlenderFrame */
diff --git a/source/blender/blenkernel/intern/suggestions.c b/source/blender/blenkernel/intern/suggestions.c
index 99e33594a3e..ff9774f85af 100644
--- a/source/blender/blenkernel/intern/suggestions.c
+++ b/source/blender/blenkernel/intern/suggestions.c
@@ -47,6 +47,7 @@ static SuggList suggestions = {NULL, NULL, NULL, NULL, NULL};
static char *documentation = NULL;
//static int doc_lines = 0;
+/* TODO, replace with BLI_strncasecmp() */
static int txttl_cmp(const char *first, const char *second, int len)
{
int cmp, i;
@@ -113,19 +114,18 @@ short texttool_text_is_active(Text *text)
void texttool_suggest_add(const char *name, char type)
{
+ const int len = strlen(name);
+ int cmp;
SuggItem *newitem, *item;
- int len, cmp;
- newitem = MEM_mallocN(sizeof(SuggItem) + strlen(name) + 1, "SuggestionItem");
+ newitem = MEM_mallocN(sizeof(SuggItem) + len + 1, "SuggItem");
if (!newitem) {
printf("Failed to allocate memory for suggestion.\n");
return;
}
newitem->name = (char *) (newitem + 1);
- len = strlen(name);
- strncpy(newitem->name, name, len);
- newitem->name[len] = '\0';
+ memcpy(newitem->name, name, len + 1);
newitem->type = type;
newitem->prev = newitem->next = NULL;
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index d230cf8f1fe..e6339d07e66 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -96,17 +96,6 @@
* If the user moves the cursor the st containing that cursor should
* be popped ... other st's retain their own top location.
*
- * Markers
- * --
- * The mrk->flags define the behavior and relationships between markers. The
- * upper two bytes are used to hold a group ID, the lower two are normal flags. If
- * TMARK_EDITALL is set the group ID defines which other markers should be edited.
- *
- * The mrk->clr field is used to visually group markers where the flags may not
- * match. A template system, for example, may allow editing of repeating tokens
- * (in one group) but include other marked positions (in another group) all in the
- * same template with the same color.
- *
* Undo
* --
* Undo/Redo works by storing
@@ -136,8 +125,7 @@
static void txt_pop_first(Text *text);
static void txt_pop_last(Text *text);
-static void txt_undo_add_op(Text *text, int op);
-static void txt_undo_add_block(Text *text, int op, const char *buf);
+static void txt_undo_add_blockop(Text *text, int op, const char *buf);
static void txt_delete_line(Text *text, TextLine *line);
static void txt_delete_sel(Text *text);
static void txt_make_dirty(Text *text);
@@ -175,7 +163,6 @@ void BKE_text_free(Text *text)
}
BLI_freelistN(&text->lines);
- BLI_freelistN(&text->markers);
if (text->name) MEM_freeN(text->name);
MEM_freeN(text->undo_buf);
@@ -203,7 +190,6 @@ Text *BKE_text_add(const char *name)
ta->flags |= TXT_TABSTOSPACES;
ta->lines.first = ta->lines.last = NULL;
- ta->markers.first = ta->markers.last = NULL;
tmp = (TextLine *) MEM_mallocN(sizeof(TextLine), "textline");
tmp->line = (char *) MEM_mallocN(1, "textline_string");
@@ -399,7 +385,6 @@ Text *BKE_text_load(const char *file, const char *relpath)
ta->id.us = 1;
ta->lines.first = ta->lines.last = NULL;
- ta->markers.first = ta->markers.last = NULL;
ta->curl = ta->sell = NULL;
if ((U.flag & USER_TXT_TABSTOSPACES_DISABLE) == 0)
@@ -496,7 +481,6 @@ Text *BKE_text_copy(Text *ta)
tan->flags = ta->flags | TXT_ISDIRTY;
tan->lines.first = tan->lines.last = NULL;
- tan->markers.first = tan->markers.last = NULL;
tan->curl = tan->sell = NULL;
tan->nlines = ta->nlines;
@@ -785,23 +769,6 @@ static void txt_curs_sel(Text *text, TextLine ***linep, int **charp)
*linep = &text->sell; *charp = &text->selc;
}
-static void txt_curs_first(Text *text, TextLine **linep, int *charp)
-{
- if (text->curl == text->sell) {
- *linep = text->curl;
- if (text->curc < text->selc) *charp = text->curc;
- else *charp = text->selc;
- }
- else if (txt_get_span(text->lines.first, text->curl) < txt_get_span(text->lines.first, text->sell)) {
- *linep = text->curl;
- *charp = text->curc;
- }
- else {
- *linep = text->sell;
- *charp = text->selc;
- }
-}
-
/*****************************/
/* Cursor movement functions */
/*****************************/
@@ -843,13 +810,11 @@ void txt_move_up(Text *text, short sel)
{
TextLine **linep;
int *charp;
- /* int old; */ /* UNUSED */
if (!text) return;
if (sel) txt_curs_sel(text, &linep, &charp);
else { txt_pop_first(text); txt_curs_cur(text, &linep, &charp); }
if (!*linep) return;
- /* old = *charp; */ /* UNUSED */
if ((*linep)->prev) {
int index = txt_utf8_offset_to_index((*linep)->line, *charp);
@@ -857,8 +822,6 @@ void txt_move_up(Text *text, short sel)
if (index > txt_utf8_len((*linep)->line)) *charp = (*linep)->len;
else *charp = txt_utf8_index_to_offset((*linep)->line, index);
- if (!undoing)
- txt_undo_add_op(text, sel ? UNDO_SUP : UNDO_CUP);
}
else {
txt_move_bol(text, sel);
@@ -871,22 +834,17 @@ void txt_move_down(Text *text, short sel)
{
TextLine **linep;
int *charp;
- /* int old; */ /* UNUSED */
if (!text) return;
if (sel) txt_curs_sel(text, &linep, &charp);
else { txt_pop_last(text); txt_curs_cur(text, &linep, &charp); }
if (!*linep) return;
- /* old = *charp; */ /* UNUSED */
if ((*linep)->next) {
int index = txt_utf8_offset_to_index((*linep)->line, *charp);
*linep = (*linep)->next;
if (index > txt_utf8_len((*linep)->line)) *charp = (*linep)->len;
else *charp = txt_utf8_index_to_offset((*linep)->line, index);
-
- if (!undoing)
- txt_undo_add_op(text, sel ? UNDO_SDOWN : UNDO_CDOWN);
}
else {
txt_move_eol(text, sel);
@@ -898,7 +856,7 @@ void txt_move_down(Text *text, short sel)
void txt_move_left(Text *text, short sel)
{
TextLine **linep;
- int *charp, oundoing = undoing;
+ int *charp;
int tabsize = 0, i = 0;
if (!text) return;
@@ -906,8 +864,6 @@ void txt_move_left(Text *text, short sel)
else { txt_pop_first(text); txt_curs_cur(text, &linep, &charp); }
if (!*linep) return;
- undoing = 1;
-
if (*charp == 0) {
if ((*linep)->prev) {
txt_move_up(text, sel);
@@ -939,24 +895,19 @@ void txt_move_left(Text *text, short sel)
}
}
- undoing = oundoing;
- if (!undoing) txt_undo_add_op(text, sel ? UNDO_SLEFT : UNDO_CLEFT);
-
if (!sel) txt_pop_sel(text);
}
void txt_move_right(Text *text, short sel)
{
TextLine **linep;
- int *charp, oundoing = undoing, do_tab = FALSE, i;
+ int *charp, do_tab = FALSE, i;
if (!text) return;
if (sel) txt_curs_sel(text, &linep, &charp);
else { txt_pop_last(text); txt_curs_cur(text, &linep, &charp); }
if (!*linep) return;
- undoing = 1;
-
if (*charp == (*linep)->len) {
if ((*linep)->next) {
txt_move_down(text, sel);
@@ -984,124 +935,103 @@ void txt_move_right(Text *text, short sel)
else (*charp) += BLI_str_utf8_size((*linep)->line + *charp);
}
- undoing = oundoing;
- if (!undoing) txt_undo_add_op(text, sel ? UNDO_SRIGHT : UNDO_CRIGHT);
-
if (!sel) txt_pop_sel(text);
}
void txt_jump_left(Text *text, short sel)
{
TextLine **linep;
- int *charp, oldc;
+ int *charp;
if (!text) return;
if (sel) txt_curs_sel(text, &linep, &charp);
else { txt_pop_first(text); txt_curs_cur(text, &linep, &charp); }
if (!*linep) return;
- oldc = *charp;
BLI_str_cursor_step_utf8((*linep)->line, (*linep)->len,
charp, STRCUR_DIR_PREV,
STRCUR_JUMP_DELIM);
if (!sel) txt_pop_sel(text);
- if (!undoing) {
- int span = txt_get_span(text->lines.first, *linep);
- txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, span, oldc, span, (unsigned short)*charp);
- }
}
void txt_jump_right(Text *text, short sel)
{
TextLine **linep;
- int *charp, oldc;
+ int *charp;
if (!text) return;
if (sel) txt_curs_sel(text, &linep, &charp);
else { txt_pop_last(text); txt_curs_cur(text, &linep, &charp); }
if (!*linep) return;
- oldc = *charp;
BLI_str_cursor_step_utf8((*linep)->line, (*linep)->len,
charp, STRCUR_DIR_NEXT,
STRCUR_JUMP_DELIM);
if (!sel) txt_pop_sel(text);
- if (!undoing) {
- int span = txt_get_span(text->lines.first, *linep);
- txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, span, oldc, span, (unsigned short)*charp);
- }
}
void txt_move_bol(Text *text, short sel)
{
TextLine **linep;
- int *charp, old;
+ int *charp;
if (!text) return;
if (sel) txt_curs_sel(text, &linep, &charp);
else txt_curs_cur(text, &linep, &charp);
if (!*linep) return;
- old = *charp;
*charp = 0;
if (!sel) txt_pop_sel(text);
- if (!undoing) txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, txt_get_span(text->lines.first, *linep), old, txt_get_span(text->lines.first, *linep), (unsigned short)*charp);
}
void txt_move_eol(Text *text, short sel)
{
TextLine **linep;
- int *charp, old;
+ int *charp;
if (!text) return;
if (sel) txt_curs_sel(text, &linep, &charp);
else txt_curs_cur(text, &linep, &charp);
if (!*linep) return;
- old = *charp;
-
+
*charp = (*linep)->len;
if (!sel) txt_pop_sel(text);
- if (!undoing) txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, txt_get_span(text->lines.first, *linep), old, txt_get_span(text->lines.first, *linep), (unsigned short)*charp);
}
void txt_move_bof(Text *text, short sel)
{
TextLine **linep;
- int *charp, old;
+ int *charp;
if (!text) return;
if (sel) txt_curs_sel(text, &linep, &charp);
else txt_curs_cur(text, &linep, &charp);
if (!*linep) return;
- old = *charp;
*linep = text->lines.first;
*charp = 0;
if (!sel) txt_pop_sel(text);
- if (!undoing) txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, txt_get_span(text->lines.first, *linep), old, txt_get_span(text->lines.first, *linep), (unsigned short)*charp);
}
void txt_move_eof(Text *text, short sel)
{
TextLine **linep;
- int *charp, old;
+ int *charp;
if (!text) return;
if (sel) txt_curs_sel(text, &linep, &charp);
else txt_curs_cur(text, &linep, &charp);
if (!*linep) return;
- old = *charp;
*linep = text->lines.last;
*charp = (*linep)->len;
if (!sel) txt_pop_sel(text);
- if (!undoing) txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, txt_get_span(text->lines.first, *linep), old, txt_get_span(text->lines.first, *linep), (unsigned short)*charp);
}
void txt_move_toline(Text *text, unsigned int line, short sel)
@@ -1112,16 +1042,14 @@ void txt_move_toline(Text *text, unsigned int line, short sel)
/* Moves to a certain byte in a line, not a certain utf8-character! */
void txt_move_to(Text *text, unsigned int line, unsigned int ch, short sel)
{
- TextLine **linep, *oldl;
- int *charp, oldc;
+ TextLine **linep;
+ int *charp;
unsigned int i;
if (!text) return;
if (sel) txt_curs_sel(text, &linep, &charp);
else txt_curs_cur(text, &linep, &charp);
if (!*linep) return;
- oldc = *charp;
- oldl = *linep;
*linep = text->lines.first;
for (i = 0; i < line; i++) {
@@ -1133,7 +1061,6 @@ void txt_move_to(Text *text, unsigned int line, unsigned int ch, short sel)
*charp = ch;
if (!sel) txt_pop_sel(text);
- if (!undoing) txt_undo_add_toop(text, sel ? UNDO_STO : UNDO_CTO, txt_get_span(text->lines.first, oldl), oldc, txt_get_span(text->lines.first, *linep), (unsigned short)*charp);
}
/****************************/
@@ -1152,8 +1079,6 @@ static void txt_curs_swap(Text *text)
tmpc = text->curc;
text->curc = text->selc;
text->selc = tmpc;
-
- if (!undoing) txt_undo_add_op(text, UNDO_SWAP);
}
static void txt_pop_first(Text *text)
@@ -1164,12 +1089,6 @@ static void txt_pop_first(Text *text)
{
txt_curs_swap(text);
}
-
- if (!undoing) txt_undo_add_toop(text, UNDO_STO,
- txt_get_span(text->lines.first, text->sell),
- text->selc,
- txt_get_span(text->lines.first, text->curl),
- text->curc);
txt_pop_sel(text);
}
@@ -1181,12 +1100,6 @@ static void txt_pop_last(Text *text)
{
txt_curs_swap(text);
}
-
- if (!undoing) txt_undo_add_toop(text, UNDO_STO,
- txt_get_span(text->lines.first, text->sell),
- text->selc,
- txt_get_span(text->lines.first, text->curl),
- text->curc);
txt_pop_sel(text);
}
@@ -1222,9 +1135,7 @@ int txt_has_sel(Text *text)
static void txt_delete_sel(Text *text)
{
TextLine *tmpl;
- TextMarker *mrk;
char *buf;
- int move, lineno;
if (!text) return;
if (!text->curl) return;
@@ -1236,33 +1147,11 @@ static void txt_delete_sel(Text *text)
if (!undoing) {
buf = txt_sel_to_buf(text);
- txt_undo_add_block(text, UNDO_DBLOCK, buf);
+ txt_undo_add_blockop(text, UNDO_DBLOCK, buf);
MEM_freeN(buf);
}
buf = MEM_mallocN(text->curc + (text->sell->len - text->selc) + 1, "textline_string");
-
- if (text->curl != text->sell) {
- txt_clear_marker_region(text, text->curl, text->curc, text->curl->len, 0, 0);
- move = txt_get_span(text->curl, text->sell);
- }
- else {
- mrk = txt_find_marker_region(text, text->curl, text->curc, text->selc, 0, 0);
- if (mrk && (mrk->start > text->curc || mrk->end < text->selc))
- txt_clear_marker_region(text, text->curl, text->curc, text->selc, 0, 0);
- move = 0;
- }
-
- mrk = txt_find_marker_region(text, text->sell, text->selc - 1, text->sell->len, 0, 0);
- if (mrk) {
- lineno = mrk->lineno;
- do {
- mrk->lineno -= move;
- if (mrk->start > text->curc) mrk->start -= text->selc - text->curc;
- mrk->end -= text->selc - text->curc;
- mrk = mrk->next;
- } while (mrk && mrk->lineno == lineno);
- }
strncpy(buf, text->curl->line, text->curc);
strcpy(buf + text->curc, text->sell->line + text->selc);
@@ -1491,19 +1380,9 @@ char *txt_sel_to_buf(Text *text)
return buf;
}
-static void txt_shift_markers(Text *text, int lineno, int count)
-{
- TextMarker *marker;
-
- for (marker = text->markers.first; marker; marker = marker->next)
- if (marker->lineno >= lineno) {
- marker->lineno += count;
- }
-}
-
void txt_insert_buf(Text *text, const char *in_buffer)
{
- int l = 0, u, len, lineno = -1, count = 0;
+ int l = 0, u, len;
size_t i = 0, j;
TextLine *add;
char *buffer;
@@ -1517,7 +1396,7 @@ void txt_insert_buf(Text *text, const char *in_buffer)
buffer = BLI_strdupn(in_buffer, len);
len += txt_extended_ascii_as_utf8(&buffer);
- if (!undoing) txt_undo_add_block(text, UNDO_IBLOCK, buffer);
+ if (!undoing) txt_undo_add_blockop(text, UNDO_IBLOCK, buffer);
u = undoing;
undoing = 1;
@@ -1530,9 +1409,6 @@ void txt_insert_buf(Text *text, const char *in_buffer)
else { undoing = u; MEM_freeN(buffer); return; }
i++;
- /* Read as many full lines as we can */
- lineno = txt_get_span(text->lines.first, text->curl);
-
while (i < len) {
l = 0;
@@ -1544,14 +1420,8 @@ void txt_insert_buf(Text *text, const char *in_buffer)
add = txt_new_linen(buffer + (i - l), l);
BLI_insertlinkbefore(&text->lines, text->curl, add);
i++;
- count++;
}
else {
- if (count) {
- txt_shift_markers(text, lineno, count);
- count = 0;
- }
-
for (j = i - l; j < i && j < len; )
txt_add_raw_char(text, BLI_str_utf8_as_unicode_step(buffer, &j));
break;
@@ -1560,10 +1430,6 @@ void txt_insert_buf(Text *text, const char *in_buffer)
MEM_freeN(buffer);
- if (count) {
- txt_shift_markers(text, lineno, count);
- }
-
undoing = u;
}
@@ -1599,6 +1465,7 @@ static void dump_buffer(Text *text)
while (i++ < text->undo_pos) printf("%d: %d %c\n", i, text->undo_buf[i], text->undo_buf[i]);
}
+/* Note: this function is outdated and must be updated if needed for future use */
void txt_print_undo(Text *text)
{
int i = 0;
@@ -1615,37 +1482,7 @@ void txt_print_undo(Text *text)
while (i <= text->undo_pos) {
op = text->undo_buf[i];
- if (op == UNDO_CLEFT) {
- ops = "Cursor left";
- }
- else if (op == UNDO_CRIGHT) {
- ops = "Cursor right";
- }
- else if (op == UNDO_CUP) {
- ops = "Cursor up";
- }
- else if (op == UNDO_CDOWN) {
- ops = "Cursor down";
- }
- else if (op == UNDO_SLEFT) {
- ops = "Selection left";
- }
- else if (op == UNDO_SRIGHT) {
- ops = "Selection right";
- }
- else if (op == UNDO_SUP) {
- ops = "Selection up";
- }
- else if (op == UNDO_SDOWN) {
- ops = "Selection down";
- }
- else if (op == UNDO_STO) {
- ops = "Selection ";
- }
- else if (op == UNDO_CTO) {
- ops = "Cursor ";
- }
- else if (op == UNDO_INSERT_1) {
+ if (op == UNDO_INSERT_1) {
ops = "Insert ascii ";
}
else if (op == UNDO_INSERT_2) {
@@ -1681,9 +1518,6 @@ void txt_print_undo(Text *text)
else if (op == UNDO_DEL_4) {
ops = "Delete unicode ";
}
- else if (op == UNDO_SWAP) {
- ops = "Cursor swap";
- }
else if (op == UNDO_DBLOCK) {
ops = "Delete text block";
}
@@ -1738,29 +1572,6 @@ void txt_print_undo(Text *text)
}
}
}
- else if (op == UNDO_STO || op == UNDO_CTO) {
- i++;
-
- charp = text->undo_buf[i]; i++;
- charp = charp + (text->undo_buf[i] << 8); i++;
-
- linep = text->undo_buf[i]; i++;
- linep = linep + (text->undo_buf[i] << 8); i++;
- linep = linep + (text->undo_buf[i] << 16); i++;
- linep = linep + (text->undo_buf[i] << 24); i++;
-
- printf("to <%d, %d> ", linep, charp);
-
- charp = text->undo_buf[i]; i++;
- charp = charp + (text->undo_buf[i] << 8); i++;
-
- linep = text->undo_buf[i]; i++;
- linep = linep + (text->undo_buf[i] << 8); i++;
- linep = linep + (text->undo_buf[i] << 16); i++;
- linep = linep + (text->undo_buf[i] << 24); i++;
-
- printf("from <%d, %d>", linep, charp);
- }
else if (op == UNDO_DBLOCK || op == UNDO_IBLOCK) {
i++;
@@ -1811,16 +1622,6 @@ void txt_print_undo(Text *text)
}
}
-static void txt_undo_add_op(Text *text, int op)
-{
- if (!max_undo_test(text, 2))
- return;
-
- text->undo_pos++;
- text->undo_buf[text->undo_pos] = op;
- text->undo_buf[text->undo_pos + 1] = 0;
-}
-
static void txt_undo_store_uint16(char *undo_buf, int *undo_pos, unsigned short value)
{
undo_buf[*undo_pos] = (value) & 0xff;
@@ -1841,17 +1642,41 @@ static void txt_undo_store_uint32(char *undo_buf, int *undo_pos, unsigned int va
(*undo_pos)++;
}
-static void txt_undo_add_block(Text *text, int op, const char *buf)
+/* store the cur cursor to the undo buffer */
+static void txt_undo_store_cur(Text *text)
+{
+ txt_undo_store_uint16(text->undo_buf, &text->undo_pos, text->curc);
+ txt_undo_store_uint32(text->undo_buf, &text->undo_pos, txt_get_span(text->lines.first, text->curl));
+}
+
+/* store the sel cursor to the undo buffer */
+static void txt_undo_store_sel(Text *text)
+{
+ txt_undo_store_uint16(text->undo_buf, &text->undo_pos, text->selc);
+ txt_undo_store_uint32(text->undo_buf, &text->undo_pos, txt_get_span(text->lines.first, text->sell));
+}
+
+/* store both cursors to the undo buffer */
+static void txt_undo_store_cursors(Text *text)
+{
+ txt_undo_store_cur(text);
+ txt_undo_store_sel(text);
+}
+
+/* store an operator along with a block of data */
+static void txt_undo_add_blockop(Text *text, int op, const char *buf)
{
unsigned int length = strlen(buf);
- if (!max_undo_test(text, length + 11))
+ if (!max_undo_test(text, length + 11 + 12))
return;
text->undo_pos++;
text->undo_buf[text->undo_pos] = op;
text->undo_pos++;
+ txt_undo_store_cursors(text);
+
txt_undo_store_uint32(text->undo_buf, &text->undo_pos, length);
strncpy(text->undo_buf + text->undo_pos, buf, length);
@@ -1863,34 +1688,30 @@ static void txt_undo_add_block(Text *text, int op, const char *buf)
text->undo_buf[text->undo_pos + 1] = 0;
}
-void txt_undo_add_toop(Text *text, int op, unsigned int froml, unsigned short fromc, unsigned int tol, unsigned short toc)
+/* store a regular operator */
+void txt_undo_add_op(Text *text, int op)
{
if (!max_undo_test(text, 15))
return;
- if (froml == tol && fromc == toc) return;
-
text->undo_pos++;
text->undo_buf[text->undo_pos] = op;
text->undo_pos++;
- txt_undo_store_uint16(text->undo_buf, &text->undo_pos, fromc);
- txt_undo_store_uint32(text->undo_buf, &text->undo_pos, froml);
- txt_undo_store_uint16(text->undo_buf, &text->undo_pos, toc);
- txt_undo_store_uint32(text->undo_buf, &text->undo_pos, tol);
+ txt_undo_store_cursors(text);
text->undo_buf[text->undo_pos] = op;
-
text->undo_buf[text->undo_pos + 1] = 0;
}
+/* store an operator for a single character */
static void txt_undo_add_charop(Text *text, int op_start, unsigned int c)
{
char utf8[BLI_UTF8_MAX];
size_t i, utf8_size = BLI_str_utf8_from_unicode(c, utf8);
- if (!max_undo_test(text, 3 + utf8_size))
+ if (!max_undo_test(text, 3 + utf8_size + 12))
return;
text->undo_pos++;
@@ -1899,6 +1720,8 @@ static void txt_undo_add_charop(Text *text, int op_start, unsigned int c)
text->undo_buf[text->undo_pos] = op_start + utf8_size - 1;
text->undo_pos++;
+ txt_undo_store_cur(text);
+
for (i = 0; i < utf8_size; i++) {
text->undo_buf[text->undo_pos] = utf8[i];
text->undo_pos++;
@@ -1909,6 +1732,9 @@ static void txt_undo_add_charop(Text *text, int op_start, unsigned int c)
else {
text->undo_buf[text->undo_pos] = op_start + 3;
text->undo_pos++;
+
+ txt_undo_store_cursors(text);
+
txt_undo_store_uint32(text->undo_buf, &text->undo_pos, c);
text->undo_buf[text->undo_pos] = op_start + 3;
}
@@ -1934,6 +1760,29 @@ static unsigned int txt_undo_read_uint32(const char *undo_buf, int *undo_pos)
return val;
}
+/* read the cur cursor from the undo buffer */
+static void txt_undo_read_cur(const char *undo_buf, int *undo_pos, unsigned int *curln, unsigned short *curc)
+{
+ *curln = txt_undo_read_uint32(undo_buf, undo_pos);
+ *curc = txt_undo_read_uint16(undo_buf, undo_pos);
+}
+
+/* read the sel cursor from the undo buffer */
+static void txt_undo_read_sel(const char *undo_buf, int *undo_pos, unsigned int *selln, unsigned short *selc)
+{
+ *selln = txt_undo_read_uint32(undo_buf, undo_pos);
+ *selc = txt_undo_read_uint16(undo_buf, undo_pos);
+}
+
+/* read both cursors from the undo buffer */
+static void txt_undo_read_cursors(const char *undo_buf, int *undo_pos,
+ unsigned int *curln, unsigned short *curc,
+ unsigned int *selln, unsigned short *selc)
+{
+ txt_undo_read_sel(undo_buf, undo_pos, selln, selc);
+ txt_undo_read_cur(undo_buf, undo_pos, curln, curc);
+}
+
static unsigned int txt_undo_read_unicode(const char *undo_buf, int *undo_pos, short bytes)
{
unsigned int unicode;
@@ -1986,6 +1835,29 @@ static unsigned int txt_redo_read_uint32(const char *undo_buf, int *undo_pos)
return val;
}
+/* redo read cur cursor from the undo buffer */
+static void txt_redo_read_cur(const char *undo_buf, int *undo_pos, unsigned int *curln, unsigned short *curc)
+{
+ *curc = txt_redo_read_uint16(undo_buf, undo_pos);
+ *curln = txt_redo_read_uint32(undo_buf, undo_pos);
+}
+
+/* redo read sel cursor from the undo buffer */
+static void txt_redo_read_sel(const char *undo_buf, int *undo_pos, unsigned int *selln, unsigned short *selc)
+{
+ *selc = txt_redo_read_uint16(undo_buf, undo_pos);
+ *selln = txt_redo_read_uint32(undo_buf, undo_pos);
+}
+
+/* redo read both cursors from the undo buffer */
+static void txt_redo_read_cursors(const char *undo_buf, int *undo_pos,
+ unsigned int *curln, unsigned short *curc,
+ unsigned int *selln, unsigned short *selc)
+{
+ txt_redo_read_cur(undo_buf, undo_pos, curln, curc);
+ txt_redo_read_sel(undo_buf, undo_pos, selln, selc);
+}
+
static unsigned int txt_redo_read_unicode(const char *undo_buf, int *undo_pos, short bytes)
{
unsigned int unicode;
@@ -2024,9 +1896,10 @@ void txt_do_undo(Text *text)
{
int op = text->undo_buf[text->undo_pos];
unsigned int linep, i;
+ unsigned int uchar;
+ unsigned int curln, selln;
+ unsigned short curc, selc;
unsigned short charp;
- TextLine *holdl;
- int holdc, holdln;
char *buf;
if (text->undo_pos < 0) {
@@ -2038,88 +1911,60 @@ void txt_do_undo(Text *text)
undoing = 1;
switch (op) {
- case UNDO_CLEFT:
- txt_move_right(text, 0);
- break;
+ case UNDO_INSERT_1:
+ case UNDO_INSERT_2:
+ case UNDO_INSERT_3:
+ case UNDO_INSERT_4:
+ text->undo_pos -= op - UNDO_INSERT_1 + 1;
- case UNDO_CRIGHT:
- txt_move_left(text, 0);
- break;
+ /* get and restore the cursors */
+ txt_undo_read_cur(text->undo_buf, &text->undo_pos, &curln, &curc);
+ txt_move_to(text, curln, curc, 0);
+ txt_move_to(text, curln, curc, 1);
- case UNDO_CUP:
- txt_move_down(text, 0);
- break;
+ txt_delete_char(text);
- case UNDO_CDOWN:
- txt_move_up(text, 0);
- break;
-
- case UNDO_SLEFT:
- txt_move_right(text, 1);
- break;
-
- case UNDO_SRIGHT:
- txt_move_left(text, 1);
- break;
-
- case UNDO_SUP:
- txt_move_down(text, 1);
+ text->undo_pos--;
break;
- case UNDO_SDOWN:
- txt_move_up(text, 1);
- break;
-
- case UNDO_CTO:
- case UNDO_STO:
- text->undo_pos--;
- text->undo_pos--;
- text->undo_pos--;
- text->undo_pos--;
-
- text->undo_pos--;
- text->undo_pos--;
-
- linep = txt_undo_read_uint32(text->undo_buf, &text->undo_pos);
- charp = txt_undo_read_uint16(text->undo_buf, &text->undo_pos);
-
- if (op == UNDO_CTO) {
- txt_move_toline(text, linep, 0);
- text->curc = charp;
- txt_pop_sel(text);
- }
- else {
- txt_move_toline(text, linep, 1);
- text->selc = charp;
- }
+ case UNDO_BS_1:
+ case UNDO_BS_2:
+ case UNDO_BS_3:
+ case UNDO_BS_4:
+ charp = op - UNDO_BS_1 + 1;
+ uchar = txt_undo_read_unicode(text->undo_buf, &text->undo_pos, charp);
- text->undo_pos--;
- break;
+ /* get and restore the cursors */
+ txt_undo_read_cur(text->undo_buf, &text->undo_pos, &curln, &curc);
+ txt_move_to(text, curln, curc, 0);
+ txt_move_to(text, curln, curc, 1);
- case UNDO_INSERT_1: case UNDO_INSERT_2: case UNDO_INSERT_3: case UNDO_INSERT_4:
- txt_backspace_char(text);
- text->undo_pos -= op - UNDO_INSERT_1 + 1;
- text->undo_pos--;
- break;
+ txt_add_char(text, uchar);
- case UNDO_BS_1: case UNDO_BS_2: case UNDO_BS_3: case UNDO_BS_4:
- charp = op - UNDO_BS_1 + 1;
- txt_add_char(text, txt_undo_read_unicode(text->undo_buf, &text->undo_pos, charp));
text->undo_pos--;
break;
-
- case UNDO_DEL_1: case UNDO_DEL_2: case UNDO_DEL_3: case UNDO_DEL_4:
+
+ case UNDO_DEL_1:
+ case UNDO_DEL_2:
+ case UNDO_DEL_3:
+ case UNDO_DEL_4:
charp = op - UNDO_DEL_1 + 1;
- txt_add_char(text, txt_undo_read_unicode(text->undo_buf, &text->undo_pos, charp));
+ uchar = txt_undo_read_unicode(text->undo_buf, &text->undo_pos, charp);
+
+ /* get and restore the cursors */
+ txt_undo_read_cur(text->undo_buf, &text->undo_pos, &curln, &curc);
+ txt_move_to(text, curln, curc, 0);
+ txt_move_to(text, curln, curc, 1);
+
+ txt_add_char(text, uchar);
+
txt_move_left(text, 0);
- text->undo_pos--;
- break;
- case UNDO_SWAP:
- txt_curs_swap(text);
+ text->undo_pos--;
break;
case UNDO_DBLOCK:
+ /* length of the string in the buffer */
linep = txt_undo_read_uint32(text->undo_buf, &text->undo_pos);
buf = MEM_mallocN(linep + 1, "dblock buffer");
@@ -2128,34 +1973,33 @@ void txt_do_undo(Text *text)
text->undo_pos--;
}
buf[i] = 0;
-
- txt_curs_first(text, &holdl, &holdc);
- holdln = txt_get_span(text->lines.first, holdl);
-
- txt_insert_buf(text, buf);
- MEM_freeN(buf);
-
- text->curl = text->lines.first;
- while (holdln > 0) {
- if (text->curl->next)
- text->curl = text->curl->next;
-
- holdln--;
- }
- text->curc = holdc;
+ /* skip over the length that was stored again */
text->undo_pos--;
text->undo_pos--;
text->undo_pos--;
text->undo_pos--;
+ /* Get the cursor positions */
+ txt_undo_read_cursors(text->undo_buf, &text->undo_pos, &curln, &curc, &selln, &selc);
+
+ /* move cur to location that needs buff inserted */
+ txt_move_to(text, curln, curc, 0);
+
+ txt_insert_buf(text, buf);
+ MEM_freeN(buf);
+
+ /* restore the cursors */
+ txt_move_to(text, curln, curc, 0);
+ txt_move_to(text, selln, selc, 1);
+
text->undo_pos--;
break;
case UNDO_IBLOCK:
+ /* length of the string in the buffer */
linep = txt_undo_read_uint32(text->undo_buf, &text->undo_pos);
- txt_delete_sel(text);
/* txt_backspace_char removes utf8-characters, not bytes */
buf = MEM_mallocN(linep + 1, "iblock buffer");
@@ -2167,47 +2011,32 @@ void txt_do_undo(Text *text)
linep = txt_utf8_len(buf);
MEM_freeN(buf);
- while (linep > 0) {
- txt_backspace_char(text);
- linep--;
- }
-
+ /* skip over the length that was stored again */
text->undo_pos--;
text->undo_pos--;
- text->undo_pos--;
text->undo_pos--;
-
text->undo_pos--;
+
+ /* get and restore the cursors */
+ txt_undo_read_cursors(text->undo_buf, &text->undo_pos, &curln, &curc, &selln, &selc);
+ txt_move_to(text, curln, curc, 0);
+ txt_move_to(text, curln, curc + linep, 1);
+
+ txt_delete_selected(text);
+ text->undo_pos--;
break;
case UNDO_INDENT:
case UNDO_UNINDENT:
case UNDO_COMMENT:
case UNDO_UNCOMMENT:
- linep = txt_undo_read_uint32(text->undo_buf, &text->undo_pos);
- //linep is now the end line of the selection
-
- charp = txt_undo_read_uint16(text->undo_buf, &text->undo_pos);
- //charp is the last char selected or text->line->len
-
- //set the selection for this now
- text->selc = charp;
- text->sell = text->lines.first;
- for (i = 0; i < linep; i++) {
- text->sell = text->sell->next;
- }
-
- linep = txt_undo_read_uint32(text->undo_buf, &text->undo_pos);
- //first line to be selected
-
- charp = txt_undo_read_uint16(text->undo_buf, &text->undo_pos);
- //first postion to be selected
- text->curc = charp;
- text->curl = text->lines.first;
- for (i = 0; i < linep; i++) {
- text->curl = text->curl->next;
- }
-
+ case UNDO_DUPLICATE:
+ case UNDO_MOVE_LINES_UP:
+ case UNDO_MOVE_LINES_DOWN:
+ /* get and restore the cursors */
+ txt_undo_read_cursors(text->undo_buf, &text->undo_pos, &curln, &curc, &selln, &selc);
+ txt_move_to(text, curln, curc, 0);
+ txt_move_to(text, selln, selc, 1);
if (op == UNDO_INDENT) {
txt_unindent(text);
@@ -2221,37 +2050,24 @@ void txt_do_undo(Text *text)
else if (op == UNDO_UNCOMMENT) {
txt_comment(text);
}
+ else if (op == UNDO_DUPLICATE) {
+ txt_delete_line(text, text->curl->next);
+ }
+ else if (op == UNDO_MOVE_LINES_UP) {
+ txt_move_lines(text, TXT_MOVE_LINE_DOWN);
+ }
+ else if (op == UNDO_MOVE_LINES_DOWN) {
+ txt_move_lines(text, TXT_MOVE_LINE_UP);
+ }
text->undo_pos--;
break;
- case UNDO_DUPLICATE:
- txt_delete_line(text, text->curl->next);
- break;
- case UNDO_MOVE_LINES_UP:
- txt_move_lines(text, TXT_MOVE_LINE_DOWN);
- break;
- case UNDO_MOVE_LINES_DOWN:
- txt_move_lines(text, TXT_MOVE_LINE_UP);
- break;
default:
//XXX error("Undo buffer error - resetting");
text->undo_pos = -1;
break;
}
-
- /* next undo step may need evaluating */
- if (text->undo_pos >= 0) {
- switch (text->undo_buf[text->undo_pos]) {
- case UNDO_STO:
- txt_do_undo(text);
- txt_do_redo(text); /* selections need restoring */
- break;
- case UNDO_SWAP:
- txt_do_undo(text); /* swaps should appear transparent */
- break;
- }
- }
undoing = 0;
}
@@ -2259,9 +2075,12 @@ void txt_do_undo(Text *text)
void txt_do_redo(Text *text)
{
char op;
- unsigned int linep, i;
- unsigned short charp;
char *buf;
+ unsigned int linep;
+ unsigned short charp;
+ unsigned int uchar;
+ unsigned int curln, selln;
+ unsigned short curc, selc;
text->undo_pos++;
op = text->undo_buf[text->undo_pos];
@@ -2274,104 +2093,91 @@ void txt_do_redo(Text *text)
undoing = 1;
switch (op) {
- case UNDO_CLEFT:
- txt_move_left(text, 0);
- break;
-
- case UNDO_CRIGHT:
- txt_move_right(text, 0);
- break;
+ case UNDO_INSERT_1:
+ case UNDO_INSERT_2:
+ case UNDO_INSERT_3:
+ case UNDO_INSERT_4:
+ text->undo_pos++;
- case UNDO_CUP:
- txt_move_up(text, 0);
- break;
+ /* get and restore the cursors */
+ txt_redo_read_cur(text->undo_buf, &text->undo_pos, &curln, &curc);
+ txt_move_to(text, curln, curc, 0);
+ txt_move_to(text, curln, curc, 1);
- case UNDO_CDOWN:
- txt_move_down(text, 0);
- break;
-
- case UNDO_SLEFT:
- txt_move_left(text, 1);
- break;
-
- case UNDO_SRIGHT:
- txt_move_right(text, 1);
- break;
-
- case UNDO_SUP:
- txt_move_up(text, 1);
- break;
-
- case UNDO_SDOWN:
- txt_move_down(text, 1);
- break;
-
- case UNDO_INSERT_1: case UNDO_INSERT_2: case UNDO_INSERT_3: case UNDO_INSERT_4:
- text->undo_pos++;
charp = op - UNDO_INSERT_1 + 1;
- txt_add_char(text, txt_redo_read_unicode(text->undo_buf, &text->undo_pos, charp));
- break;
+ uchar = txt_redo_read_unicode(text->undo_buf, &text->undo_pos, charp);
- case UNDO_BS_1: case UNDO_BS_2: case UNDO_BS_3: case UNDO_BS_4:
- text->undo_pos++;
- txt_backspace_char(text);
- text->undo_pos += op - UNDO_BS_1 + 1;
+ txt_add_char(text, uchar);
break;
- case UNDO_DEL_1: case UNDO_DEL_2: case UNDO_DEL_3: case UNDO_DEL_4:
+ case UNDO_BS_1:
+ case UNDO_BS_2:
+ case UNDO_BS_3:
+ case UNDO_BS_4:
text->undo_pos++;
- txt_delete_char(text);
- text->undo_pos += op - UNDO_DEL_1 + 1;
- break;
- case UNDO_SWAP:
- txt_curs_swap(text);
- txt_do_redo(text); /* swaps should appear transparent a*/
- break;
+ /* get and restore the cursors */
+ txt_redo_read_cur(text->undo_buf, &text->undo_pos, &curln, &curc);
+ txt_move_to(text, curln, curc, 0);
+ txt_move_to(text, curln, curc, 1);
+
+ text->undo_pos += op - UNDO_BS_1 + 1;
- case UNDO_CTO:
- case UNDO_STO:
- text->undo_pos++;
- text->undo_pos++;
+ /* move right so we backspace the correct char */
+ txt_move_right(text, 0);
+ txt_backspace_char(text);
- text->undo_pos++;
- text->undo_pos++;
- text->undo_pos++;
- text->undo_pos++;
+ break;
+ case UNDO_DEL_1:
+ case UNDO_DEL_2:
+ case UNDO_DEL_3:
+ case UNDO_DEL_4:
text->undo_pos++;
- charp = txt_redo_read_uint16(text->undo_buf, &text->undo_pos);
- linep = txt_redo_read_uint32(text->undo_buf, &text->undo_pos);
+ /* get and restore the cursors */
+ txt_redo_read_cur(text->undo_buf, &text->undo_pos, &curln, &curc);
+ txt_move_to(text, curln, curc, 0);
+ txt_move_to(text, curln, curc, 1);
- if (op == UNDO_CTO) {
- txt_move_toline(text, linep, 0);
- text->curc = charp;
- txt_pop_sel(text);
- }
- else {
- txt_move_toline(text, linep, 1);
- text->selc = charp;
- }
+ text->undo_pos += op - UNDO_DEL_1 + 1;
+
+ txt_delete_char(text);
break;
case UNDO_DBLOCK:
text->undo_pos++;
+
+ /* get and restore the cursors */
+ txt_redo_read_cursors(text->undo_buf, &text->undo_pos, &curln, &curc, &selln, &selc);
+ txt_move_to(text, curln, curc, 0);
+ txt_move_to(text, selln, selc, 1);
+
+ /* length of the block */
linep = txt_redo_read_uint32(text->undo_buf, &text->undo_pos);
- txt_delete_sel(text);
text->undo_pos += linep;
+ /* skip over the length that was stored again */
text->undo_pos++;
text->undo_pos++;
text->undo_pos++;
text->undo_pos++;
+ txt_delete_sel(text);
+
break;
case UNDO_IBLOCK:
text->undo_pos++;
+
+ /* get and restore the cursors */
+ txt_redo_read_cursors(text->undo_buf, &text->undo_pos, &curln, &curc, &selln, &selc);
+ txt_move_to(text, curln, curc, 0);
+ txt_move_to(text, curln, curc, 1);
+
+ /* length of the block */
linep = txt_redo_read_uint32(text->undo_buf, &text->undo_pos);
buf = MEM_mallocN(linep + 1, "iblock buffer");
@@ -2382,40 +2188,27 @@ void txt_do_redo(Text *text)
txt_insert_buf(text, buf);
MEM_freeN(buf);
+ /* skip over the length that was stored again */
text->undo_pos++;
text->undo_pos++;
text->undo_pos++;
text->undo_pos++;
+
break;
case UNDO_INDENT:
case UNDO_UNINDENT:
case UNDO_COMMENT:
case UNDO_UNCOMMENT:
+ case UNDO_DUPLICATE:
+ case UNDO_MOVE_LINES_UP:
+ case UNDO_MOVE_LINES_DOWN:
text->undo_pos++;
- charp = txt_redo_read_uint16(text->undo_buf, &text->undo_pos);
- //charp is the first char selected or 0
-
- linep = txt_redo_read_uint32(text->undo_buf, &text->undo_pos);
- //linep is now the first line of the selection
- //set the selcetion for this now
- text->curc = charp;
- text->curl = text->lines.first;
- for (i = 0; i < linep; i++) {
- text->curl = text->curl->next;
- }
-
- charp = txt_redo_read_uint16(text->undo_buf, &text->undo_pos);
- //last postion to be selected
-
- linep = txt_redo_read_uint32(text->undo_buf, &text->undo_pos);
- //Last line to be selected
-
- text->selc = charp;
- text->sell = text->lines.first;
- for (i = 0; i < linep; i++) {
- text->sell = text->sell->next;
- }
+
+ /* get and restore the cursors */
+ txt_redo_read_cursors(text->undo_buf, &text->undo_pos, &curln, &curc, &selln, &selc);
+ txt_move_to(text, curln, curc, 0);
+ txt_move_to(text, selln, selc, 1);
if (op == UNDO_INDENT) {
txt_indent(text);
@@ -2429,15 +2222,28 @@ void txt_do_redo(Text *text)
else if (op == UNDO_UNCOMMENT) {
txt_uncomment(text);
}
- break;
- case UNDO_DUPLICATE:
- txt_duplicate_line(text);
- break;
- case UNDO_MOVE_LINES_UP:
- txt_move_lines(text, TXT_MOVE_LINE_UP);
- break;
- case UNDO_MOVE_LINES_DOWN:
- txt_move_lines(text, TXT_MOVE_LINE_DOWN);
+ else if (op == UNDO_DUPLICATE) {
+ txt_duplicate_line(text);
+ }
+ else if (op == UNDO_MOVE_LINES_UP) {
+ /* offset the cursor by + 1 */
+ txt_move_to(text, curln + 1, curc, 0);
+ txt_move_to(text, selln + 1, selc, 1);
+
+ txt_move_lines(text, TXT_MOVE_LINE_UP);
+ }
+ else if (op == UNDO_MOVE_LINES_DOWN) {
+ /* offset the cursor by - 1 */
+ txt_move_to(text, curln - 1, curc, 0);
+ txt_move_to(text, selln - 1, selc, 1);
+
+ txt_move_lines(text, TXT_MOVE_LINE_DOWN);
+ }
+
+ /* re-restore the cursors since they got moved when redoing */
+ txt_move_to(text, curln, curc, 0);
+ txt_move_to(text, selln, selc, 1);
+
break;
default:
//XXX error("Undo buffer error - resetting");
@@ -2456,31 +2262,13 @@ void txt_do_redo(Text *text)
void txt_split_curline(Text *text)
{
TextLine *ins;
- TextMarker *mrk;
char *left, *right;
- int lineno = -1;
if (!text) return;
if (!text->curl) return;
txt_delete_sel(text);
- /* Move markers */
-
- lineno = txt_get_span(text->lines.first, text->curl);
- mrk = text->markers.first;
- while (mrk) {
- if (mrk->lineno == lineno && mrk->start > text->curc) {
- mrk->lineno++;
- mrk->start -= text->curc;
- mrk->end -= text->curc;
- }
- else if (mrk->lineno > lineno) {
- mrk->lineno++;
- }
- mrk = mrk->next;
- }
-
/* Make the two half strings */
left = MEM_mallocN(text->curc + 1, "textline_string");
@@ -2517,23 +2305,9 @@ void txt_split_curline(Text *text)
static void txt_delete_line(Text *text, TextLine *line)
{
- TextMarker *mrk = NULL, *nxt;
- int lineno = -1;
-
if (!text) return;
if (!text->curl) return;
- lineno = txt_get_span(text->lines.first, line);
- mrk = text->markers.first;
- while (mrk) {
- nxt = mrk->next;
- if (mrk->lineno == lineno)
- BLI_freelinkN(&text->markers, mrk);
- else if (mrk->lineno > lineno)
- mrk->lineno--;
- mrk = nxt;
- }
-
BLI_remlink(&text->lines, line);
if (line->line) MEM_freeN(line->line);
@@ -2548,25 +2322,12 @@ static void txt_delete_line(Text *text, TextLine *line)
static void txt_combine_lines(Text *text, TextLine *linea, TextLine *lineb)
{
char *tmp;
- TextMarker *mrk = NULL;
- int lineno = -1;
-
+
if (!text) return;
if (!linea || !lineb) return;
- mrk = txt_find_marker_region(text, lineb, 0, lineb->len, 0, 0);
- if (mrk) {
- lineno = mrk->lineno;
- do {
- mrk->lineno--;
- mrk->start += linea->len;
- mrk->end += linea->len;
- mrk = mrk->next;
- } while (mrk && mrk->lineno == lineno);
- }
- if (lineno == -1) lineno = txt_get_span(text->lines.first, lineb);
-
+
tmp = MEM_mallocN(linea->len + lineb->len + 1, "textline_string");
strcpy(tmp, linea->line);
@@ -2619,27 +2380,7 @@ void txt_delete_char(Text *text)
}
else { /* Just deleting a char */
size_t c_len = 0;
- TextMarker *mrk;
c = BLI_str_utf8_as_unicode_and_size(text->curl->line + text->curc, &c_len);
-
- mrk = txt_find_marker_region(text, text->curl, text->curc - c_len, text->curl->len, 0, 0);
- if (mrk) {
- int lineno = mrk->lineno;
- if (mrk->end == text->curc) {
- if ((mrk->flags & TMARK_TEMP) && !(mrk->flags & TMARK_EDITALL)) {
- txt_clear_markers(text, mrk->group, TMARK_TEMP);
- }
- else {
- BLI_freelinkN(&text->markers, mrk);
- }
- return;
- }
- do {
- if (mrk->start > text->curc) mrk->start -= c_len;
- mrk->end -= c_len;
- mrk = mrk->next;
- } while (mrk && mrk->lineno == lineno);
- }
memmove(text->curl->line + text->curc, text->curl->line + text->curc + c_len, text->curl->len - text->curc - c_len + 1);
@@ -2683,28 +2424,8 @@ void txt_backspace_char(Text *text)
}
else { /* Just backspacing a char */
size_t c_len = 0;
- TextMarker *mrk;
char *prev = BLI_str_prev_char_utf8(text->curl->line + text->curc);
c = BLI_str_utf8_as_unicode_and_size(prev, &c_len);
-
- mrk = txt_find_marker_region(text, text->curl, text->curc - c_len, text->curl->len, 0, 0);
- if (mrk) {
- int lineno = mrk->lineno;
- if (mrk->start == text->curc) {
- if ((mrk->flags & TMARK_TEMP) && !(mrk->flags & TMARK_EDITALL)) {
- txt_clear_markers(text, mrk->group, TMARK_TEMP);
- }
- else {
- BLI_freelinkN(&text->markers, mrk);
- }
- return;
- }
- do {
- if (mrk->start > text->curc - c_len) mrk->start -= c_len;
- mrk->end -= c_len;
- mrk = mrk->next;
- } while (mrk && mrk->lineno == lineno);
- }
/* source and destination overlap, don't use memcpy() */
memmove(text->curl->line + text->curc - c_len,
@@ -2746,9 +2467,7 @@ static void txt_convert_tab_to_spaces(Text *text)
static int txt_add_char_intern(Text *text, unsigned int add, int replace_tabs)
{
- int lineno;
char *tmp, ch[BLI_UTF8_MAX];
- TextMarker *mrk;
size_t add_len;
if (!text) return 0;
@@ -2767,16 +2486,9 @@ static int txt_add_char_intern(Text *text, unsigned int add, int replace_tabs)
txt_delete_sel(text);
+ if (!undoing) txt_undo_add_charop(text, UNDO_INSERT_1, add);
+
add_len = BLI_str_utf8_from_unicode(add, ch);
- mrk = txt_find_marker_region(text, text->curl, text->curc - 1, text->curl->len, 0, 0);
- if (mrk) {
- lineno = mrk->lineno;
- do {
- if (mrk->start > text->curc) mrk->start += add_len;
- mrk->end += add_len;
- mrk = mrk->next;
- } while (mrk && mrk->lineno == lineno);
- }
tmp = MEM_mallocN(text->curl->len + add_len + 1, "textline_string");
@@ -2793,7 +2505,6 @@ static int txt_add_char_intern(Text *text, unsigned int add, int replace_tabs)
txt_make_dirty(text);
txt_clean_text(text);
- if (!undoing) txt_undo_add_charop(text, UNDO_INSERT_1, add);
return 1;
}
@@ -2824,10 +2535,7 @@ int txt_replace_char(Text *text, unsigned int add)
/* If text is selected or we're at the end of the line just use txt_add_char */
if (text->curc == text->curl->len || txt_has_sel(text) || add == '\n') {
- int i = txt_add_char(text, add);
- TextMarker *mrk = txt_find_marker(text, text->curl, text->curc, 0, 0);
- if (mrk) BLI_freelinkN(&text->markers, mrk);
- return i;
+ return txt_add_char(text, add);
}
del = BLI_str_utf8_as_unicode_and_size(text->curl->line + text->curc, &del_size);
@@ -2854,8 +2562,8 @@ int txt_replace_char(Text *text, unsigned int add)
/* Should probably create a new op for this */
if (!undoing) {
- txt_undo_add_charop(text, UNDO_DEL_1, del);
txt_undo_add_charop(text, UNDO_INSERT_1, add);
+ txt_undo_add_charop(text, UNDO_DEL_1, del);
}
return 1;
}
@@ -2924,7 +2632,7 @@ void txt_indent(Text *text)
}
if (!undoing) {
- txt_undo_add_toop(text, UNDO_INDENT, txt_get_span(text->lines.first, text->curl), text->curc, txt_get_span(text->lines.first, text->sell), text->selc);
+ txt_undo_add_op(text, UNDO_INDENT);
}
}
@@ -2982,7 +2690,7 @@ void txt_unindent(Text *text)
}
if (!undoing) {
- txt_undo_add_toop(text, UNDO_UNINDENT, txt_get_span(text->lines.first, text->curl), text->curc, txt_get_span(text->lines.first, text->sell), text->selc);
+ txt_undo_add_op(text, UNDO_UNINDENT);
}
}
@@ -3031,7 +2739,7 @@ void txt_comment(Text *text)
}
if (!undoing) {
- txt_undo_add_toop(text, UNDO_COMMENT, txt_get_span(text->lines.first, text->curl), text->curc, txt_get_span(text->lines.first, text->sell), text->selc);
+ txt_undo_add_op(text, UNDO_COMMENT);
}
}
@@ -3076,7 +2784,7 @@ void txt_uncomment(Text *text)
}
if (!undoing) {
- txt_undo_add_toop(text, UNDO_UNCOMMENT, txt_get_span(text->lines.first, text->curl), text->curc, txt_get_span(text->lines.first, text->sell), text->selc);
+ txt_undo_add_op(text, UNDO_UNCOMMENT);
}
}
@@ -3165,157 +2873,6 @@ int setcurr_tab_spaces(Text *text, int space)
return i;
}
-/*********************************/
-/* Text marker utility functions */
-/*********************************/
-
-/* Creates and adds a marker to the list maintaining sorted order */
-void txt_add_marker(Text *text, TextLine *line, int start, int end, const unsigned char color[4], int group, int flags)
-{
- TextMarker *tmp, *marker;
-
- marker = MEM_mallocN(sizeof(TextMarker), "text_marker");
-
- marker->lineno = txt_get_span(text->lines.first, line);
- marker->start = MIN2(start, end);
- marker->end = MAX2(start, end);
- marker->group = group;
- marker->flags = flags;
-
- marker->color[0] = color[0];
- marker->color[1] = color[1];
- marker->color[2] = color[2];
- marker->color[3] = color[3];
-
- for (tmp = text->markers.last; tmp; tmp = tmp->prev)
- if (tmp->lineno < marker->lineno || (tmp->lineno == marker->lineno && tmp->start < marker->start))
- break;
-
- if (tmp) BLI_insertlinkafter(&text->markers, tmp, marker);
- else BLI_addhead(&text->markers, marker);
-}
-
-/* Returns the first matching marker on the specified line between two points.
- * If the group or flags fields are non-zero the returned flag must be in the
- * specified group and have at least the specified flags set. */
-TextMarker *txt_find_marker_region(Text *text, TextLine *line, int start, int end, int group, int flags)
-{
- TextMarker *marker, *next;
- int lineno = txt_get_span(text->lines.first, line);
-
- for (marker = text->markers.first; marker; marker = next) {
- next = marker->next;
-
- if (group && marker->group != group) continue;
- else if ((marker->flags & flags) != flags) continue;
- else if (marker->lineno < lineno) continue;
- else if (marker->lineno > lineno) break;
-
- if ((marker->start == marker->end && start <= marker->start && marker->start <= end) ||
- (marker->start < end && marker->end > start))
- {
- return marker;
- }
- }
- return NULL;
-}
-
-/* Clears all markers on the specified line between two points. If the group or
- * flags fields are non-zero the returned flag must be in the specified group
- * and have at least the specified flags set. */
-short txt_clear_marker_region(Text *text, TextLine *line, int start, int end, int group, int flags)
-{
- TextMarker *marker, *next;
- int lineno = txt_get_span(text->lines.first, line);
- short cleared = 0;
-
- for (marker = text->markers.first; marker; marker = next) {
- next = marker->next;
-
- if (group && marker->group != group) continue;
- else if ((marker->flags & flags) != flags) continue;
- else if (marker->lineno < lineno) continue;
- else if (marker->lineno > lineno) break;
-
- if ((marker->start == marker->end && start <= marker->start && marker->start <= end) ||
- (marker->start < end && marker->end > start))
- {
- BLI_freelinkN(&text->markers, marker);
- cleared = 1;
- }
- }
- return cleared;
-}
-
-/* Clears all markers in the specified group (if given) with at least the
- * specified flags set. Useful for clearing temporary markers (group = 0,
- * flags = TMARK_TEMP) */
-short txt_clear_markers(Text *text, int group, int flags)
-{
- TextMarker *marker, *next;
- short cleared = 0;
-
- for (marker = text->markers.first; marker; marker = next) {
- next = marker->next;
-
- if ((!group || marker->group == group) &&
- (marker->flags & flags) == flags)
- {
- BLI_freelinkN(&text->markers, marker);
- cleared = 1;
- }
- }
- return cleared;
-}
-
-/* Finds the marker at the specified line and cursor position with at least the
- * specified flags set in the given group (if non-zero). */
-TextMarker *txt_find_marker(Text *text, TextLine *line, int curs, int group, int flags)
-{
- TextMarker *marker;
- int lineno = txt_get_span(text->lines.first, line);
-
- for (marker = text->markers.first; marker; marker = marker->next) {
- if (group && marker->group != group) continue;
- else if ((marker->flags & flags) != flags) continue;
- else if (marker->lineno < lineno) continue;
- else if (marker->lineno > lineno) break;
-
- if (marker->start <= curs && curs <= marker->end)
- return marker;
- }
- return NULL;
-}
-
-/* Finds the previous marker in the same group. If no other is found, the same
- * marker will be returned */
-TextMarker *txt_prev_marker(Text *text, TextMarker *marker)
-{
- TextMarker *tmp = marker;
- while (tmp) {
- if (tmp->prev) tmp = tmp->prev;
- else tmp = text->markers.last;
- if (tmp->group == marker->group)
- return tmp;
- }
- return NULL; /* Only if (marker == NULL) */
-}
-
-/* Finds the next marker in the same group. If no other is found, the same
- * marker will be returned */
-TextMarker *txt_next_marker(Text *text, TextMarker *marker)
-{
- TextMarker *tmp = marker;
- while (tmp) {
- if (tmp->next) tmp = tmp->next;
- else tmp = text->markers.first;
- if (tmp->group == marker->group)
- return tmp;
- }
- return NULL; /* Only if (marker == NULL) */
-}
-
-
/*******************************/
/* Character utility functions */
/*******************************/
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c
index b174f27b7e1..30b48401046 100644
--- a/source/blender/blenkernel/intern/tracking.c
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -1124,10 +1124,10 @@ void BKE_tracking_marker_pattern_minmax(const MovieTrackingMarker *marker, float
{
INIT_MINMAX2(min, max);
- DO_MINMAX2(marker->pattern_corners[0], min, max);
- DO_MINMAX2(marker->pattern_corners[1], min, max);
- DO_MINMAX2(marker->pattern_corners[2], min, max);
- DO_MINMAX2(marker->pattern_corners[3], min, max);
+ minmax_v2v2_v2(min, max, marker->pattern_corners[0]);
+ minmax_v2v2_v2(min, max, marker->pattern_corners[1]);
+ minmax_v2v2_v2(min, max, marker->pattern_corners[2]);
+ minmax_v2v2_v2(min, max, marker->pattern_corners[3]);
}
void BKE_tracking_marker_get_subframe_position(MovieTrackingTrack *track, float framenr, float pos[2])
@@ -3161,7 +3161,7 @@ static int stabilization_median_point_get(MovieTracking *tracking, int framenr,
if (track->flag & TRACK_USE_2D_STAB) {
MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
- DO_MINMAX2(marker->pos, min, max);
+ minmax_v2v2_v2(min, max, marker->pos);
ok = TRUE;
}
diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index da9c919c109..0f861a7ed37 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -111,6 +111,11 @@ static void delete_picture(AVFrame *f)
}
}
+static int use_float_audio_buffer(int codec_id)
+{
+ return codec_id == CODEC_ID_AAC || codec_id == CODEC_ID_AC3 || codec_id == CODEC_ID_VORBIS;
+}
+
#ifdef WITH_AUDASPACE
static int write_audio_frame(void)
{
@@ -599,12 +604,14 @@ static AVStream *alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
/* Prepare an audio stream for the output file */
-static AVStream *alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContext *of)
+static AVStream *alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContext *of, char *error, int error_size)
{
AVStream *st;
AVCodecContext *c;
AVCodec *codec;
+ error[0] = '\0';
+
st = av_new_stream(of, 1);
if (!st) return NULL;
@@ -616,6 +623,10 @@ static AVStream *alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex
c->bit_rate = ffmpeg_audio_bitrate * 1000;
c->sample_fmt = AV_SAMPLE_FMT_S16;
c->channels = rd->ffcodecdata.audio_channels;
+ if (use_float_audio_buffer(codec_id)) {
+ c->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
+ c->sample_fmt = AV_SAMPLE_FMT_FLT;
+ }
codec = avcodec_find_encoder(c->codec_id);
if (!codec) {
//XXX error("Couldn't find a valid audio codec");
@@ -626,6 +637,7 @@ static AVStream *alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex
if (avcodec_open(c, codec) < 0) {
//XXX error("Couldn't initialize audio codec");
+ BLI_strncpy(error, IMB_ffmpeg_last_error(), error_size);
return NULL;
}
@@ -646,7 +658,12 @@ static AVStream *alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex
audio_output_buffer = (uint8_t *) av_malloc(audio_outbuf_size);
- audio_input_buffer = (uint8_t *) av_malloc(audio_input_samples * c->channels * sizeof(int16_t));
+ if (use_float_audio_buffer(codec_id)) {
+ audio_input_buffer = (uint8_t *) av_malloc(audio_input_samples * c->channels * sizeof(float));
+ }
+ else {
+ audio_input_buffer = (uint8_t *) av_malloc(audio_input_samples * c->channels * sizeof(int16_t));
+ }
audio_time = 0.0f;
@@ -801,9 +818,12 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
}
if (ffmpeg_audio_codec != CODEC_ID_NONE) {
- audio_stream = alloc_audio_stream(rd, fmt->audio_codec, of);
+ audio_stream = alloc_audio_stream(rd, fmt->audio_codec, of, error, sizeof(error));
if (!audio_stream) {
- BKE_report(reports, RPT_ERROR, "Error initializing audio stream");
+ if (error[0])
+ BKE_report(reports, RPT_ERROR, error);
+ else
+ BKE_report(reports, RPT_ERROR, "Error initializing audio stream");
av_dict_free(&opts);
return 0;
}
@@ -943,7 +963,12 @@ int BKE_ffmpeg_start(struct Scene *scene, RenderData *rd, int rectx, int recty,
AVCodecContext *c = audio_stream->codec;
AUD_DeviceSpecs specs;
specs.channels = c->channels;
- specs.format = AUD_FORMAT_S16;
+ if (use_float_audio_buffer(c->codec_id)) {
+ specs.format = AUD_FORMAT_FLOAT32;
+ }
+ else {
+ specs.format = AUD_FORMAT_S16;
+ }
specs.rate = rd->ffcodecdata.audio_mixrate;
audio_mixdown_device = sound_mixdown(scene, specs, rd->sfra, rd->ffcodecdata.audio_volume);
#ifdef FFMPEG_CODEC_TIME_BASE