diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2011-10-25 02:51:44 +0400 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2011-10-25 02:51:44 +0400 |
commit | 47463742e264d5bfbf81215ea7d907c4e9a3a1e1 (patch) | |
tree | bab7eea6ec1903c5922d3d9dcea9c99a4b1cc42e /source/blender | |
parent | 4cd1e6337e516015383f3c47886b180ee16d2e3a (diff) | |
parent | 5b6224c84719213883334bcd9d2c46216053fe35 (diff) |
Cycles: svn merge -r41232:41266 ^/trunk/blender
Diffstat (limited to 'source/blender')
27 files changed, 651 insertions, 286 deletions
diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h index b5e4cde53ca..27e9140ba77 100644 --- a/source/blender/blenkernel/BKE_fcurve.h +++ b/source/blender/blenkernel/BKE_fcurve.h @@ -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); /* .............. */ diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h index a44618dcbe8..947eafa9dd3 100644 --- a/source/blender/blenkernel/BKE_library.h +++ b/source/blender/blenkernel/BKE_library.h @@ -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); diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h index 759060d408e..e64de965db5 100644 --- a/source/blender/blenkernel/BKE_sequencer.h +++ b/source/blender/blenkernel/BKE_sequencer.h @@ -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 */ diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c index 8d18a1c27e7..e46e2df8353 100644 --- a/source/blender/blenkernel/intern/action.c +++ b/source/blender/blenkernel/intern/action.c @@ -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); diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 5e38e06ed0c..4cbdbeb890d 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -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(); } diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index 737baa1ddc4..3529b7b9e6d 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -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 -------------------------- */ diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 6cde2511a47..c44ccd7aa57 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -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); + } +} diff --git a/source/blender/blenkernel/intern/seqcache.c b/source/blender/blenkernel/intern/seqcache.c index 31a780aa977..c5761dcc456 100644 --- a/source/blender/blenkernel/intern/seqcache.c +++ b/source/blender/blenkernel/intern/seqcache.c @@ -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 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 struct MovieCache *moviecache = NULL; + +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 (!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(moviecache && seq) { + seqCacheKey key; - if (e && e->ibuf) { - IMB_refImBuf(e->ibuf); + key.seq = seq; + key.context = context; + key.cfra = cfra - seq->start; + key.type = type; - MEM_CacheLimiter_touch(e->c_handle); - return e->ibuf; + return IMB_moviecache_get(moviecache, &key); } + 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; - - 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); + key.seq = seq; + key.context = context; + key.cfra = cfra - seq->start; + key.type = type; - MEM_CacheLimiter_ref(e->c_handle); - MEM_CacheLimiter_enforce_limits(limitor); - MEM_CacheLimiter_unref(e->c_handle); + IMB_moviecache_put(moviecache, &key, i); } diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 5d52874b3b3..6b319e6b5e1 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -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); } diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c index ed0a351716c..bdca3c8e618 100644 --- a/source/blender/blenkernel/intern/writeffmpeg.c +++ b/source/blender/blenkernel/intern/writeffmpeg.c @@ -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; diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h index 2bb51870fd6..e259071a27a 100644 --- a/source/blender/blenlib/BLI_math_vector.h +++ b/source/blender/blenlib/BLI_math_vector.h @@ -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]); diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c index 5f5a0acc427..c460b69679b 100644 --- a/source/blender/blenlib/intern/math_vector_inline.c +++ b/source/blender/blenlib/intern/math_vector_inline.c @@ -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]; diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 9f77317292c..9d8e2f33f5c 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -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); diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index 7bf0f98b471..eb29dfb2ce1 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -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); diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index 10ca482ae0e..608a3c4c0b2 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -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); } } } diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index 5df61619ece..6e26fb15873 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -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); diff --git a/source/blender/imbuf/CMakeLists.txt b/source/blender/imbuf/CMakeLists.txt index 76c69292b0f..6aef9a4254e 100644 --- a/source/blender/imbuf/CMakeLists.txt +++ b/source/blender/imbuf/CMakeLists.txt @@ -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 diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h index e57130c7c35..5f03ca9ba28 100644 --- a/source/blender/imbuf/IMB_imbuf.h +++ b/source/blender/imbuf/IMB_imbuf.h @@ -137,19 +137,6 @@ 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 - */ struct ImBuf *IMB_dupImBuf(struct ImBuf *ibuf1); /** diff --git a/source/blender/imbuf/IMB_moviecache.h b/source/blender/imbuf/IMB_moviecache.h new file mode 100644 index 00000000000..309c6ee550e --- /dev/null +++ b/source/blender/imbuf/IMB_moviecache.h @@ -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 diff --git a/source/blender/imbuf/intern/allocimbuf.c b/source/blender/imbuf/intern/allocimbuf.c index 077d907dda0..98828c58511 100644 --- a/source/blender/imbuf/intern/allocimbuf.c +++ b/source/blender/imbuf/intern/allocimbuf.c @@ -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; -} - diff --git a/source/blender/imbuf/intern/indexer.c b/source/blender/imbuf/intern/indexer.c index 242d7dcb700..3a94c79f48d 100644 --- a/source/blender/imbuf/intern/indexer.c +++ b/source/blender/imbuf/intern/indexer.c @@ -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"); diff --git a/source/blender/imbuf/intern/module.c b/source/blender/imbuf/intern/module.c index f787a6c777e..55a29333620 100644 --- a/source/blender/imbuf/intern/module.c +++ b/source/blender/imbuf/intern/module.c @@ -37,7 +37,6 @@ void IMB_init(void) void IMB_exit(void) { - IMB_free_cache_limiter(); imb_tile_cache_exit(); imb_filetypes_exit(); } diff --git a/source/blender/imbuf/intern/moviecache.c b/source/blender/imbuf/intern/moviecache.c new file mode 100644 index 00000000000..7492b6aec44 --- /dev/null +++ b/source/blender/imbuf/intern/moviecache.c @@ -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); + } +} diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index 48ad8a0c017..6f2933d154b 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -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; diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index 71b34d31e96..ba7d2881ad8 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -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"); diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c index 08a71e0cd4f..c651dca4b31 100644 --- a/source/blender/makesrna/intern/rna_fcurve.c +++ b/source/blender/makesrna/intern/rna_fcurve.c @@ -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 diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index 369272e0be6..5968a6e64f8 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -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); } } } |