Cycles: svn merge -r41232:41266 ^/trunk/blender

This commit is contained in:
Brecht Van Lommel 2011-10-24 22:51:44 +00:00
commit 47463742e2
34 changed files with 718 additions and 310 deletions

@ -104,7 +104,7 @@ def is_glsl(filename):
def is_c(filename):
ext = splitext(filename)[1]
return (ext in (".c", ".cpp", ".cxx", ".m", ".mm", ".rc"))
return (ext in (".c", ".cpp", ".cxx", ".m", ".mm", ".rc", ".cc"))
def is_c_any(filename):

@ -1685,6 +1685,10 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr)
}
}
/* arrow keys should not have utf8 */
if ((keyCode > 266) && (keyCode < 271))
utf8_buf[0] = '\0';
if ((keyCode == GHOST_kKeyQ) && (m_modifierMask & NSCommandKeyMask))
break; //Cmd-Q is directly handled by Cocoa

@ -125,6 +125,10 @@ class MEM_CacheLimiter {
public:
typedef typename std::list<MEM_CacheLimiterHandle<T> *,
MEM_Allocator<MEM_CacheLimiterHandle<T> *> >::iterator iterator;
typedef intptr_t (*MEM_CacheLimiter_DataSize_Func) (void *data);
MEM_CacheLimiter(MEM_CacheLimiter_DataSize_Func getDataSize_)
: getDataSize(getDataSize_) {
}
~MEM_CacheLimiter() {
for (iterator it = queue.begin(); it != queue.end(); it++) {
delete *it;
@ -143,17 +147,36 @@ public:
}
void enforce_limits() {
intptr_t max = MEM_CacheLimiter_get_maximum();
intptr_t mem_in_use= MEM_get_memory_in_use();
intptr_t mmap_in_use= MEM_get_mapped_memory_in_use();
intptr_t mem_in_use, cur_size;
if (max == 0) {
return;
}
if(getDataSize) {
mem_in_use = total_size();
} else {
mem_in_use = MEM_get_memory_in_use();
}
for (iterator it = queue.begin();
it != queue.end() && mem_in_use + mmap_in_use > max;) {
it != queue.end() && mem_in_use > max;) {
iterator jt = it;
++it;
if(getDataSize) {
cur_size= getDataSize((*jt)->get()->get_data());
} else {
cur_size= mem_in_use;
}
(*jt)->destroy_if_possible();
if(getDataSize) {
mem_in_use-= cur_size;
} else {
mem_in_use-= cur_size - MEM_get_memory_in_use();
}
}
}
void touch(MEM_CacheLimiterHandle<T> * handle) {
@ -164,8 +187,17 @@ public:
handle->me = it;
}
private:
intptr_t total_size() {
intptr_t size = 0;
for (iterator it = queue.begin(); it != queue.end(); it++) {
size+= getDataSize((*it)->get()->get_data());
}
return size;
}
std::list<MEM_CacheLimiterHandle<T>*,
MEM_Allocator<MEM_CacheLimiterHandle<T> *> > queue;
MEM_CacheLimiter_DataSize_Func getDataSize;
};
#endif // MEM_CACHELIMITER_H

@ -41,6 +41,9 @@ typedef struct MEM_CacheLimiterHandle_s MEM_CacheLimiterHandleC;
/* function used to remove data from memory */
typedef void(*MEM_CacheLimiter_Destruct_Func)(void*);
/* function used to measure stored data element size */
typedef intptr_t(*MEM_CacheLimiter_DataSize_Func) (void*);
#ifndef MEM_CACHELIMITER_H
extern void MEM_CacheLimiter_set_maximum(int m);
extern int MEM_CacheLimiter_get_maximum(void);
@ -54,7 +57,8 @@ extern int MEM_CacheLimiter_get_maximum(void);
*/
extern MEM_CacheLimiterC * new_MEM_CacheLimiter(
MEM_CacheLimiter_Destruct_Func data_destructor);
MEM_CacheLimiter_Destruct_Func data_destructor,
MEM_CacheLimiter_DataSize_Func data_size);
/**
* Delete MEM_CacheLimiter

@ -54,8 +54,8 @@ typedef std::list<MEM_CacheLimiterHandleCClass*,
class MEM_CacheLimiterCClass {
public:
MEM_CacheLimiterCClass(MEM_CacheLimiter_Destruct_Func data_destructor_)
: data_destructor(data_destructor_) {
MEM_CacheLimiterCClass(MEM_CacheLimiter_Destruct_Func data_destructor_, MEM_CacheLimiter_DataSize_Func data_size)
: data_destructor(data_destructor_), cache(data_size) {
}
~MEM_CacheLimiterCClass();
@ -142,10 +142,12 @@ static inline handle_t* cast(MEM_CacheLimiterHandleC * l)
}
MEM_CacheLimiterC * new_MEM_CacheLimiter(
MEM_CacheLimiter_Destruct_Func data_destructor)
MEM_CacheLimiter_Destruct_Func data_destructor,
MEM_CacheLimiter_DataSize_Func data_size)
{
return (MEM_CacheLimiterC*) new MEM_CacheLimiterCClass(
data_destructor);
data_destructor,
data_size);
}
void delete_MEM_CacheLimiter(MEM_CacheLimiterC * This)

@ -213,10 +213,12 @@ struct FCurve *rna_get_fcurve(struct PointerRNA *ptr, struct PropertyRNA *prop,
int binarysearch_bezt_index(struct BezTriple array[], float frame, int arraylen, short *replace);
/* get the time extents for F-Curve */
void calc_fcurve_range(struct FCurve *fcu, float *min, float *max, const short selOnly);
void calc_fcurve_range(struct FCurve *fcu, float *min, float *max,
const short do_sel_only, const short do_min_length);
/* get the bounding-box extents for F-Curve */
void calc_fcurve_bounds(struct FCurve *fcu, float *xmin, float *xmax, float *ymin, float *ymax, const short selOnly);
void calc_fcurve_bounds(struct FCurve *fcu, float *xmin, float *xmax, float *ymin, float *ymax,
const short do_sel_only);
/* .............. */

@ -50,6 +50,7 @@ void *copy_libblock(void *rt);
void copy_libblock_data(struct ID *id, const struct ID *id_from, const short do_action);
void id_lib_extern(struct ID *id);
void BKE_library_filepath_set(struct Library *lib, const char *filepath);
void id_us_plus(struct ID *id);
void id_us_min(struct ID *id);
int id_make_local(struct ID *id, int test);

@ -215,9 +215,7 @@ typedef enum {
SEQ_STRIPELEM_IBUF_ENDSTILL
} seq_stripelem_ibuf_t;
void seq_stripelem_cache_init(void);
void seq_stripelem_cache_destruct(void);
void seq_stripelem_cache_cleanup(void);
/* returned ImBuf is properly refed and has to be freed */

@ -881,7 +881,7 @@ void calc_action_range(const bAction *act, float *start, float *end, short incl_
/* get extents for this curve */
// TODO: allow enabling/disabling this?
calc_fcurve_range(fcu, &nmin, &nmax, FALSE);
calc_fcurve_range(fcu, &nmin, &nmax, FALSE, TRUE);
/* compare to the running tally */
min= MIN2(min, nmin);

@ -61,6 +61,7 @@
#include "BLI_callbacks.h"
#include "IMB_imbuf.h"
#include "IMB_moviecache.h"
#include "BKE_blender.h"
#include "BKE_context.h"
@ -111,6 +112,7 @@ void free_blender(void)
BLI_cb_finalize();
seq_stripelem_cache_destruct();
IMB_moviecache_destruct();
free_nodesystem();
}

@ -433,7 +433,8 @@ int binarysearch_bezt_index (BezTriple array[], float frame, int arraylen, short
/* ...................................... */
/* helper for calc_fcurve_* functions -> find first and last BezTriple to be used */
static void get_fcurve_end_keyframes (FCurve *fcu, BezTriple **first, BezTriple **last, const short selOnly)
static void get_fcurve_end_keyframes (FCurve *fcu, BezTriple **first, BezTriple **last,
const short do_sel_only)
{
/* init outputs */
*first = NULL;
@ -444,7 +445,7 @@ static void get_fcurve_end_keyframes (FCurve *fcu, BezTriple **first, BezTriple
return;
/* only include selected items? */
if (selOnly) {
if (do_sel_only) {
BezTriple *bezt;
unsigned int i;
@ -475,11 +476,12 @@ static void get_fcurve_end_keyframes (FCurve *fcu, BezTriple **first, BezTriple
/* Calculate the extents of F-Curve's data */
void calc_fcurve_bounds (FCurve *fcu, float *xmin, float *xmax, float *ymin, float *ymax, const short selOnly)
void calc_fcurve_bounds (FCurve *fcu, float *xmin, float *xmax, float *ymin, float *ymax,
const short do_sel_only)
{
float xminv=999999999.0f, xmaxv=-999999999.0f;
float yminv=999999999.0f, ymaxv=-999999999.0f;
short foundvert=0;
short foundvert= FALSE;
unsigned int i;
if (fcu->totvert) {
@ -488,7 +490,7 @@ void calc_fcurve_bounds (FCurve *fcu, float *xmin, float *xmax, float *ymin, flo
if (xmin || xmax) {
/* get endpoint keyframes */
get_fcurve_end_keyframes(fcu, &bezt_first, &bezt_last, selOnly);
get_fcurve_end_keyframes(fcu, &bezt_first, &bezt_last, do_sel_only);
if (bezt_first) {
BLI_assert(bezt_last != NULL);
@ -503,11 +505,12 @@ void calc_fcurve_bounds (FCurve *fcu, float *xmin, float *xmax, float *ymin, flo
BezTriple *bezt;
for (bezt=fcu->bezt, i=0; i < fcu->totvert; bezt++, i++) {
if ((selOnly == 0) || BEZSELECTED(bezt)) {
if ((do_sel_only == 0) || BEZSELECTED(bezt)) {
if (bezt->vec[1][1] < yminv)
yminv= bezt->vec[1][1];
if (bezt->vec[1][1] > ymaxv)
ymaxv= bezt->vec[1][1];
foundvert= TRUE;
}
}
}
@ -528,11 +531,11 @@ void calc_fcurve_bounds (FCurve *fcu, float *xmin, float *xmax, float *ymin, flo
yminv= fpt->vec[1];
if (fpt->vec[1] > ymaxv)
ymaxv= fpt->vec[1];
foundvert= TRUE;
}
}
}
foundvert=1;
}
if (foundvert) {
@ -555,43 +558,50 @@ void calc_fcurve_bounds (FCurve *fcu, float *xmin, float *xmax, float *ymin, flo
}
/* Calculate the extents of F-Curve's keyframes */
void calc_fcurve_range (FCurve *fcu, float *start, float *end, const short selOnly)
void calc_fcurve_range (FCurve *fcu, float *start, float *end,
const short do_sel_only, const short do_min_length)
{
float min=999999999.0f, max=-999999999.0f;
short foundvert=0;
short foundvert= FALSE;
if (fcu->totvert) {
if (fcu->bezt) {
BezTriple *bezt_first= NULL, *bezt_last= NULL;
/* get endpoint keyframes */
get_fcurve_end_keyframes(fcu, &bezt_first, &bezt_last, selOnly);
get_fcurve_end_keyframes(fcu, &bezt_first, &bezt_last, do_sel_only);
if (bezt_first) {
BLI_assert(bezt_last != NULL);
min= MIN2(min, bezt_first->vec[1][0]);
max= MAX2(max, bezt_last->vec[1][0]);
foundvert= TRUE;
}
}
else if (fcu->fpt) {
min= MIN2(min, fcu->fpt[0].vec[0]);
max= MAX2(max, fcu->fpt[fcu->totvert-1].vec[0]);
foundvert= TRUE;
}
foundvert=1;
}
/* minimum length is 1 frame */
if (foundvert) {
if (min == max) max += 1.0f;
*start= min;
*end= max;
if (foundvert == FALSE) {
min= max= 0.0f;
}
else {
*start= 0.0f;
*end= 1.0f;
if (do_min_length) {
/* minimum length is 1 frame */
if (min == max) {
max += 1.0f;
}
}
*start= min;
*end= max;
}
/* ----------------- Status Checks -------------------------- */

@ -1461,3 +1461,21 @@ void name_uiprefix_id(char *name, ID *id)
strcpy(name+3, id->name+2);
}
void BKE_library_filepath_set(Library *lib, const char *filepath)
{
BLI_strncpy(lib->name, filepath, sizeof(lib->name));
BLI_strncpy(lib->filepath, filepath, sizeof(lib->filepath));
/* not essential but set filepath is an absolute copy of value which
* is more useful if its kept in sync */
if (strncmp(lib->filepath, "//", 2) == 0) {
/* note that the file may be unsaved, in this case, setting the
* filepath on an indirectly linked path is not allowed from the
* outliner, and its not really supported but allow from here for now
* since making local could cause this to be directly linked - campbell
*/
const char *basepath= lib->parent ? lib->parent->filepath : G.main->name;
BLI_path_abs(lib->filepath, basepath);
}
}

@ -17,6 +17,8 @@
*
* Peter Schlaile <peter [at] schlaile [dot] de> 2010
*
* Contributor(s): Sergey Sharybin
*
* ***** END GPL LICENSE BLOCK *****
*/
@ -26,22 +28,15 @@
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "BLO_sys_types.h" /* for intptr_t */
#include "MEM_guardedalloc.h"
#include "MEM_CacheLimiterC-Api.h"
#include "DNA_sequence_types.h"
#include "BKE_sequencer.h"
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
#include "BLI_mempool.h"
#include <pthread.h>
#include "IMB_imbuf.h"
#include "IMB_imbuf_types.h"
#include "IMB_moviecache.h"
typedef struct seqCacheKey
{
@ -51,20 +46,9 @@ typedef struct seqCacheKey
seq_stripelem_ibuf_t type;
} seqCacheKey;
typedef struct seqCacheEntry
{
ImBuf * ibuf;
MEM_CacheLimiterHandleC * c_handle;
} seqCacheEntry;
static struct MovieCache *moviecache = NULL;
static GHash * hash = NULL;
static MEM_CacheLimiterC * limitor = NULL;
static struct BLI_mempool * entrypool = NULL;
static struct BLI_mempool * keypool = NULL;
static int ibufs_in = 0;
static int ibufs_rem = 0;
static unsigned int HashHash(const void *key_)
static unsigned int seqcache_hashhash(const void *key_)
{
const seqCacheKey *key = (seqCacheKey*) key_;
unsigned int rval = seq_hash_render_data(&key->context);
@ -76,7 +60,7 @@ static unsigned int HashHash(const void *key_)
return rval;
}
static int HashCmp(const void *a_, const void *b_)
static int seqcache_hashcmp(const void *a_, const void *b_)
{
const seqCacheKey * a = (seqCacheKey*) a_;
const seqCacheKey * b = (seqCacheKey*) b_;
@ -105,109 +89,37 @@ static int HashCmp(const void *a_, const void *b_)
return seq_cmp_render_data(&a->context, &b->context);
}
static void HashKeyFree(void *key)
{
BLI_mempool_free(keypool, key);
}
static void HashValFree(void *val)
{
seqCacheEntry* e = (seqCacheEntry*) val;
if (e->ibuf) {
/* fprintf(stderr, "Removing: %p, cnt: %d\n", e->ibuf,
e->ibuf->refcounter); */
IMB_freeImBuf(e->ibuf);
MEM_CacheLimiter_unmanage(e->c_handle);
ibufs_rem++;
}
e->ibuf = NULL;
e->c_handle = NULL;
BLI_mempool_free(entrypool, e);
}
static void IMB_seq_cache_destructor(void * p)
{
seqCacheEntry* e = (seqCacheEntry*) p;
if (e && e->ibuf) {
/* fprintf(stderr, "Removing: %p, cnt: %d\n", e->ibuf,
e->ibuf->refcounter); */
IMB_freeImBuf(e->ibuf);
ibufs_rem++;
e->ibuf = NULL;
e->c_handle = NULL;
}
}
void seq_stripelem_cache_init(void)
{
hash = BLI_ghash_new(HashHash, HashCmp, "seq stripelem cache hash");
limitor = new_MEM_CacheLimiter( IMB_seq_cache_destructor );
entrypool = BLI_mempool_create(sizeof(seqCacheEntry), 64, 64, 0);
keypool = BLI_mempool_create(sizeof(seqCacheKey), 64, 64, 0);
}
void seq_stripelem_cache_destruct(void)
{
if (!entrypool) {
return;
}
BLI_ghash_free(hash, HashKeyFree, HashValFree);
delete_MEM_CacheLimiter(limitor);
BLI_mempool_destroy(entrypool);
BLI_mempool_destroy(keypool);
if(moviecache)
IMB_moviecache_free(moviecache);
}
void seq_stripelem_cache_cleanup(void)
{
if (!entrypool) {
seq_stripelem_cache_init();
if(moviecache) {
IMB_moviecache_free(moviecache);
moviecache = IMB_moviecache_create(sizeof(seqCacheKey), seqcache_hashhash,
seqcache_hashcmp, NULL);
}
/* fprintf(stderr, "Stats before cleanup: in: %d rem: %d\n",
ibufs_in, ibufs_rem); */
BLI_ghash_free(hash, HashKeyFree, HashValFree);
hash = BLI_ghash_new(HashHash, HashCmp, "seq stripelem cache hash");
/* fprintf(stderr, "Stats after cleanup: in: %d rem: %d\n",
ibufs_in, ibufs_rem); */
}
struct ImBuf * seq_stripelem_cache_get(
SeqRenderData context, struct Sequence * seq,
float cfra, seq_stripelem_ibuf_t type)
{
seqCacheKey key;
seqCacheEntry * e;
if (!seq) {
return NULL;
if(moviecache && seq) {
seqCacheKey key;
key.seq = seq;
key.context = context;
key.cfra = cfra - seq->start;
key.type = type;
return IMB_moviecache_get(moviecache, &key);
}
if (!entrypool) {
seq_stripelem_cache_init();
}
key.seq = seq;
key.context = context;
key.cfra = cfra - seq->start;
key.type = type;
e = (seqCacheEntry*) BLI_ghash_lookup(hash, &key);
if (e && e->ibuf) {
IMB_refImBuf(e->ibuf);
MEM_CacheLimiter_touch(e->c_handle);
return e->ibuf;
}
return NULL;
}
@ -215,39 +127,21 @@ void seq_stripelem_cache_put(
SeqRenderData context, struct Sequence * seq,
float cfra, seq_stripelem_ibuf_t type, struct ImBuf * i)
{
seqCacheKey * key;
seqCacheEntry * e;
seqCacheKey key;
if (!i) {
return;
}
ibufs_in++;
if (!entrypool) {
seq_stripelem_cache_init();
if(!moviecache) {
moviecache = IMB_moviecache_create(sizeof(seqCacheKey), seqcache_hashhash,
seqcache_hashcmp, NULL);
}
key = (seqCacheKey*) BLI_mempool_alloc(keypool);
key.seq = seq;
key.context = context;
key.cfra = cfra - seq->start;
key.type = type;
key->seq = seq;
key->context = context;
key->cfra = cfra - seq->start;
key->type = type;
IMB_refImBuf(i);
e = (seqCacheEntry*) BLI_mempool_alloc(entrypool);
e->ibuf = i;
e->c_handle = NULL;
BLI_ghash_remove(hash, key, HashKeyFree, HashValFree);
BLI_ghash_insert(hash, key, e);
e->c_handle = MEM_CacheLimiter_insert(limitor, e);
MEM_CacheLimiter_ref(e->c_handle);
MEM_CacheLimiter_enforce_limits(limitor);
MEM_CacheLimiter_unref(e->c_handle);
IMB_moviecache_put(moviecache, &key, i);
}

@ -1324,6 +1324,10 @@ static void seq_proxy_build_frame(SeqRenderData context,
quality = seq->strip->proxy->quality;
ibuf->ftype= JPG | quality;
/* unsupported feature only confuses other s/w */
if(ibuf->depth==32)
ibuf->depth= 24;
BLI_make_existing_file(name);
ok = IMB_saveiff(ibuf, name, IB_rect | IB_zbuf | IB_zbuffloat);
@ -2501,9 +2505,6 @@ static void *seq_prefetch_thread(void * This_)
for (e = prefetch_done.first; e; e = e->next) {
if (s_last > e->monoton_cfra) {
if (e->ibuf) {
IMB_cache_limiter_unref(e->ibuf);
}
BLI_remlink(&prefetch_done, e);
MEM_freeN(e);
}
@ -2581,9 +2582,6 @@ static void seq_stop_threads()
}
for (e = prefetch_done.first; e; e = e->next) {
if (e->ibuf) {
IMB_cache_limiter_unref(e->ibuf);
}
BLI_remlink(&prefetch_done, e);
MEM_freeN(e);
}

@ -396,6 +396,20 @@ static void set_ffmpeg_property_option(AVCodecContext* c, IDProperty * prop)
}
}
static int ffmpeg_proprty_valid(AVCodecContext *c, const char *prop_name, IDProperty *curr)
{
int valid= 1;
if(strcmp(prop_name, "video")==0) {
if(strcmp(curr->name, "bf")==0) {
/* flash codec doesn't support b frames */
valid&= c->codec_id!=CODEC_ID_FLV1;
}
}
return valid;
}
static void set_ffmpeg_properties(RenderData *rd, AVCodecContext *c, const char * prop_name)
{
IDProperty * prop;
@ -414,7 +428,8 @@ static void set_ffmpeg_properties(RenderData *rd, AVCodecContext *c, const char
iter = IDP_GetGroupIterator(prop);
while ((curr = IDP_GroupIterNext(iter)) != NULL) {
set_ffmpeg_property_option(c, curr);
if(ffmpeg_proprty_valid(c, prop_name, curr))
set_ffmpeg_property_option(c, curr);
}
}
@ -1187,6 +1202,9 @@ void ffmpeg_set_preset(RenderData *rd, int preset)
{
int isntsc = (rd->frs_sec != 25);
if(rd->ffcodecdata.properties)
IDP_FreeProperty(rd->ffcodecdata.properties);
switch (preset) {
case FFMPEG_PRESET_VCD:
rd->ffcodecdata.type = FFMPEG_MPEG1;
@ -1217,8 +1235,11 @@ void ffmpeg_set_preset(RenderData *rd, int preset)
case FFMPEG_PRESET_DVD:
rd->ffcodecdata.type = FFMPEG_MPEG2;
rd->ffcodecdata.video_bitrate = 6000;
rd->xsch = 720;
rd->ysch = isntsc ? 480 : 576;
/* Don't set resolution, see [#21351]
* rd->xsch = 720;
* rd->ysch = isntsc ? 480 : 576; */
rd->ffcodecdata.gop_size = isntsc ? 18 : 15;
rd->ffcodecdata.rc_max_rate = 9000;
rd->ffcodecdata.rc_min_rate = 0;
@ -1321,8 +1342,8 @@ void ffmpeg_verify_image_type(RenderData *rd)
rd->ffcodecdata.video_bitrate <= 1) {
rd->ffcodecdata.codec = CODEC_ID_MPEG2VIDEO;
/* Don't set preset, disturbs render resolution.
* ffmpeg_set_preset(rd, FFMPEG_PRESET_DVD); */
ffmpeg_set_preset(rd, FFMPEG_PRESET_DVD);
}
if(rd->ffcodecdata.type == FFMPEG_OGG) {
rd->ffcodecdata.type = FFMPEG_MPEG2;

@ -92,6 +92,8 @@ MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], floa
MINLINE void madd_v3_v3v3v3(float r[3], const float a[3], const float b[3], const float c[3]);
MINLINE void madd_v4_v4fl(float r[4], const float a[4], float f);
MINLINE void negate_v2(float r[2]);
MINLINE void negate_v2_v2(float r[2], const float a[2]);
MINLINE void negate_v3(float r[3]);
MINLINE void negate_v3_v3(float r[3], const float a[3]);
MINLINE void negate_v4(float r[4]);

@ -308,6 +308,18 @@ MINLINE void mul_v3_v3v3(float r[3], const float v1[3], const float v2[3])
r[2] = v1[2] * v2[2];
}
MINLINE void negate_v2(float r[3])
{
r[0]= -r[0];
r[1]= -r[1];
}
MINLINE void negate_v2_v2(float r[2], const float a[2])
{
r[0]= -a[0];
r[1]= -a[1];
}
MINLINE void negate_v3(float r[3])
{
r[0]= -r[0];

@ -1437,8 +1437,11 @@ static void ui_textedit_set_cursor_select(uiBut *but, uiHandleButtonData *data,
ui_check_but(but);
}
/* note: utf8 & ascii funcs should be merged */
static int ui_textedit_type_utf8(uiBut *but, uiHandleButtonData *data, const char utf8_buf[6])
/* this is used for both utf8 and ascii, its meant to be used for single keys,
* notie the buffer is either copied or not, so its not suitable for pasting in
* - campbell */
static int ui_textedit_type_buf(uiBut *but, uiHandleButtonData *data,
const char *utf8_buf, int utf8_buf_len)
{
char *str;
int len, changed= 0;
@ -1447,7 +1450,7 @@ static int ui_textedit_type_utf8(uiBut *but, uiHandleButtonData *data, const cha
len= strlen(str);
if(len-(but->selend - but->selsta)+1 <= data->maxlen) {
int step= BLI_str_utf8_size(utf8_buf);
int step= utf8_buf_len;
/* type over the current selection */
if ((but->selend - but->selsta) > 0) {
@ -1468,8 +1471,17 @@ static int ui_textedit_type_utf8(uiBut *but, uiHandleButtonData *data, const cha
static int ui_textedit_type_ascii(uiBut *but, uiHandleButtonData *data, char ascii)
{
char utf8_buf[6]= {ascii, '\0'};
return ui_textedit_type_utf8(but, data, utf8_buf);
char buf[2]= {ascii, '\0'};
if (ui_is_but_utf8(but) && (BLI_str_utf8_size(buf) == -1)) {
printf("%s: entering invalid ascii char into an ascii key (%d)\n",
__func__, (int)(unsigned char)ascii);
return 0;
}
/* in some cases we want to allow invalid utf8 chars */
return ui_textedit_type_buf(but, data, buf, 1);
}
static void ui_textedit_move(uiBut *but, uiHandleButtonData *data, int direction, int select, uiButtonJumpType jump)
@ -1941,9 +1953,9 @@ static void ui_do_but_textedit(bContext *C, uiBlock *block, uiBut *but, uiHandle
if(event->utf8_buf[0]) {
/* keep this printf until utf8 is well tested */
printf("%s: utf8 char '%s'\n", __func__, event->utf8_buf);
printf("%s: utf8 char '%.*s'\n", __func__, BLI_str_utf8_size(event->utf8_buf), event->utf8_buf);
// strcpy(event->utf8_buf, "12345");
changed= ui_textedit_type_utf8(but, data, event->utf8_buf);
changed= ui_textedit_type_buf(but, data, event->utf8_buf, BLI_str_utf8_size(event->utf8_buf));
}
else {
changed= ui_textedit_type_ascii(but, data, ascii);

@ -261,7 +261,7 @@ static void get_keyframe_extents (bAnimContext *ac, float *min, float *max, cons
float tmin, tmax;
/* get range and apply necessary scaling before processing */
calc_fcurve_range(fcu, &tmin, &tmax, onlySel);
calc_fcurve_range(fcu, &tmin, &tmax, onlySel, TRUE);
if (adt) {
tmin= BKE_nla_tweakedit_remap(adt, tmin, NLATIME_CONVERT_MAP);

@ -310,11 +310,19 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
}
/* Check the library target exists */
if (te->idcode == ID_LI) {
char expanded[FILE_MAXDIR + FILE_MAXFILE];
BLI_strncpy(expanded, ((Library *)tselem->id)->name, FILE_MAXDIR + FILE_MAXFILE);
Library *lib= (Library *)tselem->id;
char expanded[FILE_MAX];
BLI_strncpy(expanded, lib->name, sizeof(expanded));
/* even though we already set the name this syncs the absolute
* path, this is intentionally not already expanded yet to
* avoid copying lib->name to its self. */
BKE_library_filepath_set(lib, expanded);
BLI_path_abs(expanded, G.main->name);
if (!BLI_exists(expanded)) {
BKE_report(CTX_wm_reports(C), RPT_ERROR, "This path does not exist, correct this before saving");
BKE_reportf(CTX_wm_reports(C), RPT_ERROR, "Library path '%s' does not exist, correct this before saving", expanded);
}
}
}

@ -161,17 +161,6 @@ void view3d_keymap(wmKeyConfig *keyconf)
RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", HOMEKEY, KM_PRESS, 0, 0)->ptr, "center", 0); /* only without camera view */
RNA_boolean_set(WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", CKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "center", 1);
/* 3D mouse */
WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_orbit", NDOF_MOTION, 0, 0, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_pan", NDOF_MOTION, 0, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_view_selected", NDOF_BUTTON_FIT, KM_PRESS, 0, 0);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_FRONT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_FRONT);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_BACK, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_BACK);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_LEFT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_LEFT);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_RIGHT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_RIGHT);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_TOP, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_TOP);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_BOTTOM, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_BOTTOM);
/* numpad view hotkeys*/
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD0, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_CAMERA);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD1, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_FRONT);
@ -220,6 +209,17 @@ void view3d_keymap(wmKeyConfig *keyconf)
kmi= WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", PAD7, KM_PRESS, KM_SHIFT|KM_CTRL, 0);
RNA_enum_set(kmi->ptr, "type", RV3D_VIEW_BOTTOM);
RNA_boolean_set(kmi->ptr, "align_active", TRUE);
/* 3D mouse */
WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_orbit", NDOF_MOTION, 0, 0, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_ndof_pan", NDOF_MOTION, 0, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "VIEW3D_OT_view_selected", NDOF_BUTTON_FIT, KM_PRESS, 0, 0);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_FRONT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_FRONT);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_BACK, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_BACK);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_LEFT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_LEFT);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_RIGHT, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_RIGHT);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_TOP, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_TOP);
RNA_enum_set(WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_BOTTOM, KM_PRESS, 0, 0)->ptr, "type", RV3D_VIEW_BOTTOM);
/* 3D mouse align */
kmi= WM_keymap_add_item(keymap, "VIEW3D_OT_viewnumpad", NDOF_BUTTON_FRONT, KM_PRESS, KM_SHIFT, 0);

@ -61,6 +61,7 @@ set(SRC
intern/md5.c
intern/metadata.c
intern/module.c
intern/moviecache.c
intern/openimageio.cpp
intern/png.c
intern/readimage.c
@ -75,6 +76,7 @@ set(SRC
IMB_imbuf.h
IMB_imbuf_types.h
IMB_moviecache.h
IMB_thumbs.h
intern/IMB_allocimbuf.h
intern/IMB_anim.h

@ -133,19 +133,6 @@ struct ImBuf *IMB_allocImBuf(unsigned int x, unsigned int y,
void IMB_refImBuf(struct ImBuf *ibuf);
struct ImBuf * IMB_makeSingleUser(struct ImBuf *ibuf);
/**
*
* @attention Defined in allocimbuf.c
*/
void IMB_cache_limiter_insert(struct ImBuf *i);
void IMB_cache_limiter_unmanage(struct ImBuf *i);
void IMB_cache_limiter_touch(struct ImBuf *i);
void IMB_cache_limiter_ref(struct ImBuf *i);
void IMB_cache_limiter_unref(struct ImBuf *i);
int IMB_cache_limiter_get_refcount(struct ImBuf *i);
void IMB_free_cache_limiter(void);
/**
*
* @attention Defined in allocimbuf.c

@ -0,0 +1,56 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2011 Blender Foundation.
* All rights reserved.
*
* Contributor(s): Blender Foundation,
* Sergey Sharybin
*
* ***** END GPL LICENSE BLOCK *****
*/
#ifndef IMB_MOVIECACHE_H
#define IMB_MOVIECACHE_H
/** \file IMB_moviecache.h
* \ingroup imbuf
* \author Sergey Sharybin
*/
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
/* Cache system for movie data - now supports stoting ImBufs only
Supposed to provide unified cache system for movie clips, sequencer and
other movie-related areas */
struct ImBuf;
struct MovieCache;
typedef void (*MovieCacheGetKeyDataFP) (void *userkey, int *framenr, int *proxy, int *render_flags);
void IMB_moviecache_init(void);
void IMB_moviecache_destruct(void);
struct MovieCache *IMB_moviecache_create(int keysize, GHashHashFP hashfp, GHashCmpFP cmpfp, MovieCacheGetKeyDataFP getdatafp);
void IMB_moviecache_put(struct MovieCache *cache, void *userkey, struct ImBuf *ibuf);
struct ImBuf* IMB_moviecache_get(struct MovieCache *cache, void *userkey);
void IMB_moviecache_free(struct MovieCache *cache);
void IMB_moviecache_get_cache_segments(struct MovieCache *cache, int proxy, int render_flags, int *totseg_r, int **points_r);
#endif

@ -164,7 +164,6 @@ void IMB_freeImBuf(ImBuf *ibuf)
IMB_freezbufImBuf(ibuf);
IMB_freezbuffloatImBuf(ibuf);
freeencodedbufferImBuf(ibuf);
IMB_cache_limiter_unmanage(ibuf);
IMB_metadata_free(ibuf);
MEM_freeN(ibuf);
}
@ -467,60 +466,7 @@ static MEM_CacheLimiterC **get_imbuf_cache_limiter(void)
static MEM_CacheLimiterC *c = NULL;
if(!c)
c = new_MEM_CacheLimiter(imbuf_cache_destructor);
c = new_MEM_CacheLimiter(imbuf_cache_destructor, NULL);
return &c;
}
void IMB_free_cache_limiter(void)
{
delete_MEM_CacheLimiter(*get_imbuf_cache_limiter());
*get_imbuf_cache_limiter() = NULL;
}
void IMB_cache_limiter_insert(ImBuf *i)
{
if(!i->c_handle) {
i->c_handle = MEM_CacheLimiter_insert(
*get_imbuf_cache_limiter(), i);
MEM_CacheLimiter_ref(i->c_handle);
MEM_CacheLimiter_enforce_limits(
*get_imbuf_cache_limiter());
MEM_CacheLimiter_unref(i->c_handle);
}
}
void IMB_cache_limiter_unmanage(ImBuf *i)
{
if(i->c_handle) {
MEM_CacheLimiter_unmanage(i->c_handle);
i->c_handle = NULL;
}
}
void IMB_cache_limiter_touch(ImBuf *i)
{
if(i->c_handle)
MEM_CacheLimiter_touch(i->c_handle);
}
void IMB_cache_limiter_ref(ImBuf *i)
{
if(i->c_handle)
MEM_CacheLimiter_ref(i->c_handle);
}
void IMB_cache_limiter_unref(ImBuf *i)
{
if(i->c_handle)
MEM_CacheLimiter_unref(i->c_handle);
}
int IMB_cache_limiter_get_refcount(ImBuf *i)
{
if(i->c_handle)
return MEM_CacheLimiter_get_refcount(i->c_handle);
return 0;
}

@ -452,7 +452,7 @@ static int round_up(int x, int mod)
static struct proxy_output_ctx * alloc_proxy_output_ffmpeg(
struct anim * anim,
AVStream * st, int proxy_size, int width, int height,
int quality)
int UNUSED(quality))
{
struct proxy_output_ctx * rv = MEM_callocN(
sizeof(struct proxy_output_ctx), "alloc_proxy_output");

@ -37,7 +37,6 @@ void IMB_init(void)
void IMB_exit(void)
{
IMB_free_cache_limiter();
imb_tile_cache_exit();
imb_filetypes_exit();
}

@ -0,0 +1,382 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2011 Blender Foundation.
* All rights reserved.
*
* Contributor(s): Blender Foundation,
* Sergey Sharybin,
* Peter Schlaile
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/blenkernel/intern/moviecache.c
* \ingroup bke
*/
#include <stdlib.h> /* for qsort */
#include <memory.h>
#include "MEM_guardedalloc.h"
#include "MEM_CacheLimiterC-Api.h"
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
#include "BLI_mempool.h"
#include "IMB_moviecache.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
static MEM_CacheLimiterC *limitor= NULL;
typedef struct MovieCache {
GHash *hash;
GHashHashFP hashfp;
GHashCmpFP cmpfp;
MovieCacheGetKeyDataFP getdatafp;
struct BLI_mempool *keys_pool;
struct BLI_mempool *items_pool;
struct BLI_mempool *userkeys_pool;
int keysize;
unsigned long curtime;
int totseg, *points, proxy, render_flags; /* for visual statistics optimization */
int pad;
} MovieCache;
typedef struct MovieCacheKey {
MovieCache *cache_owner;
void *userkey;
} MovieCacheKey;
typedef struct MovieCacheItem {
MovieCache *cache_owner;
ImBuf *ibuf;
MEM_CacheLimiterHandleC * c_handle;
unsigned long last_access;
} MovieCacheItem;
static unsigned int moviecache_hashhash(const void *keyv)
{
MovieCacheKey *key= (MovieCacheKey*)keyv;
return key->cache_owner->hashfp(key->userkey);
}
static int moviecache_hashcmp(const void *av, const void *bv)
{
const MovieCacheKey *a= (MovieCacheKey*)av;
const MovieCacheKey *b= (MovieCacheKey*)bv;
return a->cache_owner->cmpfp(a->userkey, b->userkey);
}
static void moviecache_keyfree(void *val)
{
MovieCacheKey *key= (MovieCacheKey*)val;
BLI_mempool_free(key->cache_owner->keys_pool, key);
}
static void moviecache_valfree(void *val)
{
MovieCacheItem *item= (MovieCacheItem*)val;
if (item->ibuf) {
MEM_CacheLimiter_unmanage(item->c_handle);
IMB_freeImBuf(item->ibuf);
}
BLI_mempool_free(item->cache_owner->items_pool, item);
}
static void check_unused_keys(MovieCache *cache)
{
GHashIterator *iter;
iter= BLI_ghashIterator_new(cache->hash);
while(!BLI_ghashIterator_isDone(iter)) {
MovieCacheKey *key= BLI_ghashIterator_getKey(iter);
MovieCacheItem *item= BLI_ghashIterator_getValue(iter);
BLI_ghashIterator_step(iter);
if(!item->ibuf)
BLI_ghash_remove(cache->hash, key, moviecache_keyfree, moviecache_valfree);
}
BLI_ghashIterator_free(iter);
}
static int compare_int(const void *av, const void *bv)
{
const int *a= (int *)av;
const int *b= (int *)bv;
return *a-*b;
}
static void IMB_moviecache_destructor(void *p)
{
MovieCacheItem *item= (MovieCacheItem *) p;
if (item && item->ibuf) {
IMB_freeImBuf(item->ibuf);
item->ibuf= NULL;
item->c_handle= NULL;
}
}
/* approximate size of ImBuf in memory */
static intptr_t IMB_get_size_in_memory(ImBuf *ibuf)
{
int a;
intptr_t size= 0, channel_size= 0;
size+= sizeof(ImBuf);
if(ibuf->rect)
channel_size+= sizeof(char);
if(ibuf->rect_float)
channel_size+= sizeof(float);
size+= channel_size*ibuf->x*ibuf->y*ibuf->channels;
if(ibuf->miptot) {
for(a= 0; a<ibuf->miptot; a++) {
if(ibuf->mipmap[a])
size+= IMB_get_size_in_memory(ibuf->mipmap[a]);
}
}
if(ibuf->tiles) {
size+= sizeof(unsigned int)*ibuf->ytiles*ibuf->xtiles;
}
return size;
}
static intptr_t get_item_size (void *p)
{
intptr_t size= sizeof(MovieCacheItem);
MovieCacheItem *item= (MovieCacheItem *) p;
if(item->ibuf)
size+= IMB_get_size_in_memory(item->ibuf);
return size;
}
void IMB_moviecache_init(void)
{
limitor= new_MEM_CacheLimiter(IMB_moviecache_destructor, get_item_size);
}
void IMB_moviecache_destruct(void)
{
if(limitor)
delete_MEM_CacheLimiter(limitor);
}
struct MovieCache *IMB_moviecache_create(int keysize, GHashHashFP hashfp, GHashCmpFP cmpfp,
MovieCacheGetKeyDataFP getdatafp)
{
MovieCache *cache;
cache= MEM_callocN(sizeof(MovieCache), "MovieCache");
cache->keys_pool= BLI_mempool_create(sizeof(MovieCacheKey), 64, 64, 0);
cache->items_pool= BLI_mempool_create(sizeof(MovieCacheItem), 64, 64, 0);
cache->userkeys_pool= BLI_mempool_create(keysize, 64, 64, 0);
cache->hash= BLI_ghash_new(moviecache_hashhash, moviecache_hashcmp, "MovieClip ImBuf cache hash");
cache->keysize= keysize;
cache->hashfp= hashfp;
cache->cmpfp= cmpfp;
cache->getdatafp= getdatafp;
cache->proxy= -1;
return cache;
}
void IMB_moviecache_put(MovieCache *cache, void *userkey, ImBuf *ibuf)
{
MovieCacheKey *key;
MovieCacheItem *item;
if(!limitor)
IMB_moviecache_init();
IMB_refImBuf(ibuf);
key= BLI_mempool_alloc(cache->keys_pool);
key->cache_owner= cache;
key->userkey= BLI_mempool_alloc(cache->userkeys_pool);;
memcpy(key->userkey, userkey, cache->keysize);
item= BLI_mempool_alloc(cache->items_pool);
item->ibuf= ibuf;
item->cache_owner= cache;
item->last_access= cache->curtime++;
item->c_handle= NULL;
BLI_ghash_remove(cache->hash, key, moviecache_keyfree, moviecache_valfree);
BLI_ghash_insert(cache->hash, key, item);
item->c_handle= MEM_CacheLimiter_insert(limitor, item);
MEM_CacheLimiter_ref(item->c_handle);
MEM_CacheLimiter_enforce_limits(limitor);
MEM_CacheLimiter_unref(item->c_handle);
/* cache limiter can't remove unused keys which points to destoryed values */
check_unused_keys(cache);
if(cache->points) {
MEM_freeN(cache->points);
cache->points= NULL;
}
}
ImBuf* IMB_moviecache_get(MovieCache *cache, void *userkey)
{
MovieCacheKey key;
MovieCacheItem *item;
key.cache_owner= cache;
key.userkey= userkey;
item= (MovieCacheItem*)BLI_ghash_lookup(cache->hash, &key);
if(item) {
item->last_access= cache->curtime++;
if(item->ibuf) {
MEM_CacheLimiter_touch(item->c_handle);
IMB_refImBuf(item->ibuf);
return item->ibuf;
}
}
return NULL;
}
void IMB_moviecache_free(MovieCache *cache)
{
BLI_ghash_free(cache->hash, moviecache_keyfree, moviecache_valfree);
BLI_mempool_destroy(cache->keys_pool);
BLI_mempool_destroy(cache->items_pool);
BLI_mempool_destroy(cache->userkeys_pool);
if(cache->points)
MEM_freeN(cache->points);
MEM_freeN(cache);
}
/* get segments of cached frames. useful for debugging cache policies */
void IMB_moviecache_get_cache_segments(MovieCache *cache, int proxy, int render_flags, int *totseg_r, int **points_r)
{
*totseg_r= 0;
*points_r= NULL;
if(!cache->getdatafp)
return;
if(cache->proxy!=proxy || cache->render_flags!=render_flags) {
if(cache->points)
MEM_freeN(cache->points);
cache->points= NULL;
}
if(cache->points) {
*totseg_r= cache->totseg;
*points_r= cache->points;
} else {
int totframe= BLI_ghash_size(cache->hash);
int *frames= MEM_callocN(totframe*sizeof(int), "movieclip cache frames");
int a, totseg= 0;
GHashIterator *iter;
iter= BLI_ghashIterator_new(cache->hash);
a= 0;
while(!BLI_ghashIterator_isDone(iter)) {
MovieCacheKey *key= BLI_ghashIterator_getKey(iter);
MovieCacheItem *item= BLI_ghashIterator_getValue(iter);
int framenr, curproxy, curflags;
if(item->ibuf) {
cache->getdatafp(key->userkey, &framenr, &curproxy, &curflags);
if(curproxy==proxy && curflags==render_flags)
frames[a++]= framenr;
}
BLI_ghashIterator_step(iter);
}
BLI_ghashIterator_free(iter);
qsort(frames, totframe, sizeof(int), compare_int);
/* count */
for(a= 0; a<totframe; a++) {
if(a && frames[a]-frames[a-1]!=1)
totseg++;
if(a==totframe-1)
totseg++;
}
if(totseg) {
int b, *points;
points= MEM_callocN(2*sizeof(int)*totseg, "movieclip cache segments");
/* fill */
for(a= 0, b= 0; a<totframe; a++) {
if(a==0)
points[b++]= frames[a];
if(a && frames[a]-frames[a-1]!=1) {
points[b++]= frames[a-1];
points[b++]= frames[a];
}
if(a==totframe-1)
points[b++]= frames[a];
}
*totseg_r= totseg;
*points_r= points;
cache->totseg= totseg;
cache->points= points;
cache->proxy= proxy;
cache->render_flags= render_flags;
}
MEM_freeN(frames);
}
}

@ -116,7 +116,13 @@ typedef struct Library {
ID *idblock;
struct FileData *filedata;
char name[240]; /* path name used for reading, can be relative and edited in the outliner */
char filepath[240]; /* temp. absolute filepath, only used while reading */
char filepath[240]; /* absolute filepath, this is only for convenience,
* 'name' is the real path used on file read but in
* some cases its useful to access the absolute one,
* This is set on file read.
* Use BKE_library_filepath_set() rather than
* setting 'name' directly and it will be kepk in
* sync - campbell */
int tot, pad; /* tot, idblock and filedata are only fo read and write */
struct Library *parent; /* set for indirectly linked libs, used in the outliner and while reading */
} Library;

@ -326,6 +326,12 @@ int rna_IDMaterials_assign_int(PointerRNA *ptr, int key, const PointerRNA *assig
}
}
void rna_Library_filepath_set(PointerRNA *ptr, const char *value)
{
Library *lib= (Library*)ptr->data;
BKE_library_filepath_set(lib, value);
}
#else
static void rna_def_ID_properties(BlenderRNA *brna)
@ -531,7 +537,7 @@ static void rna_def_library(BlenderRNA *brna)
prop= RNA_def_property(srna, "filepath", PROP_STRING, PROP_FILEPATH);
RNA_def_property_string_sdna(prop, NULL, "name");
RNA_def_property_ui_text(prop, "File Path", "Path to the library .blend file");
/* TODO - lib->filename isnt updated, however the outliner also skips this, probably only needed on read. */
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_Library_filepath_set");
prop= RNA_def_property(srna, "parent", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "Library");

@ -621,7 +621,7 @@ static void rna_FKeyframe_points_remove(FCurve *fcu, ReportList *reports, BezTri
static void rna_fcurve_range(FCurve *fcu, float range[2])
{
calc_fcurve_range(fcu, range, range+1, FALSE);
calc_fcurve_range(fcu, range, range+1, FALSE, FALSE);
}
#else

@ -3345,9 +3345,7 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
mul_m4_v3(mat, ver->co);
mul_transposed_m3_v3(imat, ver->n);
normalize_v3(ver->n);
if(!negative_scale)
negate_v3(ver->n);
negate_v3(ver->n);
}
if(orco) {
@ -3405,10 +3403,11 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
if( mface->mat_nr==a1 ) {
float len;
v1= mface->v1;
int reverse_verts = negative_scale!=0 && do_autosmooth==0;
int rev_tab[] = {reverse_verts==0 ? 0 : 2, 1, reverse_verts==0 ? 2 : 0, 3};
v1= reverse_verts==0 ? mface->v1 : mface->v3;
v2= mface->v2;
v3= mface->v3;
v3= reverse_verts==0 ? mface->v3 : mface->v1;
v4= mface->v4;
flag= mface->flag & ME_SMOOTH;
@ -3445,36 +3444,40 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
CustomDataLayer *layer;
MTFace *mtface, *mtf;
MCol *mcol, *mc;
int index, mtfn= 0, mcn= 0, mtng=0;
int index, mtfn= 0, mcn= 0, mtng=0, vindex;
char *name;
int nr_verts = v4!=0 ? 4 : 3;
for(index=0; index<dm->faceData.totlayer; index++) {
layer= &dm->faceData.layers[index];
name= layer->name;
if(layer->type == CD_MTFACE && mtfn < MAX_MTFACE) {
int t;
mtf= RE_vlakren_get_tface(obr, vlr, mtfn++, &name, 1);
mtface= (MTFace*)layer->data;
*mtf= mtface[a];
*mtf= mtface[a]; // copy face info
for(vindex=0; vindex<nr_verts; vindex++)
for(t=0; t<2; t++)
mtf->uv[vindex][t]=mtface[a].uv[rev_tab[vindex]][t];
}
else if(layer->type == CD_MCOL && mcn < MAX_MCOL) {
mc= RE_vlakren_get_mcol(obr, vlr, mcn++, &name, 1);
mcol= (MCol*)layer->data;
memcpy(mc, &mcol[a*4], sizeof(MCol)*4);
for(vindex=0; vindex<nr_verts; vindex++)
mc[vindex]=mcol[a*4+rev_tab[vindex]];
}
else if(layer->type == CD_TANGENT && mtng < 1)
{
if(need_nmap_tangent!=0)
{
const float * tangent = (const float *) layer->data;
int t;
int nr_verts = v4!=0 ? 4 : 3;
float * ftang = RE_vlakren_get_nmap_tangent(obr, vlr, 1);
for(t=0; t<nr_verts; t++)
for(vindex=0; vindex<nr_verts; vindex++)
{
QUATCOPY(ftang+t*4, tangent+a*16+t*4);
mul_mat3_m4_v3(mat, ftang+t*4);
normalize_v3(ftang+t*4);
QUATCOPY(ftang+vindex*4, tangent+a*16+rev_tab[vindex]*4);
mul_mat3_m4_v3(mat, ftang+vindex*4);
normalize_v3(ftang+vindex*4);
}
}
}

@ -158,6 +158,8 @@ void BL_ActionActuator::SetLocalTime(float curtime)
m_starttime = curtime;
m_flag ^= ACT_FLAG_REVERSE;
break;
}
}
@ -206,9 +208,8 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
if (m_flag & ACT_FLAG_REVERSE)
{
m_localtime = start;
start = end;
end = m_localtime;
start = m_endframe;
end = m_startframe;
}
break;
@ -236,6 +237,12 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
RemoveAllEvents();
}
if (bUseContinue && (m_flag & ACT_FLAG_ACTIVE))
{
m_localtime = obj->GetActionFrame(m_layer);
ResetStartTime(curtime);
}
if (m_flag & ACT_FLAG_ATTEMPT_PLAY)
SetLocalTime(curtime);
@ -257,6 +264,9 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
{
m_flag &= ~ACT_FLAG_ACTIVE;
m_flag &= ~ACT_FLAG_ATTEMPT_PLAY;
if (m_playtype == ACT_ACTION_PINGPONG)
m_flag ^= ACT_FLAG_REVERSE;
return false;
}
@ -266,7 +276,7 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
if (bPositiveEvent || (m_flag & ACT_FLAG_ATTEMPT_PLAY && !(m_flag & ACT_FLAG_ACTIVE)))
{
if (bPositiveEvent)
if (bPositiveEvent && m_playtype == ACT_ACTION_PLAY)
{
if (obj->IsActionDone(m_layer))
m_localtime = start;
@ -279,7 +289,7 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
if (bUseContinue)
obj->SetActionFrame(m_layer, m_localtime);
if (m_playtype == ACT_ACTION_PLAY)
if (m_playtype == ACT_ACTION_PLAY || m_playtype == ACT_ACTION_PINGPONG)
m_flag |= ACT_FLAG_PLAY_END;
else
m_flag &= ~ACT_FLAG_PLAY_END;
@ -307,9 +317,6 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
// We're done
m_flag &= ~ACT_FLAG_ACTIVE;
return false;
case ACT_ACTION_PINGPONG:
m_flag ^= ACT_FLAG_REVERSE;
// Now fallthrough to LOOP_END code
case ACT_ACTION_LOOP_END:
// Convert into a play and let it finish
obj->SetPlayMode(m_layer, BL_Action::ACT_MODE_PLAY);
@ -327,12 +334,6 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
break;
}
}
if (bUseContinue && (m_flag & ACT_FLAG_ACTIVE))
{
m_localtime = obj->GetActionFrame(m_layer);
ResetStartTime(curtime);
}
return true;
}

@ -279,7 +279,7 @@ void BL_Action::SetLocalTime(float curtime)
void BL_Action::ResetStartTime(float curtime)
{
float dt = m_localtime - m_startframe;
float dt = (m_localtime > m_startframe) ? m_localtime - m_startframe : m_startframe - m_localtime;
m_starttime = curtime - dt / (KX_KetsjiEngine::GetAnimFrameRate()*m_speed);
SetLocalTime(curtime);