From 2d50e5feaaaf9fa6e73aa2b1d62921265c77d041 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 15 Oct 2014 09:23:43 +0200 Subject: Fix T42226: Glibc <= 2.8 fails to build --- source/blender/blenlib/BLI_sort.h | 3 ++- source/blender/blenlib/intern/sort.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_sort.h b/source/blender/blenlib/BLI_sort.h index 516f917a351..cb6b87bda38 100644 --- a/source/blender/blenlib/BLI_sort.h +++ b/source/blender/blenlib/BLI_sort.h @@ -35,7 +35,8 @@ #include -#ifdef __GLIBC__ +/* glibc 2.8+ */ +#if defined(__GLIBC__) && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8)) # define BLI_qsort_r qsort_r #endif diff --git a/source/blender/blenlib/intern/sort.c b/source/blender/blenlib/intern/sort.c index 9fad7505f79..d7c314c95e3 100644 --- a/source/blender/blenlib/intern/sort.c +++ b/source/blender/blenlib/intern/sort.c @@ -32,7 +32,7 @@ #include -#ifndef __GLIBC__ +#if defined(__GLIBC__) && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8)) #include "BLI_utildefines.h" -- cgit v1.2.3 From 858e7b2f84287360c1d82a381c023569a43cb57f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 15 Oct 2014 10:10:05 +0200 Subject: Correct last commit --- source/blender/blenlib/intern/sort.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/intern/sort.c b/source/blender/blenlib/intern/sort.c index d7c314c95e3..c5922feb0ed 100644 --- a/source/blender/blenlib/intern/sort.c +++ b/source/blender/blenlib/intern/sort.c @@ -33,6 +33,8 @@ #include #if defined(__GLIBC__) && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8)) +/* do nothing! */ +#else #include "BLI_utildefines.h" -- cgit v1.2.3 From be4b2e42c627a7631c9f02866806bd1702554255 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Tue, 21 Oct 2014 11:56:46 +0200 Subject: BLI_listbase: add `BLI_swaplinks` which swaps given links' positions in given list. Can be much simpler and quicker than using remlink/insert functions. --- source/blender/blenlib/BLI_listbase.h | 2 ++ source/blender/blenlib/intern/listbase.c | 38 ++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h index fb388977ddf..fec05221596 100644 --- a/source/blender/blenlib/BLI_listbase.h +++ b/source/blender/blenlib/BLI_listbase.h @@ -73,6 +73,8 @@ void BLI_freelist(struct ListBase *listbase) ATTR_NONNULL(1); int BLI_countlist(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1); +void BLI_swaplinks(struct ListBase *listbase, void *vlinka, void *vlinkb) ATTR_NONNULL(1, 2); + void BLI_movelisttolist(struct ListBase *dst, struct ListBase *src) ATTR_NONNULL(1, 2); void BLI_duplicatelist(struct ListBase *dst, const struct ListBase *src) ATTR_NONNULL(1, 2); void BLI_listbase_reverse(struct ListBase *lb) ATTR_NONNULL(1); diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c index d9cf8971246..6d61a046094 100644 --- a/source/blender/blenlib/intern/listbase.c +++ b/source/blender/blenlib/intern/listbase.c @@ -129,6 +129,44 @@ bool BLI_remlink_safe(ListBase *listbase, void *vlink) } } +/** + * Swaps \a vlinka and \a vlinkb in the list. Assumes they are both already in the list! + */ +void BLI_swaplinks(ListBase *listbase, void *vlinka, void *vlinkb) +{ + Link *linka = vlinka; + Link *linkb = vlinkb; + + if (!linka || !linkb) + return; + + if (linkb->next == linka) { + SWAP(Link *, linka, linkb); + } + + if (linka->next == linkb) { + linka->next = linkb->next; + linkb->prev = linka->prev; + linka->prev = linkb; + linkb->next = linka; + } + else { /* Non-contiguous items, we can safely swap. */ + SWAP(Link *, linka->prev, linkb->prev); + SWAP(Link *, linka->next, linkb->next); + } + + /* Update neighbors of linka and linkb. */ + if (linka->prev) linka->prev->next = linka; + if (linka->next) linka->next->prev = linka; + if (linkb->prev) linkb->prev->next = linkb; + if (linkb->next) linkb->next->prev = linkb; + + if (listbase->last == linka) listbase->last = linkb; + else if (listbase->last == linkb) listbase->last = linka; + if (listbase->first == linka) listbase->first = linkb; + else if (listbase->first == linkb) listbase->first = linka; +} + /** * Removes the head from \a listbase and returns it. */ -- cgit v1.2.3 From 282315d9915094d589b09f3e25d11eee6b468a16 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 21 Oct 2014 14:06:16 +0200 Subject: ListBase: use BLI_listbase_ for new api calls --- source/blender/blenlib/BLI_listbase.h | 2 +- source/blender/blenlib/intern/listbase.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h index fec05221596..3f03c4e3845 100644 --- a/source/blender/blenlib/BLI_listbase.h +++ b/source/blender/blenlib/BLI_listbase.h @@ -73,7 +73,7 @@ void BLI_freelist(struct ListBase *listbase) ATTR_NONNULL(1); int BLI_countlist(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1); -void BLI_swaplinks(struct ListBase *listbase, void *vlinka, void *vlinkb) ATTR_NONNULL(1, 2); +void BLI_listbase_swaplinks(struct ListBase *listbase, void *vlinka, void *vlinkb) ATTR_NONNULL(1, 2); void BLI_movelisttolist(struct ListBase *dst, struct ListBase *src) ATTR_NONNULL(1, 2); void BLI_duplicatelist(struct ListBase *dst, const struct ListBase *src) ATTR_NONNULL(1, 2); diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c index 6d61a046094..6fcc5888382 100644 --- a/source/blender/blenlib/intern/listbase.c +++ b/source/blender/blenlib/intern/listbase.c @@ -132,7 +132,7 @@ bool BLI_remlink_safe(ListBase *listbase, void *vlink) /** * Swaps \a vlinka and \a vlinkb in the list. Assumes they are both already in the list! */ -void BLI_swaplinks(ListBase *listbase, void *vlinka, void *vlinkb) +void BLI_listbase_swaplinks(ListBase *listbase, void *vlinka, void *vlinkb) { Link *linka = vlinka; Link *linkb = vlinkb; -- cgit v1.2.3 From dfc4de036e39f74aa0a3b1e1734a02f4a9530a78 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 22 Oct 2014 11:56:52 +0200 Subject: Meshdeform modifier: Use threaded evaluation This commit switches meshdeform modifier to use threads to evaluate the vertices positions using the central task scheduler. SO now we've got an utility function to help splitting the for loop into tasks using BLI_task module which is pretty straightforward to use: it gets range (which is an integer lower and higher bounds) and the function and userdata to be invoked for each of the iterations. The only weak point for now is the passing the data to the callback, this isn't so trivial to improve in pure C. Reviewers: campbellbarton Differential Revision: https://developer.blender.org/D838 --- source/blender/blenlib/BLI_task.h | 12 ++++ source/blender/blenlib/intern/task.c | 112 +++++++++++++++++++++++++++++++++++ 2 files changed, 124 insertions(+) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_task.h b/source/blender/blenlib/BLI_task.h index c9cbaf997fb..8c22a25fe14 100644 --- a/source/blender/blenlib/BLI_task.h +++ b/source/blender/blenlib/BLI_task.h @@ -100,6 +100,18 @@ ThreadMutex *BLI_task_pool_user_mutex(TaskPool *pool); /* number of tasks done, for stats, don't use this to make decisions */ size_t BLI_task_pool_tasks_done(TaskPool *pool); +/* Parallel for routines */ +typedef void (*TaskParallelRangeFunc)(void *userdata, int iter); +void BLI_task_parallel_range_ex( + int start, int stop, + void *userdata, + TaskParallelRangeFunc func, + const int range_threshold); +void BLI_task_parallel_range( + int start, int stop, + void *userdata, + TaskParallelRangeFunc func); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenlib/intern/task.c b/source/blender/blenlib/intern/task.c index 8d867b9f295..3a49abc7060 100644 --- a/source/blender/blenlib/intern/task.c +++ b/source/blender/blenlib/intern/task.c @@ -428,3 +428,115 @@ size_t BLI_task_pool_tasks_done(TaskPool *pool) return pool->done; } +/* Parallel range routines */ + +/** + * + * Main functions: + * - #BLI_task_parallel_range + * + * TODO: + * - #BLI_task_parallel_foreach_listbase (#ListBase - double linked list) + * - #BLI_task_parallel_foreach_link (#Link - single linked list) + * - #BLI_task_parallel_foreach_ghash/gset (#GHash/#GSet - hash & set) + * - #BLI_task_parallel_foreach_mempool (#BLI_mempool - iterate over mempools) + * + * Possible improvements: + * + * - Chunk iterations to reduce number of spin locks. + */ + +typedef struct ParallelRangeState { + int start, stop; + void *userdata; + TaskParallelRangeFunc func; + + int iter; + SpinLock lock; +} ParallelRangeState; + +BLI_INLINE bool parallel_range_next_iter_get( + ParallelRangeState *state, + int *iter) +{ + bool result = false; + if (state->iter < state->stop) { + BLI_spin_lock(&state->lock); + if (state->iter < state->stop) { + *iter = state->iter++; + result = true; + } + BLI_spin_unlock(&state->lock); + } + return result; +} + +static void parallel_range_func( + TaskPool *pool, + void *UNUSED(taskdata), + int UNUSED(threadid)) +{ + ParallelRangeState *state = BLI_task_pool_userdata(pool); + int iter; + while (parallel_range_next_iter_get(state, &iter)) { + state->func(state->userdata, iter); + } +} + +void BLI_task_parallel_range_ex( + int start, int stop, + void *userdata, + TaskParallelRangeFunc func, + const int range_threshold) +{ + TaskScheduler *task_scheduler; + TaskPool *task_pool; + ParallelRangeState state; + int i; + + BLI_assert(start < stop); + + /* If it's not enough data to be cranched, don't bother with tasks at all, + * do everything from the main thread. + */ + if (stop - start < range_threshold) { + for (i = start; i < stop; ++i) { + func(userdata, i); + } + return; + } + + BLI_spin_init(&state.lock); + state.start = start; + state.stop = stop; + state.userdata = userdata; + state.func = func; + state.iter = start; + + task_scheduler = BLI_task_scheduler_get(); + task_pool = BLI_task_pool_create(task_scheduler, &state); + + /* The idea here is to prevent creating task for each of the loop iterations + * and instead have tasks which are evenly distributed across CPU cores and + * pull next iter to be cranched using the queue. + */ + for (i = 0; i < 2 * BLI_task_scheduler_num_threads(task_scheduler); i++) { + BLI_task_pool_push(task_pool, + parallel_range_func, + NULL, false, + TASK_PRIORITY_HIGH); + } + + BLI_task_pool_work_and_wait(task_pool); + BLI_task_pool_free(task_pool); + + BLI_spin_end(&state.lock); +} + +void BLI_task_parallel_range( + int start, int stop, + void *userdata, + TaskParallelRangeFunc func) +{ + BLI_task_parallel_range_ex(start, stop, userdata, func, 64); +} -- cgit v1.2.3 From 88fe8962434b7fe00fa713a84c58d2dbee481e3b Mon Sep 17 00:00:00 2001 From: Jason Wilkins Date: Wed, 22 Oct 2014 20:03:25 -0500 Subject: Checked each of my (jwilkins) XXX notes. The ones in extern/glew-es have been changed to NOTE instead of XXX GHOST_ContextEGL.cpp: It really does seem that it is not possible to query the swap interval using EGL GHOST_WidnowCocoa.h: The comment referring to Carbon is clearly out of date, so I removed it. math_geom.c: The node about not using tmax again is correct, but the code is kept for a future maintainer who will need to know how to compute it if they modify that code. paint_image_proj.c (2698): The question about integer truncation does not appear to have been resolved. It still seems to be an incorrectly implementation of rounding (I'd suggest using the round function instead of this hack). --- source/blender/blenlib/intern/math_geom.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index da0855ad022..015313431cb 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -1756,8 +1756,8 @@ bool isect_ray_aabb(const IsectRayAABBData *data, const float bb_min[3], if (tzmin > tmin) tmin = tzmin; - /* XXX jwilkins: tmax does not need to be updated since we don't use it - * keeping this here for future reference */ + /* Note: tmax does not need to be updated since we don't use it + * keeping this here for future reference - jwilkins */ //if (tzmax < tmax) tmax = tzmax; if (tmin_out) -- cgit v1.2.3 From eaaeae469968c5c78a5d7e6d202f1af00b382a79 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 23 Oct 2014 10:38:14 +0200 Subject: Cleanup: spelling --- source/blender/blenlib/intern/task.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/intern/task.c b/source/blender/blenlib/intern/task.c index 3a49abc7060..07c67f001f9 100644 --- a/source/blender/blenlib/intern/task.c +++ b/source/blender/blenlib/intern/task.c @@ -496,7 +496,7 @@ void BLI_task_parallel_range_ex( BLI_assert(start < stop); - /* If it's not enough data to be cranched, don't bother with tasks at all, + /* If it's not enough data to be crunched, don't bother with tasks at all, * do everything from the main thread. */ if (stop - start < range_threshold) { @@ -518,7 +518,7 @@ void BLI_task_parallel_range_ex( /* The idea here is to prevent creating task for each of the loop iterations * and instead have tasks which are evenly distributed across CPU cores and - * pull next iter to be cranched using the queue. + * pull next iter to be crunched using the queue. */ for (i = 0; i < 2 * BLI_task_scheduler_num_threads(task_scheduler); i++) { BLI_task_pool_push(task_pool, -- cgit v1.2.3 From 133f79e4492eca400d0e043733d43ca522cdb2b9 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 29 Oct 2014 14:11:19 +0100 Subject: Cleanup: warnings, typos --- source/blender/blenlib/intern/path_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c index d5af980e373..e3e13b0bcac 100644 --- a/source/blender/blenlib/intern/path_util.c +++ b/source/blender/blenlib/intern/path_util.c @@ -1580,7 +1580,7 @@ void BLI_make_existing_file(const char *name) char di[FILE_MAX]; BLI_split_dir_part(name, di, sizeof(di)); - /* make if if the dir doesn't exist */ + /* make if the dir doesn't exist */ BLI_dir_create_recursive(di); } -- cgit v1.2.3 From 8054372d22310bad504012ca70a692ad9dc94973 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 30 Oct 2014 10:26:22 +0100 Subject: Fix negate_m3 (taking 4x4 matrix) Cycles bake used incorrectly. --- source/blender/blenlib/BLI_math_matrix.h | 2 +- source/blender/blenlib/intern/math_matrix.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h index 732f4b66f38..e58e42f3c2d 100644 --- a/source/blender/blenlib/BLI_math_matrix.h +++ b/source/blender/blenlib/BLI_math_matrix.h @@ -125,7 +125,7 @@ void mul_m3_fl(float R[3][3], float f); void mul_m4_fl(float R[4][4], float f); void mul_mat3_m4_fl(float R[4][4], float f); -void negate_m3(float R[4][4]); +void negate_m3(float R[3][3]); void negate_m4(float R[4][4]); bool invert_m3_ex(float m[3][3], const float epsilon); diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index af42af88582..6b40f0cf28e 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -639,7 +639,7 @@ void mul_mat3_m4_fl(float m[4][4], float f) m[i][j] *= f; } -void negate_m3(float m[4][4]) +void negate_m3(float m[3][3]) { int i, j; -- cgit v1.2.3 From 0414ed1c480fa53a057a0b2077122e27ffd058fd Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 30 Oct 2014 10:37:27 +0100 Subject: Fix for mat3_to_rot_size modifying input matrix --- source/blender/blenlib/intern/math_matrix.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index 6b40f0cf28e..115980cb3e6 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -1425,11 +1425,19 @@ void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3]) /* scale */ /* note: mat4_to_size(ob->size, mat) fails for negative scale */ invert_m3_m3(imat3_n, mat3_n); + + /* better not edit mat3 */ +#if 0 mul_m3_m3m3(mat3, imat3_n, mat3); size[0] = mat3[0][0]; size[1] = mat3[1][1]; size[2] = mat3[2][2]; +#else + size[0] = dot_m3_v3_row_x(imat3_n, mat3[0]); + size[1] = dot_m3_v3_row_y(imat3_n, mat3[1]); + size[2] = dot_m3_v3_row_z(imat3_n, mat3[2]); +#endif } void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], float wmat[4][4]) -- cgit v1.2.3 From c2dc51d8271bc91586ef3c731c3cd7382456d482 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 30 Oct 2014 12:13:00 +0100 Subject: Math Lib: add transpose_m3_m3, m3_m4, m4_m4 --- source/blender/blenlib/BLI_math_matrix.h | 3 ++ source/blender/blenlib/intern/math_matrix.c | 64 +++++++++++++++++++++++++---- 2 files changed, 59 insertions(+), 8 deletions(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h index e58e42f3c2d..ee8b53037b0 100644 --- a/source/blender/blenlib/BLI_math_matrix.h +++ b/source/blender/blenlib/BLI_math_matrix.h @@ -144,7 +144,10 @@ void mul_v4d_m4v4d(double r[4], float M[4][4], double v[4]); /****************************** Linear Algebra *******************************/ void transpose_m3(float R[3][3]); +void transpose_m3_m3(float R[3][3], float A[3][3]); +void transpose_m3_m4(float R[3][3], float A[4][4]); void transpose_m4(float R[4][4]); +void transpose_m4_m4(float R[4][4], float A[4][4]); int compare_m4m4(float mat1[4][4], float mat2[4][4], float limit); diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index 115980cb3e6..293e90c8713 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -876,6 +876,37 @@ void transpose_m3(float mat[3][3]) mat[2][1] = t; } +void transpose_m3_m3(float rmat[3][3], float mat[3][3]) +{ + BLI_assert(rmat != mat); + + rmat[0][0] = mat[0][0]; + rmat[0][1] = mat[1][0]; + rmat[0][2] = mat[2][0]; + rmat[1][0] = mat[0][1]; + rmat[1][1] = mat[1][1]; + rmat[1][2] = mat[2][1]; + rmat[2][0] = mat[0][2]; + rmat[2][1] = mat[1][2]; + rmat[2][2] = mat[2][2]; +} + +/* seems obscure but in-fact a common operation */ +void transpose_m3_m4(float rmat[3][3], float mat[4][4]) +{ + BLI_assert(&rmat[0][0] != &mat[0][0]); + + rmat[0][0] = mat[0][0]; + rmat[0][1] = mat[1][0]; + rmat[0][2] = mat[2][0]; + rmat[1][0] = mat[0][1]; + rmat[1][1] = mat[1][1]; + rmat[1][2] = mat[2][1]; + rmat[2][0] = mat[0][2]; + rmat[2][1] = mat[1][2]; + rmat[2][2] = mat[2][2]; +} + void transpose_m4(float mat[4][4]) { float t; @@ -902,6 +933,28 @@ void transpose_m4(float mat[4][4]) mat[3][2] = t; } +void transpose_m4_m4(float rmat[4][4], float mat[4][4]) +{ + BLI_assert(rmat != mat); + + rmat[0][0] = mat[0][0]; + rmat[0][1] = mat[1][0]; + rmat[0][2] = mat[2][0]; + rmat[0][3] = mat[3][0]; + rmat[1][0] = mat[0][1]; + rmat[1][1] = mat[1][1]; + rmat[1][2] = mat[2][1]; + rmat[1][3] = mat[3][1]; + rmat[2][0] = mat[0][2]; + rmat[2][1] = mat[1][2]; + rmat[2][2] = mat[2][2]; + rmat[2][3] = mat[3][2]; + rmat[3][0] = mat[0][3]; + rmat[3][1] = mat[1][3]; + rmat[3][2] = mat[2][3]; + rmat[3][3] = mat[3][3]; +} + int compare_m4m4(float mat1[4][4], float mat2[4][4], float limit) { if (compare_v4v4(mat1[0], mat2[0], limit)) @@ -1145,8 +1198,7 @@ bool is_uniform_scaled_m3(float m[3][3]) float t[3][3]; float l1, l2, l3, l4, l5, l6; - copy_m3_m3(t, m); - transpose_m3(t); + transpose_m3_m3(t, m); l1 = len_squared_v3(m[0]); l2 = len_squared_v3(m[1]); @@ -1413,9 +1465,7 @@ void mat3_to_rot_size(float rot[3][3], float size[3], float mat3[3][3]) /* note: this is a workaround for negative matrix not working for rotation conversion, FIXME */ normalize_m3_m3(mat3_n, mat3); if (is_negative_m3(mat3)) { - negate_v3(mat3_n[0]); - negate_v3(mat3_n[1]); - negate_v3(mat3_n[2]); + negate_m3(mat3_n); } /* rotation */ @@ -1462,9 +1512,7 @@ void mat4_to_loc_quat(float loc[3], float quat[4], float wmat[4][4]) /* so scale doesn't interfere with rotation [#24291] */ /* note: this is a workaround for negative matrix not working for rotation conversion, FIXME */ if (is_negative_m3(mat3)) { - negate_v3(mat3_n[0]); - negate_v3(mat3_n[1]); - negate_v3(mat3_n[2]); + negate_m3(mat3_n); } mat3_to_quat(quat, mat3_n); -- cgit v1.2.3 From be63ba315f10a85d381c860bfcad7c96c8eb3191 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 30 Oct 2014 14:49:57 +0100 Subject: Math Lib: pseudoinverse_m4_m4 changed input matrix --- source/blender/blenlib/intern/math_matrix.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index 293e90c8713..fb04271fedd 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -2239,14 +2239,14 @@ void svd_m4(float U[4][4], float s[4], float V[4][4], float A_[4][4]) } } -void pseudoinverse_m4_m4(float Ainv[4][4], float A[4][4], float epsilon) +void pseudoinverse_m4_m4(float Ainv[4][4], float A_[4][4], float epsilon) { /* compute moon-penrose pseudo inverse of matrix, singular values * below epsilon are ignored for stability (truncated SVD) */ - float V[4][4], W[4], Wm[4][4], U[4][4]; + float A[4][4], V[4][4], W[4], Wm[4][4], U[4][4]; int i; - transpose_m4(A); + transpose_m4_m4(A, A_); svd_m4(V, W, U, A); transpose_m4(U); transpose_m4(V); -- cgit v1.2.3 From af9da0be438812ee95698ae3e9adbbb49ba6b825 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20T=C3=B6nne?= Date: Thu, 30 Oct 2014 15:26:41 +0100 Subject: Complementary fix for rB8054372: Follow the common naming scheme by using negate_mat3_m4 instead of negate_m4. This avoids changing the behavior and only flips the 3x3 part of the matrix. --- source/blender/blenlib/BLI_math_matrix.h | 1 + source/blender/blenlib/intern/math_matrix.c | 9 +++++++++ 2 files changed, 10 insertions(+) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h index ee8b53037b0..45972d03175 100644 --- a/source/blender/blenlib/BLI_math_matrix.h +++ b/source/blender/blenlib/BLI_math_matrix.h @@ -126,6 +126,7 @@ void mul_m4_fl(float R[4][4], float f); void mul_mat3_m4_fl(float R[4][4], float f); void negate_m3(float R[3][3]); +void negate_mat3_m4(float R[4][4]); void negate_m4(float R[4][4]); bool invert_m3_ex(float m[3][3], const float epsilon); diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index fb04271fedd..0204c3bc86c 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -648,6 +648,15 @@ void negate_m3(float m[3][3]) m[i][j] *= -1.0f; } +void negate_mat3_m4(float m[4][4]) +{ + int i, j; + + for (i = 0; i < 3; i++) + for (j = 0; j < 3; j++) + m[i][j] *= -1.0f; +} + void negate_m4(float m[4][4]) { int i, j; -- cgit v1.2.3 From 7bb910cd4e97cfb39fd5b874d9d634b13e4cee51 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 31 Oct 2014 12:35:20 +0100 Subject: Fix T42344: EWA filter produces blured results Derivatives variable names are swapped in the old EWA filter code, need to adjust for that. TODO: Make naming fore clear in there. --- source/blender/blenlib/intern/math_interp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/intern/math_interp.c b/source/blender/blenlib/intern/math_interp.c index 4feb954a31a..a0c47be8d48 100644 --- a/source/blender/blenlib/intern/math_interp.c +++ b/source/blender/blenlib/intern/math_interp.c @@ -467,7 +467,7 @@ void BLI_ewa_filter(const int width, const int height, /* scaling dxt/dyt by full resolution can cause overflow because of huge A/B/C and esp. F values, * scaling by aspect ratio alone does the opposite, so try something in between instead... */ const float ff2 = (float)width, ff = sqrtf(ff2), q = (float)height / ff; - const float Ux = du[0] * ff, Vx = dv[0] * q, Uy = du[1] * ff, Vy = dv[1] * q; + const float Ux = du[0] * ff, Vx = du[1] * q, Uy = dv[0] * ff, Vy = dv[1] * q; float A = Vx * Vx + Vy * Vy; float B = -2.0f * (Ux * Vx + Uy * Vy); float C = Ux * Ux + Uy * Uy; -- cgit v1.2.3 From e43b74d87a43ab919b86434db9881608c5b9f762 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 3 Nov 2014 18:24:08 +0100 Subject: Optimization of parallel range It now supports different scheduling schemas: dynamic and static. Static one is the default and it splits work into equal number of range iterations. Dynamic one allocates chunks of 32 iterations which then being dynamically send to a thread which is currently idling. This gives slightly better performance. Still some tricks are possible to have. For example we can use some smarter static scheduling when one thread might steal tasks from another threads when it runs out of work to be done. Also removed unneeded spin lock in the mesh deform evaluation, on the first glance it seemed to be a reduction involved here but int fact threads are just adding value to the original vertex coordinates. No write access to the same element of vertexCos happens from separate threads. --- source/blender/blenlib/BLI_task.h | 3 +- source/blender/blenlib/intern/task.c | 55 +++++++++++++++++++++++------------- 2 files changed, 38 insertions(+), 20 deletions(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_task.h b/source/blender/blenlib/BLI_task.h index 8c22a25fe14..28da673ea97 100644 --- a/source/blender/blenlib/BLI_task.h +++ b/source/blender/blenlib/BLI_task.h @@ -106,7 +106,8 @@ void BLI_task_parallel_range_ex( int start, int stop, void *userdata, TaskParallelRangeFunc func, - const int range_threshold); + const int range_threshold, + const bool use_dynamic_scheduling); void BLI_task_parallel_range( int start, int stop, void *userdata, diff --git a/source/blender/blenlib/intern/task.c b/source/blender/blenlib/intern/task.c index 07c67f001f9..219ccb18d98 100644 --- a/source/blender/blenlib/intern/task.c +++ b/source/blender/blenlib/intern/task.c @@ -29,6 +29,7 @@ #include "MEM_guardedalloc.h" #include "BLI_listbase.h" +#include "BLI_math.h" #include "BLI_task.h" #include "BLI_threads.h" @@ -452,18 +453,21 @@ typedef struct ParallelRangeState { TaskParallelRangeFunc func; int iter; + int chunk_size; SpinLock lock; } ParallelRangeState; BLI_INLINE bool parallel_range_next_iter_get( - ParallelRangeState *state, - int *iter) + ParallelRangeState * __restrict state, + int * __restrict iter, int * __restrict count) { bool result = false; if (state->iter < state->stop) { BLI_spin_lock(&state->lock); if (state->iter < state->stop) { - *iter = state->iter++; + *count = min_ii(state->chunk_size, state->stop - state->iter); + *iter = state->iter; + state->iter += *count; result = true; } BLI_spin_unlock(&state->lock); @@ -472,14 +476,17 @@ BLI_INLINE bool parallel_range_next_iter_get( } static void parallel_range_func( - TaskPool *pool, + TaskPool * __restrict pool, void *UNUSED(taskdata), int UNUSED(threadid)) { - ParallelRangeState *state = BLI_task_pool_userdata(pool); - int iter; - while (parallel_range_next_iter_get(state, &iter)) { - state->func(state->userdata, iter); + ParallelRangeState * __restrict state = BLI_task_pool_userdata(pool); + int iter, count; + while (parallel_range_next_iter_get(state, &iter, &count)) { + int i; + for (i = 0; i < count; ++i) { + state->func(state->userdata, iter + i); + } } } @@ -487,12 +494,13 @@ void BLI_task_parallel_range_ex( int start, int stop, void *userdata, TaskParallelRangeFunc func, - const int range_threshold) + const int range_threshold, + const bool use_dynamic_scheduling) { TaskScheduler *task_scheduler; TaskPool *task_pool; ParallelRangeState state; - int i; + int i, num_threads, num_tasks; BLI_assert(start < stop); @@ -506,21 +514,30 @@ void BLI_task_parallel_range_ex( return; } - BLI_spin_init(&state.lock); - state.start = start; - state.stop = stop; - state.userdata = userdata; - state.func = func; - state.iter = start; - task_scheduler = BLI_task_scheduler_get(); task_pool = BLI_task_pool_create(task_scheduler, &state); + num_threads = BLI_task_scheduler_num_threads(task_scheduler); /* The idea here is to prevent creating task for each of the loop iterations * and instead have tasks which are evenly distributed across CPU cores and * pull next iter to be crunched using the queue. */ - for (i = 0; i < 2 * BLI_task_scheduler_num_threads(task_scheduler); i++) { + num_tasks = num_threads * 2; + + BLI_spin_init(&state.lock); + state.start = start; + state.stop = stop; + state.userdata = userdata; + state.func = func; + state.iter = start; + if (use_dynamic_scheduling) { + state.chunk_size = 32; + } + else { + state.chunk_size = (stop - start) / (num_tasks); + } + + for (i = 0; i < num_tasks; i++) { BLI_task_pool_push(task_pool, parallel_range_func, NULL, false, @@ -538,5 +555,5 @@ void BLI_task_parallel_range( void *userdata, TaskParallelRangeFunc func) { - BLI_task_parallel_range_ex(start, stop, userdata, func, 64); + BLI_task_parallel_range_ex(start, stop, userdata, func, 64, false); } -- cgit v1.2.3 From 5e0e1754227514d0f6ebd328f1b9a07cda607779 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 3 Nov 2014 23:26:43 +0100 Subject: Cleanup: spelling (D831) --- source/blender/blenlib/intern/storage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c index f3ecc799e1e..c062d62bca5 100644 --- a/source/blender/blenlib/intern/storage.c +++ b/source/blender/blenlib/intern/storage.c @@ -280,7 +280,7 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname) closedir(dir); } else { - printf("%s non-existant directory\n", dirname); + printf("%s non-existent directory\n", dirname); } } -- cgit v1.2.3 From 988b3d718835c1474353ff3aa04fce5e17ed2f2e Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 4 Nov 2014 16:31:42 +0500 Subject: Add utility macros to clamp all elements of 2,3,4 component vectors --- source/blender/blenlib/BLI_utildefines.h | 54 ++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h index 736578361b3..f318ae0e39f 100644 --- a/source/blender/blenlib/BLI_utildefines.h +++ b/source/blender/blenlib/BLI_utildefines.h @@ -335,6 +335,60 @@ if ((a) < (b)) (a) = (b); \ } (void)0 +#define CLAMP2(vec, b, c) { \ + CLAMP((vec)[0], b, c); \ + CLAMP((vec)[1], b, c); \ +} (void)0 + +#define CLAMP2_MIN(vec, b) { \ + CLAMP_MIN((vec)[0], b); \ + CLAMP_MIN((vec)[1], b); \ +} (void)0 + +#define CLAMP2_MAX(vec, b) { \ + CLAMP_MAX((vec)[0], b); \ + CLAMP_MAX((vec)[1], b); \ +} (void)0 + +#define CLAMP3(vec, b, c) { \ + CLAMP((vec)[0], b, c); \ + CLAMP((vec)[1], b, c); \ + CLAMP((vec)[2], b, c); \ +} (void)0 + +#define CLAMP3_MIN(vec, b) { \ + CLAMP_MIN((vec)[0], b); \ + CLAMP_MIN((vec)[1], b); \ + CLAMP_MIN((vec)[2], b); \ +} (void)0 + +#define CLAMP3_MAX(vec, b) { \ + CLAMP_MAX((vec)[0], b); \ + CLAMP_MAX((vec)[1], b); \ + CLAMP_MAX((vec)[2], b); \ +} (void)0 + +#define CLAMP4(vec, b, c) { \ + CLAMP((vec)[0], b, c); \ + CLAMP((vec)[1], b, c); \ + CLAMP((vec)[2], b, c); \ + CLAMP((vec)[3], b, c); \ +} (void)0 + +#define CLAMP4_MIN(vec, b) { \ + CLAMP_MIN((vec)[0], b); \ + CLAMP_MIN((vec)[1], b); \ + CLAMP_MIN((vec)[2], b); \ + CLAMP_MIN((vec)[3], b); \ +} (void)0 + +#define CLAMP4_MAX(vec, b) { \ + CLAMP_MAX((vec)[0], b); \ + CLAMP_MAX((vec)[1], b); \ + CLAMP_MAX((vec)[2], b); \ + CLAMP_MAX((vec)[3], b); \ +} (void)0 + #define IS_EQ(a, b) ( \ CHECK_TYPE_INLINE(a, double), CHECK_TYPE_INLINE(b, double), \ ((fabs((double)((a) - (b))) >= (double) FLT_EPSILON) ? false : true)) -- cgit v1.2.3 From 52d571e189d5ba48dbbc2ad0cf24608f30c6bbc2 Mon Sep 17 00:00:00 2001 From: Sergej Reich Date: Tue, 11 Nov 2014 18:16:20 +0100 Subject: Avoid calling powf with integer exponent in more places Move powX functions from particle code into math library and use them. --- source/blender/blenlib/BLI_math_base.h | 5 +++++ source/blender/blenlib/intern/math_base_inline.c | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_math_base.h b/source/blender/blenlib/BLI_math_base.h index 07de074e717..5711d09b530 100644 --- a/source/blender/blenlib/BLI_math_base.h +++ b/source/blender/blenlib/BLI_math_base.h @@ -157,6 +157,11 @@ static const int NAN_INT = 0x7FC00000; /******************************* Float ******************************/ +MINLINE float pow2f(float x); +MINLINE float pow3f(float x); +MINLINE float pow4f(float x); +MINLINE float pow7f(float x); + MINLINE float sqrt3f(float f); MINLINE double sqrt3d(double d); diff --git a/source/blender/blenlib/intern/math_base_inline.c b/source/blender/blenlib/intern/math_base_inline.c index e6217329145..39116d6f30f 100644 --- a/source/blender/blenlib/intern/math_base_inline.c +++ b/source/blender/blenlib/intern/math_base_inline.c @@ -44,6 +44,24 @@ # define UNLIKELY(x) (x) #endif +/* powf is really slow for raising to integer powers. */ +MINLINE float pow2f(float x) +{ + return x * x; +} +MINLINE float pow3f(float x) +{ + return pow2f(x) * x; +} +MINLINE float pow4f(float x) +{ + return pow2f(pow2f(x)); +} +MINLINE float pow7f(float x) +{ + return pow2f(pow3f(x)) * x; +} + MINLINE float sqrt3f(float f) { if (UNLIKELY(f == 0.0f)) return 0.0f; -- cgit v1.2.3 From 64c0c13e6e08c51e92504631468db864f553d9b5 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 14 Nov 2014 11:00:10 +0100 Subject: Add Murmur2A hashing feature to BLI Murmur2a is a very fast hashing function generation int32 hashes. It also features a very good distribution of generated hashes. However, it is not endianness-agnostic, meaning it will usually generate different hashes for a same key on big- and little-endian architectures. Consequently, **it shall not be used to generate persistent hashes** (never store them in .blend file e.g.). This implementation supports incremental hashing, and is a direct adaptation of reference implementation (in c++): https://smhasher.googlecode.com/svn-history/r130/trunk/MurmurHash2.cpp That cpp code was also used to generate reference values in gtests file. Reviewers: sergey, campbellbarton Reviewed By: campbellbarton Projects: #bf_blender Differential Revision: https://developer.blender.org/D892 --- source/blender/blenlib/BLI_hash_md5.h | 46 ++++ source/blender/blenlib/BLI_hash_mm2a.h | 45 ++++ source/blender/blenlib/BLI_md5.h | 47 ---- source/blender/blenlib/CMakeLists.txt | 6 +- source/blender/blenlib/intern/hash_md5.c | 408 ++++++++++++++++++++++++++++++ source/blender/blenlib/intern/hash_mm2a.c | 107 ++++++++ source/blender/blenlib/intern/md5.c | 408 ------------------------------ 7 files changed, 610 insertions(+), 457 deletions(-) create mode 100644 source/blender/blenlib/BLI_hash_md5.h create mode 100644 source/blender/blenlib/BLI_hash_mm2a.h delete mode 100644 source/blender/blenlib/BLI_md5.h create mode 100644 source/blender/blenlib/intern/hash_md5.c create mode 100644 source/blender/blenlib/intern/hash_mm2a.c delete mode 100644 source/blender/blenlib/intern/md5.c (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_hash_md5.h b/source/blender/blenlib/BLI_hash_md5.h new file mode 100644 index 00000000000..cab3671a5ca --- /dev/null +++ b/source/blender/blenlib/BLI_hash_md5.h @@ -0,0 +1,46 @@ +/* + * ***** 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. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __BLI_MD5_H__ +#define __BLI_MD5_H__ + +/** \file BLI_hash_md5.h + * \ingroup bli + */ + +#include +#include + +/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The + * result is always in little endian byte order, so that a byte-wise + * output yields to the wanted ASCII representation of the message + * digest. */ + +void *md5_buffer(const char *buffer, size_t len, void *resblock); + +/* Compute MD5 message digest for bytes read from STREAM. The + * resulting message digest number will be written into the 16 bytes + * beginning at RESBLOCK. */ + +int md5_stream(FILE *stream, void *resblock); + +char *md5_to_hexdigest(void *resblock, char r_hex_digest[33]); + +#endif /* __BLI_MD5_H__ */ diff --git a/source/blender/blenlib/BLI_hash_mm2a.h b/source/blender/blenlib/BLI_hash_mm2a.h new file mode 100644 index 00000000000..503eb5e96d9 --- /dev/null +++ b/source/blender/blenlib/BLI_hash_mm2a.h @@ -0,0 +1,45 @@ +/* + * ***** 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. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __BLI_MM2A_H__ +#define __BLI_MM2A_H__ + +/** \file BLI_hash_mm2a.h + * \ingroup bli + */ + +#include "BLI_sys_types.h" + +typedef struct BLI_HashMurmur2A { + uint32_t hash; + uint32_t tail; + uint32_t count; + uint32_t size; +} BLI_HashMurmur2A; + +void BLI_hash_mm2a_init(BLI_HashMurmur2A *mm2, uint32_t seed); + +void BLI_hash_mm2a_add(BLI_HashMurmur2A *mm2, const unsigned char *data, size_t len); + +void BLI_hash_mm2a_add_int(BLI_HashMurmur2A *mm2, int data); + +uint32_t BLI_hash_mm2a_end(BLI_HashMurmur2A *mm2); + +#endif /* __BLI_MM2A_H__ */ diff --git a/source/blender/blenlib/BLI_md5.h b/source/blender/blenlib/BLI_md5.h deleted file mode 100644 index 6a760f53e45..00000000000 --- a/source/blender/blenlib/BLI_md5.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * ***** 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. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#ifndef __BLI_MD5_H__ -#define __BLI_MD5_H__ - -/** \file BLI_md5.h - * \ingroup bli - */ - -#include -#include - -/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The - * result is always in little endian byte order, so that a byte-wise - * output yields to the wanted ASCII representation of the message - * digest. */ - -void *md5_buffer(const char *buffer, size_t len, void *resblock); - -/* Compute MD5 message digest for bytes read from STREAM. The - * resulting message digest number will be written into the 16 bytes - * beginning at RESBLOCK. */ - -int md5_stream(FILE *stream, void *resblock); - -char *md5_to_hexdigest(void *resblock, char r_hex_digest[33]); - -#endif - diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index 9efa20da13e..ba166b11960 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -65,6 +65,8 @@ set(SRC intern/freetypefont.c intern/graph.c intern/gsqueue.c + intern/hash_md5.c + intern/hash_mm2a.c intern/jitter.c intern/lasso.c intern/listbase.c @@ -80,7 +82,6 @@ set(SRC intern/math_rotation.c intern/math_vector.c intern/math_vector_inline.c - intern/md5.c intern/noise.c intern/path_util.c intern/polyfill2d.c @@ -134,6 +135,8 @@ set(SRC BLI_ghash.h BLI_graph.h BLI_gsqueue.h + BLI_hash_md5.h + BLI_hash_mm2a.h BLI_heap.h BLI_jitter.h BLI_kdopbvh.h @@ -153,7 +156,6 @@ set(SRC BLI_math_matrix.h BLI_math_rotation.h BLI_math_vector.h - BLI_md5.h BLI_memarena.h BLI_mempool.h BLI_noise.h diff --git a/source/blender/blenlib/intern/hash_md5.c b/source/blender/blenlib/intern/hash_md5.c new file mode 100644 index 00000000000..98a5cc545b5 --- /dev/null +++ b/source/blender/blenlib/intern/hash_md5.c @@ -0,0 +1,408 @@ +/* + * ***** 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. + * + * ***** END GPL LICENSE BLOCK ***** + * + * Copyright (C) 1995 Software Foundation, Inc. + * + * Written by Ulrich Drepper . + */ + +/** \file blender/blenlib/intern/md5.c + * \ingroup bli + * + * Functions to compute MD5 message digest of files or memory blocks + * according to the definition of MD5 in RFC 1321 from April 1992. + */ + +#include "BLI_hash_md5.h" /* own include */ + +#include +#include +#include +#include + +#if defined HAVE_LIMITS_H || defined _LIBC +# include +#endif + +/* The following contortions are an attempt to use the C preprocessor to determine an unsigned integral type + * that is 32 bits wide. An alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but doing that + * would require that the configure script compile and *run* the resulting executable. + * Locally running cross-compiled executables is usually not possible. + */ + +#if defined __STDC__ && __STDC__ +# define UINT_MAX_32_BITS 4294967295U +#else +# define UINT_MAX_32_BITS 0xFFFFFFFF +#endif + +/* If UINT_MAX isn't defined, assume it's a 32-bit type. + * This should be valid for all systems GNU cares about because that doesn't include 16-bit systems, + * and only modern systems (that certainly have ) have 64+-bit integral types. + */ + +#ifndef UINT_MAX +# define UINT_MAX UINT_MAX_32_BITS +#endif + +#if UINT_MAX == UINT_MAX_32_BITS + typedef unsigned int md5_uint32; +#else +# if USHRT_MAX == UINT_MAX_32_BITS + typedef unsigned short md5_uint32; +# else +# if ULONG_MAX == UINT_MAX_32_BITS + typedef unsigned long md5_uint32; +# else + /* The following line is intended to evoke an error. Using #error is not portable enough. */ + "Cannot determine unsigned 32-bit data type." +# endif +# endif +#endif + + +/* Following code is low level, upon which are built up the functions 'md5_stream' and 'md5_buffer'. */ + +/* Structure to save state of computation between the single steps. */ +struct md5_ctx +{ + md5_uint32 A; + md5_uint32 B; + md5_uint32 C; + md5_uint32 D; +}; + +#ifdef __BIG_ENDIAN__ +# define SWAP(n) (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24)) +#else +# define SWAP(n) (n) +#endif + +/* This array contains the bytes used to pad the buffer to the next 64-byte boundary. (RFC 1321, 3.1: Step 1) */ +static const unsigned char fillbuf[64] = {0x80, 0 /* , 0, 0, ... */}; + +/** Initialize structure containing state of computation. + * (RFC 1321, 3.3: Step 3) + */ +static void md5_init_ctx(struct md5_ctx *ctx) +{ + ctx->A = 0x67452301; + ctx->B = 0xefcdab89; + ctx->C = 0x98badcfe; + ctx->D = 0x10325476; +} + +/** Starting with the result of former calls of this function (or the initialization), this function updates + * the 'ctx' context for the next 'len' bytes starting at 'buffer'. + * It is necessary that 'len' is a multiple of 64!!! + */ +static void md5_process_block (const void *buffer, size_t len, struct md5_ctx *ctx) +{ +/* These are the four functions used in the four steps of the MD5 algorithm and defined in the RFC 1321. + * The first function is a little bit optimized (as found in Colin Plumbs public domain implementation). + */ +/* #define FF(b, c, d) ((b & c) | (~b & d)) */ +#define FF(b, c, d) (d ^ (b & (c ^ d))) +#define FG(b, c, d) FF (d, b, c) +#define FH(b, c, d) (b ^ c ^ d) +#define FI(b, c, d) (c ^ (b | ~d)) + +/* It is unfortunate that C does not provide an operator for cyclic rotation. Hope the C compiler is smart enough. */ +#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s))) + + md5_uint32 correct_words[16]; + const md5_uint32 *words = buffer; + size_t nwords = len / sizeof(md5_uint32); + const md5_uint32 *endp = words + nwords; + md5_uint32 A = ctx->A; + md5_uint32 B = ctx->B; + md5_uint32 C = ctx->C; + md5_uint32 D = ctx->D; + + /* Process all bytes in the buffer with 64 bytes in each round of the loop. */ + while (words < endp) { + md5_uint32 *cwp = correct_words; + md5_uint32 A_save = A; + md5_uint32 B_save = B; + md5_uint32 C_save = C; + md5_uint32 D_save = D; + + /* First round: using the given function, the context and a constant the next context is computed. + * Because the algorithms processing unit is a 32-bit word and it is determined to work on words in + * little endian byte order we perhaps have to change the byte order before the computation. + * To reduce the work for the next steps we store the swapped words in the array CORRECT_WORDS. + */ +#define OP(a, b, c, d, s, T) \ + a += FF(b, c, d) + (*cwp++ = SWAP(*words)) + T; \ + ++words; \ + CYCLIC(a, s); \ + a += b; \ + (void)0 + + /* Before we start, one word to the strange constants. They are defined in RFC 1321 as: + * T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64 + */ + + /* Round 1. */ + OP(A, B, C, D, 7, 0xd76aa478); + OP(D, A, B, C, 12, 0xe8c7b756); + OP(C, D, A, B, 17, 0x242070db); + OP(B, C, D, A, 22, 0xc1bdceee); + OP(A, B, C, D, 7, 0xf57c0faf); + OP(D, A, B, C, 12, 0x4787c62a); + OP(C, D, A, B, 17, 0xa8304613); + OP(B, C, D, A, 22, 0xfd469501); + OP(A, B, C, D, 7, 0x698098d8); + OP(D, A, B, C, 12, 0x8b44f7af); + OP(C, D, A, B, 17, 0xffff5bb1); + OP(B, C, D, A, 22, 0x895cd7be); + OP(A, B, C, D, 7, 0x6b901122); + OP(D, A, B, C, 12, 0xfd987193); + OP(C, D, A, B, 17, 0xa679438e); + OP(B, C, D, A, 22, 0x49b40821); + +#undef OP + + /* For the second to fourth round we have the possibly swapped words in CORRECT_WORDS. + * Redefine the macro to take an additional first argument specifying the function to use. + */ +#define OP(f, a, b, c, d, k, s, T) \ + a += f(b, c, d) + correct_words[k] + T; \ + CYCLIC(a, s); \ + a += b; \ + (void)0 + + /* Round 2. */ + OP(FG, A, B, C, D, 1, 5, 0xf61e2562); + OP(FG, D, A, B, C, 6, 9, 0xc040b340); + OP(FG, C, D, A, B, 11, 14, 0x265e5a51); + OP(FG, B, C, D, A, 0, 20, 0xe9b6c7aa); + OP(FG, A, B, C, D, 5, 5, 0xd62f105d); + OP(FG, D, A, B, C, 10, 9, 0x02441453); + OP(FG, C, D, A, B, 15, 14, 0xd8a1e681); + OP(FG, B, C, D, A, 4, 20, 0xe7d3fbc8); + OP(FG, A, B, C, D, 9, 5, 0x21e1cde6); + OP(FG, D, A, B, C, 14, 9, 0xc33707d6); + OP(FG, C, D, A, B, 3, 14, 0xf4d50d87); + OP(FG, B, C, D, A, 8, 20, 0x455a14ed); + OP(FG, A, B, C, D, 13, 5, 0xa9e3e905); + OP(FG, D, A, B, C, 2, 9, 0xfcefa3f8); + OP(FG, C, D, A, B, 7, 14, 0x676f02d9); + OP(FG, B, C, D, A, 12, 20, 0x8d2a4c8a); + + /* Round 3. */ + OP(FH, A, B, C, D, 5, 4, 0xfffa3942); + OP(FH, D, A, B, C, 8, 11, 0x8771f681); + OP(FH, C, D, A, B, 11, 16, 0x6d9d6122); + OP(FH, B, C, D, A, 14, 23, 0xfde5380c); + OP(FH, A, B, C, D, 1, 4, 0xa4beea44); + OP(FH, D, A, B, C, 4, 11, 0x4bdecfa9); + OP(FH, C, D, A, B, 7, 16, 0xf6bb4b60); + OP(FH, B, C, D, A, 10, 23, 0xbebfbc70); + OP(FH, A, B, C, D, 13, 4, 0x289b7ec6); + OP(FH, D, A, B, C, 0, 11, 0xeaa127fa); + OP(FH, C, D, A, B, 3, 16, 0xd4ef3085); + OP(FH, B, C, D, A, 6, 23, 0x04881d05); + OP(FH, A, B, C, D, 9, 4, 0xd9d4d039); + OP(FH, D, A, B, C, 12, 11, 0xe6db99e5); + OP(FH, C, D, A, B, 15, 16, 0x1fa27cf8); + OP(FH, B, C, D, A, 2, 23, 0xc4ac5665); + + /* Round 4. */ + OP(FI, A, B, C, D, 0, 6, 0xf4292244); + OP(FI, D, A, B, C, 7, 10, 0x432aff97); + OP(FI, C, D, A, B, 14, 15, 0xab9423a7); + OP(FI, B, C, D, A, 5, 21, 0xfc93a039); + OP(FI, A, B, C, D, 12, 6, 0x655b59c3); + OP(FI, D, A, B, C, 3, 10, 0x8f0ccc92); + OP(FI, C, D, A, B, 10, 15, 0xffeff47d); + OP(FI, B, C, D, A, 1, 21, 0x85845dd1); + OP(FI, A, B, C, D, 8, 6, 0x6fa87e4f); + OP(FI, D, A, B, C, 15, 10, 0xfe2ce6e0); + OP(FI, C, D, A, B, 6, 15, 0xa3014314); + OP(FI, B, C, D, A, 13, 21, 0x4e0811a1); + OP(FI, A, B, C, D, 4, 6, 0xf7537e82); + OP(FI, D, A, B, C, 11, 10, 0xbd3af235); + OP(FI, C, D, A, B, 2, 15, 0x2ad7d2bb); + OP(FI, B, C, D, A, 9, 21, 0xeb86d391); + +#undef OP + + /* Add the starting values of the context. */ + A += A_save; + B += B_save; + C += C_save; + D += D_save; + } + + /* Put checksum in context given as argument. */ + ctx->A = A; + ctx->B = B; + ctx->C = C; + ctx->D = D; + +#undef FF +#undef FG +#undef FH +#undef FI +#undef CYCLIC +} + +/** Put result from 'ctx' in first 16 bytes of 'resbuf'. The result is always in little endian byte order, + * so that a byte-wise output yields to the wanted ASCII representation of the message digest. + */ +static void *md5_read_ctx(const struct md5_ctx *ctx, void *resbuf) +{ + md5_uint32 *digest = resbuf; + digest[0] = SWAP(ctx->A); + digest[1] = SWAP(ctx->B); + digest[2] = SWAP(ctx->C); + digest[3] = SWAP(ctx->D); + + return resbuf; +} + +/* Top level public functions. */ + +/** Compute MD5 message digest for bytes read from 'stream'. + * The resulting message digest number will be written into the 16 bytes beginning at 'resblock'. + * \return Non-zero if an error occurred. + */ +int md5_stream(FILE *stream, void *resblock) +{ +#define BLOCKSIZE 4096 /* Important: must be a multiple of 64. */ + struct md5_ctx ctx; + md5_uint32 len[2]; + char buffer[BLOCKSIZE + 72]; + size_t pad, sum; + + /* Initialize the computation context. */ + md5_init_ctx(&ctx); + + len[0] = 0; + len[1] = 0; + + /* Iterate over full file contents. */ + while (1) { + /* We read the file in blocks of BLOCKSIZE bytes. One call of the computation function processes + * the whole buffer so that with the next round of the loop another block can be read. + */ + size_t n; + sum = 0; + + /* Read block. Take care for partial reads. */ + do { + n = fread(buffer, 1, BLOCKSIZE - sum, stream); + sum += n; + } while (sum < BLOCKSIZE && n != 0); + + if (n == 0 && ferror(stream)) + return 1; + + /* RFC 1321 specifies the possible length of the file up to 2^64 bits. + * Here we only compute the number of bytes. Do a double word increment. + */ + len[0] += sum; + if (len[0] < sum) + ++len[1]; + + /* If end of file is reached, end the loop. */ + if (n == 0) + break; + + /* Process buffer with BLOCKSIZE bytes. Note that BLOCKSIZE % 64 == 0. */ + md5_process_block(buffer, BLOCKSIZE, &ctx); + } + + /* We can copy 64 bytes because the buffer is always big enough. 'fillbuf' contains the needed bits. */ + memcpy(&buffer[sum], fillbuf, 64); + + /* Compute amount of padding bytes needed. Alignment is done to (N + PAD) % 64 == 56. + * There is always at least one byte padded, i.e. if the alignment is correctly aligned, + * 64 padding bytes are added. + */ + pad = sum & 63; + pad = pad >= 56 ? 64 + 56 - pad : 56 - pad; + + /* Put the 64-bit file length in *bits* at the end of the buffer. */ + *(md5_uint32 *) &buffer[sum + pad] = SWAP(len[0] << 3); + *(md5_uint32 *) &buffer[sum + pad + 4] = SWAP((len[1] << 3) | (len[0] >> 29)); + + /* Process last bytes. */ + md5_process_block(buffer, sum + pad + 8, &ctx); + + /* Construct result in desired memory. */ + md5_read_ctx(&ctx, resblock); + return 0; +} + +/** Compute MD5 message digest for 'len' bytes beginning at 'buffer'. + * The result is always in little endian byte order, so that a byte-wise output yields to the wanted + * ASCII representation of the message digest. + */ +void *md5_buffer(const char *buffer, size_t len, void *resblock) +{ + struct md5_ctx ctx; + char restbuf[64 + 72]; + size_t blocks = len & ~63; + size_t pad, rest; + + /* Initialize the computation context. */ + md5_init_ctx(&ctx); + + /* Process whole buffer but last len % 64 bytes. */ + md5_process_block(buffer, blocks, &ctx); + + /* REST bytes are not processed yet. */ + rest = len - blocks; + /* Copy to own buffer. */ + memcpy(restbuf, &buffer[blocks], rest); + /* Append needed fill bytes at end of buffer. We can copy 64 bytes because the buffer is always big enough. */ + memcpy(&restbuf[rest], fillbuf, 64); + + /* PAD bytes are used for padding to correct alignment. Note that always at least one byte is padded. */ + pad = rest >= 56 ? 64 + 56 - rest : 56 - rest; + + /* Put length of buffer in *bits* in last eight bytes. */ + *(md5_uint32 *) &restbuf[rest + pad] = (md5_uint32) SWAP(len << 3); + *(md5_uint32 *) &restbuf[rest + pad + 4] = (md5_uint32) SWAP(len >> 29); + + /* Process last bytes. */ + md5_process_block(restbuf, rest + pad + 8, &ctx); + + /* Put result in desired memory area. */ + return md5_read_ctx(&ctx, resblock); +} + +char *md5_to_hexdigest(void *resblock, char r_hex_digest[33]) +{ + static const char hex_map[17] = "0123456789abcdef"; + const unsigned char *p; + char *q; + short len; + + for (q = r_hex_digest, p = (const unsigned char *)resblock, len = 0; len < 16; ++p, ++len) { + const unsigned char c = *p; + *q++ = hex_map[c >> 4]; + *q++ = hex_map[c & 15]; + } + *q = '\0'; + + return r_hex_digest; +} diff --git a/source/blender/blenlib/intern/hash_mm2a.c b/source/blender/blenlib/intern/hash_mm2a.c new file mode 100644 index 00000000000..8b4242fa5be --- /dev/null +++ b/source/blender/blenlib/intern/hash_mm2a.c @@ -0,0 +1,107 @@ +/* + * ***** 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. + * + * ***** END GPL LICENSE BLOCK ***** + * + * Copyright (C) 2014 Blender Foundation. + * + */ + +/** \file blender/blenlib/intern/hash_mm2a.c + * \ingroup bli + * + * Functions to compute Murmur2A hash key. + * + * A very fast hash generating int32 result, with few collisions and good repartition. + * + * See also: + * reference implementation: https://smhasher.googlecode.com/svn-history/r130/trunk/MurmurHash2.cpp + * and http://programmers.stackexchange.com/questions/49550/which-hashing-algorithm-is-best-for-uniqueness-and-speed + * + * \warning Do not store that hash in files or such, it is not endian-agnostic, so you should only use it + * for temporary data. + */ + +#include "BLI_hash_mm2a.h" /* own include */ + +/* Helpers. */ +#define MM2A_M 0x5bd1e995 + +#define MM2A_MIX(h, k) \ +{ \ + (k) *= MM2A_M; \ + (k) ^= (k) >> 24; \ + (k) *= MM2A_M; \ + (h) = ((h) * MM2A_M) ^ (k); \ +} (void)0 + +static void mm2a_mix_tail(BLI_HashMurmur2A *mm2, const unsigned char **data, size_t *len) +{ + while (*len && ((*len < 4) || mm2->count)) { + mm2->tail |= (uint32_t)(**data) << (mm2->count * 8); + + mm2->count++; + (*len)--; + (*data)++; + + if (mm2->count == 4) { + MM2A_MIX(mm2->hash, mm2->tail); + mm2->tail = 0; + mm2->count = 0; + } + } +} + +void BLI_hash_mm2a_init(BLI_HashMurmur2A *mm2, uint32_t seed) +{ + mm2->hash = seed; + mm2->tail = 0; + mm2->count = 0; + mm2->size = 0; +} + +void BLI_hash_mm2a_add(BLI_HashMurmur2A *mm2, const unsigned char *data, size_t len) +{ + mm2->size += (uint32_t)len; + + mm2a_mix_tail(mm2, &data, &len); + + for (; len >= 4; data += 4, len -= 4) { + uint32_t k = *(uint32_t *)data; + + MM2A_MIX(mm2->hash, k); + } + + mm2a_mix_tail(mm2, &data, &len); +} + +void BLI_hash_mm2a_add_int(BLI_HashMurmur2A *mm2, int data) +{ + BLI_hash_mm2a_add(mm2, (const unsigned char *)&data, sizeof(data)); +} + +uint32_t BLI_hash_mm2a_end(BLI_HashMurmur2A *mm2) +{ + MM2A_MIX(mm2->hash, mm2->tail); + MM2A_MIX(mm2->hash, mm2->size); + + mm2->hash ^= mm2->hash >> 13; + mm2->hash *= MM2A_M; + mm2->hash ^= mm2->hash >> 15; + + return mm2->hash; +} diff --git a/source/blender/blenlib/intern/md5.c b/source/blender/blenlib/intern/md5.c deleted file mode 100644 index 3d1a9cdb7a4..00000000000 --- a/source/blender/blenlib/intern/md5.c +++ /dev/null @@ -1,408 +0,0 @@ -/* - * ***** 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. - * - * ***** END GPL LICENSE BLOCK ***** - * - * Copyright (C) 1995 Software Foundation, Inc. - * - * Written by Ulrich Drepper . - */ - -/** \file blender/blenlib/intern/md5.c - * \ingroup bli - * - * Functions to compute MD5 message digest of files or memory blocks - * according to the definition of MD5 in RFC 1321 from April 1992. - */ - -#include "BLI_md5.h" /* own include */ - -#include -#include -#include -#include - -#if defined HAVE_LIMITS_H || defined _LIBC -# include -#endif - -/* The following contortions are an attempt to use the C preprocessor to determine an unsigned integral type - * that is 32 bits wide. An alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but doing that - * would require that the configure script compile and *run* the resulting executable. - * Locally running cross-compiled executables is usually not possible. - */ - -#if defined __STDC__ && __STDC__ -# define UINT_MAX_32_BITS 4294967295U -#else -# define UINT_MAX_32_BITS 0xFFFFFFFF -#endif - -/* If UINT_MAX isn't defined, assume it's a 32-bit type. - * This should be valid for all systems GNU cares about because that doesn't include 16-bit systems, - * and only modern systems (that certainly have ) have 64+-bit integral types. - */ - -#ifndef UINT_MAX -# define UINT_MAX UINT_MAX_32_BITS -#endif - -#if UINT_MAX == UINT_MAX_32_BITS - typedef unsigned int md5_uint32; -#else -# if USHRT_MAX == UINT_MAX_32_BITS - typedef unsigned short md5_uint32; -# else -# if ULONG_MAX == UINT_MAX_32_BITS - typedef unsigned long md5_uint32; -# else - /* The following line is intended to evoke an error. Using #error is not portable enough. */ - "Cannot determine unsigned 32-bit data type." -# endif -# endif -#endif - - -/* Following code is low level, upon which are built up the functions 'md5_stream' and 'md5_buffer'. */ - -/* Structure to save state of computation between the single steps. */ -struct md5_ctx -{ - md5_uint32 A; - md5_uint32 B; - md5_uint32 C; - md5_uint32 D; -}; - -#ifdef __BIG_ENDIAN__ -# define SWAP(n) (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24)) -#else -# define SWAP(n) (n) -#endif - -/* This array contains the bytes used to pad the buffer to the next 64-byte boundary. (RFC 1321, 3.1: Step 1) */ -static const unsigned char fillbuf[64] = {0x80, 0 /* , 0, 0, ... */}; - -/** Initialize structure containing state of computation. - * (RFC 1321, 3.3: Step 3) - */ -static void md5_init_ctx(struct md5_ctx *ctx) -{ - ctx->A = 0x67452301; - ctx->B = 0xefcdab89; - ctx->C = 0x98badcfe; - ctx->D = 0x10325476; -} - -/** Starting with the result of former calls of this function (or the initialization), this function updates - * the 'ctx' context for the next 'len' bytes starting at 'buffer'. - * It is necessary that 'len' is a multiple of 64!!! - */ -static void md5_process_block (const void *buffer, size_t len, struct md5_ctx *ctx) -{ -/* These are the four functions used in the four steps of the MD5 algorithm and defined in the RFC 1321. - * The first function is a little bit optimized (as found in Colin Plumbs public domain implementation). - */ -/* #define FF(b, c, d) ((b & c) | (~b & d)) */ -#define FF(b, c, d) (d ^ (b & (c ^ d))) -#define FG(b, c, d) FF (d, b, c) -#define FH(b, c, d) (b ^ c ^ d) -#define FI(b, c, d) (c ^ (b | ~d)) - -/* It is unfortunate that C does not provide an operator for cyclic rotation. Hope the C compiler is smart enough. */ -#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s))) - - md5_uint32 correct_words[16]; - const md5_uint32 *words = buffer; - size_t nwords = len / sizeof(md5_uint32); - const md5_uint32 *endp = words + nwords; - md5_uint32 A = ctx->A; - md5_uint32 B = ctx->B; - md5_uint32 C = ctx->C; - md5_uint32 D = ctx->D; - - /* Process all bytes in the buffer with 64 bytes in each round of the loop. */ - while (words < endp) { - md5_uint32 *cwp = correct_words; - md5_uint32 A_save = A; - md5_uint32 B_save = B; - md5_uint32 C_save = C; - md5_uint32 D_save = D; - - /* First round: using the given function, the context and a constant the next context is computed. - * Because the algorithms processing unit is a 32-bit word and it is determined to work on words in - * little endian byte order we perhaps have to change the byte order before the computation. - * To reduce the work for the next steps we store the swapped words in the array CORRECT_WORDS. - */ -#define OP(a, b, c, d, s, T) \ - a += FF(b, c, d) + (*cwp++ = SWAP(*words)) + T; \ - ++words; \ - CYCLIC(a, s); \ - a += b; \ - (void)0 - - /* Before we start, one word to the strange constants. They are defined in RFC 1321 as: - * T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64 - */ - - /* Round 1. */ - OP(A, B, C, D, 7, 0xd76aa478); - OP(D, A, B, C, 12, 0xe8c7b756); - OP(C, D, A, B, 17, 0x242070db); - OP(B, C, D, A, 22, 0xc1bdceee); - OP(A, B, C, D, 7, 0xf57c0faf); - OP(D, A, B, C, 12, 0x4787c62a); - OP(C, D, A, B, 17, 0xa8304613); - OP(B, C, D, A, 22, 0xfd469501); - OP(A, B, C, D, 7, 0x698098d8); - OP(D, A, B, C, 12, 0x8b44f7af); - OP(C, D, A, B, 17, 0xffff5bb1); - OP(B, C, D, A, 22, 0x895cd7be); - OP(A, B, C, D, 7, 0x6b901122); - OP(D, A, B, C, 12, 0xfd987193); - OP(C, D, A, B, 17, 0xa679438e); - OP(B, C, D, A, 22, 0x49b40821); - -#undef OP - - /* For the second to fourth round we have the possibly swapped words in CORRECT_WORDS. - * Redefine the macro to take an additional first argument specifying the function to use. - */ -#define OP(f, a, b, c, d, k, s, T) \ - a += f(b, c, d) + correct_words[k] + T; \ - CYCLIC(a, s); \ - a += b; \ - (void)0 - - /* Round 2. */ - OP(FG, A, B, C, D, 1, 5, 0xf61e2562); - OP(FG, D, A, B, C, 6, 9, 0xc040b340); - OP(FG, C, D, A, B, 11, 14, 0x265e5a51); - OP(FG, B, C, D, A, 0, 20, 0xe9b6c7aa); - OP(FG, A, B, C, D, 5, 5, 0xd62f105d); - OP(FG, D, A, B, C, 10, 9, 0x02441453); - OP(FG, C, D, A, B, 15, 14, 0xd8a1e681); - OP(FG, B, C, D, A, 4, 20, 0xe7d3fbc8); - OP(FG, A, B, C, D, 9, 5, 0x21e1cde6); - OP(FG, D, A, B, C, 14, 9, 0xc33707d6); - OP(FG, C, D, A, B, 3, 14, 0xf4d50d87); - OP(FG, B, C, D, A, 8, 20, 0x455a14ed); - OP(FG, A, B, C, D, 13, 5, 0xa9e3e905); - OP(FG, D, A, B, C, 2, 9, 0xfcefa3f8); - OP(FG, C, D, A, B, 7, 14, 0x676f02d9); - OP(FG, B, C, D, A, 12, 20, 0x8d2a4c8a); - - /* Round 3. */ - OP(FH, A, B, C, D, 5, 4, 0xfffa3942); - OP(FH, D, A, B, C, 8, 11, 0x8771f681); - OP(FH, C, D, A, B, 11, 16, 0x6d9d6122); - OP(FH, B, C, D, A, 14, 23, 0xfde5380c); - OP(FH, A, B, C, D, 1, 4, 0xa4beea44); - OP(FH, D, A, B, C, 4, 11, 0x4bdecfa9); - OP(FH, C, D, A, B, 7, 16, 0xf6bb4b60); - OP(FH, B, C, D, A, 10, 23, 0xbebfbc70); - OP(FH, A, B, C, D, 13, 4, 0x289b7ec6); - OP(FH, D, A, B, C, 0, 11, 0xeaa127fa); - OP(FH, C, D, A, B, 3, 16, 0xd4ef3085); - OP(FH, B, C, D, A, 6, 23, 0x04881d05); - OP(FH, A, B, C, D, 9, 4, 0xd9d4d039); - OP(FH, D, A, B, C, 12, 11, 0xe6db99e5); - OP(FH, C, D, A, B, 15, 16, 0x1fa27cf8); - OP(FH, B, C, D, A, 2, 23, 0xc4ac5665); - - /* Round 4. */ - OP(FI, A, B, C, D, 0, 6, 0xf4292244); - OP(FI, D, A, B, C, 7, 10, 0x432aff97); - OP(FI, C, D, A, B, 14, 15, 0xab9423a7); - OP(FI, B, C, D, A, 5, 21, 0xfc93a039); - OP(FI, A, B, C, D, 12, 6, 0x655b59c3); - OP(FI, D, A, B, C, 3, 10, 0x8f0ccc92); - OP(FI, C, D, A, B, 10, 15, 0xffeff47d); - OP(FI, B, C, D, A, 1, 21, 0x85845dd1); - OP(FI, A, B, C, D, 8, 6, 0x6fa87e4f); - OP(FI, D, A, B, C, 15, 10, 0xfe2ce6e0); - OP(FI, C, D, A, B, 6, 15, 0xa3014314); - OP(FI, B, C, D, A, 13, 21, 0x4e0811a1); - OP(FI, A, B, C, D, 4, 6, 0xf7537e82); - OP(FI, D, A, B, C, 11, 10, 0xbd3af235); - OP(FI, C, D, A, B, 2, 15, 0x2ad7d2bb); - OP(FI, B, C, D, A, 9, 21, 0xeb86d391); - -#undef OP - - /* Add the starting values of the context. */ - A += A_save; - B += B_save; - C += C_save; - D += D_save; - } - - /* Put checksum in context given as argument. */ - ctx->A = A; - ctx->B = B; - ctx->C = C; - ctx->D = D; - -#undef FF -#undef FG -#undef FH -#undef FI -#undef CYCLIC -} - -/** Put result from 'ctx' in first 16 bytes of 'resbuf'. The result is always in little endian byte order, - * so that a byte-wise output yields to the wanted ASCII representation of the message digest. - */ -static void *md5_read_ctx(const struct md5_ctx *ctx, void *resbuf) -{ - md5_uint32 *digest = resbuf; - digest[0] = SWAP(ctx->A); - digest[1] = SWAP(ctx->B); - digest[2] = SWAP(ctx->C); - digest[3] = SWAP(ctx->D); - - return resbuf; -} - -/* Top level public functions. */ - -/** Compute MD5 message digest for bytes read from 'stream'. - * The resulting message digest number will be written into the 16 bytes beginning at 'resblock'. - * \return Non-zero if an error occurred. - */ -int md5_stream(FILE *stream, void *resblock) -{ -#define BLOCKSIZE 4096 /* Important: must be a multiple of 64. */ - struct md5_ctx ctx; - md5_uint32 len[2]; - char buffer[BLOCKSIZE + 72]; - size_t pad, sum; - - /* Initialize the computation context. */ - md5_init_ctx(&ctx); - - len[0] = 0; - len[1] = 0; - - /* Iterate over full file contents. */ - while (1) { - /* We read the file in blocks of BLOCKSIZE bytes. One call of the computation function processes - * the whole buffer so that with the next round of the loop another block can be read. - */ - size_t n; - sum = 0; - - /* Read block. Take care for partial reads. */ - do { - n = fread(buffer, 1, BLOCKSIZE - sum, stream); - sum += n; - } while (sum < BLOCKSIZE && n != 0); - - if (n == 0 && ferror(stream)) - return 1; - - /* RFC 1321 specifies the possible length of the file up to 2^64 bits. - * Here we only compute the number of bytes. Do a double word increment. - */ - len[0] += sum; - if (len[0] < sum) - ++len[1]; - - /* If end of file is reached, end the loop. */ - if (n == 0) - break; - - /* Process buffer with BLOCKSIZE bytes. Note that BLOCKSIZE % 64 == 0. */ - md5_process_block(buffer, BLOCKSIZE, &ctx); - } - - /* We can copy 64 bytes because the buffer is always big enough. 'fillbuf' contains the needed bits. */ - memcpy(&buffer[sum], fillbuf, 64); - - /* Compute amount of padding bytes needed. Alignment is done to (N + PAD) % 64 == 56. - * There is always at least one byte padded, i.e. if the alignment is correctly aligned, - * 64 padding bytes are added. - */ - pad = sum & 63; - pad = pad >= 56 ? 64 + 56 - pad : 56 - pad; - - /* Put the 64-bit file length in *bits* at the end of the buffer. */ - *(md5_uint32 *) &buffer[sum + pad] = SWAP(len[0] << 3); - *(md5_uint32 *) &buffer[sum + pad + 4] = SWAP((len[1] << 3) | (len[0] >> 29)); - - /* Process last bytes. */ - md5_process_block(buffer, sum + pad + 8, &ctx); - - /* Construct result in desired memory. */ - md5_read_ctx(&ctx, resblock); - return 0; -} - -/** Compute MD5 message digest for 'len' bytes beginning at 'buffer'. - * The result is always in little endian byte order, so that a byte-wise output yields to the wanted - * ASCII representation of the message digest. - */ -void *md5_buffer(const char *buffer, size_t len, void *resblock) -{ - struct md5_ctx ctx; - char restbuf[64 + 72]; - size_t blocks = len & ~63; - size_t pad, rest; - - /* Initialize the computation context. */ - md5_init_ctx(&ctx); - - /* Process whole buffer but last len % 64 bytes. */ - md5_process_block(buffer, blocks, &ctx); - - /* REST bytes are not processed yet. */ - rest = len - blocks; - /* Copy to own buffer. */ - memcpy(restbuf, &buffer[blocks], rest); - /* Append needed fill bytes at end of buffer. We can copy 64 bytes because the buffer is always big enough. */ - memcpy(&restbuf[rest], fillbuf, 64); - - /* PAD bytes are used for padding to correct alignment. Note that always at least one byte is padded. */ - pad = rest >= 56 ? 64 + 56 - rest : 56 - rest; - - /* Put length of buffer in *bits* in last eight bytes. */ - *(md5_uint32 *) &restbuf[rest + pad] = (md5_uint32) SWAP(len << 3); - *(md5_uint32 *) &restbuf[rest + pad + 4] = (md5_uint32) SWAP(len >> 29); - - /* Process last bytes. */ - md5_process_block(restbuf, rest + pad + 8, &ctx); - - /* Put result in desired memory area. */ - return md5_read_ctx(&ctx, resblock); -} - -char *md5_to_hexdigest(void *resblock, char r_hex_digest[33]) -{ - static const char hex_map[17] = "0123456789abcdef"; - const unsigned char *p; - char *q; - short len; - - for (q = r_hex_digest, p = (const unsigned char *)resblock, len = 0; len < 16; ++p, ++len) { - const unsigned char c = *p; - *q++ = hex_map[c >> 4]; - *q++ = hex_map[c & 15]; - } - *q = '\0'; - - return r_hex_digest; -} -- cgit v1.2.3 From 14795baf2142024905c6936a82eaa2321dae8cb8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 14 Nov 2014 11:49:45 +0100 Subject: Cleanup: headers --- source/blender/blenlib/BLI_hash_md5.h | 9 +++------ source/blender/blenlib/BLI_hash_mm2a.h | 6 +++--- source/blender/blenlib/intern/hash_md5.c | 4 ++-- 3 files changed, 8 insertions(+), 11 deletions(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_hash_md5.h b/source/blender/blenlib/BLI_hash_md5.h index cab3671a5ca..81a0eb9e828 100644 --- a/source/blender/blenlib/BLI_hash_md5.h +++ b/source/blender/blenlib/BLI_hash_md5.h @@ -18,16 +18,13 @@ * ***** END GPL LICENSE BLOCK ***** */ -#ifndef __BLI_MD5_H__ -#define __BLI_MD5_H__ +#ifndef __BLI_HASH_MD5_H__ +#define __BLI_HASH_MD5_H__ /** \file BLI_hash_md5.h * \ingroup bli */ -#include -#include - /* Compute MD5 message digest for LEN bytes beginning at BUFFER. The * result is always in little endian byte order, so that a byte-wise * output yields to the wanted ASCII representation of the message @@ -43,4 +40,4 @@ int md5_stream(FILE *stream, void *resblock); char *md5_to_hexdigest(void *resblock, char r_hex_digest[33]); -#endif /* __BLI_MD5_H__ */ +#endif /* __BLI_HASH_MD5_H__ */ diff --git a/source/blender/blenlib/BLI_hash_mm2a.h b/source/blender/blenlib/BLI_hash_mm2a.h index 503eb5e96d9..007dec4f4d6 100644 --- a/source/blender/blenlib/BLI_hash_mm2a.h +++ b/source/blender/blenlib/BLI_hash_mm2a.h @@ -18,8 +18,8 @@ * ***** END GPL LICENSE BLOCK ***** */ -#ifndef __BLI_MM2A_H__ -#define __BLI_MM2A_H__ +#ifndef __BLI_HASH_MM2A_H__ +#define __BLI_HASH_MM2A_H__ /** \file BLI_hash_mm2a.h * \ingroup bli @@ -42,4 +42,4 @@ void BLI_hash_mm2a_add_int(BLI_HashMurmur2A *mm2, int data); uint32_t BLI_hash_mm2a_end(BLI_HashMurmur2A *mm2); -#endif /* __BLI_MM2A_H__ */ +#endif /* __BLI_HASH_MM2A_H__ */ diff --git a/source/blender/blenlib/intern/hash_md5.c b/source/blender/blenlib/intern/hash_md5.c index 98a5cc545b5..43019781577 100644 --- a/source/blender/blenlib/intern/hash_md5.c +++ b/source/blender/blenlib/intern/hash_md5.c @@ -29,13 +29,13 @@ * according to the definition of MD5 in RFC 1321 from April 1992. */ -#include "BLI_hash_md5.h" /* own include */ - #include #include #include #include +#include "BLI_hash_md5.h" /* own include */ + #if defined HAVE_LIMITS_H || defined _LIBC # include #endif -- cgit v1.2.3 From 60ffc08547476781f9b3f61c344af13fbad13ec5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 14 Nov 2014 11:53:27 +0100 Subject: Cleanup: use BLI_hash_ prefix for md5 api --- source/blender/blenlib/BLI_hash_md5.h | 6 +++--- source/blender/blenlib/intern/hash_md5.c | 9 +++++---- 2 files changed, 8 insertions(+), 7 deletions(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_hash_md5.h b/source/blender/blenlib/BLI_hash_md5.h index 81a0eb9e828..544ae753793 100644 --- a/source/blender/blenlib/BLI_hash_md5.h +++ b/source/blender/blenlib/BLI_hash_md5.h @@ -30,14 +30,14 @@ * output yields to the wanted ASCII representation of the message * digest. */ -void *md5_buffer(const char *buffer, size_t len, void *resblock); +void *BLI_hash_md5_buffer(const char *buffer, size_t len, void *resblock); /* Compute MD5 message digest for bytes read from STREAM. The * resulting message digest number will be written into the 16 bytes * beginning at RESBLOCK. */ -int md5_stream(FILE *stream, void *resblock); +int BLI_hash_md5_stream(FILE *stream, void *resblock); -char *md5_to_hexdigest(void *resblock, char r_hex_digest[33]); +char *BLI_hash_md5_to_hexdigest(void *resblock, char r_hex_digest[33]); #endif /* __BLI_HASH_MD5_H__ */ diff --git a/source/blender/blenlib/intern/hash_md5.c b/source/blender/blenlib/intern/hash_md5.c index 43019781577..bc7a495f213 100644 --- a/source/blender/blenlib/intern/hash_md5.c +++ b/source/blender/blenlib/intern/hash_md5.c @@ -77,7 +77,8 @@ #endif -/* Following code is low level, upon which are built up the functions 'md5_stream' and 'md5_buffer'. */ +/* Following code is low level, upon which are built up the functions + * 'BLI_hash_md5_stream' and 'BLI_hash_md5_buffer'. */ /* Structure to save state of computation between the single steps. */ struct md5_ctx @@ -284,7 +285,7 @@ static void *md5_read_ctx(const struct md5_ctx *ctx, void *resbuf) * The resulting message digest number will be written into the 16 bytes beginning at 'resblock'. * \return Non-zero if an error occurred. */ -int md5_stream(FILE *stream, void *resblock) +int BLI_hash_md5_stream(FILE *stream, void *resblock) { #define BLOCKSIZE 4096 /* Important: must be a multiple of 64. */ struct md5_ctx ctx; @@ -356,7 +357,7 @@ int md5_stream(FILE *stream, void *resblock) * The result is always in little endian byte order, so that a byte-wise output yields to the wanted * ASCII representation of the message digest. */ -void *md5_buffer(const char *buffer, size_t len, void *resblock) +void *BLI_hash_md5_buffer(const char *buffer, size_t len, void *resblock) { struct md5_ctx ctx; char restbuf[64 + 72]; @@ -390,7 +391,7 @@ void *md5_buffer(const char *buffer, size_t len, void *resblock) return md5_read_ctx(&ctx, resblock); } -char *md5_to_hexdigest(void *resblock, char r_hex_digest[33]) +char *BLI_hash_md5_to_hexdigest(void *resblock, char r_hex_digest[33]) { static const char hex_map[17] = "0123456789abcdef"; const unsigned char *p; -- cgit v1.2.3 From 7d040d2a088ec425550da4242650f1ff75680e0d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 16 Nov 2014 13:57:58 +0100 Subject: Cleanup: use BLI_listbase_*** prefix for count,sort,sort_r --- source/blender/blenlib/BLI_listbase.h | 6 +++--- source/blender/blenlib/intern/listbase.c | 6 +++--- source/blender/blenlib/intern/scanfill.c | 2 +- source/blender/blenlib/intern/scanfill_utils.c | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h index 3f03c4e3845..543a662c5e5 100644 --- a/source/blender/blenlib/BLI_listbase.h +++ b/source/blender/blenlib/BLI_listbase.h @@ -67,10 +67,10 @@ void *BLI_poptail(ListBase *listbase) ATTR_NONNULL(1); void BLI_addhead(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1); void BLI_insertlinkbefore(struct ListBase *listbase, void *vnextlink, void *vnewlink) ATTR_NONNULL(1); void BLI_insertlinkafter(struct ListBase *listbase, void *vprevlink, void *vnewlink) ATTR_NONNULL(1); -void BLI_sortlist(struct ListBase *listbase, int (*cmp)(const void *, const void *)) ATTR_NONNULL(1, 2); -void BLI_sortlist_r(ListBase *listbase, void *thunk, int (*cmp)(void *, const void *, const void *)) ATTR_NONNULL(1, 3); +void BLI_listbase_sort(struct ListBase *listbase, int (*cmp)(const void *, const void *)) ATTR_NONNULL(1, 2); +void BLI_listbase_sort_r(ListBase *listbase, void *thunk, int (*cmp)(void *, const void *, const void *)) ATTR_NONNULL(1, 3); void BLI_freelist(struct ListBase *listbase) ATTR_NONNULL(1); -int BLI_countlist(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); +int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1); void BLI_listbase_swaplinks(struct ListBase *listbase, void *vlinka, void *vlinkb) ATTR_NONNULL(1, 2); diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c index 6fcc5888382..cd2e343560f 100644 --- a/source/blender/blenlib/intern/listbase.c +++ b/source/blender/blenlib/intern/listbase.c @@ -211,7 +211,7 @@ void BLI_freelinkN(ListBase *listbase, void *vlink) * (which should return 1 iff its first arg should come after its second arg). * This uses insertion sort, so NOT ok for large list. */ -void BLI_sortlist(ListBase *listbase, int (*cmp)(const void *, const void *)) +void BLI_listbase_sort(ListBase *listbase, int (*cmp)(const void *, const void *)) { Link *current = NULL; Link *previous = NULL; @@ -233,7 +233,7 @@ void BLI_sortlist(ListBase *listbase, int (*cmp)(const void *, const void *)) } } -void BLI_sortlist_r(ListBase *listbase, void *thunk, int (*cmp)(void *, const void *, const void *)) +void BLI_listbase_sort_r(ListBase *listbase, void *thunk, int (*cmp)(void *, const void *, const void *)) { Link *current = NULL; Link *previous = NULL; @@ -376,7 +376,7 @@ void BLI_freelistN(ListBase *listbase) /** * Returns the number of elements in \a listbase. */ -int BLI_countlist(const ListBase *listbase) +int BLI_listbase_count(const ListBase *listbase) { Link *link; int count = 0; diff --git a/source/blender/blenlib/intern/scanfill.c b/source/blender/blenlib/intern/scanfill.c index cf0d8cff870..1653ba5ae6e 100644 --- a/source/blender/blenlib/intern/scanfill.c +++ b/source/blender/blenlib/intern/scanfill.c @@ -807,7 +807,7 @@ unsigned int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const #if 0 if (flag & BLI_SCANFILL_CALC_QUADTRI_FASTPATH) { - const int totverts = BLI_countlist(&sf_ctx->fillvertbase); + const int totverts = BLI_listbase_count(&sf_ctx->fillvertbase); if (totverts == 3) { eve = sf_ctx->fillvertbase.first; diff --git a/source/blender/blenlib/intern/scanfill_utils.c b/source/blender/blenlib/intern/scanfill_utils.c index 9fc1db1f1e4..029e98bad5e 100644 --- a/source/blender/blenlib/intern/scanfill_utils.c +++ b/source/blender/blenlib/intern/scanfill_utils.c @@ -265,7 +265,7 @@ static bool scanfill_preprocess_self_isect( } if (BLI_listbase_is_single(e_ls) == false) { - BLI_sortlist_r(e_ls, eed->v2->co, edge_isect_ls_sort_cb); + BLI_listbase_sort_r(e_ls, eed->v2->co, edge_isect_ls_sort_cb); } /* move original edge to filledgebase and add replacement -- cgit v1.2.3 From 0e60accf2afa4fc69da99743bb64d82cb3e0fbc4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 16 Nov 2014 14:02:18 +0100 Subject: BLI_listbase: Add BLI_listbase_count_ex (sets a limit) This can be used to avoid redundant looping when we only want to know if a list is smaller then some size. also remove paranoid NULL check in list counting. --- source/blender/blenlib/BLI_listbase.h | 1 + source/blender/blenlib/intern/listbase.c | 22 +++++++++++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h index 543a662c5e5..2e01f743f9e 100644 --- a/source/blender/blenlib/BLI_listbase.h +++ b/source/blender/blenlib/BLI_listbase.h @@ -70,6 +70,7 @@ void BLI_insertlinkafter(struct ListBase *listbase, void *vprevlink, void *vnewl void BLI_listbase_sort(struct ListBase *listbase, int (*cmp)(const void *, const void *)) ATTR_NONNULL(1, 2); void BLI_listbase_sort_r(ListBase *listbase, void *thunk, int (*cmp)(void *, const void *, const void *)) ATTR_NONNULL(1, 3); void BLI_freelist(struct ListBase *listbase) ATTR_NONNULL(1); +int BLI_listbase_count_ex(const struct ListBase *listbase, const int count_max) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1); void BLI_freelinkN(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1); diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c index cd2e343560f..ea33b9b1e3b 100644 --- a/source/blender/blenlib/intern/listbase.c +++ b/source/blender/blenlib/intern/listbase.c @@ -372,6 +372,17 @@ void BLI_freelistN(ListBase *listbase) BLI_listbase_clear(listbase); } +int BLI_listbase_count_ex(const ListBase *listbase, const int count_max) +{ + Link *link; + int count = 0; + + for (link = listbase->first; link && count != count_max; link = link->next) { + count++; + } + + return count; +} /** * Returns the number of elements in \a listbase. @@ -380,14 +391,11 @@ int BLI_listbase_count(const ListBase *listbase) { Link *link; int count = 0; - - if (listbase) { - link = listbase->first; - while (link) { - count++; - link = link->next; - } + + for (link = listbase->first; link; link = link->next) { + count++; } + return count; } -- cgit v1.2.3 From c31f74de6bb7938ce0e36f75caeedfa16ac90b53 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 16 Nov 2014 14:23:37 +0100 Subject: Cleanup: use BLI_listbase_count_ex to avoid redundant looping --- source/blender/blenlib/intern/listbase.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c index ea33b9b1e3b..bd3e1e0bbb0 100644 --- a/source/blender/blenlib/intern/listbase.c +++ b/source/blender/blenlib/intern/listbase.c @@ -372,6 +372,11 @@ void BLI_freelistN(ListBase *listbase) BLI_listbase_clear(listbase); } +/** + * Returns the number of elements in \a listbase, up until (and including count_max) + * + * \note Use to avoid redundant looping. + */ int BLI_listbase_count_ex(const ListBase *listbase, const int count_max) { Link *link; -- cgit v1.2.3 From 832a97f00270ad6d5740d3b8938d82269760964e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 16 Nov 2014 14:29:17 +0100 Subject: Macros: ELEM() can now take 2 args Handy when used indirectly. --- source/blender/blenlib/BLI_utildefines.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h index f318ae0e39f..16d3c2f8a42 100644 --- a/source/blender/blenlib/BLI_utildefines.h +++ b/source/blender/blenlib/BLI_utildefines.h @@ -51,7 +51,7 @@ _49_, _50_, _51_, _52_, _53_, _54_, _55_, _56_, _57_, _58_, _59_, _60_, _61_, _62_, _63_, _64_, \ count, ...) count #define _VA_NARGS_EXPAND(args) _VA_NARGS_RETURN_COUNT args -#define _VA_NARGS_COUNT_MAX32(...) _VA_NARGS_EXPAND((__VA_ARGS__, \ +#define _VA_NARGS_COUNT_MAX64(...) _VA_NARGS_EXPAND((__VA_ARGS__, \ 64, 63, 62, 61, 60, 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, \ 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, 37, 36, 35, 34, 33, \ 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, \ @@ -61,7 +61,7 @@ #define _VA_NARGS_OVERLOAD_MACRO(name, count) _VA_NARGS_OVERLOAD_MACRO1(name, count) /* --- expose for re-use --- */ #define VA_NARGS_CALL_OVERLOAD(name, ...) \ - _VA_NARGS_GLUE(_VA_NARGS_OVERLOAD_MACRO(name, _VA_NARGS_COUNT_MAX32(__VA_ARGS__)), (__VA_ARGS__)) + _VA_NARGS_GLUE(_VA_NARGS_OVERLOAD_MACRO(name, _VA_NARGS_COUNT_MAX64(__VA_ARGS__)), (__VA_ARGS__)) /* useful for finding bad use of min/max */ #if 0 @@ -179,8 +179,10 @@ /* ELEM#(v, ...): is the first arg equal any others? */ /* internal helpers*/ +#define _VA_ELEM2(v, a) \ + ((v) == (a)) #define _VA_ELEM3(v, a, b) \ - (((v) == (a)) || ((v) == (b))) + (_VA_ELEM2(v, a) || ((v) == (b))) #define _VA_ELEM4(v, a, b, c) \ (_VA_ELEM3(v, a, b) || ((v) == (c))) #define _VA_ELEM5(v, a, b, c, d) \ -- cgit v1.2.3 From 94f0d18470fc454b456f711c9d040a7fef6780fb Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 18 Nov 2014 00:20:56 +0100 Subject: BLI_assert: print a backtrace with the error Add BLI_system_backtrace() --- source/blender/blenlib/BLI_system.h | 5 ++- source/blender/blenlib/BLI_utildefines.h | 2 + source/blender/blenlib/intern/system.c | 75 ++++++++++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 1 deletion(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_system.h b/source/blender/blenlib/BLI_system.h index 8cdc9e4e6c5..bc81b85303d 100644 --- a/source/blender/blenlib/BLI_system.h +++ b/source/blender/blenlib/BLI_system.h @@ -27,6 +27,10 @@ int BLI_cpu_support_sse2(void); +#if !defined(NDEBUG) && !defined(__BLI_UTILDEFINES_H__) +void BLI_system_backtrace(FILE *fp); +#endif + /* getpid */ #ifdef WIN32 # define BLI_SYSTEM_PID_H @@ -35,4 +39,3 @@ int BLI_cpu_support_sse2(void); #endif #endif /* __BLI_SYSTEM_H__ */ - diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h index 16d3c2f8a42..a6dee7fd263 100644 --- a/source/blender/blenlib/BLI_utildefines.h +++ b/source/blender/blenlib/BLI_utildefines.h @@ -510,6 +510,7 @@ * for aborting need to define WITH_ASSERT_ABORT */ #ifndef NDEBUG +extern void BLI_system_backtrace(FILE *fp); # ifdef WITH_ASSERT_ABORT # define _BLI_DUMMY_ABORT abort # else @@ -519,6 +520,7 @@ # define BLI_assert(a) \ (void)((!(a)) ? ( \ ( \ + BLI_system_backtrace(stderr), \ fprintf(stderr, \ "BLI_assert failed: %s:%d, %s(), at \'%s\'\n", \ __FILE__, __LINE__, __func__, STRINGIFY(a)), \ diff --git a/source/blender/blenlib/intern/system.c b/source/blender/blenlib/intern/system.c index e6389bc68f3..51b8efbb79f 100644 --- a/source/blender/blenlib/intern/system.c +++ b/source/blender/blenlib/intern/system.c @@ -22,9 +22,18 @@ * \ingroup bli */ +#include +#include #include "BLI_system.h" +/* for backtrace */ +#if defined(__linux__) || defined(__APPLE__) +# include +#elif defined(_MSV_VER) +# include +#endif + int BLI_cpu_support_sse2(void) { #if defined(__x86_64__) || defined(_M_X64) @@ -57,3 +66,69 @@ int BLI_cpu_support_sse2(void) #endif } +/** + * Write a backtrace into a file for systems which support it. + */ +void BLI_system_backtrace(FILE *fp) +{ + /* ------------- */ + /* Linux / Apple */ +#if defined(__linux__) || defined(__APPLE__) + +#define SIZE 100 + void *buffer[SIZE]; + int nptrs; + char **strings; + int i; + + /* include a backtrace for good measure */ + nptrs = backtrace(buffer, SIZE); + strings = backtrace_symbols(buffer, nptrs); + for (i = 0; i < nptrs; i++) { + fputs(strings[i], fp); + fputc('\n', fp); + } + + free(strings); +#undef SIZE + + /* -------- */ + /* Windows */ +#elif defined(_MSC_VER) + + (void)fp; +#if 0 +#define MAXSYMBOL 256 + unsigned short i; + void *stack[SIZE]; + unsigned short nframes; + SYMBOL_INFO *symbolinfo; + HANDLE process; + + process = GetCurrentProcess(); + + SymInitialize(process, NULL, true); + + nframes = CaptureStackBackTrace(0, SIZE, stack, NULL); + symbolinfo = MEM_callocN(sizeof(SYMBOL_INFO) + MAXSYMBOL * sizeof(char), "crash Symbol table"); + symbolinfo->MaxNameLen = MAXSYMBOL - 1; + symbolinfo->SizeOfStruct = sizeof(SYMBOL_INFO); + + for (i = 0; i < nframes; i++) { + SymFromAddr(process, ( DWORD64 )( stack[ i ] ), 0, symbolinfo); + + fprintf(fp, "%u: %s - 0x%0X\n", nframes - i - 1, symbolinfo->Name, symbolinfo->Address); + } + + MEM_freeN(symbolinfo); +#undef MAXSYMBOL +#endif + + /* ------------------ */ + /* non msvc/osx/linux */ +#else + (void)fp; +#endif + +} +/* end BLI_system_backtrace */ -- cgit v1.2.3 From b72eab5d6bd13df535664e5044a78ce6618fa904 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 18 Nov 2014 10:24:24 +0100 Subject: Error in last commit (broke release build) --- source/blender/blenlib/BLI_system.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_system.h b/source/blender/blenlib/BLI_system.h index bc81b85303d..cb8cb6f5a0d 100644 --- a/source/blender/blenlib/BLI_system.h +++ b/source/blender/blenlib/BLI_system.h @@ -27,7 +27,7 @@ int BLI_cpu_support_sse2(void); -#if !defined(NDEBUG) && !defined(__BLI_UTILDEFINES_H__) +#if defined(NDEBUG) || !defined(__BLI_UTILDEFINES_H__) void BLI_system_backtrace(FILE *fp); #endif -- cgit v1.2.3 From 5efd2b7f36fbe2444e77d2b7b275d793da997c84 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 18 Nov 2014 10:55:46 +0100 Subject: correct another problem with BLI_assert need to use extern C for C++ --- source/blender/blenlib/BLI_utildefines.h | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h index a6dee7fd263..9a8877e39c3 100644 --- a/source/blender/blenlib/BLI_utildefines.h +++ b/source/blender/blenlib/BLI_utildefines.h @@ -32,6 +32,10 @@ * \ingroup bli */ +#ifdef __cplusplus +extern "C" { +#endif + /* avoid many includes for now */ #include "BLI_sys_types.h" #include "BLI_compiler_compat.h" @@ -560,4 +564,8 @@ extern void BLI_system_backtrace(FILE *fp); # define UNLIKELY(x) (x) #endif +#ifdef __cplusplus +} +#endif + #endif /* __BLI_UTILDEFINES_H__ */ -- cgit v1.2.3 From 391096252b8848099517f4e78dec020e4707f2a3 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Thu, 20 Nov 2014 14:57:35 +0100 Subject: Fix T42638: Roll angle inconsistent flip in edit mode. Basically, `angle_compat_rad()` was completely broken - example of result it could produce: | new angle | compat angle | result | -0.000000 | 3.141593 | -> 3.141593 ... Where 0.0 (or 2 * PI) would be expected! --- source/blender/blenlib/intern/math_rotation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c index 9a6515daf68..3ac031d7b90 100644 --- a/source/blender/blenlib/intern/math_rotation.c +++ b/source/blender/blenlib/intern/math_rotation.c @@ -1867,7 +1867,7 @@ float angle_wrap_deg(float angle) /* returns an angle compatible with angle_compat */ float angle_compat_rad(float angle, float angle_compat) { - return angle + (floorf(((angle_compat - angle) / (float)M_PI) + 0.5f)) * (float)M_PI; + return angle_compat + angle_wrap_rad(angle - angle_compat); } /* axis conversion */ -- cgit v1.2.3 From 7b0c529fe211e4481fe8e459cbf11159857c611d Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 21 Nov 2014 11:31:30 +0100 Subject: Task scheduler: Add an option to limit number of threads per pool This way we can have scheduler capable of scheduling tasks on all the CPUs but in the same time we can limit tasks like baking (in the future) to use no more than given number of threads. --- source/blender/blenlib/BLI_task.h | 3 ++ source/blender/blenlib/intern/task.c | 62 ++++++++++++++++++++++++++++-------- 2 files changed, 51 insertions(+), 14 deletions(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_task.h b/source/blender/blenlib/BLI_task.h index 28da673ea97..8f85bc4ec31 100644 --- a/source/blender/blenlib/BLI_task.h +++ b/source/blender/blenlib/BLI_task.h @@ -88,6 +88,9 @@ void BLI_task_pool_cancel(TaskPool *pool); /* stop all worker threads */ void BLI_task_pool_stop(TaskPool *pool); +/* set number of threads allowed to be used by this pool */ +void BLI_pool_set_num_threads(TaskPool *pool, int num_threads); + /* for worker threads, test if canceled */ bool BLI_task_pool_canceled(TaskPool *pool); diff --git a/source/blender/blenlib/intern/task.c b/source/blender/blenlib/intern/task.c index 219ccb18d98..e4cded18b76 100644 --- a/source/blender/blenlib/intern/task.c +++ b/source/blender/blenlib/intern/task.c @@ -49,6 +49,8 @@ struct TaskPool { volatile size_t num; volatile size_t done; + volatile int num_threads; + volatile int currently_running_tasks; ThreadMutex num_mutex; ThreadCondition num_cond; @@ -84,6 +86,7 @@ static void task_pool_num_decrease(TaskPool *pool, size_t done) BLI_assert(pool->num >= done); pool->num -= done; + pool->currently_running_tasks -= done; pool->done += done; if (pool->num == 0) @@ -104,19 +107,37 @@ static void task_pool_num_increase(TaskPool *pool) static bool task_scheduler_thread_wait_pop(TaskScheduler *scheduler, Task **task) { + bool found_task = false; BLI_mutex_lock(&scheduler->queue_mutex); while (!scheduler->queue.first && !scheduler->do_exit) BLI_condition_wait(&scheduler->queue_cond, &scheduler->queue_mutex); - if (!scheduler->queue.first) { - BLI_mutex_unlock(&scheduler->queue_mutex); - BLI_assert(scheduler->do_exit); - return false; - } - - *task = scheduler->queue.first; - BLI_remlink(&scheduler->queue, *task); + do { + Task *current_task; + if (!scheduler->queue.first) { + BLI_mutex_unlock(&scheduler->queue_mutex); + BLI_assert(scheduler->do_exit); + return false; + } + for (current_task = scheduler->queue.first; + current_task != NULL; + current_task = current_task->next) + { + TaskPool *pool = current_task->pool; + if (pool->num_threads == 0 || + pool->currently_running_tasks < pool->num_threads) + { + *task = current_task; + found_task = true; + pool->currently_running_tasks++; + BLI_remlink(&scheduler->queue, *task); + break; + } + } + if (!found_task) + BLI_condition_wait(&scheduler->queue_cond, &scheduler->queue_mutex); + } while (!found_task); BLI_mutex_unlock(&scheduler->queue_mutex); @@ -288,6 +309,8 @@ TaskPool *BLI_task_pool_create(TaskScheduler *scheduler, void *userdata) pool->scheduler = scheduler; pool->num = 0; + pool->num_threads = 0; + pool->currently_running_tasks = 0; pool->do_cancel = false; BLI_mutex_init(&pool->num_mutex); @@ -351,12 +374,16 @@ void BLI_task_pool_work_and_wait(TaskPool *pool) /* find task from this pool. if we get a task from another pool, * we can get into deadlock */ - for (task = scheduler->queue.first; task; task = task->next) { - if (task->pool == pool) { - work_task = task; - found_task = true; - BLI_remlink(&scheduler->queue, task); - break; + if (pool->num_threads == 0 || + pool->currently_running_tasks < pool->num_threads) + { + for (task = scheduler->queue.first; task; task = task->next) { + if (task->pool == pool) { + work_task = task; + found_task = true; + BLI_remlink(&scheduler->queue, task); + break; + } } } @@ -365,6 +392,7 @@ void BLI_task_pool_work_and_wait(TaskPool *pool) /* if found task, do it, otherwise wait until other tasks are done */ if (found_task) { /* run task */ + pool->currently_running_tasks++; work_task->run(pool, work_task->taskdata, 0); /* delete task */ @@ -387,6 +415,12 @@ void BLI_task_pool_work_and_wait(TaskPool *pool) BLI_mutex_unlock(&pool->num_mutex); } +void BLI_pool_set_num_threads(TaskPool *pool, int num_threads) +{ + /* NOTE: Don't try to modify threads while tasks are running! */ + pool->num_threads = num_threads; +} + void BLI_task_pool_cancel(TaskPool *pool) { pool->do_cancel = true; -- cgit v1.2.3 From 46e2d5ee41751542ea54177bb268ac957527867b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 21 Nov 2014 14:14:50 +0100 Subject: Cleanup: typo --- source/blender/blenlib/intern/convexhull2d.c | 4 ++-- source/blender/blenlib/intern/easing.c | 2 +- source/blender/blenlib/intern/math_geom.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/intern/convexhull2d.c b/source/blender/blenlib/intern/convexhull2d.c index 361e4b4eadb..5f64088f433 100644 --- a/source/blender/blenlib/intern/convexhull2d.c +++ b/source/blender/blenlib/intern/convexhull2d.c @@ -187,8 +187,8 @@ static int pointref_cmp_yx(const void *a_, const void *b_) * \param points An array of 2D points. * \param n The number of points in points. * \param r_points An array of the convex hull vertex indices (max is n). - * _must_ be allocated as ``n * 2`` because of how its used internally, - * even though the final result will be no more then \a n in size. + * _must_ be allocated as ``n * 2`` because of how its used internally, + * even though the final result will be no more than \a n in size. * \returns the number of points in r_points. */ int BLI_convexhull_2d(const float (*points)[2], const int n, int r_points[]) diff --git a/source/blender/blenlib/intern/easing.c b/source/blender/blenlib/intern/easing.c index 80f02d54eaa..90c8528338e 100644 --- a/source/blender/blenlib/intern/easing.c +++ b/source/blender/blenlib/intern/easing.c @@ -139,7 +139,7 @@ float BLI_easing_cubic_ease_in_out(float time, float begin, float change, float #ifdef USE_ELASTIC_BLEND /** - * When the amplitude is less then the change, we need to blend + * When the amplitude is less than the change, we need to blend * \a f when we're close to the crossing point (int time), else we get an ugly sharp falloff. */ static float elastic_blend(float time, float change, float duration, float amplitude, float s, float f) diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 015313431cb..60373458a5c 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -1840,7 +1840,7 @@ float line_plane_factor_v3(const float plane_co[3], const float plane_no[3], return (dot != 0.0f) ? -dot_v3v3(plane_no, h) / dot : 0.0f; } -/** Ensure the distance between these points is no greater then 'dist'. +/** Ensure the distance between these points is no greater than 'dist'. * If it is, scale then both into the center. */ void limit_dist_v3(float v1[3], float v2[3], const float dist) -- cgit v1.2.3 From 25c5542fe78abe79cdf9d2ec46607de01762f32e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 22 Nov 2014 18:11:46 +0100 Subject: Math Lib: add constant: M_SQRT1_3 1/sqrt(3) --- source/blender/blenlib/BLI_math_base.h | 9 ++++++--- source/blender/blenlib/intern/math_matrix.c | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_math_base.h b/source/blender/blenlib/BLI_math_base.h index 5711d09b530..13718e83621 100644 --- a/source/blender/blenlib/BLI_math_base.h +++ b/source/blender/blenlib/BLI_math_base.h @@ -48,13 +48,16 @@ #define M_PI_2 1.57079632679489661923 #endif #ifndef M_SQRT2 -#define M_SQRT2 1.41421356237309504880 +#define M_SQRT2 1.41421356237309504880 /* sqrt(2) */ #endif #ifndef M_SQRT1_2 -#define M_SQRT1_2 0.70710678118654752440 +#define M_SQRT1_2 0.70710678118654752440 /* 1/sqrt(2) */ #endif #ifndef M_SQRT3 -#define M_SQRT3 1.7320508075688772 +#define M_SQRT3 1.73205080756887729352 /* sqrt(3) */ +#endif +#ifndef M_SQRT1_3 +#define M_SQRT1_3 0.57735026918962576450 /* 1/sqrt(3) */ #endif #ifndef M_1_PI #define M_1_PI 0.318309886183790671538 diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index 0204c3bc86c..2da1f225034 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -1448,7 +1448,7 @@ float mat3_to_scale(float mat[3][3]) { /* unit length vector */ float unit_vec[3]; - copy_v3_fl(unit_vec, (float)(1.0 / M_SQRT3)); + copy_v3_fl(unit_vec, (float)M_SQRT1_3); mul_m3_v3(mat, unit_vec); return len_v3(unit_vec); } @@ -1457,7 +1457,7 @@ float mat4_to_scale(float mat[4][4]) { /* unit length vector */ float unit_vec[3]; - copy_v3_fl(unit_vec, (float)(1.0 / M_SQRT3)); + copy_v3_fl(unit_vec, (float)M_SQRT1_3); mul_mat3_m4_v3(mat, unit_vec); return len_v3(unit_vec); } -- cgit v1.2.3 From 6308c16675fa7d5d6a3b91eb8591402c65b767d6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 23 Nov 2014 14:37:13 +0100 Subject: Refactor: BLI_path_util (split out app directory access) This module is intended for path manipulation functions but had utility functions added to access various directories. --- source/blender/blenlib/BLI_path_util.h | 47 -- source/blender/blenlib/CMakeLists.txt | 1 - source/blender/blenlib/intern/path_util.c | 759 +----------------------------- 3 files changed, 1 insertion(+), 806 deletions(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h index 3d82480d050..bade390d056 100644 --- a/source/blender/blenlib/BLI_path_util.h +++ b/source/blender/blenlib/BLI_path_util.h @@ -40,40 +40,6 @@ extern "C" { struct ListBase; struct direntry; -const char *BLI_getDefaultDocumentFolder(void); - -const char *BLI_get_folder(int folder_id, const char *subfolder); -const char *BLI_get_folder_create(int folder_id, const char *subfolder); -const char *BLI_get_user_folder_notest(int folder_id, const char *subfolder); -const char *BLI_get_folder_version(const int id, const int ver, const bool do_check); - -/* folder_id */ - -/* general, will find based on user/local/system priority */ -#define BLENDER_DATAFILES 2 - -/* user-specific */ -#define BLENDER_USER_CONFIG 31 -#define BLENDER_USER_DATAFILES 32 -#define BLENDER_USER_SCRIPTS 33 -#define BLENDER_USER_AUTOSAVE 34 - -/* system */ -#define BLENDER_SYSTEM_DATAFILES 52 -#define BLENDER_SYSTEM_SCRIPTS 53 -#define BLENDER_SYSTEM_PYTHON 54 - -/* for BLI_get_folder_version only */ -#define BLENDER_RESOURCE_PATH_USER 0 -#define BLENDER_RESOURCE_PATH_LOCAL 1 -#define BLENDER_RESOURCE_PATH_SYSTEM 2 - -#define BLENDER_STARTUP_FILE "startup.blend" -#define BLENDER_USERPREF_FILE "userpref.blend" -#define BLENDER_QUIT_FILE "quit.blend" -#define BLENDER_BOOKMARK_FILE "bookmarks.txt" -#define BLENDER_HISTORY_FILE "recent-files.txt" - #ifdef WIN32 #define SEP '\\' #define ALTSEP '/' @@ -185,19 +151,6 @@ bool BLI_path_suffix(char *string, size_t maxlen, const char *suffix, const char void BLI_char_switch(char *string, char from, char to) ATTR_NONNULL(); -/* Initialize path to program executable */ -void BLI_init_program_path(const char *argv0); -/* Initialize path to temporary directory. - * NOTE: On Window userdir will be set to the temporary directory! */ -void BLI_temp_dir_init(char *userdir); - -const char *BLI_program_path(void); -const char *BLI_program_dir(void); -const char *BLI_temp_dir_session(void); -const char *BLI_temp_dir_base(void); -void BLI_system_temporary_dir(char *dir); -void BLI_temp_dir_session_purge(void); - #ifdef WITH_ICONV void BLI_string_to_utf8(char *original, char *utf_8, const char *code); #endif diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index ba166b11960..cb84c0d2e52 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -29,7 +29,6 @@ set(INC . # ../blenkernel # dont add this back! ../makesdna - ../../../intern/ghost ../../../intern/guardedalloc ../../../extern/wcwidth ) diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c index e3e13b0bcac..9a9385e0687 100644 --- a/source/blender/blenlib/intern/path_util.c +++ b/source/blender/blenlib/intern/path_util.c @@ -45,12 +45,6 @@ #include "BLI_string_utf8.h" #include "BLI_fnmatch.h" -#include "../blenkernel/BKE_blender.h" /* BLENDER_VERSION, bad level include (no function call) */ - -#include "GHOST_Path-api.h" - -#include "MEM_guardedalloc.h" - #ifdef WIN32 # include "utf_winfunc.h" # include "utfconv.h" @@ -62,21 +56,12 @@ # include # include # include "BLI_winstuff.h" -#else /* non windows */ -# ifdef WITH_BINRELOC -# include "binreloc.h" -# endif -# include /* mkdtemp on OSX (and probably all *BSD?), not worth making specific check for this OS. */ +# include "MEM_guardedalloc.h" #endif /* WIN32 */ /* local */ #define UNIQUE_NAME_MAX 128 -static char bprogname[FILE_MAX]; /* full path to program executable */ -static char bprogdir[FILE_MAX]; /* full path to directory in which executable is located */ -static char btempdir_base[FILE_MAX]; /* persistent temporary directory */ -static char btempdir_session[FILE_MAX] = ""; /* volatile temporary directory */ - /* implementation */ /** @@ -1038,446 +1023,8 @@ void BLI_getlastdir(const char *dir, char *last, const size_t maxlen) } } -/* This is now only used to really get the user's default document folder */ -/* On Windows I chose the 'Users//Documents' since it's used - * as default location to save documents */ -const char *BLI_getDefaultDocumentFolder(void) -{ -#ifndef WIN32 - const char * const xdg_documents_dir = getenv("XDG_DOCUMENTS_DIR"); - - if (xdg_documents_dir) - return xdg_documents_dir; - - return getenv("HOME"); -#else /* Windows */ - static char documentfolder[MAXPATHLEN]; - HRESULT hResult; - - /* Check for %HOME% env var */ - if (uput_getenv("HOME", documentfolder, MAXPATHLEN)) { - if (BLI_is_dir(documentfolder)) return documentfolder; - } - - /* add user profile support for WIN 2K / NT. - * This is %APPDATA%, which translates to either - * %USERPROFILE%\Application Data or since Vista - * to %USERPROFILE%\AppData\Roaming - */ - hResult = SHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, documentfolder); - - if (hResult == S_OK) { - if (BLI_is_dir(documentfolder)) return documentfolder; - } - - return NULL; -#endif /* WIN32 */ -} - -/* NEW stuff, to be cleaned up when fully migrated */ -/* ************************************************************* */ -/* ************************************************************* */ - -// #define PATH_DEBUG - -/* returns a formatted representation of the specified version number. Non-reentrant! */ -static char *blender_version_decimal(const int ver) -{ - static char version_str[5]; - sprintf(version_str, "%d.%02d", ver / 100, ver % 100); - return version_str; -} - -/** - * Concatenates path_base, (optional) path_sep and (optional) folder_name into targetpath, - * returning true if result points to a directory. - */ -static bool test_path(char *targetpath, const char *path_base, const char *path_sep, const char *folder_name) -{ - char tmppath[FILE_MAX]; - - if (path_sep) BLI_join_dirfile(tmppath, sizeof(tmppath), path_base, path_sep); - else BLI_strncpy(tmppath, path_base, sizeof(tmppath)); - - /* rare cases folder_name is omitted (when looking for ~/.blender/2.xx dir only) */ - if (folder_name) - BLI_make_file_string("/", targetpath, tmppath, folder_name); - else - BLI_strncpy(targetpath, tmppath, sizeof(tmppath)); - /* FIXME: why is "//" on front of tmppath expanded to "/" (by BLI_join_dirfile) - * if folder_name is specified but not otherwise? */ - - if (BLI_is_dir(targetpath)) { -#ifdef PATH_DEBUG - printf("\t%s found: %s\n", __func__, targetpath); -#endif - return true; - } - else { -#ifdef PATH_DEBUG - printf("\t%s missing: %s\n", __func__, targetpath); -#endif - //targetpath[0] = '\0'; - return false; - } -} - -/** - * Puts the value of the specified environment variable into *path if it exists - * and points at a directory. Returns true if this was done. - */ -static bool test_env_path(char *path, const char *envvar) -{ - const char *env = envvar ? getenv(envvar) : NULL; - if (!env) return false; - - if (BLI_is_dir(env)) { - BLI_strncpy(path, env, FILE_MAX); -#ifdef PATH_DEBUG - printf("\t%s env %s found: %s\n", __func__, envvar, env); -#endif - return true; - } - else { - path[0] = '\0'; -#ifdef PATH_DEBUG - printf("\t%s env %s missing: %s\n", __func__, envvar, env); -#endif - return false; - } -} - -/** - * Constructs in \a targetpath the name of a directory relative to a version-specific - * subdirectory in the parent directory of the Blender executable. - * - * \param targetpath String to return path - * \param folder_name Optional folder name within version-specific directory - * \param subfolder_name Optional subfolder name within folder_name - * \param ver To construct name of version-specific directory within bprogdir - * \return true if such a directory exists. - */ -static bool get_path_local(char *targetpath, const char *folder_name, const char *subfolder_name, const int ver) -{ - char relfolder[FILE_MAX]; - -#ifdef PATH_DEBUG - printf("%s...\n", __func__); -#endif - if (folder_name) { - if (subfolder_name) { - BLI_join_dirfile(relfolder, sizeof(relfolder), folder_name, subfolder_name); - } - else { - BLI_strncpy(relfolder, folder_name, sizeof(relfolder)); - } - } - else { - relfolder[0] = '\0'; - } - /* try EXECUTABLE_DIR/2.5x/folder_name - new default directory for local blender installed files */ -#ifdef __APPLE__ - static char osx_resourses[FILE_MAX]; /* due new codesign situation in OSX > 10.9.5 we must move the blender_version dir with contents to Resources */ - sprintf(osx_resourses, "%s../Resources", bprogdir); - return test_path(targetpath, osx_resourses, blender_version_decimal(ver), relfolder); -#else - return test_path(targetpath, bprogdir, blender_version_decimal(ver), relfolder); -#endif -} - -/** - * Is this an install with user files kept together with the Blender executable and its - * installation files. - */ -static bool is_portable_install(void) -{ - /* detect portable install by the existence of config folder */ - const int ver = BLENDER_VERSION; - char path[FILE_MAX]; - - return get_path_local(path, "config", NULL, ver); -} - -/** - * Returns the path of a folder within the user-files area. - * - * - * \param targetpath String to return path - * \param folder_name default name of folder within user area - * \param subfolder_name optional name of subfolder within folder - * \param envvar name of environment variable which, if defined, overrides folder_name - * \param ver Blender version, used to construct a subdirectory name - * \return true if it was able to construct such a path. - */ -static bool get_path_user(char *targetpath, const char *folder_name, const char *subfolder_name, const char *envvar, const int ver) -{ - char user_path[FILE_MAX]; - const char *user_base_path; - - /* for portable install, user path is always local */ - if (is_portable_install()) - return get_path_local(targetpath, folder_name, subfolder_name, ver); - - user_path[0] = '\0'; - - if (test_env_path(user_path, envvar)) { - if (subfolder_name) { - return test_path(targetpath, user_path, NULL, subfolder_name); - } - else { - BLI_strncpy(targetpath, user_path, FILE_MAX); - return true; - } - } - - user_base_path = (const char *)GHOST_getUserDir(ver, blender_version_decimal(ver)); - if (user_base_path) - BLI_strncpy(user_path, user_base_path, FILE_MAX); - - if (!user_path[0]) - return false; - -#ifdef PATH_DEBUG - printf("%s: %s\n", __func__, user_path); -#endif - - if (subfolder_name) { - return test_path(targetpath, user_path, folder_name, subfolder_name); - } - else { - return test_path(targetpath, user_path, NULL, folder_name); - } -} - -/** - * Returns the path of a folder within the Blender installation directory. - * - * \param targetpath String to return path - * \param folder_name default name of folder within installation area - * \param subfolder_name optional name of subfolder within folder - * \param envvar name of environment variable which, if defined, overrides folder_name - * \param ver Blender version, used to construct a subdirectory name - * \return true if it was able to construct such a path. - */ -static bool get_path_system(char *targetpath, const char *folder_name, const char *subfolder_name, const char *envvar, const int ver) -{ - char system_path[FILE_MAX]; - const char *system_base_path; - char cwd[FILE_MAX]; - char relfolder[FILE_MAX]; - - if (folder_name) { - if (subfolder_name) { - BLI_join_dirfile(relfolder, sizeof(relfolder), folder_name, subfolder_name); - } - else { - BLI_strncpy(relfolder, folder_name, sizeof(relfolder)); - } - } - else { - relfolder[0] = '\0'; - } - - /* first allow developer only overrides to the system path - * these are only used when running blender from source */ - - /* try CWD/release/folder_name */ - if (BLI_current_working_dir(cwd, sizeof(cwd))) { - if (test_path(targetpath, cwd, "release", relfolder)) { - return true; - } - } - - /* try EXECUTABLE_DIR/release/folder_name */ - if (test_path(targetpath, bprogdir, "release", relfolder)) - return true; - - /* end developer overrides */ - - - - system_path[0] = '\0'; - - if (test_env_path(system_path, envvar)) { - if (subfolder_name) { - return test_path(targetpath, system_path, NULL, subfolder_name); - } - else { - BLI_strncpy(targetpath, system_path, FILE_MAX); - return true; - } - } - - system_base_path = (const char *)GHOST_getSystemDir(ver, blender_version_decimal(ver)); - if (system_base_path) - BLI_strncpy(system_path, system_base_path, FILE_MAX); - - if (!system_path[0]) - return false; - -#ifdef PATH_DEBUG - printf("%s: %s\n", __func__, system_path); -#endif - - if (subfolder_name) { - /* try $BLENDERPATH/folder_name/subfolder_name */ - return test_path(targetpath, system_path, folder_name, subfolder_name); - } - else { - /* try $BLENDERPATH/folder_name */ - return test_path(targetpath, system_path, NULL, folder_name); - } -} - -/* get a folder out of the 'folder_id' presets for paths */ -/* returns the path if found, NULL string if not */ -const char *BLI_get_folder(int folder_id, const char *subfolder) -{ - const int ver = BLENDER_VERSION; - static char path[FILE_MAX] = ""; - - switch (folder_id) { - case BLENDER_DATAFILES: /* general case */ - if (get_path_user(path, "datafiles", subfolder, "BLENDER_USER_DATAFILES", ver)) break; - if (get_path_local(path, "datafiles", subfolder, ver)) break; - if (get_path_system(path, "datafiles", subfolder, "BLENDER_SYSTEM_DATAFILES", ver)) break; - return NULL; - - case BLENDER_USER_DATAFILES: - if (get_path_user(path, "datafiles", subfolder, "BLENDER_USER_DATAFILES", ver)) break; - return NULL; - - case BLENDER_SYSTEM_DATAFILES: - if (get_path_local(path, "datafiles", subfolder, ver)) break; - if (get_path_system(path, "datafiles", subfolder, "BLENDER_SYSTEM_DATAFILES", ver)) break; - return NULL; - - case BLENDER_USER_AUTOSAVE: - if (get_path_user(path, "autosave", subfolder, "BLENDER_USER_DATAFILES", ver)) break; - return NULL; - - case BLENDER_USER_CONFIG: - if (get_path_user(path, "config", subfolder, "BLENDER_USER_CONFIG", ver)) break; - return NULL; - - case BLENDER_USER_SCRIPTS: - if (get_path_user(path, "scripts", subfolder, "BLENDER_USER_SCRIPTS", ver)) break; - return NULL; - - case BLENDER_SYSTEM_SCRIPTS: - if (get_path_local(path, "scripts", subfolder, ver)) break; - if (get_path_system(path, "scripts", subfolder, "BLENDER_SYSTEM_SCRIPTS", ver)) break; - return NULL; - - case BLENDER_SYSTEM_PYTHON: - if (get_path_local(path, "python", subfolder, ver)) break; - if (get_path_system(path, "python", subfolder, "BLENDER_SYSTEM_PYTHON", ver)) break; - return NULL; - - default: - BLI_assert(0); - break; - } - - return path; -} - -/** - * Returns the path to a folder in the user area without checking that it actually exists first. - */ -const char *BLI_get_user_folder_notest(int folder_id, const char *subfolder) -{ - const int ver = BLENDER_VERSION; - static char path[FILE_MAX] = ""; - - switch (folder_id) { - case BLENDER_USER_DATAFILES: - get_path_user(path, "datafiles", subfolder, "BLENDER_USER_DATAFILES", ver); - break; - case BLENDER_USER_CONFIG: - get_path_user(path, "config", subfolder, "BLENDER_USER_CONFIG", ver); - break; - case BLENDER_USER_AUTOSAVE: - get_path_user(path, "autosave", subfolder, "BLENDER_USER_AUTOSAVE", ver); - break; - case BLENDER_USER_SCRIPTS: - get_path_user(path, "scripts", subfolder, "BLENDER_USER_SCRIPTS", ver); - break; - default: - BLI_assert(0); - break; - } - - if ('\0' == path[0]) { - return NULL; - } - return path; -} - -/** - * Returns the path to a folder in the user area, creating it if it doesn't exist. - */ -const char *BLI_get_folder_create(int folder_id, const char *subfolder) -{ - const char *path; - - /* only for user folders */ - if (!ELEM(folder_id, BLENDER_USER_DATAFILES, BLENDER_USER_CONFIG, BLENDER_USER_SCRIPTS, BLENDER_USER_AUTOSAVE)) - return NULL; - - path = BLI_get_folder(folder_id, subfolder); - - if (!path) { - path = BLI_get_user_folder_notest(folder_id, subfolder); - if (path) BLI_dir_create_recursive(path); - } - - return path; -} - -/** - * Returns the path of the top-level version-specific local, user or system directory. - * If do_check, then the result will be NULL if the directory doesn't exist. - */ -const char *BLI_get_folder_version(const int id, const int ver, const bool do_check) -{ - static char path[FILE_MAX] = ""; - bool ok; - switch (id) { - case BLENDER_RESOURCE_PATH_USER: - ok = get_path_user(path, NULL, NULL, NULL, ver); - break; - case BLENDER_RESOURCE_PATH_LOCAL: - ok = get_path_local(path, NULL, NULL, ver); - break; - case BLENDER_RESOURCE_PATH_SYSTEM: - ok = get_path_system(path, NULL, NULL, NULL, ver); - break; - default: - path[0] = '\0'; /* in case do_check is false */ - ok = false; - BLI_assert(!"incorrect ID"); - break; - } - - if (!ok && do_check) { - return NULL; - } - - return path; -} - -/* End new stuff */ -/* ************************************************************* */ -/* ************************************************************* */ - - - -#ifdef PATH_DEBUG -# undef PATH_DEBUG -#endif /** * Sets the specified environment variable to the specified value, @@ -2153,310 +1700,6 @@ void BLI_path_native_slash(char *path) #endif } -/** - * Tries appending each of the semicolon-separated extensions in the PATHEXT - * environment variable (Windows-only) onto *name in turn until such a file is found. - * Returns success/failure. - */ -static int add_win32_extension(char *name) -{ - int retval = 0; - int type; - - type = BLI_exists(name); - if ((type == 0) || S_ISDIR(type)) { -#ifdef _WIN32 - char filename[FILE_MAX]; - char ext[FILE_MAX]; - const char *extensions = getenv("PATHEXT"); - if (extensions) { - char *temp; - do { - strcpy(filename, name); - temp = strstr(extensions, ";"); - if (temp) { - strncpy(ext, extensions, temp - extensions); - ext[temp - extensions] = 0; - extensions = temp + 1; - strcat(filename, ext); - } - else { - strcat(filename, extensions); - } - - type = BLI_exists(filename); - if (type && (!S_ISDIR(type))) { - retval = 1; - strcpy(name, filename); - break; - } - } while (temp); - } -#endif - } - else { - retval = 1; - } - - return (retval); -} - -/** - * Checks if name is a fully qualified filename to an executable. - * If not it searches $PATH for the file. On Windows it also - * adds the correct extension (.com .exe etc) from - * $PATHEXT if necessary. Also on Windows it translates - * the name to its 8.3 version to prevent problems with - * spaces and stuff. Final result is returned in fullname. - * - * \param fullname The full path and full name of the executable - * (must be FILE_MAX minimum) - * \param name The name of the executable (usually argv[0]) to be checked - */ -static void bli_where_am_i(char *fullname, const size_t maxlen, const char *name) -{ - char filename[FILE_MAX]; - const char *path = NULL, *temp; - -#ifdef _WIN32 - const char *separator = ";"; -#else - const char *separator = ":"; -#endif - - -#ifdef WITH_BINRELOC - /* linux uses binreloc since argv[0] is not reliable, call br_init( NULL ) first */ - path = br_find_exe(NULL); - if (path) { - BLI_strncpy(fullname, path, maxlen); - free((void *)path); - return; - } -#endif - -#ifdef _WIN32 - wchar_t *fullname_16 = MEM_mallocN(maxlen * sizeof(wchar_t), "ProgramPath"); - if (GetModuleFileNameW(0, fullname_16, maxlen)) { - conv_utf_16_to_8(fullname_16, fullname, maxlen); - if (!BLI_exists(fullname)) { - printf("path can't be found: \"%.*s\"\n", (int)maxlen, fullname); - MessageBox(NULL, "path contains invalid characters or is too long (see console)", "Error", MB_OK); - } - MEM_freeN(fullname_16); - return; - } - - MEM_freeN(fullname_16); -#endif - - /* unix and non linux */ - if (name && name[0]) { - - BLI_strncpy(fullname, name, maxlen); - if (name[0] == '.') { - char wdir[FILE_MAX] = ""; - BLI_current_working_dir(wdir, sizeof(wdir)); /* backup cwd to restore after */ - - // not needed but avoids annoying /./ in name - if (name[1] == SEP) - BLI_join_dirfile(fullname, maxlen, wdir, name + 2); - else - BLI_join_dirfile(fullname, maxlen, wdir, name); - - add_win32_extension(fullname); /* XXX, doesnt respect length */ - } - else if (BLI_last_slash(name)) { - // full path - BLI_strncpy(fullname, name, maxlen); - add_win32_extension(fullname); - } - else { - // search for binary in $PATH - path = getenv("PATH"); - if (path) { - do { - temp = strstr(path, separator); - if (temp) { - strncpy(filename, path, temp - path); - filename[temp - path] = 0; - path = temp + 1; - } - else { - strncpy(filename, path, sizeof(filename)); - } - BLI_path_append(fullname, maxlen, name); - if (add_win32_extension(filename)) { - BLI_strncpy(fullname, filename, maxlen); - break; - } - } while (temp); - } - } -#if defined(DEBUG) - if (strcmp(name, fullname)) { - printf("guessing '%s' == '%s'\n", name, fullname); - } -#endif - } -} - -void BLI_init_program_path(const char *argv0) -{ - bli_where_am_i(bprogname, sizeof(bprogname), argv0); - BLI_split_dir_part(bprogname, bprogdir, sizeof(bprogdir)); -} - -/** - * Path to executable - */ -const char *BLI_program_path(void) -{ - return bprogname; -} - -/** - * Path to directory of executable - */ -const char *BLI_program_dir(void) -{ - return bprogdir; -} - -/** - * Gets the temp directory when blender first runs. - * If the default path is not found, use try $TEMP - * - * Also make sure the temp dir has a trailing slash - * - * \param fullname The full path to the temporary temp directory - * \param basename The full path to the persistent temp directory (may be NULL) - * \param maxlen The size of the fullname buffer - * \param userdir Directory specified in user preferences - */ -static void BLI_where_is_temp(char *fullname, char *basename, const size_t maxlen, char *userdir) -{ - /* Clear existing temp dir, if needed. */ - BLI_temp_dir_session_purge(); - - fullname[0] = '\0'; - if (basename) { - basename[0] = '\0'; - } - - if (userdir && BLI_is_dir(userdir)) { - BLI_strncpy(fullname, userdir, maxlen); - } - - -#ifdef WIN32 - if (fullname[0] == '\0') { - const char *tmp = getenv("TEMP"); /* Windows */ - if (tmp && BLI_is_dir(tmp)) { - BLI_strncpy(fullname, tmp, maxlen); - } - } -#else - /* Other OS's - Try TMP and TMPDIR */ - if (fullname[0] == '\0') { - const char *tmp = getenv("TMP"); - if (tmp && BLI_is_dir(tmp)) { - BLI_strncpy(fullname, tmp, maxlen); - } - } - - if (fullname[0] == '\0') { - const char *tmp = getenv("TMPDIR"); - if (tmp && BLI_is_dir(tmp)) { - BLI_strncpy(fullname, tmp, maxlen); - } - } -#endif - - if (fullname[0] == '\0') { - BLI_strncpy(fullname, "/tmp/", maxlen); - } - else { - /* add a trailing slash if needed */ - BLI_add_slash(fullname); -#ifdef WIN32 - if (userdir && userdir != fullname) { - BLI_strncpy(userdir, fullname, maxlen); /* also set user pref to show %TEMP%. /tmp/ is just plain confusing for Windows users. */ - } -#endif - } - - /* Now that we have a valid temp dir, add system-generated unique sub-dir. */ - if (basename) { - /* 'XXXXXX' is kind of tag to be replaced by mktemp-familly by an uuid. */ - char *tmp_name = BLI_strdupcat(fullname, "blender_XXXXXX"); - const size_t ln = strlen(tmp_name) + 1; - if (ln <= maxlen) { -#ifdef WIN32 - if (_mktemp_s(tmp_name, ln) == 0) { - BLI_dir_create_recursive(tmp_name); - } -#else - mkdtemp(tmp_name); -#endif - } - if (BLI_is_dir(tmp_name)) { - BLI_strncpy(basename, fullname, maxlen); - BLI_strncpy(fullname, tmp_name, maxlen); - BLI_add_slash(fullname); - } - else { - printf("Warning! Could not generate a temp file name for '%s', falling back to '%s'\n", tmp_name, fullname); - } - - MEM_freeN(tmp_name); - } -} - -/** - * Sets btempdir_base to userdir if specified and is a valid directory, otherwise - * chooses a suitable OS-specific temporary directory. - * Sets btempdir_session to a mkdtemp-generated sub-dir of btempdir_base. - */ -void BLI_temp_dir_init(char *userdir) -{ - BLI_where_is_temp(btempdir_session, btempdir_base, FILE_MAX, userdir); -; -} - -/** - * Path to temporary directory (with trailing slash) - */ -const char *BLI_temp_dir_session(void) -{ - return btempdir_session[0] ? btempdir_session : BLI_temp_dir_base(); -} - -/** - * Path to persistent temporary directory (with trailing slash) - */ -const char *BLI_temp_dir_base(void) -{ - return btempdir_base; -} - -/** - * Path to the system temporary directory (with trailing slash) - */ -void BLI_system_temporary_dir(char *dir) -{ - BLI_where_is_temp(dir, NULL, FILE_MAX, NULL); -} - -/** - * Delete content of this instance's temp dir. - */ -void BLI_temp_dir_session_purge(void) -{ - if (btempdir_session[0] && BLI_is_dir(btempdir_session)) { - BLI_delete(btempdir_session, true, true); - } -} #ifdef WITH_ICONV -- cgit v1.2.3 From 48a720055f736c5be257f85c22589f81f09247a8 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Sun, 23 Nov 2014 20:51:08 +0100 Subject: Fix BLI_Bitmap - was not usable in BKE area (strict compile flags). --- source/blender/blenlib/BLI_bitmap.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_bitmap.h b/source/blender/blenlib/BLI_bitmap.h index 594bf89b667..e4c625439d3 100644 --- a/source/blender/blenlib/BLI_bitmap.h +++ b/source/blender/blenlib/BLI_bitmap.h @@ -47,7 +47,7 @@ typedef unsigned int BLI_bitmap; /* size (in bytes) used to hold '_tot' bits */ #define BLI_BITMAP_SIZE(_tot) \ - (_BITMAP_NUM_BLOCKS(_tot) * sizeof(BLI_bitmap)) + ((size_t)(_BITMAP_NUM_BLOCKS(_tot)) * sizeof(BLI_bitmap)) /* allocate memory for a bitmap with '_tot' bits; free * with MEM_freeN() */ -- cgit v1.2.3 From 73633388ff2814300c007a6261f4e9fcbd1b5fc6 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 24 Nov 2014 00:47:32 +0100 Subject: SCons: correct includes after recent refactor --- source/blender/blenlib/SConscript | 1 - 1 file changed, 1 deletion(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/SConscript b/source/blender/blenlib/SConscript index b712d2032bf..2dabb5a7334 100644 --- a/source/blender/blenlib/SConscript +++ b/source/blender/blenlib/SConscript @@ -34,7 +34,6 @@ cflags='' incs = [ '.', '#/extern/wcwidth', - '#/intern/ghost', '#/intern/guardedalloc', '../makesdna', env['BF_FREETYPE_INC'], -- cgit v1.2.3 From 7b0d6a1e6c8233722731e77cd1b4641285c0c62d Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 24 Nov 2014 09:33:12 +0100 Subject: SCons: correct include for win, also minor cleanup --- source/blender/blenlib/intern/hash_md5.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/intern/hash_md5.c b/source/blender/blenlib/intern/hash_md5.c index bc7a495f213..4eec38278e9 100644 --- a/source/blender/blenlib/intern/hash_md5.c +++ b/source/blender/blenlib/intern/hash_md5.c @@ -22,7 +22,7 @@ * Written by Ulrich Drepper . */ -/** \file blender/blenlib/intern/md5.c +/** \file blender/blenlib/intern/hash_md5.c * \ingroup bli * * Functions to compute MD5 message digest of files or memory blocks -- cgit v1.2.3 From 08fd38cf52e4d540e6a7d3ceeaedf4a4c3858f55 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 24 Nov 2014 12:01:51 +0100 Subject: BLI_utildefines: add UNUSED_VARS() macro --- source/blender/blenlib/BLI_utildefines.h | 50 ++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h index 9a8877e39c3..ef1312a1d94 100644 --- a/source/blender/blenlib/BLI_utildefines.h +++ b/source/blender/blenlib/BLI_utildefines.h @@ -497,6 +497,56 @@ extern "C" { # define UNUSED_FUNCTION(x) UNUSED_ ## x #endif +/** + * UNUSED_VARS#(a, ...): quiet unused warnings + * + *
+ * for i in range(16):
+ *     args = [(chr(ord('a') + (c % 26)) + (chr(ord('0') + (c // 26)))) for c in range(i + 1)]
+ *     print("#define _VA_UNUSED_VARS_%d(%s) \\" % (i + 1, ", ".join(args)))
+ *     print("\t((void)(%s)%s)" %
+ *             (args[0], ((", _VA_UNUSED_VARS_" + str(i) + "(%s)") if i else "%s") % ", ".join((args[1:]))))
+ * 
+ * + */ + +#define _VA_UNUSED_VARS_1(a0) \ + ((void)(a0)) +#define _VA_UNUSED_VARS_2(a0, b0) \ + ((void)(a0), _VA_UNUSED_VARS_1(b0)) +#define _VA_UNUSED_VARS_3(a0, b0, c0) \ + ((void)(a0), _VA_UNUSED_VARS_2(b0, c0)) +#define _VA_UNUSED_VARS_4(a0, b0, c0, d0) \ + ((void)(a0), _VA_UNUSED_VARS_3(b0, c0, d0)) +#define _VA_UNUSED_VARS_5(a0, b0, c0, d0, e0) \ + ((void)(a0), _VA_UNUSED_VARS_4(b0, c0, d0, e0)) +#define _VA_UNUSED_VARS_6(a0, b0, c0, d0, e0, f0) \ + ((void)(a0), _VA_UNUSED_VARS_5(b0, c0, d0, e0, f0)) +#define _VA_UNUSED_VARS_7(a0, b0, c0, d0, e0, f0, g0) \ + ((void)(a0), _VA_UNUSED_VARS_6(b0, c0, d0, e0, f0, g0)) +#define _VA_UNUSED_VARS_8(a0, b0, c0, d0, e0, f0, g0, h0) \ + ((void)(a0), _VA_UNUSED_VARS_7(b0, c0, d0, e0, f0, g0, h0)) +#define _VA_UNUSED_VARS_9(a0, b0, c0, d0, e0, f0, g0, h0, i0) \ + ((void)(a0), _VA_UNUSED_VARS_8(b0, c0, d0, e0, f0, g0, h0, i0)) +#define _VA_UNUSED_VARS_10(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0) \ + ((void)(a0), _VA_UNUSED_VARS_9(b0, c0, d0, e0, f0, g0, h0, i0, j0)) +#define _VA_UNUSED_VARS_11(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0) \ + ((void)(a0), _VA_UNUSED_VARS_10(b0, c0, d0, e0, f0, g0, h0, i0, j0, k0)) +#define _VA_UNUSED_VARS_12(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0) \ + ((void)(a0), _VA_UNUSED_VARS_11(b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0)) +#define _VA_UNUSED_VARS_13(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0) \ + ((void)(a0), _VA_UNUSED_VARS_12(b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0)) +#define _VA_UNUSED_VARS_14(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0) \ + ((void)(a0), _VA_UNUSED_VARS_13(b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0)) +#define _VA_UNUSED_VARS_15(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0) \ + ((void)(a0), _VA_UNUSED_VARS_14(b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0)) +#define _VA_UNUSED_VARS_16(a0, b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0) \ + ((void)(a0), _VA_UNUSED_VARS_15(b0, c0, d0, e0, f0, g0, h0, i0, j0, k0, l0, m0, n0, o0, p0)) + + +/* reusable ELEM macro */ +#define UNUSED_VARS(...) VA_NARGS_CALL_OVERLOAD(_VA_UNUSED_VARS_, __VA_ARGS__) + /*little macro so inline keyword works*/ #if defined(_MSC_VER) # define BLI_INLINE static __forceinline -- cgit v1.2.3 From f1ea1da5e50d4319fe96ff75bfc75f73941e5cb1 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Tue, 25 Nov 2014 21:09:13 +0100 Subject: BLI_bitmap: add allocation from a MemArena. --- source/blender/blenlib/BLI_bitmap.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_bitmap.h b/source/blender/blenlib/BLI_bitmap.h index e4c625439d3..e9a828c678c 100644 --- a/source/blender/blenlib/BLI_bitmap.h +++ b/source/blender/blenlib/BLI_bitmap.h @@ -59,6 +59,11 @@ typedef unsigned int BLI_bitmap; #define BLI_BITMAP_NEW_ALLOCA(_tot) \ ((BLI_bitmap *)memset(alloca(BLI_BITMAP_SIZE(_tot)), 0, BLI_BITMAP_SIZE(_tot))) +/* Allocate using given MemArena */ +#define BLI_BITMAP_NEW_MEMARENA(_mem, _tot) \ + (CHECK_TYPE_INLINE(_mem, MemArena *), \ + ((BLI_bitmap *)BLI_memarena_calloc(_mem, BLI_BITMAP_SIZE(_tot)))) + /* get the value of a single bit at '_index' */ #define BLI_BITMAP_TEST(_bitmap, _index) \ (CHECK_TYPE_INLINE(_bitmap, BLI_bitmap *), \ -- cgit v1.2.3 From 915235c87a1621ba000a427ad3eac8a49ff2c0c7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 28 Nov 2014 22:16:14 +0100 Subject: Cleanup: unused headers --- source/blender/blenlib/intern/lasso.c | 1 - 1 file changed, 1 deletion(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/intern/lasso.c b/source/blender/blenlib/intern/lasso.c index e89f7fd795b..23704538413 100644 --- a/source/blender/blenlib/intern/lasso.c +++ b/source/blender/blenlib/intern/lasso.c @@ -33,7 +33,6 @@ #include "DNA_vec_types.h" #include "BLI_math.h" -#include "BLI_rect.h" #include "BLI_strict_flags.h" #include "BLI_lasso.h" /* own include */ -- cgit v1.2.3 From 1cb59394ae69148904de34a32d09319f02c86a09 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 29 Nov 2014 17:49:38 +0100 Subject: Cleanup: use const, avoid float -> double in matrix invert --- source/blender/blenlib/intern/math_matrix.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index 2da1f225034..8f9fcbc252c 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -848,9 +848,10 @@ bool invert_m4_m4(float inverse[4][4], float mat[4][4]) } } - temp = tempmat[i][i]; - if (temp == 0) - return 0; /* No non-zero pivot */ + if (UNLIKELY(tempmat[i][i] == 0.0f)) { + return false; /* No non-zero pivot */ + } + temp = (double)tempmat[i][i]; for (k = 0; k < 4; k++) { tempmat[i][k] = (float)((double)tempmat[i][k] / temp); inverse[i][k] = (float)((double)inverse[i][k] / temp); -- cgit v1.2.3 From b7d053beaa70f0331629723f2b575ecf7f842493 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 30 Nov 2014 19:28:59 +0100 Subject: Cleanup: warnings & space --- source/blender/blenlib/intern/path_util.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c index 9a9385e0687..49af04626c3 100644 --- a/source/blender/blenlib/intern/path_util.c +++ b/source/blender/blenlib/intern/path_util.c @@ -1024,8 +1024,6 @@ void BLI_getlastdir(const char *dir, char *last, const size_t maxlen) } - - /** * Sets the specified environment variable to the specified value, * and clears it if val == NULL. -- cgit v1.2.3 From 72f75927f5079e72e45019899bdea384447d5992 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 1 Dec 2014 16:01:08 +0100 Subject: Fix T42588: Absolute paths not cleaned on win32 Making paths absolute would leave in "\..\" part on windows. --- source/blender/blenlib/intern/path_util.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c index 49af04626c3..abb6cc3f3cd 100644 --- a/source/blender/blenlib/intern/path_util.c +++ b/source/blender/blenlib/intern/path_util.c @@ -939,8 +939,6 @@ bool BLI_path_abs(char *path, const char *basepath) BLI_strncpy(path, tmp, FILE_MAX); } - BLI_cleanup_path(NULL, path); - #ifdef WIN32 /* skip first two chars, which in case of * absolute path will be drive:/blabla and @@ -950,7 +948,10 @@ bool BLI_path_abs(char *path, const char *basepath) */ BLI_char_switch(path + 2, '/', '\\'); #endif - + + /* ensure this is after correcting for path switch */ + BLI_cleanup_path(NULL, path); + return wasrelative; } -- cgit v1.2.3 From 9c782c17ba03b3ed61bec1f1e9c73bc5f6522ded Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Mon, 1 Dec 2014 14:33:38 +0100 Subject: Cleanup: hopefully last int->bool one in this area! --- source/blender/blenlib/intern/BLI_kdopbvh.c | 4 +- source/blender/blenlib/intern/graph.c | 8 ++-- source/blender/blenlib/intern/math_geom.c | 62 ++++++++++++++--------------- source/blender/blenlib/intern/math_matrix.c | 22 +++++----- source/blender/blenlib/intern/path_util.c | 3 +- source/blender/blenlib/intern/scanfill.c | 28 ++++++------- 6 files changed, 63 insertions(+), 64 deletions(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index d28215ee8ed..b76b925e6cc 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -986,7 +986,7 @@ bool BLI_bvhtree_update_node(BVHTree *tree, int index, const float co[3], const /* check if index exists */ if (index > tree->totleaf) - return 0; + return false; node = tree->nodearray + index; @@ -1001,7 +1001,7 @@ bool BLI_bvhtree_update_node(BVHTree *tree, int index, const float co[3], const node->bv[(2 * axis_iter) + 1] += tree->epsilon; /* maximum */ } - return 1; + return true; } /* call BLI_bvhtree_update_node() first for every node/point/triangle */ diff --git a/source/blender/blenlib/intern/graph.c b/source/blender/blenlib/intern/graph.c index d4d87dfdbf6..81cc9fde01f 100644 --- a/source/blender/blenlib/intern/graph.c +++ b/source/blender/blenlib/intern/graph.c @@ -170,11 +170,11 @@ bool BLI_hasAdjacencyList(BGraph *graph) for (node = graph->nodes.first; node; node = node->next) { if (node->arcs == NULL) { - return 0; + return false; } } - return 1; + return true; } void BLI_replaceNodeInArc(BGraph *graph, BArc *arc, BNode *node_src, BNode *node_replaced) @@ -337,7 +337,7 @@ static bool detectCycle(BNode *node, BArc *src_arc) } } else { - value = 1; + value = true; } return value; @@ -354,7 +354,7 @@ bool BLI_isGraphCyclic(BGraph *graph) BLI_flagNodes(graph, 0); /* detectCycles in subgraphs */ - for (node = graph->nodes.first; node && value == 0; node = node->next) { + for (node = graph->nodes.first; node && value == false; node = node->next) { /* only for nodes in subgraphs that haven't been visited yet */ if (node->flag == 0) { value = value || detectCycle(node, NULL); diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 60373458a5c..1c75a907a95 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -912,12 +912,12 @@ bool isect_point_tri_v2_cw(const float pt[2], const float v1[2], const float v2[ if (line_point_side_v2(v1, v2, pt) >= 0.0f) { if (line_point_side_v2(v2, v3, pt) >= 0.0f) { if (line_point_side_v2(v3, v1, pt) >= 0.0f) { - return 1; + return true; } } } - return 0; + return false; } int isect_point_tri_v2(const float pt[2], const float v1[2], const float v2[2], const float v3[2]) @@ -983,28 +983,28 @@ bool isect_line_tri_v3(const float p1[3], const float p2[3], cross_v3_v3v3(p, d, e2); a = dot_v3v3(e1, p); - if (a == 0.0f) return 0; + if (a == 0.0f) return false; f = 1.0f / a; sub_v3_v3v3(s, p1, v0); u = f * dot_v3v3(s, p); - if ((u < 0.0f) || (u > 1.0f)) return 0; + if ((u < 0.0f) || (u > 1.0f)) return false; cross_v3_v3v3(q, s, e1); v = f * dot_v3v3(d, q); - if ((v < 0.0f) || ((u + v) > 1.0f)) return 0; + if ((v < 0.0f) || ((u + v) > 1.0f)) return false; *r_lambda = f * dot_v3v3(e2, q); - if ((*r_lambda < 0.0f) || (*r_lambda > 1.0f)) return 0; + if ((*r_lambda < 0.0f) || (*r_lambda > 1.0f)) return false; if (r_uv) { r_uv[0] = u; r_uv[1] = v; } - return 1; + return true; } /* like isect_line_tri_v3, but allows epsilon tolerance around triangle */ @@ -1022,28 +1022,28 @@ bool isect_line_tri_epsilon_v3(const float p1[3], const float p2[3], cross_v3_v3v3(p, d, e2); a = dot_v3v3(e1, p); - if (a == 0.0f) return 0; + if (a == 0.0f) return false; f = 1.0f / a; sub_v3_v3v3(s, p1, v0); u = f * dot_v3v3(s, p); - if ((u < -epsilon) || (u > 1.0f + epsilon)) return 0; + if ((u < -epsilon) || (u > 1.0f + epsilon)) return false; cross_v3_v3v3(q, s, e1); v = f * dot_v3v3(d, q); - if ((v < -epsilon) || ((u + v) > 1.0f + epsilon)) return 0; + if ((v < -epsilon) || ((u + v) > 1.0f + epsilon)) return false; *r_lambda = f * dot_v3v3(e2, q); - if ((*r_lambda < 0.0f) || (*r_lambda > 1.0f)) return 0; + if ((*r_lambda < 0.0f) || (*r_lambda > 1.0f)) return false; if (r_uv) { r_uv[0] = u; r_uv[1] = v; } - return 1; + return true; } /* moved from effect.c @@ -1064,28 +1064,28 @@ bool isect_ray_tri_v3(const float p1[3], const float d[3], a = dot_v3v3(e1, p); /* note: these values were 0.000001 in 2.4x but for projection snapping on * a human head (1BU == 1m), subsurf level 2, this gave many errors - campbell */ - if ((a > -0.00000001f) && (a < 0.00000001f)) return 0; + if ((a > -0.00000001f) && (a < 0.00000001f)) return false; f = 1.0f / a; sub_v3_v3v3(s, p1, v0); u = f * dot_v3v3(s, p); - if ((u < 0.0f) || (u > 1.0f)) return 0; + if ((u < 0.0f) || (u > 1.0f)) return false; cross_v3_v3v3(q, s, e1); v = f * dot_v3v3(d, q); - if ((v < 0.0f) || ((u + v) > 1.0f)) return 0; + if ((v < 0.0f) || ((u + v) > 1.0f)) return false; *r_lambda = f * dot_v3v3(e2, q); - if ((*r_lambda < 0.0f)) return 0; + if ((*r_lambda < 0.0f)) return false; if (r_uv) { r_uv[0] = u; r_uv[1] = v; } - return 1; + return true; } /** @@ -1107,7 +1107,7 @@ bool isect_ray_plane_v3(const float p1[3], const float d[3], a = dot_v3v3(e1, p); /* note: these values were 0.000001 in 2.4x but for projection snapping on * a human head (1BU == 1m), subsurf level 2, this gave many errors - campbell */ - if ((a > -0.00000001f) && (a < 0.00000001f)) return 0; + if ((a > -0.00000001f) && (a < 0.00000001f)) return false; f = 1.0f / a; sub_v3_v3v3(s, p1, v0); @@ -1119,9 +1119,9 @@ bool isect_ray_plane_v3(const float p1[3], const float d[3], /* v = f * dot_v3v3(d, q); */ /*UNUSED*/ *r_lambda = f * dot_v3v3(e2, q); - if (clip && (*r_lambda < 0.0f)) return 0; + if (clip && (*r_lambda < 0.0f)) return false; - return 1; + return true; } bool isect_ray_tri_epsilon_v3(const float p1[3], const float d[3], @@ -1142,22 +1142,22 @@ bool isect_ray_tri_epsilon_v3(const float p1[3], const float d[3], sub_v3_v3v3(s, p1, v0); u = f * dot_v3v3(s, p); - if ((u < -epsilon) || (u > 1.0f + epsilon)) return 0; + if ((u < -epsilon) || (u > 1.0f + epsilon)) return false; cross_v3_v3v3(q, s, e1); v = f * dot_v3v3(d, q); - if ((v < -epsilon) || ((u + v) > 1.0f + epsilon)) return 0; + if ((v < -epsilon) || ((u + v) > 1.0f + epsilon)) return false; *r_lambda = f * dot_v3v3(e2, q); - if ((*r_lambda < 0.0f)) return 0; + if ((*r_lambda < 0.0f)) return false; if (uv) { uv[0] = u; uv[1] = v; } - return 1; + return true; } bool isect_ray_tri_threshold_v3(const float p1[3], const float d[3], @@ -1173,14 +1173,14 @@ bool isect_ray_tri_threshold_v3(const float p1[3], const float d[3], cross_v3_v3v3(p, d, e2); a = dot_v3v3(e1, p); - if ((a > -0.000001f) && (a < 0.000001f)) return 0; + if ((a > -0.000001f) && (a < 0.000001f)) return false; f = 1.0f / a; sub_v3_v3v3(s, p1, v0); cross_v3_v3v3(q, s, e1); *r_lambda = f * dot_v3v3(e2, q); - if ((*r_lambda < 0.0f)) return 0; + if ((*r_lambda < 0.0f)) return false; u = f * dot_v3v3(s, p); v = f * dot_v3v3(d, q); @@ -1204,7 +1204,7 @@ bool isect_ray_tri_threshold_v3(const float p1[3], const float d[3], mul_v3_fl(e2, dv); if (len_squared_v3(e1) + len_squared_v3(e2) > threshold * threshold) { - return 0; + return false; } if (r_uv) { @@ -1212,7 +1212,7 @@ bool isect_ray_tri_threshold_v3(const float p1[3], const float d[3], r_uv[1] = v; } - return 1; + return true; } /** @@ -1363,7 +1363,7 @@ bool isect_sweeping_sphere_tri_v3(const float p1[3], const float p2[3], const fl if (t0 > t1) SWAP(float, t0, t1); - if (t0 > 1.0f || t1 < 0.0f) return 0; + if (t0 > 1.0f || t1 < 0.0f) return false; /* clamp to [0, 1] */ CLAMP(t0, 0.0f, 1.0f); @@ -1542,7 +1542,7 @@ bool isect_axial_line_tri_v3(const int axis, const float p1[3], const float p2[3 if ((f > -0.000001f) && (f < 0.000001f)) return false; v = (p[a2] * e1[a1] - p[a1] * e1[a2]) / f; - if ((v < 0.0f) || (v > 1.0f)) return 0; + if ((v < 0.0f) || (v > 1.0f)) return false; f = e1[a1]; if ((f > -0.000001f) && (f < 0.000001f)) { @@ -1553,7 +1553,7 @@ bool isect_axial_line_tri_v3(const int axis, const float p1[3], const float p2[3 else u = (-p[a1] - v * e2[a1]) / f; - if ((u < 0.0f) || ((u + v) > 1.0f)) return 0; + if ((u < 0.0f) || ((u + v) > 1.0f)) return false; *r_lambda = (p[a0] + u * e1[a0] + v * e2[a0]) / (p2[a0] - p1[a0]); diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index 8f9fcbc252c..1b4bbafdb04 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -866,7 +866,7 @@ bool invert_m4_m4(float inverse[4][4], float mat[4][4]) } } } - return 1; + return true; } /****************************** Linear Algebra *******************************/ @@ -1150,11 +1150,11 @@ bool is_orthogonal_m3(float m[3][3]) for (i = 0; i < 3; i++) { for (j = 0; j < i; j++) { if (fabsf(dot_v3v3(m[i], m[j])) > 1.5f * FLT_EPSILON) - return 0; + return false; } } - return 1; + return true; } bool is_orthogonal_m4(float m[4][4]) @@ -1164,12 +1164,12 @@ bool is_orthogonal_m4(float m[4][4]) for (i = 0; i < 4; i++) { for (j = 0; j < i; j++) { if (fabsf(dot_v4v4(m[i], m[j])) > 1.5f * FLT_EPSILON) - return 0; + return false; } } - return 1; + return true; } bool is_orthonormal_m3(float m[3][3]) @@ -1179,12 +1179,12 @@ bool is_orthonormal_m3(float m[3][3]) for (i = 0; i < 3; i++) if (fabsf(dot_v3v3(m[i], m[i]) - 1) > 1.5f * FLT_EPSILON) - return 0; + return false; - return 1; + return true; } - return 0; + return false; } bool is_orthonormal_m4(float m[4][4]) @@ -1194,12 +1194,12 @@ bool is_orthonormal_m4(float m[4][4]) for (i = 0; i < 4; i++) if (fabsf(dot_v4v4(m[i], m[i]) - 1) > 1.5f * FLT_EPSILON) - return 0; + return false; - return 1; + return true; } - return 0; + return false; } bool is_uniform_scaled_m3(float m[3][3]) diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c index abb6cc3f3cd..0a30a35ba7c 100644 --- a/source/blender/blenlib/intern/path_util.c +++ b/source/blender/blenlib/intern/path_util.c @@ -1253,11 +1253,10 @@ bool BLI_testextensie_n(const char *str, ...) while ((ext = (const char *) va_arg(args, void *))) { if (testextensie_ex(str, str_len, ext, strlen(ext))) { ret = true; - goto finally; + break; } } -finally: va_end(args); return ret; diff --git a/source/blender/blenlib/intern/scanfill.c b/source/blender/blenlib/intern/scanfill.c index 1653ba5ae6e..8a96daeeb91 100644 --- a/source/blender/blenlib/intern/scanfill.c +++ b/source/blender/blenlib/intern/scanfill.c @@ -173,13 +173,13 @@ static bool boundisect(PolyFill *pf2, PolyFill *pf1) /* has pf2 been touched (intersected) by pf1 ? with bounding box */ /* test first if polys exist */ - if (pf1->edges == 0 || pf2->edges == 0) return 0; + if (pf1->edges == 0 || pf2->edges == 0) return false; - if (pf2->max_xy[0] < pf1->min_xy[0]) return 0; - if (pf2->max_xy[1] < pf1->min_xy[1]) return 0; + if (pf2->max_xy[0] < pf1->min_xy[0]) return false; + if (pf2->max_xy[1] < pf1->min_xy[1]) return false; - if (pf2->min_xy[0] > pf1->max_xy[0]) return 0; - if (pf2->min_xy[1] > pf1->max_xy[1]) return 0; + if (pf2->min_xy[0] > pf1->max_xy[0]) return false; + if (pf2->min_xy[1] > pf1->max_xy[1]) return false; /* join */ if (pf2->max_xy[0] < pf1->max_xy[0]) pf2->max_xy[0] = pf1->max_xy[0]; @@ -188,7 +188,7 @@ static bool boundisect(PolyFill *pf2, PolyFill *pf1) if (pf2->min_xy[0] > pf1->min_xy[0]) pf2->min_xy[0] = pf1->min_xy[0]; if (pf2->min_xy[1] > pf1->min_xy[1]) pf2->min_xy[1] = pf1->min_xy[1]; - return 1; + return true; } @@ -225,13 +225,13 @@ static bool testedgeside(const float v1[2], const float v2[2], const float v3[2] (v1[1] - v2[1]) * (v1[0] - v3[0]); if (inp < 0.0f) { - return 0; + return false; } else if (inp == 0.0f) { - if (v1[0] == v3[0] && v1[1] == v3[1]) return 0; - if (v2[0] == v3[0] && v2[1] == v3[1]) return 0; + if (v1[0] == v3[0] && v1[1] == v3[1]) return false; + if (v2[0] == v3[0] && v2[1] == v3[1]) return false; } - return 1; + return true; } static bool addedgetoscanvert(ScanFillVertLink *sc, ScanFillEdge *eed) @@ -261,7 +261,7 @@ static bool addedgetoscanvert(ScanFillVertLink *sc, ScanFillEdge *eed) for (ed = sc->edge_first; ed; ed = ed->next) { if (ed->v2 == eed->v2) { - return 0; + return false; } fac = ed->v2->xy[1] - y; @@ -279,7 +279,7 @@ static bool addedgetoscanvert(ScanFillVertLink *sc, ScanFillEdge *eed) if (ed) BLI_insertlinkbefore((ListBase *)&(sc->edge_first), ed, eed); else BLI_addtail((ListBase *)&(sc->edge_first), eed); - return 1; + return true; } @@ -341,10 +341,10 @@ static bool boundinsideEV(ScanFillEdge *eed, ScanFillVert *eve) maxy = eed->v1->xy[1]; } if (eve->xy[1] >= miny && eve->xy[1] <= maxy) { - return 1; + return true; } } - return 0; + return false; } -- cgit v1.2.3 From ee010650f61c759a1b5d3279bbdbbc5b8915152b Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 1 Dec 2014 18:27:45 +0100 Subject: Python: add 'render_write' callback This is useful for addons which intend to write data next to the rendered image/movie, but not for preview renders. --- source/blender/blenlib/BLI_callbacks.h | 1 + 1 file changed, 1 insertion(+) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_callbacks.h b/source/blender/blenlib/BLI_callbacks.h index 2f963cfac51..7cf524749c2 100644 --- a/source/blender/blenlib/BLI_callbacks.h +++ b/source/blender/blenlib/BLI_callbacks.h @@ -41,6 +41,7 @@ typedef enum { BLI_CB_EVT_FRAME_CHANGE_POST, BLI_CB_EVT_RENDER_PRE, BLI_CB_EVT_RENDER_POST, + BLI_CB_EVT_RENDER_WRITE, BLI_CB_EVT_RENDER_STATS, BLI_CB_EVT_RENDER_INIT, BLI_CB_EVT_RENDER_COMPLETE, -- cgit v1.2.3 From f86fd544c1023a17e32693c7d8481d74c19e54d1 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 2 Dec 2014 14:27:18 +0500 Subject: Use more unique allocation strings for new links in the list --- source/blender/blenlib/intern/BLI_linklist.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/intern/BLI_linklist.c b/source/blender/blenlib/intern/BLI_linklist.c index a0b61e7945c..51297075418 100644 --- a/source/blender/blenlib/intern/BLI_linklist.c +++ b/source/blender/blenlib/intern/BLI_linklist.c @@ -96,7 +96,7 @@ void BLI_linklist_prepend_nlink(LinkNode **listp, void *ptr, LinkNode *nlink) void BLI_linklist_prepend(LinkNode **listp, void *ptr) { - LinkNode *nlink = MEM_mallocN(sizeof(*nlink), "nlink"); + LinkNode *nlink = MEM_mallocN(sizeof(*nlink), __func__); BLI_linklist_prepend_nlink(listp, ptr, nlink); } @@ -135,7 +135,7 @@ void BLI_linklist_append_nlink(LinkNode **listp, void *ptr, LinkNode *nlink) void BLI_linklist_append(LinkNode **listp, void *ptr) { - LinkNode *nlink = MEM_mallocN(sizeof(*nlink), "nlink"); + LinkNode *nlink = MEM_mallocN(sizeof(*nlink), __func__); BLI_linklist_append_nlink(listp, ptr, nlink); } @@ -177,7 +177,7 @@ void *BLI_linklist_pop_pool(struct LinkNode **listp, struct BLI_mempool *mempool void BLI_linklist_insert_after(LinkNode **listp, void *ptr) { - LinkNode *nlink = MEM_mallocN(sizeof(*nlink), "nlink"); + LinkNode *nlink = MEM_mallocN(sizeof(*nlink), __func__); LinkNode *node = *listp; nlink->link = ptr; -- cgit v1.2.3 From e177c5143055306d4b128663d537568bd1256645 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 2 Dec 2014 15:23:58 +0500 Subject: Use atomic operations in task pool This ensures proper values of currently running tasks in the pool (previously difference between mutex locks when acquiring new job and releasing it might in theory give wrong values). --- source/blender/blenlib/CMakeLists.txt | 1 + source/blender/blenlib/SConscript | 1 + source/blender/blenlib/intern/task.c | 12 +++++++----- 3 files changed, 9 insertions(+), 5 deletions(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index cb84c0d2e52..55a5d911d78 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -30,6 +30,7 @@ set(INC # ../blenkernel # dont add this back! ../makesdna ../../../intern/guardedalloc + ../../../intern/atomic ../../../extern/wcwidth ) diff --git a/source/blender/blenlib/SConscript b/source/blender/blenlib/SConscript index 2dabb5a7334..55747a426f0 100644 --- a/source/blender/blenlib/SConscript +++ b/source/blender/blenlib/SConscript @@ -35,6 +35,7 @@ incs = [ '.', '#/extern/wcwidth', '#/intern/guardedalloc', + '#/intern/atomic', '../makesdna', env['BF_FREETYPE_INC'], env['BF_ZLIB_INC'], diff --git a/source/blender/blenlib/intern/task.c b/source/blender/blenlib/intern/task.c index e4cded18b76..d187a8d1968 100644 --- a/source/blender/blenlib/intern/task.c +++ b/source/blender/blenlib/intern/task.c @@ -33,6 +33,8 @@ #include "BLI_task.h" #include "BLI_threads.h" +#include "atomic_ops.h" + /* Types */ typedef struct Task { @@ -49,8 +51,8 @@ struct TaskPool { volatile size_t num; volatile size_t done; - volatile int num_threads; - volatile int currently_running_tasks; + size_t num_threads; + size_t currently_running_tasks; ThreadMutex num_mutex; ThreadCondition num_cond; @@ -86,7 +88,7 @@ static void task_pool_num_decrease(TaskPool *pool, size_t done) BLI_assert(pool->num >= done); pool->num -= done; - pool->currently_running_tasks -= done; + atomic_sub_z(&pool->currently_running_tasks, done); pool->done += done; if (pool->num == 0) @@ -130,7 +132,7 @@ static bool task_scheduler_thread_wait_pop(TaskScheduler *scheduler, Task **task { *task = current_task; found_task = true; - pool->currently_running_tasks++; + atomic_add_z(&pool->currently_running_tasks, 1); BLI_remlink(&scheduler->queue, *task); break; } @@ -392,7 +394,7 @@ void BLI_task_pool_work_and_wait(TaskPool *pool) /* if found task, do it, otherwise wait until other tasks are done */ if (found_task) { /* run task */ - pool->currently_running_tasks++; + atomic_add_z(&pool->currently_running_tasks, 1); work_task->run(pool, work_task->taskdata, 0); /* delete task */ -- cgit v1.2.3 From 4e60462881f1f49b4e85784c4e2ce36669d95af7 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Tue, 2 Dec 2014 16:09:12 +0500 Subject: Followup to previous linked list commit Windows doesn't have __func__ and utildefines was never included. --- source/blender/blenlib/intern/BLI_linklist.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/intern/BLI_linklist.c b/source/blender/blenlib/intern/BLI_linklist.c index 51297075418..6b79cf97e86 100644 --- a/source/blender/blenlib/intern/BLI_linklist.c +++ b/source/blender/blenlib/intern/BLI_linklist.c @@ -32,6 +32,8 @@ #include "MEM_guardedalloc.h" + +#include "BLI_utildefines.h" #include "BLI_linklist.h" #include "BLI_memarena.h" #include "BLI_mempool.h" -- cgit v1.2.3 From 06515475b9c87c553d75481abfa600a0f7a5faf8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sat, 6 Dec 2014 13:01:47 +0100 Subject: CMake: remove redundant include dir --- source/blender/blenlib/intern/scanfill_utils.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/intern/scanfill_utils.c b/source/blender/blenlib/intern/scanfill_utils.c index 029e98bad5e..6ddea300404 100644 --- a/source/blender/blenlib/intern/scanfill_utils.c +++ b/source/blender/blenlib/intern/scanfill_utils.c @@ -76,7 +76,7 @@ typedef struct ScanFillIsect { #if 0 -void BKE_scanfill_obj_dump(ScanFillContext *sf_ctx) +void BLI_scanfill_obj_dump(ScanFillContext *sf_ctx) { FILE *f = fopen("test.obj", "w"); unsigned int i = 1; @@ -96,7 +96,7 @@ void BKE_scanfill_obj_dump(ScanFillContext *sf_ctx) #endif #if 0 -void BKE_scanfill_view3d_dump(ScanFillContext *sf_ctx) +void BLI_scanfill_view3d_dump(ScanFillContext *sf_ctx) { ScanFillEdge *eed; @@ -508,8 +508,8 @@ bool BLI_scanfill_calc_self_isect( sf_ctx->poly_nr = SF_POLY_UNSET; #if 0 - BKE_scanfill_view3d_dump(sf_ctx); - BKE_scanfill_obj_dump(sf_ctx); + BLI_scanfill_view3d_dump(sf_ctx); + BLI_scanfill_obj_dump(sf_ctx); #endif return changed; -- cgit v1.2.3 From e67fd7a2cbf9723a0f800d9a14834ff6838f2b7f Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Sun, 7 Dec 2014 13:21:02 +0100 Subject: Correct defines for binreloc After recent moving path functions to appdir.c patch T42826: by ldo (Lawrence D'Oliveiro) --- source/blender/blenlib/CMakeLists.txt | 7 ------- 1 file changed, 7 deletions(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index 55a5d911d78..7dfcc2a62fd 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -189,13 +189,6 @@ set(SRC PIL_time_utildefines.h ) -if(WITH_BINRELOC) - list(APPEND INC_SYS - ${BINRELOC_INCLUDE_DIRS} - ) - add_definitions(-DWITH_BINRELOC) -endif() - if(WITH_MEM_VALGRIND) add_definitions(-DWITH_MEM_VALGRIND) endif() -- cgit v1.2.3 From 3e7e97f1277d83582f314587f28f513291e2caca Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 8 Dec 2014 10:54:56 +0100 Subject: BMesh: ensure iterator macros assign to valid types note, this is for C++ code which expects a cast, (will be added later) also add a macro for nop-expressions (EXPR_NOP), when we never want an expression to be evaluated, but it should still be valid. --- source/blender/blenlib/BLI_compiler_typecheck.h | 19 ++++++++++++------- source/blender/blenlib/BLI_utildefines.h | 2 ++ 2 files changed, 14 insertions(+), 7 deletions(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_compiler_typecheck.h b/source/blender/blenlib/BLI_compiler_typecheck.h index 551569b066d..46c57772f64 100644 --- a/source/blender/blenlib/BLI_compiler_typecheck.h +++ b/source/blender/blenlib/BLI_compiler_typecheck.h @@ -51,9 +51,9 @@ })) #else -# define CHECK_TYPE(var, type) -# define CHECK_TYPE_PAIR(var_a, var_b) -# define CHECK_TYPE_PAIR_INLINE(var_a, var_b) (void)0 +# define CHECK_TYPE(var, type) { EXPR_NOP(var); }(void)0 +# define CHECK_TYPE_PAIR(var_a, var_b) { (EXPR_NOP(var_a), EXPR_NOP(var_b)); }(void)0 +# define CHECK_TYPE_PAIR_INLINE(var_a, var_b) (EXPR_NOP(var_a), EXPR_NOP(var_b)) #endif /* can be used in simple macros */ @@ -66,10 +66,15 @@ ((void)(((type)0) != (0 ? (val) : ((type)0)))) #endif -#define CHECK_TYPE_NONCONST(var) { \ - void *non_const = 0 ? (var) : NULL; \ - (void)non_const; \ -} (void)0 +#if defined(__GNUC__) || defined(__clang__) +# define CHECK_TYPE_NONCONST(var) __extension__ ({ \ + void *non_const = 0 ? (var) : NULL; \ + (void)non_const; \ +}) +#else +# define CHECK_TYPE_NONCONST(var) EXPR_NOP(var) +#endif + /** * CHECK_TYPE_ANY: handy macro, eg: diff --git a/source/blender/blenlib/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h index ef1312a1d94..53896bb31b6 100644 --- a/source/blender/blenlib/BLI_utildefines.h +++ b/source/blender/blenlib/BLI_utildefines.h @@ -219,6 +219,8 @@ extern "C" { /* reusable ELEM macro */ #define ELEM(...) VA_NARGS_CALL_OVERLOAD(_VA_ELEM, __VA_ARGS__) +/* no-op for expressions we don't want to instansiate, but must remian valid */ +#define EXPR_NOP(expr) (void)(0 ? ((void)(expr), 1) : 0) /* shift around elements */ #define SHIFT3(type, a, b, c) { \ -- cgit v1.2.3 From 03760fed0d433568b1dc6e46fb7b48c59a3300b5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 9 Dec 2014 00:02:18 +0100 Subject: Cleanup: remove unused pointer in Heap --- source/blender/blenlib/intern/BLI_heap.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/intern/BLI_heap.c b/source/blender/blenlib/intern/BLI_heap.c index 55dee4e8677..1e616d1d495 100644 --- a/source/blender/blenlib/intern/BLI_heap.c +++ b/source/blender/blenlib/intern/BLI_heap.c @@ -49,7 +49,6 @@ struct Heap { unsigned int bufsize; MemArena *arena; HeapNode *freenodes; - HeapNode *nodes; HeapNode **tree; }; @@ -163,7 +162,7 @@ HeapNode *BLI_heap_insert(Heap *heap, float value, void *ptr) if (heap->freenodes) { node = heap->freenodes; - heap->freenodes = (HeapNode *)(((HeapNode *)heap->freenodes)->ptr); + heap->freenodes = heap->freenodes->ptr; } else { node = (HeapNode *)BLI_memarena_alloc(heap->arena, sizeof(*node)); -- cgit v1.2.3 From 55812e3acd625aa93162cd9e0894efd43a1dd615 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 9 Dec 2014 00:13:35 +0100 Subject: Cleanup: simplify heap popmin --- source/blender/blenlib/intern/BLI_heap.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/intern/BLI_heap.c b/source/blender/blenlib/intern/BLI_heap.c index 1e616d1d495..05bd1074bf0 100644 --- a/source/blender/blenlib/intern/BLI_heap.c +++ b/source/blender/blenlib/intern/BLI_heap.c @@ -205,13 +205,8 @@ void *BLI_heap_popmin(Heap *heap) heap->tree[0]->ptr = heap->freenodes; heap->freenodes = heap->tree[0]; - if (UNLIKELY(heap->size == 1)) { - heap->size--; - } - else { - heap_swap(heap, 0, heap->size - 1); - heap->size--; - + if (--heap->size) { + heap_swap(heap, 0, heap->size); heap_down(heap, 0); } -- cgit v1.2.3 From 83cbcefac8349d5ff46b721318ca180dd8817af5 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 9 Dec 2014 00:32:20 +0100 Subject: Add edgehash remove, clear functions, Heap clear Edgehash was missing removal functions (remove, popkey, clear), since it wasn't needed so far, but is based on same code as ghash which has them. also add heap clear() method so we can reuse heaps. (needed for upcoming fix). --- source/blender/blenlib/BLI_edgehash.h | 3 ++ source/blender/blenlib/BLI_heap.h | 1 + source/blender/blenlib/intern/BLI_heap.c | 19 ++++++- source/blender/blenlib/intern/edgehash.c | 92 +++++++++++++++++++++++++++++++- 4 files changed, 111 insertions(+), 4 deletions(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_edgehash.h b/source/blender/blenlib/BLI_edgehash.h index a0455489d24..c5323a4cf12 100644 --- a/source/blender/blenlib/BLI_edgehash.h +++ b/source/blender/blenlib/BLI_edgehash.h @@ -55,6 +55,9 @@ bool BLI_edgehash_reinsert(EdgeHash *eh, unsigned int v0, unsigned in void *BLI_edgehash_lookup(EdgeHash *eh, unsigned int v0, unsigned int v1) ATTR_WARN_UNUSED_RESULT; void *BLI_edgehash_lookup_default(EdgeHash *eh, unsigned int v0, unsigned int v1, void *val_default) ATTR_WARN_UNUSED_RESULT; void **BLI_edgehash_lookup_p(EdgeHash *eh, unsigned int v0, unsigned int v1) ATTR_WARN_UNUSED_RESULT; +bool BLI_edgehash_remove(EdgeHash *eh, unsigned int v0, unsigned int v1, EdgeHashFreeFP valfreefp); + +void *BLI_edgehash_popkey(EdgeHash *eh, unsigned int v0, unsigned int v1) ATTR_WARN_UNUSED_RESULT; bool BLI_edgehash_haskey(EdgeHash *eh, unsigned int v0, unsigned int v1) ATTR_WARN_UNUSED_RESULT; int BLI_edgehash_size(EdgeHash *eh) ATTR_WARN_UNUSED_RESULT; void BLI_edgehash_clear_ex(EdgeHash *eh, EdgeHashFreeFP valfreefp, diff --git a/source/blender/blenlib/BLI_heap.h b/source/blender/blenlib/BLI_heap.h index ac9edfd46a2..ea361097b7b 100644 --- a/source/blender/blenlib/BLI_heap.h +++ b/source/blender/blenlib/BLI_heap.h @@ -37,6 +37,7 @@ typedef void (*HeapFreeFP)(void *ptr); * are recycled, so memory usage will not shrink. */ Heap *BLI_heap_new_ex(unsigned int tot_reserve) ATTR_WARN_UNUSED_RESULT; Heap *BLI_heap_new(void) ATTR_WARN_UNUSED_RESULT; +void BLI_heap_clear(Heap *heap, HeapFreeFP ptrfreefp) ATTR_NONNULL(1); void BLI_heap_free(Heap *heap, HeapFreeFP ptrfreefp) ATTR_NONNULL(1); /* Insert heap node with a value (often a 'cost') and pointer into the heap, diff --git a/source/blender/blenlib/intern/BLI_heap.c b/source/blender/blenlib/intern/BLI_heap.c index 05bd1074bf0..66dfa87b7b9 100644 --- a/source/blender/blenlib/intern/BLI_heap.c +++ b/source/blender/blenlib/intern/BLI_heap.c @@ -138,9 +138,9 @@ Heap *BLI_heap_new(void) void BLI_heap_free(Heap *heap, HeapFreeFP ptrfreefp) { - unsigned int i; - if (ptrfreefp) { + unsigned int i; + for (i = 0; i < heap->size; i++) { ptrfreefp(heap->tree[i]->ptr); } @@ -151,6 +151,21 @@ void BLI_heap_free(Heap *heap, HeapFreeFP ptrfreefp) MEM_freeN(heap); } +void BLI_heap_clear(Heap *heap, HeapFreeFP ptrfreefp) +{ + if (ptrfreefp) { + unsigned int i; + + for (i = 0; i < heap->size; i++) { + ptrfreefp(heap->tree[i]->ptr); + } + } + + heap->size = 0; + BLI_memarena_clear(heap->arena); + heap->freenodes = NULL; +} + HeapNode *BLI_heap_insert(Heap *heap, float value, void *ptr) { HeapNode *node; diff --git a/source/blender/blenlib/intern/edgehash.c b/source/blender/blenlib/intern/edgehash.c index 4ed82f8a473..385d9ecb1ec 100644 --- a/source/blender/blenlib/intern/edgehash.c +++ b/source/blender/blenlib/intern/edgehash.c @@ -146,7 +146,7 @@ BLI_INLINE void edgehash_buckets_reserve(EdgeHash *eh, const unsigned int nentri /** * Internal lookup function. - * Takes a hash argument to avoid calling #ghash_keyhash multiple times. + * Takes a hash argument to avoid calling #edgehash_keyhash multiple times. */ BLI_INLINE EdgeEntry *edgehash_lookup_entry_ex(EdgeHash *eh, unsigned int v0, unsigned int v1, const unsigned int hash) @@ -255,6 +255,35 @@ BLI_INLINE void edgehash_insert(EdgeHash *eh, unsigned int v0, unsigned int v1, edgehash_insert_ex(eh, v0, v1, val, hash); } +/** + * Remove the entry and return it, caller must free from eh->epool. + */ +static EdgeEntry *edgehash_remove_ex(EdgeHash *eh, unsigned int v0, unsigned int v1, EdgeHashFreeFP valfreefp, + unsigned int hash) +{ + EdgeEntry *e; + EdgeEntry *e_prev = NULL; + + BLI_assert(v0 < v1); + + for (e = eh->buckets[hash]; e; e = e->next) { + if (UNLIKELY(v0 == e->v0 && v1 == e->v1)) { + EdgeEntry *e_next = e->next; + + if (valfreefp) valfreefp(e->val); + + if (e_prev) e_prev->next = e_next; + else eh->buckets[hash] = e_next; + + eh->nentries--; + return e; + } + e_prev = e; + } + + return NULL; +} + /** * Run free callbacks for freeing entries. */ @@ -365,6 +394,57 @@ void *BLI_edgehash_lookup_default(EdgeHash *eh, unsigned int v0, unsigned int v1 return e ? e->val : val_default; } +/** + * Remove \a key from \a eh, or return false if the key wasn't found. + * + * \param key The key to remove. + * \param valfreefp Optional callback to free the value. + * \return true if \a key was removed from \a eh. + */ +bool BLI_edgehash_remove(EdgeHash *eh, unsigned int v0, unsigned int v1, EdgeHashFreeFP valfreefp) +{ + unsigned int hash; + EdgeEntry *e; + + EDGE_ORD(v0, v1); /* ensure v0 is smaller */ + hash = edgehash_keyhash(eh, v0, v1); + e = edgehash_remove_ex(eh, v0, v1, valfreefp, hash); + if (e) { + BLI_mempool_free(eh->epool, e); + return true; + } + else { + return false; + } +} + +/* same as above but return the value, + * no free value argument since it will be returned */ +/** + * Remove \a key from \a eh, returning the value or NULL if the key wasn't found. + * + * \param key The key to remove. + * \return the value of \a key int \a eh or NULL. + */ +void *BLI_edgehash_popkey(EdgeHash *eh, unsigned int v0, unsigned int v1) +{ + unsigned int hash; + EdgeEntry *e; + + EDGE_ORD(v0, v1); /* ensure v0 is smaller */ + hash = edgehash_keyhash(eh, v0, v1); + e = edgehash_remove_ex(eh, v0, v1, NULL, hash); + IS_EDGEHASH_ASSERT(eh); + if (e) { + void *val = e->val; + BLI_mempool_free(eh->epool, e); + return val; + } + else { + return NULL; + } +} + /** * Return boolean true/false if edge (v0,v1) in hash. */ @@ -404,6 +484,14 @@ void BLI_edgehash_clear_ex(EdgeHash *eh, EdgeHashFreeFP valfreefp, BLI_mempool_clear_ex(eh->epool, nentries_reserve ? (int)nentries_reserve : -1); } +/** + * Wraps #BLI_edgehash_clear_ex with zero entries reserved. + */ +void BLI_edgehash_clear(EdgeHash *eh, EdgeHashFreeFP valfreefp) +{ + BLI_edgehash_clear_ex(eh, valfreefp, 0); +} + void BLI_edgehash_free(EdgeHash *eh, EdgeHashFreeFP valfreefp) { BLI_assert((int)eh->nentries == BLI_mempool_count(eh->epool)); @@ -440,7 +528,7 @@ void BLI_edgehash_flag_clear(EdgeHash *eh, unsigned int flag) /** * Create a new EdgeHashIterator. The hash table must not be mutated * while the iterator is in use, and the iterator will step exactly - * BLI_edgehash_size(gh) times before becoming done. + * BLI_edgehash_size(eh) times before becoming done. */ EdgeHashIterator *BLI_edgehashIterator_new(EdgeHash *eh) { -- cgit v1.2.3 From 6076bedec002b92e5f316a15a45a8cdaf686aa33 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 9 Dec 2014 12:19:26 +0100 Subject: Cleanup: remove scanfill define for polyfill code also rename vars which were previously used for scanfill. --- source/blender/blenlib/BLI_polyfill2d.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_polyfill2d.h b/source/blender/blenlib/BLI_polyfill2d.h index 5c5cea8f67d..798055f9240 100644 --- a/source/blender/blenlib/BLI_polyfill2d.h +++ b/source/blender/blenlib/BLI_polyfill2d.h @@ -37,4 +37,7 @@ void BLI_polyfill_calc( const int coords_sign, unsigned int (*r_tris)[3]); +/* default size of polyfill arena */ +#define BLI_POLYFILL_ARENA_SIZE MEM_SIZE_OPTIMAL(1 << 14) + #endif /* __BLI_POLYFILL2D_H__ */ -- cgit v1.2.3 From a5c3de2e49ca348479b1f5915db9f7460422d07a Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 8 Dec 2014 16:57:39 +0100 Subject: Fix T42630: Triangulate returns invalid face-map Triangulate with beautify caused a bug when there were existing edges could make the bmesh-operator return an invalid face-map. Now the beauty is calculated on the 2d-tri's resulting from polyfill, its simpler and faster. --- source/blender/blenlib/BLI_polyfill2d_beautify.h | 39 ++ source/blender/blenlib/CMakeLists.txt | 2 + .../blender/blenlib/intern/polyfill2d_beautify.c | 498 +++++++++++++++++++++ 3 files changed, 539 insertions(+) create mode 100644 source/blender/blenlib/BLI_polyfill2d_beautify.h create mode 100644 source/blender/blenlib/intern/polyfill2d_beautify.c (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_polyfill2d_beautify.h b/source/blender/blenlib/BLI_polyfill2d_beautify.h new file mode 100644 index 00000000000..c3bb29af21e --- /dev/null +++ b/source/blender/blenlib/BLI_polyfill2d_beautify.h @@ -0,0 +1,39 @@ +/* + * ***** 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. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __BLI_POLYFILL2D_BEAUTIFY_H__ +#define __BLI_POLYFILL2D_BEAUTIFY_H__ + +struct EdgeHash; +struct Heap; +struct MemArena; + +void BLI_polyfill_beautify( + const float (*coords)[2], + const unsigned int coords_tot, + unsigned int (*tris)[3], + + /* structs for reuse */ + struct MemArena *arena, struct Heap *eheap, struct EdgeHash *eh); + +/* avoid realloc's when creating new structures for polyfill ngons */ +#define BLI_POLYFILL_ALLOC_NGON_RESERVE 64 + +#endif /* __BLI_POLYFILL2D_BEAUTIFY_H__ */ diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index 7dfcc2a62fd..c8f0e1bf26b 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -85,6 +85,7 @@ set(SRC intern/noise.c intern/path_util.c intern/polyfill2d.c + intern/polyfill2d_beautify.c intern/quadric.c intern/rand.c intern/rct.c @@ -161,6 +162,7 @@ set(SRC BLI_noise.h BLI_path_util.h BLI_polyfill2d.h + BLI_polyfill2d_beautify.h BLI_quadric.h BLI_rand.h BLI_rect.h diff --git a/source/blender/blenlib/intern/polyfill2d_beautify.c b/source/blender/blenlib/intern/polyfill2d_beautify.c new file mode 100644 index 00000000000..5bbdbeb8c06 --- /dev/null +++ b/source/blender/blenlib/intern/polyfill2d_beautify.c @@ -0,0 +1,498 @@ +/* + * ***** 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. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/blenlib/intern/polyfill2d_beautify.c + * \ingroup bli + * + * This function is to improve the tessellation resulting from polyfill2d, + * creating optimal topology. + * + * The functionality here matches #BM_mesh_beautify_fill, + * but its far simpler to perform this operation in 2d, + * on a simple polygon representation where we _know_: + * + * - The polygon is primitive with no holes with a continuous boundary. + * - Tris have consistent winding. + * - 2d (saves some hassles projecting face pairs on an axis for every edge-rotation) + * also saves us having to store all previous edge-states (see #EdRotState in bmesh_beautify.c) + * + * \note + * + * No globals - keep threadsafe. + */ + +#include "BLI_utildefines.h" +#include "BLI_math.h" + +#include "BLI_memarena.h" +#include "BLI_edgehash.h" +#include "BLI_heap.h" + +#include "BLI_polyfill2d_beautify.h" /* own include */ + +#include "BLI_strict_flags.h" + +struct PolyEdge { + /** ordered vert indices (smaller first) */ + unsigned int verts[2]; + /** ordered face indices (depends on winding compared to the edge verts) + * - (verts[0], verts[1]) == faces[0] + * - (verts[1], verts[0]) == faces[1] + */ + unsigned int faces[2]; + /** + * The face-index which isn't used by either of the edges verts [0 - 2]. + * could be calculated each time, but cleaner to store for reuse. + */ + unsigned int faces_other_v[2]; +}; + + +#ifndef NDEBUG +/** + * Only to check for error-cases. + */ +static void polyfill_validate_tri(unsigned int (*tris)[3], unsigned int tri_index, EdgeHash *ehash) +{ + const unsigned int *tri = tris[tri_index]; + int j_curr; + + BLI_assert(!ELEM(tri[0], tri[1], tri[2]) && + !ELEM(tri[1], tri[0], tri[2]) && + !ELEM(tri[2], tri[0], tri[1])); + + for (j_curr = 0; j_curr < 3; j_curr++) { + struct PolyEdge *e; + unsigned int e_v1 = tri[(j_curr ) ]; + unsigned int e_v2 = tri[(j_curr + 1) % 3]; + e = BLI_edgehash_lookup(ehash, e_v1, e_v2); + if (e) { + if (e->faces[0] == tri_index) { + BLI_assert(e->verts[0] == e_v1); + BLI_assert(e->verts[1] == e_v2); + } + else if (e->faces[1] == tri_index) { + BLI_assert(e->verts[0] == e_v2); + BLI_assert(e->verts[1] == e_v1); + } + else { + BLI_assert(0); + } + + BLI_assert(e->faces[0] != e->faces[1]); + BLI_assert(ELEM(e_v1, UNPACK3(tri))); + BLI_assert(ELEM(e_v2, UNPACK3(tri))); + BLI_assert(ELEM(e_v1, UNPACK2(e->verts))); + BLI_assert(ELEM(e_v2, UNPACK2(e->verts))); + BLI_assert(e_v1 != tris[e->faces[0]][e->faces_other_v[0]]); + BLI_assert(e_v1 != tris[e->faces[1]][e->faces_other_v[1]]); + BLI_assert(e_v2 != tris[e->faces[0]][e->faces_other_v[0]]); + BLI_assert(e_v2 != tris[e->faces[1]][e->faces_other_v[1]]); + + BLI_assert(ELEM(tri_index, UNPACK2(e->faces))); + } + } +} +#endif + +BLI_INLINE bool is_boundary_edge(unsigned int i_a, unsigned int i_b, const unsigned int coord_last) +{ + BLI_assert(i_a < i_b); + return ((i_a + 1 == i_b) || UNLIKELY((i_a == 0) && (i_b == coord_last))); +} +/** + * Assuming we have 2 triangles sharing an edge (2 - 4), + * check if the edge running from (1 - 3) gives better results + * (negative number, lager == better). + */ +static float quad_v2_rotate_beauty_calc( + const float v1[2], const float v2[2], const float v3[2], const float v4[2]) +{ + /* not a loop (only to be able to break out) */ + do { + bool is_zero_a, is_zero_b; + + const float area_2x_234 = cross_tri_v2(v2, v3, v4); + const float area_2x_241 = cross_tri_v2(v2, v4, v1); + + const float area_2x_123 = cross_tri_v2(v1, v2, v3); + const float area_2x_134 = cross_tri_v2(v1, v3, v4); + + { + BLI_assert((ELEM(v1, v2, v3, v4) == false) && + (ELEM(v2, v1, v3, v4) == false) && + (ELEM(v3, v1, v2, v4) == false) && + (ELEM(v4, v1, v2, v3) == false)); + + is_zero_a = (fabsf(area_2x_234) <= FLT_EPSILON); + is_zero_b = (fabsf(area_2x_241) <= FLT_EPSILON); + + if (is_zero_a && is_zero_b) { + break; + } + } + + if (is_zero_a == false && is_zero_b == false) { + /* both tri's are valid, check we make a concave quad */ + if (!is_quad_convex_v2(v1, v2, v3, v4)) { + break; + } + } + else { + /* one of the tri's was degenerate, chech we're not rotating + * into a different degenerate shape or flipping the face */ + if ((fabsf(area_2x_123) <= FLT_EPSILON) || (fabsf(area_2x_134) <= FLT_EPSILON)) { + /* one of the new rotations is degenerate */ + break; + } + + if ((area_2x_123 >= 0.0f) != (area_2x_134 >= 0.0f)) { + /* rotation would cause flipping */ + break; + } + } + + { + /* testing rule: the area divided by the perimeter, + * check if (1-3) beats the existing (2-4) edge rotation */ + float area_a, area_b; + float prim_a, prim_b; + float fac_24, fac_13; + + float len_12, len_23, len_34, len_41, len_24, len_13; + +#define AREA_FROM_CROSS(f) (fabsf(f) / 2.0f) + + /* edges around the quad */ + len_12 = len_v2v2(v1, v2); + len_23 = len_v2v2(v2, v3); + len_34 = len_v2v2(v3, v4); + len_41 = len_v2v2(v4, v1); + /* edges crossing the quad interior */ + len_13 = len_v2v2(v1, v3); + len_24 = len_v2v2(v2, v4); + + /* edge (2-4), current state */ + area_a = AREA_FROM_CROSS(area_2x_234); + area_b = AREA_FROM_CROSS(area_2x_241); + prim_a = len_23 + len_34 + len_24; + prim_b = len_24 + len_41 + len_12; + fac_24 = (area_a / prim_a) + (area_b / prim_b); + + /* edge (1-3), new state */ + area_a = AREA_FROM_CROSS(area_2x_123); + area_b = AREA_FROM_CROSS(area_2x_134); + prim_a = len_12 + len_23 + len_13; + prim_b = len_34 + len_41 + len_13; + fac_13 = (area_a / prim_a) + (area_b / prim_b); + +#undef AREA_FROM_CROSS + + /* negative number if (1-3) is an improved state */ + return fac_24 - fac_13; + } + } while (false); + + return FLT_MAX; +} + +static float polyedge_rotate_beauty_calc( + const float (*coords)[2], + const unsigned int (*tris)[3], + const struct PolyEdge *e) +{ + const float *v1, *v2, *v3, *v4; + + v1 = coords[tris[e->faces[0]][e->faces_other_v[0]]]; + v3 = coords[tris[e->faces[1]][e->faces_other_v[1]]]; + v2 = coords[e->verts[0]]; + v4 = coords[e->verts[1]]; + + return quad_v2_rotate_beauty_calc(v1, v2, v3, v4); +} + +static void polyedge_beauty_cost_update_single( + const float (*coords)[2], + const unsigned int (*tris)[3], + const struct PolyEdge *edges, + struct PolyEdge *e, + Heap *eheap, HeapNode **eheap_table) +{ + const unsigned int i = (unsigned int)(e - edges); + + if (eheap_table[i]) { + BLI_heap_remove(eheap, eheap_table[i]); + eheap_table[i] = NULL; + } + + { + /* recalculate edge */ + const float cost = polyedge_rotate_beauty_calc(coords, tris, e); + if (cost < 0.0f) { + eheap_table[i] = BLI_heap_insert(eheap, cost, e); + } + else { + eheap_table[i] = NULL; + } + } +} + +static void polyedge_beauty_cost_update( + const float (*coords)[2], + const unsigned int (*tris)[3], + const struct PolyEdge *edges, + struct PolyEdge *e, + Heap *eheap, HeapNode **eheap_table, + EdgeHash *ehash) +{ + const unsigned int *tri_0 = tris[e->faces[0]]; + const unsigned int *tri_1 = tris[e->faces[1]]; + unsigned int i; + + struct PolyEdge *e_arr[4] = { + BLI_edgehash_lookup(ehash, + tri_0[(e->faces_other_v[0] ) % 3], + tri_0[(e->faces_other_v[0] + 1) % 3]), + BLI_edgehash_lookup(ehash, + tri_0[(e->faces_other_v[0] + 2) % 3], + tri_0[(e->faces_other_v[0] ) % 3]), + BLI_edgehash_lookup(ehash, + tri_1[(e->faces_other_v[1] ) % 3], + tri_1[(e->faces_other_v[1] + 1) % 3]), + BLI_edgehash_lookup(ehash, + tri_1[(e->faces_other_v[1] + 2) % 3], + tri_1[(e->faces_other_v[1] ) % 3]), + }; + + + for (i = 0; i < 4; i++) { + if (e_arr[i]) { + BLI_assert(!(ELEM(e_arr[i]->faces[0], UNPACK2(e->faces)) && + ELEM(e_arr[i]->faces[1], UNPACK2(e->faces)))); + + polyedge_beauty_cost_update_single( + coords, tris, edges, + e_arr[i], + eheap, eheap_table); + } + } +} + +static void polyedge_rotate( + unsigned int (*tris)[3], + struct PolyEdge *e, + EdgeHash *ehash) +{ + unsigned int e_v1_new = tris[e->faces[0]][e->faces_other_v[0]]; + unsigned int e_v2_new = tris[e->faces[1]][e->faces_other_v[1]]; + +#ifndef NDEBUG + polyfill_validate_tri(tris, e->faces[0], ehash); + polyfill_validate_tri(tris, e->faces[1], ehash); +#endif + + BLI_assert(e_v1_new != e_v2_new); + BLI_assert(!ELEM(e_v2_new, UNPACK3(tris[e->faces[0]]))); + BLI_assert(!ELEM(e_v1_new, UNPACK3(tris[e->faces[1]]))); + + tris[e->faces[0]][(e->faces_other_v[0] + 1) % 3] = e_v2_new; + tris[e->faces[1]][(e->faces_other_v[1] + 1) % 3] = e_v1_new; + + e->faces_other_v[0] = (e->faces_other_v[0] + 2) % 3; + e->faces_other_v[1] = (e->faces_other_v[1] + 2) % 3; + + BLI_assert((tris[e->faces[0]][e->faces_other_v[0]] != e_v1_new) && + (tris[e->faces[0]][e->faces_other_v[0]] != e_v2_new)); + BLI_assert((tris[e->faces[1]][e->faces_other_v[1]] != e_v1_new) && + (tris[e->faces[1]][e->faces_other_v[1]] != e_v2_new)); + + BLI_edgehash_remove(ehash, e->verts[0], e->verts[1], NULL); + BLI_edgehash_insert(ehash, e_v1_new, e_v2_new, e); + + if (e_v1_new < e_v2_new) { + e->verts[0] = e_v1_new; + e->verts[1] = e_v2_new; + } + else { + /* maintain winding info */ + e->verts[0] = e_v2_new; + e->verts[1] = e_v1_new; + + SWAP(unsigned int, e->faces[0], e->faces[1]); + SWAP(unsigned int, e->faces_other_v[0], e->faces_other_v[1]); + } + + /* update adjacent data */ + { + unsigned int e_side = 0; + + for (e_side = 0; e_side < 2; e_side++) { + /* 't_other' which we need to swap out is always the same edge-order */ + const unsigned int t_other = (((e->faces_other_v[e_side]) + 2)) % 3; + unsigned int t_index = e->faces[e_side]; + unsigned int t_index_other = e->faces[!e_side]; + unsigned int *tri = tris[t_index]; + + struct PolyEdge *e_other; + unsigned int e_v1 = tri[(t_other ) ]; + unsigned int e_v2 = tri[(t_other + 1) % 3]; + + e_other = BLI_edgehash_lookup(ehash, e_v1, e_v2); + if (e_other) { + BLI_assert(t_index != e_other->faces[0] && t_index != e_other->faces[1]); + if (t_index_other == e_other->faces[0]) { + e_other->faces[0] = t_index; + e_other->faces_other_v[0] = (t_other + 2) % 3; + BLI_assert(!ELEM(tri[e_other->faces_other_v[0]], e_v1, e_v2)); + } + else if (t_index_other == e_other->faces[1]) { + e_other->faces[1] = t_index; + e_other->faces_other_v[1] = (t_other + 2) % 3; + BLI_assert(!ELEM(tri[e_other->faces_other_v[1]], e_v1, e_v2)); + } + else { + BLI_assert(0); + } + } + } + } + +#ifndef NDEBUG + polyfill_validate_tri(tris, e->faces[0], ehash); + polyfill_validate_tri(tris, e->faces[1], ehash); +#endif + + BLI_assert(!ELEM(tris[e->faces[0]][e->faces_other_v[0]], UNPACK2(e->verts))); + BLI_assert(!ELEM(tris[e->faces[1]][e->faces_other_v[1]], UNPACK2(e->verts))); +} + +/** + * The intention is that this calculates the output of #BLI_polyfill_calc + * + * + * \note assumes the \a coords form a boundary, + * so any edges running along contiguous (wrapped) indices, + * are ignored since the edges wont share 2 faces. + */ +void BLI_polyfill_beautify( + const float (*coords)[2], + const unsigned int coords_tot, + unsigned int (*tris)[3], + + /* structs for reuse */ + MemArena *arena, Heap *eheap, EdgeHash *ehash) +{ + const unsigned int coord_last = coords_tot - 1; + const unsigned int tris_tot = coords_tot - 2; + /* internal edges only (between 2 tris) */ + const unsigned int edges_tot = tris_tot - 1; + unsigned int edges_tot_used = 0; + unsigned int i; + + HeapNode **eheap_table; + + struct PolyEdge *edges = BLI_memarena_alloc(arena, edges_tot * sizeof(*edges)); + + BLI_assert(BLI_heap_size(eheap) == 0); + BLI_assert(BLI_edgehash_size(ehash) == 0); + + /* first build edges */ + for (i = 0; i < tris_tot; i++) { + unsigned int j_prev, j_curr, j_next; + j_prev = 2; + j_next = 1; + for (j_curr = 0; j_curr < 3; j_next = j_prev, j_prev = j_curr++) { + int e_index; + + unsigned int e_pair[2] = { + tris[i][j_prev], + tris[i][j_curr], + }; + + if (e_pair[0] > e_pair[1]) { + SWAP(unsigned int, e_pair[0], e_pair[1]); + e_index = 1; + } + else { + e_index = 0; + } + + if (!is_boundary_edge(e_pair[0], e_pair[1], coord_last)) { + struct PolyEdge *e = BLI_edgehash_lookup(ehash, e_pair[0], e_pair[1]); + if (e == NULL) { + e = &edges[edges_tot_used++]; + BLI_edgehash_insert(ehash, e_pair[0], e_pair[1], e); + memcpy(e->verts, e_pair, sizeof(e->verts)); +#ifndef NDEBUG + e->faces[!e_index] = (unsigned int)-1; +#endif + } + else { + + /* ensure each edge only ever has 2x users */ +#ifndef NDEBUG + BLI_assert(e->faces[e_index] == (unsigned int)-1); + BLI_assert((e->verts[0] == e_pair[0]) && + (e->verts[1] == e_pair[1])); +#endif + } + + e->faces[e_index] = i; + e->faces_other_v[e_index] = j_next; + } + } + } + + /* now perform iterative rotations */ + eheap_table = BLI_memarena_alloc(arena, sizeof(HeapNode *) * (size_t)edges_tot); + + // for (i = 0; i < tris_tot; i++) { polyfill_validate_tri(tris, i, eh); } + + /* build heap */ + for (i = 0; i < edges_tot; i++) { + struct PolyEdge *e = &edges[i]; + const float cost = polyedge_rotate_beauty_calc(coords, (const unsigned int (*)[3])tris, e); + if (cost < 0.0f) { + eheap_table[i] = BLI_heap_insert(eheap, cost, e); + } + else { + eheap_table[i] = NULL; + } + } + + while (BLI_heap_is_empty(eheap) == false) { + struct PolyEdge *e = BLI_heap_popmin(eheap); + i = (unsigned int)(e - edges); + eheap_table[i] = NULL; + + polyedge_rotate(tris, e, ehash); + + /* recalculate faces connected on the heap */ + polyedge_beauty_cost_update( + coords, (const unsigned int (*)[3])tris, edges, + e, + eheap, eheap_table, ehash); + } + + BLI_heap_clear(eheap, NULL); + BLI_edgehash_clear_ex(ehash, NULL, BLI_POLYFILL_ALLOC_NGON_RESERVE); + + /* MEM_freeN(eheap_table); */ /* arena */ +} -- cgit v1.2.3 From 171a6bb5dc19655b3b7aee70496849890da1e4e4 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 9 Dec 2014 15:51:58 +0100 Subject: Fix T42488: Knife (selected_only + occlude) failed --- source/blender/blenlib/BLI_ghash.h | 1 + 1 file changed, 1 insertion(+) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_ghash.h b/source/blender/blenlib/BLI_ghash.h index af2605894e3..8be19d0c08b 100644 --- a/source/blender/blenlib/BLI_ghash.h +++ b/source/blender/blenlib/BLI_ghash.h @@ -41,6 +41,7 @@ extern "C" { #endif typedef unsigned int (*GHashHashFP) (const void *key); +/** returns false when equal */ typedef bool (*GHashCmpFP) (const void *a, const void *b); typedef void (*GHashKeyFreeFP) (void *key); typedef void (*GHashValFreeFP) (void *val); -- cgit v1.2.3 From d5abe8419d3bd52dcbacd179005e4467ddfab443 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Tue, 9 Dec 2014 17:18:05 +0100 Subject: Smallhash: add support for iterating value pointers also add reinsert function --- source/blender/blenlib/BLI_smallhash.h | 3 ++ source/blender/blenlib/intern/smallhash.c | 47 +++++++++++++++++++++++++++++-- 2 files changed, 48 insertions(+), 2 deletions(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_smallhash.h b/source/blender/blenlib/BLI_smallhash.h index b80044bccff..5bc40a60515 100644 --- a/source/blender/blenlib/BLI_smallhash.h +++ b/source/blender/blenlib/BLI_smallhash.h @@ -61,13 +61,16 @@ void BLI_smallhash_init_ex(SmallHash *sh, void BLI_smallhash_init(SmallHash *sh) ATTR_NONNULL(1); void BLI_smallhash_release(SmallHash *sh) ATTR_NONNULL(1); void BLI_smallhash_insert(SmallHash *sh, uintptr_t key, void *item) ATTR_NONNULL(1); +bool BLI_smallhash_reinsert(SmallHash *sh, uintptr_t key, void *item) ATTR_NONNULL(1); bool BLI_smallhash_remove(SmallHash *sh, uintptr_t key) ATTR_NONNULL(1); void *BLI_smallhash_lookup(SmallHash *sh, uintptr_t key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; void **BLI_smallhash_lookup_p(SmallHash *sh, uintptr_t key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; bool BLI_smallhash_haskey(SmallHash *sh, uintptr_t key) ATTR_NONNULL(1); int BLI_smallhash_count(SmallHash *sh) ATTR_NONNULL(1); void *BLI_smallhash_iternext(SmallHashIter *iter, uintptr_t *key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; +void **BLI_smallhash_iternext_p(SmallHashIter *iter, uintptr_t *key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; void *BLI_smallhash_iternew(SmallHash *sh, SmallHashIter *iter, uintptr_t *key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; +void **BLI_smallhash_iternew_p(SmallHash *sh, SmallHashIter *iter, uintptr_t *key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; /* void BLI_smallhash_print(SmallHash *sh); */ /* UNUSED */ #ifdef DEBUG diff --git a/source/blender/blenlib/intern/smallhash.c b/source/blender/blenlib/intern/smallhash.c index 0cf9f69b9ae..bb91f48d396 100644 --- a/source/blender/blenlib/intern/smallhash.c +++ b/source/blender/blenlib/intern/smallhash.c @@ -246,6 +246,26 @@ void BLI_smallhash_insert(SmallHash *sh, uintptr_t key, void *val) e->val = val; } +/** + * Inserts a new value to a key that may already be in ghash. + * + * Avoids #BLI_smallhash_remove, #BLI_smallhash_insert calls (double lookups) + * + * \returns true if a new key has been added. + */ +bool BLI_smallhash_reinsert(SmallHash *sh, uintptr_t key, void *item) +{ + SmallHashEntry *e = smallhash_lookup(sh, key); + if (e) { + e->val = item; + return false; + } + else { + BLI_smallhash_insert(sh, key, item); + return true; + } +} + #ifdef USE_REMOVE bool BLI_smallhash_remove(SmallHash *sh, uintptr_t key) { @@ -290,7 +310,7 @@ int BLI_smallhash_count(SmallHash *sh) return (int)sh->nentries; } -void *BLI_smallhash_iternext(SmallHashIter *iter, uintptr_t *key) +BLI_INLINE SmallHashEntry *smallhash_iternext(SmallHashIter *iter, uintptr_t *key) { while (iter->i < iter->sh->nbuckets) { if (smallhash_val_is_used(iter->sh->buckets[iter->i].val)) { @@ -298,7 +318,7 @@ void *BLI_smallhash_iternext(SmallHashIter *iter, uintptr_t *key) *key = iter->sh->buckets[iter->i].key; } - return iter->sh->buckets[iter->i++].val; + return &iter->sh->buckets[iter->i++]; } iter->i++; @@ -307,6 +327,20 @@ void *BLI_smallhash_iternext(SmallHashIter *iter, uintptr_t *key) return NULL; } +void *BLI_smallhash_iternext(SmallHashIter *iter, uintptr_t *key) +{ + SmallHashEntry *e = smallhash_iternext(iter, key); + + return e ? e->val : NULL; +} + +void **BLI_smallhash_iternext_p(SmallHashIter *iter, uintptr_t *key) +{ + SmallHashEntry *e = smallhash_iternext(iter, key); + + return e ? &e->val : NULL; +} + void *BLI_smallhash_iternew(SmallHash *sh, SmallHashIter *iter, uintptr_t *key) { iter->sh = sh; @@ -315,6 +349,15 @@ void *BLI_smallhash_iternew(SmallHash *sh, SmallHashIter *iter, uintptr_t *key) return BLI_smallhash_iternext(iter, key); } +void **BLI_smallhash_iternew_p(SmallHash *sh, SmallHashIter *iter, uintptr_t *key) +{ + iter->sh = sh; + iter->i = 0; + + return BLI_smallhash_iternext_p(iter, key); +} + + /** \name Debugging & Introspection * \{ */ -- cgit v1.2.3 From 8555595d172a4051a0be3557bfd009299578d52a Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Wed, 10 Dec 2014 13:11:48 +0500 Subject: Fixes for compilation with msvc MSVC doesn't like caling macro argument f when using float values in the macro, it simply replaces the f in the float value with the argument.. CMake compilation still fails because of 77785ce70807, numpy is never getting unpacked. --- source/blender/blenlib/intern/polyfill2d_beautify.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/intern/polyfill2d_beautify.c b/source/blender/blenlib/intern/polyfill2d_beautify.c index 5bbdbeb8c06..c67fe444640 100644 --- a/source/blender/blenlib/intern/polyfill2d_beautify.c +++ b/source/blender/blenlib/intern/polyfill2d_beautify.c @@ -178,7 +178,7 @@ static float quad_v2_rotate_beauty_calc( float len_12, len_23, len_34, len_41, len_24, len_13; -#define AREA_FROM_CROSS(f) (fabsf(f) / 2.0f) +#define AREA_FROM_CROSS(val) (fabsf(val) / 2.0f) /* edges around the quad */ len_12 = len_v2v2(v1, v2); -- cgit v1.2.3 From 15bde0dbeac81d2fa9f4822753963a3e377ff191 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 17 Dec 2014 09:51:18 +0100 Subject: Docs: comments (hash table & beauty fill) --- source/blender/blenlib/BLI_edgehash.h | 1 - source/blender/blenlib/BLI_ghash.h | 1 - source/blender/blenlib/intern/BLI_ghash.c | 3 ++- source/blender/blenlib/intern/edgehash.c | 7 ++++--- source/blender/blenlib/intern/polyfill2d_beautify.c | 5 +++-- 5 files changed, 9 insertions(+), 8 deletions(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_edgehash.h b/source/blender/blenlib/BLI_edgehash.h index c5323a4cf12..ded4b163f71 100644 --- a/source/blender/blenlib/BLI_edgehash.h +++ b/source/blender/blenlib/BLI_edgehash.h @@ -26,7 +26,6 @@ /** \file BLI_edgehash.h * \ingroup bli * \author Daniel Dunbar - * \brief A general unordered 2-int pair hash table ADT. */ #include "BLI_compiler_attrs.h" diff --git a/source/blender/blenlib/BLI_ghash.h b/source/blender/blenlib/BLI_ghash.h index 8be19d0c08b..e9f83e786de 100644 --- a/source/blender/blenlib/BLI_ghash.h +++ b/source/blender/blenlib/BLI_ghash.h @@ -30,7 +30,6 @@ /** \file BLI_ghash.h * \ingroup bli - * \brief A general (pointer -> pointer) hash table ADT */ #include "BLI_sys_types.h" /* for bool */ diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c index 6747e5c4e7e..c87b60f08db 100644 --- a/source/blender/blenlib/intern/BLI_ghash.c +++ b/source/blender/blenlib/intern/BLI_ghash.c @@ -28,7 +28,8 @@ /** \file blender/blenlib/intern/BLI_ghash.c * \ingroup bli * - * A general (pointer -> pointer) hash table ADT + * A general (pointer -> pointer) chaining hash table + * for 'Abstract Data Types' (known as an ADT Hash Table). * * \note edgehash.c is based on this, make sure they stay in sync. */ diff --git a/source/blender/blenlib/intern/edgehash.c b/source/blender/blenlib/intern/edgehash.c index 385d9ecb1ec..8dd72406250 100644 --- a/source/blender/blenlib/intern/edgehash.c +++ b/source/blender/blenlib/intern/edgehash.c @@ -23,12 +23,13 @@ /** \file blender/blenlib/intern/edgehash.c * \ingroup bli * - * A general (pointer -> pointer) hash table ADT + * An (edge -> pointer) chaining hash table. + * Using unordered int-paits as keys. * - * \note Based on 'BLI_ghash.c', make sure these stay in sync. + * \note Based on 'BLI_ghash.c', which is a more generalized hash-table + * make sure these stay in sync. */ - #include #include #include diff --git a/source/blender/blenlib/intern/polyfill2d_beautify.c b/source/blender/blenlib/intern/polyfill2d_beautify.c index c67fe444640..c4e333d0094 100644 --- a/source/blender/blenlib/intern/polyfill2d_beautify.c +++ b/source/blender/blenlib/intern/polyfill2d_beautify.c @@ -119,8 +119,9 @@ BLI_INLINE bool is_boundary_edge(unsigned int i_a, unsigned int i_b, const unsig } /** * Assuming we have 2 triangles sharing an edge (2 - 4), - * check if the edge running from (1 - 3) gives better results - * (negative number, lager == better). + * check if the edge running from (1 - 3) gives better results. + * + * \return (negative number means the edge can be rotated, lager == better). */ static float quad_v2_rotate_beauty_calc( const float v1[2], const float v2[2], const float v3[2], const float v4[2]) -- cgit v1.2.3 From a56e31c89c8a539e8726f5060eff3445064114a8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 17 Dec 2014 11:31:33 +0100 Subject: Fix triangulating concave quads Resulting triangles could be pointing in opposing directions. --- source/blender/blenlib/BLI_math_geom.h | 1 + source/blender/blenlib/intern/math_geom.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index ba32b29becc..32678bdf680 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -77,6 +77,7 @@ float volume_tetrahedron_signed_v3(const float v1[3], const float v2[3], const f bool is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]); bool is_quad_convex_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2]); bool is_poly_convex_v2(const float verts[][2], unsigned int nr); +int is_quad_flip_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]); /********************************* Distance **********************************/ diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 1c75a907a95..42aa24d284d 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -4016,3 +4016,31 @@ bool is_poly_convex_v2(const float verts[][2], unsigned int nr) return true; } + +/** + * Check if either of the diagonals along this quad create flipped triangles + * (normals pointing away from eachother). + * - (1 << 0): (v1-v3) is flipped. + * - (1 << 1): (v2-v4) is flipped. + */ +int is_quad_flip_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3]) +{ + float d_12[3], d_23[3], d_34[3], d_41[3]; + float cross_a[3], cross_b[3]; + int ret = 0; + + sub_v3_v3v3(d_12, v1, v2); + sub_v3_v3v3(d_23, v2, v3); + sub_v3_v3v3(d_34, v3, v4); + sub_v3_v3v3(d_41, v4, v1); + + cross_v3_v3v3(cross_a, d_12, d_23); + cross_v3_v3v3(cross_b, d_34, d_41); + ret |= ((dot_v3v3(cross_a, cross_b) < 0.0f) << 0); + + cross_v3_v3v3(cross_a, d_23, d_34); + cross_v3_v3v3(cross_b, d_41, d_12); + ret |= ((dot_v3v3(cross_a, cross_b) < 0.0f) << 1); + + return ret; +} -- cgit v1.2.3 From d4aaa4f9b661cd2423a4745227b9883f5f1f4089 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 18 Dec 2014 13:12:25 +0100 Subject: cleanup: use const for smallhash & minor edits --- source/blender/blenlib/BLI_smallhash.h | 14 +++++++------- source/blender/blenlib/intern/edgehash.c | 2 +- source/blender/blenlib/intern/smallhash.c | 14 +++++++------- 3 files changed, 15 insertions(+), 15 deletions(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_smallhash.h b/source/blender/blenlib/BLI_smallhash.h index 5bc40a60515..e096354e5b1 100644 --- a/source/blender/blenlib/BLI_smallhash.h +++ b/source/blender/blenlib/BLI_smallhash.h @@ -52,7 +52,7 @@ typedef struct SmallHash { } SmallHash; typedef struct { - SmallHash *sh; + const SmallHash *sh; unsigned int i; } SmallHashIter; @@ -63,14 +63,14 @@ void BLI_smallhash_release(SmallHash *sh) ATTR_NONNULL(1); void BLI_smallhash_insert(SmallHash *sh, uintptr_t key, void *item) ATTR_NONNULL(1); bool BLI_smallhash_reinsert(SmallHash *sh, uintptr_t key, void *item) ATTR_NONNULL(1); bool BLI_smallhash_remove(SmallHash *sh, uintptr_t key) ATTR_NONNULL(1); -void *BLI_smallhash_lookup(SmallHash *sh, uintptr_t key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; -void **BLI_smallhash_lookup_p(SmallHash *sh, uintptr_t key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; -bool BLI_smallhash_haskey(SmallHash *sh, uintptr_t key) ATTR_NONNULL(1); -int BLI_smallhash_count(SmallHash *sh) ATTR_NONNULL(1); +void *BLI_smallhash_lookup(const SmallHash *sh, uintptr_t key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; +void **BLI_smallhash_lookup_p(const SmallHash *sh, uintptr_t key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; +bool BLI_smallhash_haskey(const SmallHash *sh, uintptr_t key) ATTR_NONNULL(1); +int BLI_smallhash_count(const SmallHash *sh) ATTR_NONNULL(1); void *BLI_smallhash_iternext(SmallHashIter *iter, uintptr_t *key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; void **BLI_smallhash_iternext_p(SmallHashIter *iter, uintptr_t *key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; -void *BLI_smallhash_iternew(SmallHash *sh, SmallHashIter *iter, uintptr_t *key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; -void **BLI_smallhash_iternew_p(SmallHash *sh, SmallHashIter *iter, uintptr_t *key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; +void *BLI_smallhash_iternew(const SmallHash *sh, SmallHashIter *iter, uintptr_t *key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; +void **BLI_smallhash_iternew_p(const SmallHash *sh, SmallHashIter *iter, uintptr_t *key) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT; /* void BLI_smallhash_print(SmallHash *sh); */ /* UNUSED */ #ifdef DEBUG diff --git a/source/blender/blenlib/intern/edgehash.c b/source/blender/blenlib/intern/edgehash.c index 8dd72406250..82d57dad753 100644 --- a/source/blender/blenlib/intern/edgehash.c +++ b/source/blender/blenlib/intern/edgehash.c @@ -24,7 +24,7 @@ * \ingroup bli * * An (edge -> pointer) chaining hash table. - * Using unordered int-paits as keys. + * Using unordered int-pairs as keys. * * \note Based on 'BLI_ghash.c', which is a more generalized hash-table * make sure these stay in sync. diff --git a/source/blender/blenlib/intern/smallhash.c b/source/blender/blenlib/intern/smallhash.c index bb91f48d396..ba336ab6c4b 100644 --- a/source/blender/blenlib/intern/smallhash.c +++ b/source/blender/blenlib/intern/smallhash.c @@ -118,7 +118,7 @@ BLI_INLINE void smallhash_buckets_reserve(SmallHash *sh, const unsigned int nent } } -BLI_INLINE SmallHashEntry *smallhash_lookup(SmallHash *sh, const uintptr_t key) +BLI_INLINE SmallHashEntry *smallhash_lookup(const SmallHash *sh, const uintptr_t key) { SmallHashEntry *e; unsigned int h = smallhash_key(key); @@ -284,28 +284,28 @@ bool BLI_smallhash_remove(SmallHash *sh, uintptr_t key) } #endif -void *BLI_smallhash_lookup(SmallHash *sh, uintptr_t key) +void *BLI_smallhash_lookup(const SmallHash *sh, uintptr_t key) { SmallHashEntry *e = smallhash_lookup(sh, key); return e ? e->val : NULL; } -void **BLI_smallhash_lookup_p(SmallHash *sh, uintptr_t key) +void **BLI_smallhash_lookup_p(const SmallHash *sh, uintptr_t key) { SmallHashEntry *e = smallhash_lookup(sh, key); return e ? &e->val : NULL; } -bool BLI_smallhash_haskey(SmallHash *sh, uintptr_t key) +bool BLI_smallhash_haskey(const SmallHash *sh, uintptr_t key) { SmallHashEntry *e = smallhash_lookup(sh, key); return (e != NULL); } -int BLI_smallhash_count(SmallHash *sh) +int BLI_smallhash_count(const SmallHash *sh) { return (int)sh->nentries; } @@ -341,7 +341,7 @@ void **BLI_smallhash_iternext_p(SmallHashIter *iter, uintptr_t *key) return e ? &e->val : NULL; } -void *BLI_smallhash_iternew(SmallHash *sh, SmallHashIter *iter, uintptr_t *key) +void *BLI_smallhash_iternew(const SmallHash *sh, SmallHashIter *iter, uintptr_t *key) { iter->sh = sh; iter->i = 0; @@ -349,7 +349,7 @@ void *BLI_smallhash_iternew(SmallHash *sh, SmallHashIter *iter, uintptr_t *key) return BLI_smallhash_iternext(iter, key); } -void **BLI_smallhash_iternew_p(SmallHash *sh, SmallHashIter *iter, uintptr_t *key) +void **BLI_smallhash_iternew_p(const SmallHash *sh, SmallHashIter *iter, uintptr_t *key) { iter->sh = sh; iter->i = 0; -- cgit v1.2.3 From cd4fedb285a04b1f443623e8ae9548ddaef8088b Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Mon, 22 Dec 2014 13:43:23 +0500 Subject: Fix T42966: Py_Initialize: Unable to get the locale encoding This only happened for SCons builds and caused by pure human stupidnes. --- source/blender/blenlib/SConscript | 4 ---- 1 file changed, 4 deletions(-) (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/SConscript b/source/blender/blenlib/SConscript index 55747a426f0..8b4054e00b5 100644 --- a/source/blender/blenlib/SConscript +++ b/source/blender/blenlib/SConscript @@ -44,10 +44,6 @@ incs = ' '.join(incs) defs = [] -if env['WITH_BF_BINRELOC']: - incs += ' ../../../extern/binreloc/include' - defs.append('WITH_BINRELOC') - if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc', 'win64-mingw'): incs += ' ' + env['BF_PTHREADS_INC'] incs += ' ../../../intern/utfconv' -- cgit v1.2.3