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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2019-04-17 07:17:24 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-04-17 07:21:24 +0300
commite12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch)
tree8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/blenlib/intern
parentb3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff)
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/blenlib/intern')
-rw-r--r--source/blender/blenlib/intern/BLI_args.c379
-rw-r--r--source/blender/blenlib/intern/BLI_array.c34
-rw-r--r--source/blender/blenlib/intern/BLI_dial_2d.c121
-rw-r--r--source/blender/blenlib/intern/BLI_dynstr.c404
-rw-r--r--source/blender/blenlib/intern/BLI_filelist.c593
-rw-r--r--source/blender/blenlib/intern/BLI_ghash.c1374
-rw-r--r--source/blender/blenlib/intern/BLI_ghash_utils.c161
-rw-r--r--source/blender/blenlib/intern/BLI_heap.c438
-rw-r--r--source/blender/blenlib/intern/BLI_heap_simple.c186
-rw-r--r--source/blender/blenlib/intern/BLI_kdopbvh.c2934
-rw-r--r--source/blender/blenlib/intern/BLI_linklist.c357
-rw-r--r--source/blender/blenlib/intern/BLI_linklist_lockfree.c74
-rw-r--r--source/blender/blenlib/intern/BLI_memarena.c173
-rw-r--r--source/blender/blenlib/intern/BLI_memiter.c307
-rw-r--r--source/blender/blenlib/intern/BLI_mempool.c805
-rw-r--r--source/blender/blenlib/intern/BLI_timer.c200
-rw-r--r--source/blender/blenlib/intern/DLRB_tree.c921
-rw-r--r--source/blender/blenlib/intern/array_store.c2209
-rw-r--r--source/blender/blenlib/intern/array_store_utils.c99
-rw-r--r--source/blender/blenlib/intern/array_utils.c414
-rw-r--r--source/blender/blenlib/intern/astar.c277
-rw-r--r--source/blender/blenlib/intern/bitmap.c28
-rw-r--r--source/blender/blenlib/intern/bitmap_draw_2d.c737
-rw-r--r--source/blender/blenlib/intern/boxpack_2d.c852
-rw-r--r--source/blender/blenlib/intern/buffer.c98
-rw-r--r--source/blender/blenlib/intern/callbacks.c42
-rw-r--r--source/blender/blenlib/intern/convexhull_2d.c398
-rw-r--r--source/blender/blenlib/intern/dynlib.c115
-rw-r--r--source/blender/blenlib/intern/easing.c441
-rw-r--r--source/blender/blenlib/intern/edgehash.c576
-rw-r--r--source/blender/blenlib/intern/endian_switch.c97
-rw-r--r--source/blender/blenlib/intern/expr_pylike_eval.c1238
-rw-r--r--source/blender/blenlib/intern/fileops.c1538
-rw-r--r--source/blender/blenlib/intern/fnmatch.c323
-rw-r--r--source/blender/blenlib/intern/freetypefont.c776
-rw-r--r--source/blender/blenlib/intern/gsqueue.c122
-rw-r--r--source/blender/blenlib/intern/hash_md5.c521
-rw-r--r--source/blender/blenlib/intern/hash_mm2a.c144
-rw-r--r--source/blender/blenlib/intern/hash_mm3.c116
-rw-r--r--source/blender/blenlib/intern/jitter_2d.c277
-rw-r--r--source/blender/blenlib/intern/kdtree_1d.c2
-rw-r--r--source/blender/blenlib/intern/kdtree_2d.c2
-rw-r--r--source/blender/blenlib/intern/kdtree_3d.c2
-rw-r--r--source/blender/blenlib/intern/kdtree_impl.h1418
-rw-r--r--source/blender/blenlib/intern/lasso_2d.c101
-rw-r--r--source/blender/blenlib/intern/list_sort_impl.h244
-rw-r--r--source/blender/blenlib/intern/listbase.c964
-rw-r--r--source/blender/blenlib/intern/math_base.c76
-rw-r--r--source/blender/blenlib/intern/math_base_inline.c538
-rw-r--r--source/blender/blenlib/intern/math_bits_inline.c106
-rw-r--r--source/blender/blenlib/intern/math_color.c853
-rw-r--r--source/blender/blenlib/intern/math_color_blend_inline.c1919
-rw-r--r--source/blender/blenlib/intern/math_color_inline.c405
-rw-r--r--source/blender/blenlib/intern/math_geom.c8329
-rw-r--r--source/blender/blenlib/intern/math_geom_inline.c269
-rw-r--r--source/blender/blenlib/intern/math_interp.c1116
-rw-r--r--source/blender/blenlib/intern/math_matrix.c3566
-rw-r--r--source/blender/blenlib/intern/math_rotation.c2980
-rw-r--r--source/blender/blenlib/intern/math_solvers.c271
-rw-r--r--source/blender/blenlib/intern/math_statistics.c189
-rw-r--r--source/blender/blenlib/intern/math_vector.c1398
-rw-r--r--source/blender/blenlib/intern/math_vector_inline.c934
-rw-r--r--source/blender/blenlib/intern/memory_utils.c12
-rw-r--r--source/blender/blenlib/intern/noise.c3051
-rw-r--r--source/blender/blenlib/intern/path_util.c2609
-rw-r--r--source/blender/blenlib/intern/polyfill_2d.c1203
-rw-r--r--source/blender/blenlib/intern/polyfill_2d_beautify.c658
-rw-r--r--source/blender/blenlib/intern/quadric.c135
-rw-r--r--source/blender/blenlib/intern/rand.c381
-rw-r--r--source/blender/blenlib/intern/rct.c1151
-rw-r--r--source/blender/blenlib/intern/scanfill.c1927
-rw-r--r--source/blender/blenlib/intern/scanfill_utils.c785
-rw-r--r--source/blender/blenlib/intern/smallhash.c418
-rw-r--r--source/blender/blenlib/intern/sort.c238
-rw-r--r--source/blender/blenlib/intern/sort_utils.c104
-rw-r--r--source/blender/blenlib/intern/stack.c256
-rw-r--r--source/blender/blenlib/intern/storage.c549
-rw-r--r--source/blender/blenlib/intern/string.c1349
-rw-r--r--source/blender/blenlib/intern/string_cursor_utf8.c447
-rw-r--r--source/blender/blenlib/intern/string_utf8.c1010
-rw-r--r--source/blender/blenlib/intern/string_utils.c589
-rw-r--r--source/blender/blenlib/intern/system.c225
-rw-r--r--source/blender/blenlib/intern/task.c1848
-rw-r--r--source/blender/blenlib/intern/threads.c903
-rw-r--r--source/blender/blenlib/intern/time.c107
-rw-r--r--source/blender/blenlib/intern/timecode.c352
-rw-r--r--source/blender/blenlib/intern/uvproject.c287
-rw-r--r--source/blender/blenlib/intern/voronoi_2d.c1160
-rw-r--r--source/blender/blenlib/intern/voxel.c360
-rw-r--r--source/blender/blenlib/intern/winstuff.c409
-rw-r--r--source/blender/blenlib/intern/winstuff_dir.c171
91 files changed, 35027 insertions, 34248 deletions
diff --git a/source/blender/blenlib/intern/BLI_args.c b/source/blender/blenlib/intern/BLI_args.c
index 61619bc114b..8f282373cf5 100644
--- a/source/blender/blenlib/intern/BLI_args.c
+++ b/source/blender/blenlib/intern/BLI_args.c
@@ -37,267 +37,288 @@ static char NO_DOCS[] = "NO DOCUMENTATION SPECIFIED";
struct bArgDoc;
typedef struct bArgDoc {
- struct bArgDoc *next, *prev;
- const char *short_arg;
- const char *long_arg;
- const char *documentation;
- bool done;
+ struct bArgDoc *next, *prev;
+ const char *short_arg;
+ const char *long_arg;
+ const char *documentation;
+ bool done;
} bArgDoc;
typedef struct bAKey {
- const char *arg;
- uintptr_t pass; /* cast easier */
- int case_str; /* case specific or not */
+ const char *arg;
+ uintptr_t pass; /* cast easier */
+ int case_str; /* case specific or not */
} bAKey;
typedef struct bArgument {
- bAKey *key;
- BA_ArgCallback func;
- void *data;
- bArgDoc *doc;
+ bAKey *key;
+ BA_ArgCallback func;
+ void *data;
+ bArgDoc *doc;
} bArgument;
struct bArgs {
- ListBase docs;
- GHash *items;
- int argc;
- const char **argv;
- int *passes;
+ ListBase docs;
+ GHash *items;
+ int argc;
+ const char **argv;
+ int *passes;
};
static uint case_strhash(const void *ptr)
{
- const char *s = ptr;
- uint i = 0;
- unsigned char c;
+ const char *s = ptr;
+ uint i = 0;
+ unsigned char c;
- while ((c = tolower(*s++))) {
- i = i * 37 + c;
- }
+ while ((c = tolower(*s++))) {
+ i = i * 37 + c;
+ }
- return i;
+ return i;
}
static uint keyhash(const void *ptr)
{
- const bAKey *k = ptr;
- return case_strhash(k->arg); /* ^ BLI_ghashutil_inthash((void *)k->pass); */
+ const bAKey *k = ptr;
+ return case_strhash(k->arg); /* ^ BLI_ghashutil_inthash((void *)k->pass); */
}
static bool keycmp(const void *a, const void *b)
{
- const bAKey *ka = a;
- const bAKey *kb = b;
- if (ka->pass == kb->pass || ka->pass == -1 || kb->pass == -1) { /* -1 is wildcard for pass */
- if (ka->case_str == 1 || kb->case_str == 1) {
- return (BLI_strcasecmp(ka->arg, kb->arg) != 0);
- }
- else {
- return (!STREQ(ka->arg, kb->arg));
- }
- }
- else {
- return BLI_ghashutil_intcmp((const void *)ka->pass, (const void *)kb->pass);
- }
+ const bAKey *ka = a;
+ const bAKey *kb = b;
+ if (ka->pass == kb->pass || ka->pass == -1 || kb->pass == -1) { /* -1 is wildcard for pass */
+ if (ka->case_str == 1 || kb->case_str == 1) {
+ return (BLI_strcasecmp(ka->arg, kb->arg) != 0);
+ }
+ else {
+ return (!STREQ(ka->arg, kb->arg));
+ }
+ }
+ else {
+ return BLI_ghashutil_intcmp((const void *)ka->pass, (const void *)kb->pass);
+ }
}
static bArgument *lookUp(struct bArgs *ba, const char *arg, int pass, int case_str)
{
- bAKey key;
+ bAKey key;
- key.case_str = case_str;
- key.pass = pass;
- key.arg = arg;
+ key.case_str = case_str;
+ key.pass = pass;
+ key.arg = arg;
- return BLI_ghash_lookup(ba->items, &key);
+ return BLI_ghash_lookup(ba->items, &key);
}
bArgs *BLI_argsInit(int argc, const char **argv)
{
- bArgs *ba = MEM_callocN(sizeof(bArgs), "bArgs");
- ba->passes = MEM_callocN(sizeof(int) * argc, "bArgs passes");
- ba->items = BLI_ghash_new(keyhash, keycmp, "bArgs passes gh");
- BLI_listbase_clear(&ba->docs);
- ba->argc = argc;
- ba->argv = argv;
-
- return ba;
+ bArgs *ba = MEM_callocN(sizeof(bArgs), "bArgs");
+ ba->passes = MEM_callocN(sizeof(int) * argc, "bArgs passes");
+ ba->items = BLI_ghash_new(keyhash, keycmp, "bArgs passes gh");
+ BLI_listbase_clear(&ba->docs);
+ ba->argc = argc;
+ ba->argv = argv;
+
+ return ba;
}
void BLI_argsFree(struct bArgs *ba)
{
- BLI_ghash_free(ba->items, MEM_freeN, MEM_freeN);
- MEM_freeN(ba->passes);
- BLI_freelistN(&ba->docs);
- MEM_freeN(ba);
+ BLI_ghash_free(ba->items, MEM_freeN, MEM_freeN);
+ MEM_freeN(ba->passes);
+ BLI_freelistN(&ba->docs);
+ MEM_freeN(ba);
}
void BLI_argsPrint(struct bArgs *ba)
{
- int i;
- for (i = 0; i < ba->argc; i++) {
- printf("argv[%d] = %s\n", i, ba->argv[i]);
- }
+ int i;
+ for (i = 0; i < ba->argc; i++) {
+ printf("argv[%d] = %s\n", i, ba->argv[i]);
+ }
}
const char **BLI_argsArgv(struct bArgs *ba)
{
- return ba->argv;
+ return ba->argv;
}
-static bArgDoc *internalDocs(struct bArgs *ba, const char *short_arg, const char *long_arg, const char *doc)
+static bArgDoc *internalDocs(struct bArgs *ba,
+ const char *short_arg,
+ const char *long_arg,
+ const char *doc)
{
- bArgDoc *d;
+ bArgDoc *d;
- d = MEM_callocN(sizeof(bArgDoc), "bArgDoc");
+ d = MEM_callocN(sizeof(bArgDoc), "bArgDoc");
- if (doc == NULL) {
- doc = NO_DOCS;
- }
+ if (doc == NULL) {
+ doc = NO_DOCS;
+ }
- d->short_arg = short_arg;
- d->long_arg = long_arg;
- d->documentation = doc;
+ d->short_arg = short_arg;
+ d->long_arg = long_arg;
+ d->documentation = doc;
- BLI_addtail(&ba->docs, d);
+ BLI_addtail(&ba->docs, d);
- return d;
+ return d;
}
-static void internalAdd(struct bArgs *ba, const char *arg, int pass,
- int case_str, BA_ArgCallback cb, void *data, bArgDoc *d)
+static void internalAdd(struct bArgs *ba,
+ const char *arg,
+ int pass,
+ int case_str,
+ BA_ArgCallback cb,
+ void *data,
+ bArgDoc *d)
{
- bArgument *a;
- bAKey *key;
-
- a = lookUp(ba, arg, pass, case_str);
-
- if (a) {
- printf("WARNING: conflicting argument\n");
- printf("\ttrying to add '%s' on pass %i, %scase sensitive\n",
- arg, pass, case_str == 1 ? "not " : "");
- printf("\tconflict with '%s' on pass %i, %scase sensitive\n\n",
- a->key->arg, (int)a->key->pass, a->key->case_str == 1 ? "not " : "");
- }
-
- a = MEM_callocN(sizeof(bArgument), "bArgument");
- key = MEM_callocN(sizeof(bAKey), "bAKey");
-
- key->arg = arg;
- key->pass = pass;
- key->case_str = case_str;
-
- a->key = key;
- a->func = cb;
- a->data = data;
- a->doc = d;
-
- BLI_ghash_insert(ba->items, key, a);
+ bArgument *a;
+ bAKey *key;
+
+ a = lookUp(ba, arg, pass, case_str);
+
+ if (a) {
+ printf("WARNING: conflicting argument\n");
+ printf("\ttrying to add '%s' on pass %i, %scase sensitive\n",
+ arg,
+ pass,
+ case_str == 1 ? "not " : "");
+ printf("\tconflict with '%s' on pass %i, %scase sensitive\n\n",
+ a->key->arg,
+ (int)a->key->pass,
+ a->key->case_str == 1 ? "not " : "");
+ }
+
+ a = MEM_callocN(sizeof(bArgument), "bArgument");
+ key = MEM_callocN(sizeof(bAKey), "bAKey");
+
+ key->arg = arg;
+ key->pass = pass;
+ key->case_str = case_str;
+
+ a->key = key;
+ a->func = cb;
+ a->data = data;
+ a->doc = d;
+
+ BLI_ghash_insert(ba->items, key, a);
}
-void BLI_argsAddCase(struct bArgs *ba, int pass,
- const char *short_arg, int short_case,
- const char *long_arg, int long_case,
- const char *doc, BA_ArgCallback cb, void *data)
+void BLI_argsAddCase(struct bArgs *ba,
+ int pass,
+ const char *short_arg,
+ int short_case,
+ const char *long_arg,
+ int long_case,
+ const char *doc,
+ BA_ArgCallback cb,
+ void *data)
{
- bArgDoc *d = internalDocs(ba, short_arg, long_arg, doc);
+ bArgDoc *d = internalDocs(ba, short_arg, long_arg, doc);
- if (short_arg) {
- internalAdd(ba, short_arg, pass, short_case, cb, data, d);
- }
+ if (short_arg) {
+ internalAdd(ba, short_arg, pass, short_case, cb, data, d);
+ }
- if (long_arg) {
- internalAdd(ba, long_arg, pass, long_case, cb, data, d);
- }
+ if (long_arg) {
+ internalAdd(ba, long_arg, pass, long_case, cb, data, d);
+ }
}
-void BLI_argsAdd(struct bArgs *ba, int pass,
- const char *short_arg, const char *long_arg,
- const char *doc, BA_ArgCallback cb, void *data)
+void BLI_argsAdd(struct bArgs *ba,
+ int pass,
+ const char *short_arg,
+ const char *long_arg,
+ const char *doc,
+ BA_ArgCallback cb,
+ void *data)
{
- BLI_argsAddCase(ba, pass, short_arg, 0, long_arg, 0, doc, cb, data);
+ BLI_argsAddCase(ba, pass, short_arg, 0, long_arg, 0, doc, cb, data);
}
static void internalDocPrint(bArgDoc *d)
{
- if (d->short_arg && d->long_arg) {
- printf("%s or %s", d->short_arg, d->long_arg);
- }
- else if (d->short_arg) {
- printf("%s", d->short_arg);
- }
- else if (d->long_arg) {
- printf("%s", d->long_arg);
- }
-
- printf(" %s\n\n", d->documentation);
+ if (d->short_arg && d->long_arg) {
+ printf("%s or %s", d->short_arg, d->long_arg);
+ }
+ else if (d->short_arg) {
+ printf("%s", d->short_arg);
+ }
+ else if (d->long_arg) {
+ printf("%s", d->long_arg);
+ }
+
+ printf(" %s\n\n", d->documentation);
}
void BLI_argsPrintArgDoc(struct bArgs *ba, const char *arg)
{
- bArgument *a = lookUp(ba, arg, -1, -1);
+ bArgument *a = lookUp(ba, arg, -1, -1);
- if (a) {
- bArgDoc *d = a->doc;
+ if (a) {
+ bArgDoc *d = a->doc;
- internalDocPrint(d);
+ internalDocPrint(d);
- d->done = true;
- }
+ d->done = true;
+ }
}
void BLI_argsPrintOtherDoc(struct bArgs *ba)
{
- bArgDoc *d;
+ bArgDoc *d;
- for (d = ba->docs.first; d; d = d->next) {
- if (d->done == 0) {
- internalDocPrint(d);
- }
- }
+ for (d = ba->docs.first; d; d = d->next) {
+ if (d->done == 0) {
+ internalDocPrint(d);
+ }
+ }
}
void BLI_argsParse(struct bArgs *ba, int pass, BA_ArgCallback default_cb, void *default_data)
{
- int i = 0;
-
- for (i = 1; i < ba->argc; i++) { /* skip argv[0] */
- if (ba->passes[i] == 0) {
- /* -1 signal what side of the comparison it is */
- bArgument *a = lookUp(ba, ba->argv[i], pass, -1);
- BA_ArgCallback func = NULL;
- void *data = NULL;
-
- if (a) {
- func = a->func;
- data = a->data;
- }
- else {
- func = default_cb;
- data = default_data;
- }
-
- if (func) {
- int retval = func(ba->argc - i, ba->argv + i, data);
-
- if (retval >= 0) {
- int j;
-
- /* use extra arguments */
- for (j = 0; j <= retval; j++) {
- ba->passes[i + j] = pass;
- }
- i += retval;
- }
- else if (retval == -1) {
- if (a) {
- if (a->key->pass != -1) {
- ba->passes[i] = pass;
- }
- }
- break;
- }
- }
- }
- }
+ int i = 0;
+
+ for (i = 1; i < ba->argc; i++) { /* skip argv[0] */
+ if (ba->passes[i] == 0) {
+ /* -1 signal what side of the comparison it is */
+ bArgument *a = lookUp(ba, ba->argv[i], pass, -1);
+ BA_ArgCallback func = NULL;
+ void *data = NULL;
+
+ if (a) {
+ func = a->func;
+ data = a->data;
+ }
+ else {
+ func = default_cb;
+ data = default_data;
+ }
+
+ if (func) {
+ int retval = func(ba->argc - i, ba->argv + i, data);
+
+ if (retval >= 0) {
+ int j;
+
+ /* use extra arguments */
+ for (j = 0; j <= retval; j++) {
+ ba->passes[i + j] = pass;
+ }
+ i += retval;
+ }
+ else if (retval == -1) {
+ if (a) {
+ if (a->key->pass != -1) {
+ ba->passes[i] = pass;
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
}
diff --git a/source/blender/blenlib/intern/BLI_array.c b/source/blender/blenlib/intern/BLI_array.c
index 6c22b128f5c..7a9cf416d91 100644
--- a/source/blender/blenlib/intern/BLI_array.c
+++ b/source/blender/blenlib/intern/BLI_array.c
@@ -59,26 +59,26 @@
*
* \note The caller must adjust \a arr_len
*/
-void _bli_array_grow_func(
- void **arr_p, const void *arr_static,
- const int sizeof_arr_p, const int arr_len, const int num,
- const char *alloc_str)
+void _bli_array_grow_func(void **arr_p,
+ const void *arr_static,
+ const int sizeof_arr_p,
+ const int arr_len,
+ const int num,
+ const char *alloc_str)
{
- void *arr = *arr_p;
- void *arr_tmp;
+ void *arr = *arr_p;
+ void *arr_tmp;
- arr_tmp = MEM_mallocN(
- sizeof_arr_p *
- ((num < arr_len) ?
- (arr_len * 2 + 2) : (arr_len + num)), alloc_str);
+ arr_tmp = MEM_mallocN(sizeof_arr_p * ((num < arr_len) ? (arr_len * 2 + 2) : (arr_len + num)),
+ alloc_str);
- if (arr) {
- memcpy(arr_tmp, arr, sizeof_arr_p * arr_len);
+ if (arr) {
+ memcpy(arr_tmp, arr, sizeof_arr_p * arr_len);
- if (arr != arr_static) {
- MEM_freeN(arr);
- }
- }
+ if (arr != arr_static) {
+ MEM_freeN(arr);
+ }
+ }
- *arr_p = arr_tmp;
+ *arr_p = arr_tmp;
}
diff --git a/source/blender/blenlib/intern/BLI_dial_2d.c b/source/blender/blenlib/intern/BLI_dial_2d.c
index dd983fe7f8f..c6d28e20f35 100644
--- a/source/blender/blenlib/intern/BLI_dial_2d.c
+++ b/source/blender/blenlib/intern/BLI_dial_2d.c
@@ -24,81 +24,78 @@
#include "MEM_guardedalloc.h"
struct Dial {
- /* center of the dial */
- float center[2];
+ /* center of the dial */
+ float center[2];
- /* threshold of the dial. Distance of current position has to be greater
- * than the threshold to be used in any calculations */
- float threshold_squared;
+ /* threshold of the dial. Distance of current position has to be greater
+ * than the threshold to be used in any calculations */
+ float threshold_squared;
- /* the direction of the first dial position exceeding the threshold. This
- * is later used as the basis against which rotation angle is calculated */
- float initial_direction[2];
+ /* the direction of the first dial position exceeding the threshold. This
+ * is later used as the basis against which rotation angle is calculated */
+ float initial_direction[2];
- /* cache the last angle to detect rotations bigger than -/+ PI */
- float last_angle;
+ /* cache the last angle to detect rotations bigger than -/+ PI */
+ float last_angle;
- /* number of full rotations */
- int rotations;
+ /* number of full rotations */
+ int rotations;
- /* has initial_direction been initialized */
- bool initialized;
+ /* has initial_direction been initialized */
+ bool initialized;
};
-
Dial *BLI_dial_initialize(const float start_position[2], float threshold)
{
- Dial *dial = MEM_callocN(sizeof(Dial), "dial");
+ Dial *dial = MEM_callocN(sizeof(Dial), "dial");
- copy_v2_v2(dial->center, start_position);
- dial->threshold_squared = threshold * threshold;
+ copy_v2_v2(dial->center, start_position);
+ dial->threshold_squared = threshold * threshold;
- return dial;
+ return dial;
}
float BLI_dial_angle(Dial *dial, const float current_position[2])
{
- float current_direction[2];
-
- sub_v2_v2v2(current_direction, current_position, dial->center);
-
- /* only update when we have enough precision,
- * by having the mouse adequately away from center */
- if (len_squared_v2(current_direction) > dial->threshold_squared) {
- float angle;
- float cosval, sinval;
-
- normalize_v2(current_direction);
-
- if (!dial->initialized) {
- copy_v2_v2(dial->initial_direction, current_direction);
- dial->initialized = true;
- }
-
- /* calculate mouse angle between initial and final mouse position */
- cosval = dot_v2v2(current_direction, dial->initial_direction);
- sinval = cross_v2v2(current_direction, dial->initial_direction);
-
- /* clamp to avoid nans in acos */
- angle = atan2f(sinval, cosval);
-
- /* change of sign, we passed the 180 degree threshold. This means we need to add a turn.
- * to distinguish between transition from 0 to -1 and -PI to +PI,
- * use comparison with PI/2 */
- if ((angle * dial->last_angle < 0.0f) &&
- (fabsf(dial->last_angle) > (float)M_PI_2))
- {
- if (dial->last_angle < 0.0f) {
- dial->rotations--;
- }
- else {
- dial->rotations++;
- }
- }
- dial->last_angle = angle;
-
- return angle + 2.0f * (float)M_PI * dial->rotations;
- }
-
- return dial->last_angle;
+ float current_direction[2];
+
+ sub_v2_v2v2(current_direction, current_position, dial->center);
+
+ /* only update when we have enough precision,
+ * by having the mouse adequately away from center */
+ if (len_squared_v2(current_direction) > dial->threshold_squared) {
+ float angle;
+ float cosval, sinval;
+
+ normalize_v2(current_direction);
+
+ if (!dial->initialized) {
+ copy_v2_v2(dial->initial_direction, current_direction);
+ dial->initialized = true;
+ }
+
+ /* calculate mouse angle between initial and final mouse position */
+ cosval = dot_v2v2(current_direction, dial->initial_direction);
+ sinval = cross_v2v2(current_direction, dial->initial_direction);
+
+ /* clamp to avoid nans in acos */
+ angle = atan2f(sinval, cosval);
+
+ /* change of sign, we passed the 180 degree threshold. This means we need to add a turn.
+ * to distinguish between transition from 0 to -1 and -PI to +PI,
+ * use comparison with PI/2 */
+ if ((angle * dial->last_angle < 0.0f) && (fabsf(dial->last_angle) > (float)M_PI_2)) {
+ if (dial->last_angle < 0.0f) {
+ dial->rotations--;
+ }
+ else {
+ dial->rotations++;
+ }
+ }
+ dial->last_angle = angle;
+
+ return angle + 2.0f * (float)M_PI * dial->rotations;
+ }
+
+ return dial->last_angle;
}
diff --git a/source/blender/blenlib/intern/BLI_dynstr.c b/source/blender/blenlib/intern/BLI_dynstr.c
index ef45d7b2a47..c325c010330 100644
--- a/source/blender/blenlib/intern/BLI_dynstr.c
+++ b/source/blender/blenlib/intern/BLI_dynstr.c
@@ -22,7 +22,7 @@
* \ingroup bli
*/
-#include <stdlib.h> /* malloc */
+#include <stdlib.h> /* malloc */
#include <string.h>
#include "MEM_guardedalloc.h"
@@ -32,32 +32,32 @@
#include "BLI_dynstr.h"
#ifdef _WIN32
-#ifndef vsnprintf
-#define vsnprintf _vsnprintf
-#endif
+# ifndef vsnprintf
+# define vsnprintf _vsnprintf
+# endif
#endif
#ifndef va_copy
-# ifdef __va_copy
-# define va_copy(a, b) __va_copy(a, b)
-# else /* !__va_copy */
-# define va_copy(a, b) ((a) = (b))
-# endif /* __va_copy */
-#endif /* va_copy */
+# ifdef __va_copy
+# define va_copy(a, b) __va_copy(a, b)
+# else /* !__va_copy */
+# define va_copy(a, b) ((a) = (b))
+# endif /* __va_copy */
+#endif /* va_copy */
/***/
typedef struct DynStrElem DynStrElem;
struct DynStrElem {
- DynStrElem *next;
+ DynStrElem *next;
- char *str;
+ char *str;
};
struct DynStr {
- DynStrElem *elems, *last;
- int curlen;
- MemArena *memarena;
+ DynStrElem *elems, *last;
+ int curlen;
+ MemArena *memarena;
};
/***/
@@ -69,12 +69,12 @@ struct DynStr {
*/
DynStr *BLI_dynstr_new(void)
{
- DynStr *ds = MEM_mallocN(sizeof(*ds), "DynStr");
- ds->elems = ds->last = NULL;
- ds->curlen = 0;
- ds->memarena = NULL;
+ DynStr *ds = MEM_mallocN(sizeof(*ds), "DynStr");
+ ds->elems = ds->last = NULL;
+ ds->curlen = 0;
+ ds->memarena = NULL;
- return ds;
+ return ds;
}
/**
@@ -84,17 +84,17 @@ DynStr *BLI_dynstr_new(void)
*/
DynStr *BLI_dynstr_new_memarena(void)
{
- DynStr *ds = MEM_mallocN(sizeof(*ds), "DynStr");
- ds->elems = ds->last = NULL;
- ds->curlen = 0;
- ds->memarena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
+ DynStr *ds = MEM_mallocN(sizeof(*ds), "DynStr");
+ ds->elems = ds->last = NULL;
+ ds->curlen = 0;
+ ds->memarena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
- return ds;
+ return ds;
}
BLI_INLINE void *dynstr_alloc(DynStr *__restrict ds, size_t size)
{
- return ds->memarena ? BLI_memarena_alloc(ds->memarena, size) : malloc(size);
+ return ds->memarena ? BLI_memarena_alloc(ds->memarena, size) : malloc(size);
}
/**
@@ -105,21 +105,21 @@ BLI_INLINE void *dynstr_alloc(DynStr *__restrict ds, size_t size)
*/
void BLI_dynstr_append(DynStr *__restrict ds, const char *cstr)
{
- DynStrElem *dse = dynstr_alloc(ds, sizeof(*dse));
- int cstrlen = strlen(cstr);
+ DynStrElem *dse = dynstr_alloc(ds, sizeof(*dse));
+ int cstrlen = strlen(cstr);
- dse->str = dynstr_alloc(ds, cstrlen + 1);
- memcpy(dse->str, cstr, cstrlen + 1);
- dse->next = NULL;
+ dse->str = dynstr_alloc(ds, cstrlen + 1);
+ memcpy(dse->str, cstr, cstrlen + 1);
+ dse->next = NULL;
- if (!ds->last) {
- ds->last = ds->elems = dse;
- }
- else {
- ds->last = ds->last->next = dse;
- }
+ if (!ds->last) {
+ ds->last = ds->elems = dse;
+ }
+ else {
+ ds->last = ds->last->next = dse;
+ }
- ds->curlen += cstrlen;
+ ds->curlen += cstrlen;
}
/**
@@ -131,81 +131,81 @@ void BLI_dynstr_append(DynStr *__restrict ds, const char *cstr)
*/
void BLI_dynstr_nappend(DynStr *__restrict ds, const char *cstr, int len)
{
- DynStrElem *dse = dynstr_alloc(ds, sizeof(*dse));
- int cstrlen = BLI_strnlen(cstr, len);
-
- dse->str = dynstr_alloc(ds, cstrlen + 1);
- memcpy(dse->str, cstr, cstrlen);
- dse->str[cstrlen] = '\0';
- dse->next = NULL;
-
- if (!ds->last) {
- ds->last = ds->elems = dse;
- }
- else {
- ds->last = ds->last->next = dse;
- }
-
- ds->curlen += cstrlen;
+ DynStrElem *dse = dynstr_alloc(ds, sizeof(*dse));
+ int cstrlen = BLI_strnlen(cstr, len);
+
+ dse->str = dynstr_alloc(ds, cstrlen + 1);
+ memcpy(dse->str, cstr, cstrlen);
+ dse->str[cstrlen] = '\0';
+ dse->next = NULL;
+
+ if (!ds->last) {
+ ds->last = ds->elems = dse;
+ }
+ else {
+ ds->last = ds->last->next = dse;
+ }
+
+ ds->curlen += cstrlen;
}
void BLI_dynstr_vappendf(DynStr *__restrict ds, const char *__restrict format, va_list args)
{
- char *message, fixedmessage[256];
- int len = sizeof(fixedmessage);
- const int maxlen = 65536;
- int retval;
-
- while (1) {
- va_list args_cpy;
- if (len == sizeof(fixedmessage)) {
- message = fixedmessage;
- }
- else {
- message = MEM_callocN(sizeof(char) * len, "BLI_dynstr_appendf");
- }
-
- /* cant reuse the same args, so work on a copy */
- va_copy(args_cpy, args);
- retval = vsnprintf(message, len, format, args_cpy);
- va_end(args_cpy);
-
- if (retval == -1) {
- /* -1 means not enough space, but on windows it may also mean
- * there is a formatting error, so we impose a maximum length */
- if (message != fixedmessage) {
- MEM_freeN(message);
- }
- message = NULL;
-
- len *= 2;
- if (len > maxlen) {
- fprintf(stderr, "BLI_dynstr_append text too long or format error.\n");
- break;
- }
- }
- else if (retval >= len) {
- /* in C99 the actual length required is returned */
- if (message != fixedmessage) {
- MEM_freeN(message);
- }
- message = NULL;
-
- /* retval doesn't include \0 terminator */
- len = retval + 1;
- }
- else {
- break;
- }
- }
-
- if (message) {
- BLI_dynstr_append(ds, message);
-
- if (message != fixedmessage) {
- MEM_freeN(message);
- }
- }
+ char *message, fixedmessage[256];
+ int len = sizeof(fixedmessage);
+ const int maxlen = 65536;
+ int retval;
+
+ while (1) {
+ va_list args_cpy;
+ if (len == sizeof(fixedmessage)) {
+ message = fixedmessage;
+ }
+ else {
+ message = MEM_callocN(sizeof(char) * len, "BLI_dynstr_appendf");
+ }
+
+ /* cant reuse the same args, so work on a copy */
+ va_copy(args_cpy, args);
+ retval = vsnprintf(message, len, format, args_cpy);
+ va_end(args_cpy);
+
+ if (retval == -1) {
+ /* -1 means not enough space, but on windows it may also mean
+ * there is a formatting error, so we impose a maximum length */
+ if (message != fixedmessage) {
+ MEM_freeN(message);
+ }
+ message = NULL;
+
+ len *= 2;
+ if (len > maxlen) {
+ fprintf(stderr, "BLI_dynstr_append text too long or format error.\n");
+ break;
+ }
+ }
+ else if (retval >= len) {
+ /* in C99 the actual length required is returned */
+ if (message != fixedmessage) {
+ MEM_freeN(message);
+ }
+ message = NULL;
+
+ /* retval doesn't include \0 terminator */
+ len = retval + 1;
+ }
+ else {
+ break;
+ }
+ }
+
+ if (message) {
+ BLI_dynstr_append(ds, message);
+
+ if (message != fixedmessage) {
+ MEM_freeN(message);
+ }
+ }
}
/**
@@ -216,64 +216,64 @@ void BLI_dynstr_vappendf(DynStr *__restrict ds, const char *__restrict format, v
*/
void BLI_dynstr_appendf(DynStr *__restrict ds, const char *__restrict format, ...)
{
- va_list args;
- char *message, fixedmessage[256];
- int len = sizeof(fixedmessage);
- const int maxlen = 65536;
- int retval;
-
- /* note that it's tempting to just call BLI_dynstr_vappendf here
- * and avoid code duplication, that crashes on some system because
- * va_start/va_end have to be called for each vsnprintf call */
-
- while (1) {
- if (len == sizeof(fixedmessage)) {
- message = fixedmessage;
- }
- else {
- message = MEM_callocN(sizeof(char) * (len), "BLI_dynstr_appendf");
- }
-
- va_start(args, format);
- retval = vsnprintf(message, len, format, args);
- va_end(args);
-
- if (retval == -1) {
- /* -1 means not enough space, but on windows it may also mean
- * there is a formatting error, so we impose a maximum length */
- if (message != fixedmessage) {
- MEM_freeN(message);
- }
- message = NULL;
-
- len *= 2;
- if (len > maxlen) {
- fprintf(stderr, "BLI_dynstr_append text too long or format error.\n");
- break;
- }
- }
- else if (retval >= len) {
- /* in C99 the actual length required is returned */
- if (message != fixedmessage) {
- MEM_freeN(message);
- }
- message = NULL;
-
- /* retval doesn't include \0 terminator */
- len = retval + 1;
- }
- else {
- break;
- }
- }
-
- if (message) {
- BLI_dynstr_append(ds, message);
-
- if (message != fixedmessage) {
- MEM_freeN(message);
- }
- }
+ va_list args;
+ char *message, fixedmessage[256];
+ int len = sizeof(fixedmessage);
+ const int maxlen = 65536;
+ int retval;
+
+ /* note that it's tempting to just call BLI_dynstr_vappendf here
+ * and avoid code duplication, that crashes on some system because
+ * va_start/va_end have to be called for each vsnprintf call */
+
+ while (1) {
+ if (len == sizeof(fixedmessage)) {
+ message = fixedmessage;
+ }
+ else {
+ message = MEM_callocN(sizeof(char) * (len), "BLI_dynstr_appendf");
+ }
+
+ va_start(args, format);
+ retval = vsnprintf(message, len, format, args);
+ va_end(args);
+
+ if (retval == -1) {
+ /* -1 means not enough space, but on windows it may also mean
+ * there is a formatting error, so we impose a maximum length */
+ if (message != fixedmessage) {
+ MEM_freeN(message);
+ }
+ message = NULL;
+
+ len *= 2;
+ if (len > maxlen) {
+ fprintf(stderr, "BLI_dynstr_append text too long or format error.\n");
+ break;
+ }
+ }
+ else if (retval >= len) {
+ /* in C99 the actual length required is returned */
+ if (message != fixedmessage) {
+ MEM_freeN(message);
+ }
+ message = NULL;
+
+ /* retval doesn't include \0 terminator */
+ len = retval + 1;
+ }
+ else {
+ break;
+ }
+ }
+
+ if (message) {
+ BLI_dynstr_append(ds, message);
+
+ if (message != fixedmessage) {
+ MEM_freeN(message);
+ }
+ }
}
/**
@@ -284,7 +284,7 @@ void BLI_dynstr_appendf(DynStr *__restrict ds, const char *__restrict format, ..
*/
int BLI_dynstr_get_len(DynStr *ds)
{
- return ds->curlen;
+ return ds->curlen;
}
/**
@@ -297,18 +297,18 @@ int BLI_dynstr_get_len(DynStr *ds)
*/
void BLI_dynstr_get_cstring_ex(DynStr *__restrict ds, char *__restrict rets)
{
- char *s;
- DynStrElem *dse;
+ char *s;
+ DynStrElem *dse;
- for (s = rets, dse = ds->elems; dse; dse = dse->next) {
- int slen = strlen(dse->str);
+ for (s = rets, dse = ds->elems; dse; dse = dse->next) {
+ int slen = strlen(dse->str);
- memcpy(s, dse->str, slen);
+ memcpy(s, dse->str, slen);
- s += slen;
- }
- BLI_assert((s - rets) == ds->curlen);
- rets[ds->curlen] = '\0';
+ s += slen;
+ }
+ BLI_assert((s - rets) == ds->curlen);
+ rets[ds->curlen] = '\0';
}
/**
@@ -321,9 +321,9 @@ void BLI_dynstr_get_cstring_ex(DynStr *__restrict ds, char *__restrict rets)
*/
char *BLI_dynstr_get_cstring(DynStr *ds)
{
- char *rets = MEM_mallocN(ds->curlen + 1, "dynstr_cstring");
- BLI_dynstr_get_cstring_ex(ds, rets);
- return rets;
+ char *rets = MEM_mallocN(ds->curlen + 1, "dynstr_cstring");
+ BLI_dynstr_get_cstring_ex(ds, rets);
+ return rets;
}
/**
@@ -333,20 +333,20 @@ char *BLI_dynstr_get_cstring(DynStr *ds)
*/
void BLI_dynstr_clear(DynStr *ds)
{
- if (ds->memarena) {
- BLI_memarena_clear(ds->memarena);
- }
- else {
- for (DynStrElem *dse_next, *dse = ds->elems; dse; dse = dse_next) {
- dse_next = dse->next;
-
- free(dse->str);
- free(dse);
- }
- }
-
- ds->elems = ds->last = NULL;
- ds->curlen = 0;
+ if (ds->memarena) {
+ BLI_memarena_clear(ds->memarena);
+ }
+ else {
+ for (DynStrElem *dse_next, *dse = ds->elems; dse; dse = dse_next) {
+ dse_next = dse->next;
+
+ free(dse->str);
+ free(dse);
+ }
+ }
+
+ ds->elems = ds->last = NULL;
+ ds->curlen = 0;
}
/**
@@ -356,12 +356,12 @@ void BLI_dynstr_clear(DynStr *ds)
*/
void BLI_dynstr_free(DynStr *ds)
{
- if (ds->memarena) {
- BLI_memarena_free(ds->memarena);
- }
- else {
- BLI_dynstr_clear(ds);
- }
-
- MEM_freeN(ds);
+ if (ds->memarena) {
+ BLI_memarena_free(ds->memarena);
+ }
+ else {
+ BLI_dynstr_clear(ds);
+ }
+
+ MEM_freeN(ds);
}
diff --git a/source/blender/blenlib/intern/BLI_filelist.c b/source/blender/blenlib/intern/BLI_filelist.c
index 243c7d95da1..91f16ca9b7b 100644
--- a/source/blender/blenlib/intern/BLI_filelist.c
+++ b/source/blender/blenlib/intern/BLI_filelist.c
@@ -28,7 +28,7 @@
#include <time.h>
#include <sys/stat.h>
-#include <string.h> /* strcpy etc.. */
+#include <string.h> /* strcpy etc.. */
#ifdef WIN32
# include <io.h>
@@ -54,55 +54,65 @@
#include "../imbuf/IMB_imbuf.h"
-
/*
* Ordering function for sorting lists of files/directories. Returns -1 if
* entry1 belongs before entry2, 0 if they are equal, 1 if they should be swapped.
*/
static int bli_compare(struct direntry *entry1, struct direntry *entry2)
{
- /* type is equal to stat.st_mode */
-
- /* directories come before non-directories */
- if (S_ISDIR(entry1->type)) {
- if (S_ISDIR(entry2->type) == 0) {
- return -1;
- }
- }
- else {
- if (S_ISDIR(entry2->type)) {
- return 1;
- }
- }
- /* non-regular files come after regular files */
- if (S_ISREG(entry1->type)) {
- if (S_ISREG(entry2->type) == 0) {
- return -1;
- }
- }
- else {
- if (S_ISREG(entry2->type)) {
- return 1;
- }
- }
- /* arbitrary, but consistent, ordering of different types of non-regular files */
- if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) { return -1; }
- if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) { return 1; }
-
- /* OK, now we know their S_IFMT fields are the same, go on to a name comparison */
- /* make sure "." and ".." are always first */
- if (FILENAME_IS_CURRENT(entry1->relname)) { return -1; }
- if (FILENAME_IS_CURRENT(entry2->relname)) { return 1; }
- if (FILENAME_IS_PARENT(entry1->relname)) { return -1; }
- if (FILENAME_IS_PARENT(entry2->relname)) { return 1; }
-
- return (BLI_natstrcmp(entry1->relname, entry2->relname));
+ /* type is equal to stat.st_mode */
+
+ /* directories come before non-directories */
+ if (S_ISDIR(entry1->type)) {
+ if (S_ISDIR(entry2->type) == 0) {
+ return -1;
+ }
+ }
+ else {
+ if (S_ISDIR(entry2->type)) {
+ return 1;
+ }
+ }
+ /* non-regular files come after regular files */
+ if (S_ISREG(entry1->type)) {
+ if (S_ISREG(entry2->type) == 0) {
+ return -1;
+ }
+ }
+ else {
+ if (S_ISREG(entry2->type)) {
+ return 1;
+ }
+ }
+ /* arbitrary, but consistent, ordering of different types of non-regular files */
+ if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) {
+ return -1;
+ }
+ if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) {
+ return 1;
+ }
+
+ /* OK, now we know their S_IFMT fields are the same, go on to a name comparison */
+ /* make sure "." and ".." are always first */
+ if (FILENAME_IS_CURRENT(entry1->relname)) {
+ return -1;
+ }
+ if (FILENAME_IS_CURRENT(entry2->relname)) {
+ return 1;
+ }
+ if (FILENAME_IS_PARENT(entry1->relname)) {
+ return -1;
+ }
+ if (FILENAME_IS_PARENT(entry2->relname)) {
+ return 1;
+ }
+
+ return (BLI_natstrcmp(entry1->relname, entry2->relname));
}
-
struct BuildDirCtx {
- struct direntry *files; /* array[nrfiles] */
- int nrfiles;
+ struct direntry *files; /* array[nrfiles] */
+ int nrfiles;
};
/**
@@ -110,108 +120,113 @@ struct BuildDirCtx {
*/
static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname)
{
- struct ListBase dirbase = {NULL, NULL};
- int newnum = 0;
- DIR *dir;
-
- if ((dir = opendir(dirname)) != NULL) {
- const struct dirent *fname;
- bool has_current = false, has_parent = false;
-
- while ((fname = readdir(dir)) != NULL) {
- struct dirlink * const dlink = (struct dirlink *)malloc(sizeof(struct dirlink));
- if (dlink != NULL) {
- dlink->name = BLI_strdup(fname->d_name);
- if (FILENAME_IS_PARENT(dlink->name)) {
- has_parent = true;
- }
- else if (FILENAME_IS_CURRENT(dlink->name)) {
- has_current = true;
- }
- BLI_addhead(&dirbase, dlink);
- newnum++;
- }
- }
-
- if (!has_parent) {
- char pardir[FILE_MAXDIR];
-
- BLI_strncpy(pardir, dirname, sizeof(pardir));
- if (BLI_parent_dir(pardir) && (BLI_access(pardir, R_OK) == 0)) {
- struct dirlink * const dlink = (struct dirlink *)malloc(sizeof(struct dirlink));
- if (dlink != NULL) {
- dlink->name = BLI_strdup(FILENAME_PARENT);
- BLI_addhead(&dirbase, dlink);
- newnum++;
- }
- }
- }
- if (!has_current) {
- struct dirlink * const dlink = (struct dirlink *)malloc(sizeof(struct dirlink));
- if (dlink != NULL) {
- dlink->name = BLI_strdup(FILENAME_CURRENT);
- BLI_addhead(&dirbase, dlink);
- newnum++;
- }
- }
-
- if (newnum) {
- if (dir_ctx->files) {
- void * const tmp = MEM_reallocN(dir_ctx->files, (dir_ctx->nrfiles + newnum) * sizeof(struct direntry));
- if (tmp) {
- dir_ctx->files = (struct direntry *)tmp;
- }
- else { /* realloc fail */
- MEM_freeN(dir_ctx->files);
- dir_ctx->files = NULL;
- }
- }
-
- if (dir_ctx->files == NULL) {
- dir_ctx->files = (struct direntry *)MEM_mallocN(newnum * sizeof(struct direntry), __func__);
- }
-
- if (dir_ctx->files) {
- struct dirlink * dlink = (struct dirlink *) dirbase.first;
- struct direntry *file = &dir_ctx->files[dir_ctx->nrfiles];
- while (dlink) {
- char fullname[PATH_MAX];
- memset(file, 0, sizeof(struct direntry));
- file->relname = dlink->name;
- file->path = BLI_strdupcat(dirname, dlink->name);
- BLI_join_dirfile(fullname, sizeof(fullname), dirname, dlink->name);
- if (BLI_stat(fullname, &file->s) != -1) {
- file->type = file->s.st_mode;
- }
- else if (FILENAME_IS_CURRPAR(file->relname)) {
- /* Hack around for UNC paths on windows:
- * does not support stat on '\\SERVER\foo\..', sigh... */
- file->type |= S_IFDIR;
- }
- dir_ctx->nrfiles++;
- file++;
- dlink = dlink->next;
- }
- }
- else {
- printf("Couldn't get memory for dir\n");
- exit(1);
- }
-
- BLI_freelist(&dirbase);
- if (dir_ctx->files) {
- qsort(dir_ctx->files, dir_ctx->nrfiles, sizeof(struct direntry), (int (*)(const void *, const void *))bli_compare);
- }
- }
- else {
- printf("%s empty directory\n", dirname);
- }
-
- closedir(dir);
- }
- else {
- printf("%s non-existent directory\n", dirname);
- }
+ struct ListBase dirbase = {NULL, NULL};
+ int newnum = 0;
+ DIR *dir;
+
+ if ((dir = opendir(dirname)) != NULL) {
+ const struct dirent *fname;
+ bool has_current = false, has_parent = false;
+
+ while ((fname = readdir(dir)) != NULL) {
+ struct dirlink *const dlink = (struct dirlink *)malloc(sizeof(struct dirlink));
+ if (dlink != NULL) {
+ dlink->name = BLI_strdup(fname->d_name);
+ if (FILENAME_IS_PARENT(dlink->name)) {
+ has_parent = true;
+ }
+ else if (FILENAME_IS_CURRENT(dlink->name)) {
+ has_current = true;
+ }
+ BLI_addhead(&dirbase, dlink);
+ newnum++;
+ }
+ }
+
+ if (!has_parent) {
+ char pardir[FILE_MAXDIR];
+
+ BLI_strncpy(pardir, dirname, sizeof(pardir));
+ if (BLI_parent_dir(pardir) && (BLI_access(pardir, R_OK) == 0)) {
+ struct dirlink *const dlink = (struct dirlink *)malloc(sizeof(struct dirlink));
+ if (dlink != NULL) {
+ dlink->name = BLI_strdup(FILENAME_PARENT);
+ BLI_addhead(&dirbase, dlink);
+ newnum++;
+ }
+ }
+ }
+ if (!has_current) {
+ struct dirlink *const dlink = (struct dirlink *)malloc(sizeof(struct dirlink));
+ if (dlink != NULL) {
+ dlink->name = BLI_strdup(FILENAME_CURRENT);
+ BLI_addhead(&dirbase, dlink);
+ newnum++;
+ }
+ }
+
+ if (newnum) {
+ if (dir_ctx->files) {
+ void *const tmp = MEM_reallocN(dir_ctx->files,
+ (dir_ctx->nrfiles + newnum) * sizeof(struct direntry));
+ if (tmp) {
+ dir_ctx->files = (struct direntry *)tmp;
+ }
+ else { /* realloc fail */
+ MEM_freeN(dir_ctx->files);
+ dir_ctx->files = NULL;
+ }
+ }
+
+ if (dir_ctx->files == NULL) {
+ dir_ctx->files = (struct direntry *)MEM_mallocN(newnum * sizeof(struct direntry),
+ __func__);
+ }
+
+ if (dir_ctx->files) {
+ struct dirlink *dlink = (struct dirlink *)dirbase.first;
+ struct direntry *file = &dir_ctx->files[dir_ctx->nrfiles];
+ while (dlink) {
+ char fullname[PATH_MAX];
+ memset(file, 0, sizeof(struct direntry));
+ file->relname = dlink->name;
+ file->path = BLI_strdupcat(dirname, dlink->name);
+ BLI_join_dirfile(fullname, sizeof(fullname), dirname, dlink->name);
+ if (BLI_stat(fullname, &file->s) != -1) {
+ file->type = file->s.st_mode;
+ }
+ else if (FILENAME_IS_CURRPAR(file->relname)) {
+ /* Hack around for UNC paths on windows:
+ * does not support stat on '\\SERVER\foo\..', sigh... */
+ file->type |= S_IFDIR;
+ }
+ dir_ctx->nrfiles++;
+ file++;
+ dlink = dlink->next;
+ }
+ }
+ else {
+ printf("Couldn't get memory for dir\n");
+ exit(1);
+ }
+
+ BLI_freelist(&dirbase);
+ if (dir_ctx->files) {
+ qsort(dir_ctx->files,
+ dir_ctx->nrfiles,
+ sizeof(struct direntry),
+ (int (*)(const void *, const void *))bli_compare);
+ }
+ }
+ else {
+ printf("%s empty directory\n", dirname);
+ }
+
+ closedir(dir);
+ }
+ else {
+ printf("%s non-existent directory\n", dirname);
+ }
}
/**
@@ -220,151 +235,162 @@ static void bli_builddir(struct BuildDirCtx *dir_ctx, const char *dirname)
*
* \return The length of filelist array.
*/
-unsigned int BLI_filelist_dir_contents(const char *dirname, struct direntry **r_filelist)
+unsigned int BLI_filelist_dir_contents(const char *dirname, struct direntry **r_filelist)
{
- struct BuildDirCtx dir_ctx;
+ struct BuildDirCtx dir_ctx;
- dir_ctx.nrfiles = 0;
- dir_ctx.files = NULL;
+ dir_ctx.nrfiles = 0;
+ dir_ctx.files = NULL;
- bli_builddir(&dir_ctx, dirname);
+ bli_builddir(&dir_ctx, dirname);
- if (dir_ctx.files) {
- *r_filelist = dir_ctx.files;
- }
- else {
- // keep blender happy. Blender stores this in a variable
- // where 0 has special meaning.....
- *r_filelist = MEM_mallocN(sizeof(**r_filelist), __func__);
- }
+ if (dir_ctx.files) {
+ *r_filelist = dir_ctx.files;
+ }
+ else {
+ // keep blender happy. Blender stores this in a variable
+ // where 0 has special meaning.....
+ *r_filelist = MEM_mallocN(sizeof(**r_filelist), __func__);
+ }
- return dir_ctx.nrfiles;
+ return dir_ctx.nrfiles;
}
/**
* Convert given entry's size into human-readable strings.
*/
-void BLI_filelist_entry_size_to_string(
- const struct stat *st, const uint64_t sz, const bool compact, char r_size[FILELIST_DIRENTRY_SIZE_LEN])
+void BLI_filelist_entry_size_to_string(const struct stat *st,
+ const uint64_t sz,
+ const bool compact,
+ char r_size[FILELIST_DIRENTRY_SIZE_LEN])
{
- double size;
- const char *fmt;
- const char *units[] = {"KiB", "MiB", "GiB", "TiB", NULL};
- const char *units_compact[] = {"K", "M", "G", "T", NULL};
- const char *unit = "B";
-
- /*
- * Seems st_size is signed 32-bit value in *nix and Windows. This
- * will buy us some time until files get bigger than 4GB or until
- * everyone starts using __USE_FILE_OFFSET64 or equivalent.
- */
- size = (double)(st ? st->st_size : sz);
-
- if (size > 1024.0) {
- const char **u;
- for (u = compact ? units_compact : units, size /= 1024.0; size > 1024.0 && *(u + 1); u++, size /= 1024.0) {
- /* pass */
- }
- fmt = size > 100.0 ? "%.0f %s" : (size > 10.0 ? "%.1f %s" : "%.2f %s");
- unit = *u;
- }
- else {
- fmt = "%.0f %s";
- }
-
- BLI_snprintf(r_size, sizeof(*r_size) * FILELIST_DIRENTRY_SIZE_LEN, fmt, size, unit);
+ double size;
+ const char *fmt;
+ const char *units[] = {"KiB", "MiB", "GiB", "TiB", NULL};
+ const char *units_compact[] = {"K", "M", "G", "T", NULL};
+ const char *unit = "B";
+
+ /*
+ * Seems st_size is signed 32-bit value in *nix and Windows. This
+ * will buy us some time until files get bigger than 4GB or until
+ * everyone starts using __USE_FILE_OFFSET64 or equivalent.
+ */
+ size = (double)(st ? st->st_size : sz);
+
+ if (size > 1024.0) {
+ const char **u;
+ for (u = compact ? units_compact : units, size /= 1024.0; size > 1024.0 && *(u + 1);
+ u++, size /= 1024.0) {
+ /* pass */
+ }
+ fmt = size > 100.0 ? "%.0f %s" : (size > 10.0 ? "%.1f %s" : "%.2f %s");
+ unit = *u;
+ }
+ else {
+ fmt = "%.0f %s";
+ }
+
+ BLI_snprintf(r_size, sizeof(*r_size) * FILELIST_DIRENTRY_SIZE_LEN, fmt, size, unit);
}
/**
* Convert given entry's modes into human-readable strings.
*/
-void BLI_filelist_entry_mode_to_string(
- const struct stat *st, const bool UNUSED(compact), char r_mode1[FILELIST_DIRENTRY_MODE_LEN],
- char r_mode2[FILELIST_DIRENTRY_MODE_LEN], char r_mode3[FILELIST_DIRENTRY_MODE_LEN])
+void BLI_filelist_entry_mode_to_string(const struct stat *st,
+ const bool UNUSED(compact),
+ char r_mode1[FILELIST_DIRENTRY_MODE_LEN],
+ char r_mode2[FILELIST_DIRENTRY_MODE_LEN],
+ char r_mode3[FILELIST_DIRENTRY_MODE_LEN])
{
- const char *types[8] = {"---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx"};
+ const char *types[8] = {"---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx"};
#ifdef WIN32
- BLI_strncpy(r_mode1, types[0], sizeof(*r_mode1) * FILELIST_DIRENTRY_MODE_LEN);
- BLI_strncpy(r_mode2, types[0], sizeof(*r_mode2) * FILELIST_DIRENTRY_MODE_LEN);
- BLI_strncpy(r_mode3, types[0], sizeof(*r_mode3) * FILELIST_DIRENTRY_MODE_LEN);
+ BLI_strncpy(r_mode1, types[0], sizeof(*r_mode1) * FILELIST_DIRENTRY_MODE_LEN);
+ BLI_strncpy(r_mode2, types[0], sizeof(*r_mode2) * FILELIST_DIRENTRY_MODE_LEN);
+ BLI_strncpy(r_mode3, types[0], sizeof(*r_mode3) * FILELIST_DIRENTRY_MODE_LEN);
#else
- const int mode = st->st_mode;
-
- BLI_strncpy(r_mode1, types[(mode & 0700) >> 6], sizeof(*r_mode1) * FILELIST_DIRENTRY_MODE_LEN);
- BLI_strncpy(r_mode2, types[(mode & 0070) >> 3], sizeof(*r_mode2) * FILELIST_DIRENTRY_MODE_LEN);
- BLI_strncpy(r_mode3, types[(mode & 0007)], sizeof(*r_mode3) * FILELIST_DIRENTRY_MODE_LEN);
-
- if (((mode & S_ISGID) == S_ISGID) && (r_mode2[2] == '-')) {
- r_mode2[2] = 'l';
- }
-
- if (mode & (S_ISUID | S_ISGID)) {
- if (r_mode1[2] == 'x') {
- r_mode1[2] = 's';
- }
- else {
- r_mode1[2] = 'S';
- }
-
- if (r_mode2[2] == 'x') {
- r_mode2[2] = 's';
- }
- }
-
- if (mode & S_ISVTX) {
- if (r_mode3[2] == 'x') {
- r_mode3[2] = 't';
- }
- else {
- r_mode3[2] = 'T';
- }
- }
+ const int mode = st->st_mode;
+
+ BLI_strncpy(r_mode1, types[(mode & 0700) >> 6], sizeof(*r_mode1) * FILELIST_DIRENTRY_MODE_LEN);
+ BLI_strncpy(r_mode2, types[(mode & 0070) >> 3], sizeof(*r_mode2) * FILELIST_DIRENTRY_MODE_LEN);
+ BLI_strncpy(r_mode3, types[(mode & 0007)], sizeof(*r_mode3) * FILELIST_DIRENTRY_MODE_LEN);
+
+ if (((mode & S_ISGID) == S_ISGID) && (r_mode2[2] == '-')) {
+ r_mode2[2] = 'l';
+ }
+
+ if (mode & (S_ISUID | S_ISGID)) {
+ if (r_mode1[2] == 'x') {
+ r_mode1[2] = 's';
+ }
+ else {
+ r_mode1[2] = 'S';
+ }
+
+ if (r_mode2[2] == 'x') {
+ r_mode2[2] = 's';
+ }
+ }
+
+ if (mode & S_ISVTX) {
+ if (r_mode3[2] == 'x') {
+ r_mode3[2] = 't';
+ }
+ else {
+ r_mode3[2] = 'T';
+ }
+ }
#endif
}
/**
* Convert given entry's owner into human-readable strings.
*/
-void BLI_filelist_entry_owner_to_string(
- const struct stat *st, const bool UNUSED(compact), char r_owner[FILELIST_DIRENTRY_OWNER_LEN])
+void BLI_filelist_entry_owner_to_string(const struct stat *st,
+ const bool UNUSED(compact),
+ char r_owner[FILELIST_DIRENTRY_OWNER_LEN])
{
#ifdef WIN32
- strcpy(r_owner, "unknown");
+ strcpy(r_owner, "unknown");
#else
- struct passwd *pwuser = getpwuid(st->st_uid);
-
- if (pwuser) {
- BLI_strncpy(r_owner, pwuser->pw_name, sizeof(*r_owner) * FILELIST_DIRENTRY_OWNER_LEN);
- }
- else {
- BLI_snprintf(r_owner, sizeof(*r_owner) * FILELIST_DIRENTRY_OWNER_LEN, "%u", st->st_uid);
- }
+ struct passwd *pwuser = getpwuid(st->st_uid);
+
+ if (pwuser) {
+ BLI_strncpy(r_owner, pwuser->pw_name, sizeof(*r_owner) * FILELIST_DIRENTRY_OWNER_LEN);
+ }
+ else {
+ BLI_snprintf(r_owner, sizeof(*r_owner) * FILELIST_DIRENTRY_OWNER_LEN, "%u", st->st_uid);
+ }
#endif
}
/**
* Convert given entry's time into human-readable strings.
*/
-void BLI_filelist_entry_datetime_to_string(
- const struct stat *st, const int64_t ts, const bool compact,
- char r_time[FILELIST_DIRENTRY_TIME_LEN], char r_date[FILELIST_DIRENTRY_DATE_LEN])
+void BLI_filelist_entry_datetime_to_string(const struct stat *st,
+ const int64_t ts,
+ const bool compact,
+ char r_time[FILELIST_DIRENTRY_TIME_LEN],
+ char r_date[FILELIST_DIRENTRY_DATE_LEN])
{
- time_t ts_mtime = ts;
- const struct tm *tm = localtime(st ? &st->st_mtime : &ts_mtime);
- const time_t zero = 0;
-
- /* Prevent impossible dates in windows. */
- if (tm == NULL) {
- tm = localtime(&zero);
- }
-
- if (r_time) {
- strftime(r_time, sizeof(*r_time) * FILELIST_DIRENTRY_TIME_LEN, "%H:%M", tm);
- }
- if (r_date) {
- strftime(r_date, sizeof(*r_date) * FILELIST_DIRENTRY_DATE_LEN, compact ? "%d/%m/%y" : "%d-%b-%y", tm);
- }
+ time_t ts_mtime = ts;
+ const struct tm *tm = localtime(st ? &st->st_mtime : &ts_mtime);
+ const time_t zero = 0;
+
+ /* Prevent impossible dates in windows. */
+ if (tm == NULL) {
+ tm = localtime(&zero);
+ }
+
+ if (r_time) {
+ strftime(r_time, sizeof(*r_time) * FILELIST_DIRENTRY_TIME_LEN, "%H:%M", tm);
+ }
+ if (r_date) {
+ strftime(r_date,
+ sizeof(*r_date) * FILELIST_DIRENTRY_DATE_LEN,
+ compact ? "%d/%m/%y" : "%d-%b-%y",
+ tm);
+ }
}
/**
@@ -372,29 +398,30 @@ void BLI_filelist_entry_datetime_to_string(
*/
void BLI_filelist_entry_duplicate(struct direntry *dst, const struct direntry *src)
{
- *dst = *src;
- if (dst->relname) {
- dst->relname = MEM_dupallocN(src->relname);
- }
- if (dst->path) {
- dst->path = MEM_dupallocN(src->path);
- }
+ *dst = *src;
+ if (dst->relname) {
+ dst->relname = MEM_dupallocN(src->relname);
+ }
+ if (dst->path) {
+ dst->path = MEM_dupallocN(src->path);
+ }
}
/**
* Deep-duplicate of an array of direntries, including the array itself.
*/
-void BLI_filelist_duplicate(
- struct direntry **dest_filelist, struct direntry * const src_filelist, const unsigned int nrentries)
+void BLI_filelist_duplicate(struct direntry **dest_filelist,
+ struct direntry *const src_filelist,
+ const unsigned int nrentries)
{
- unsigned int i;
-
- *dest_filelist = MEM_mallocN(sizeof(**dest_filelist) * (size_t)(nrentries), __func__);
- for (i = 0; i < nrentries; ++i) {
- struct direntry * const src = &src_filelist[i];
- struct direntry *dst = &(*dest_filelist)[i];
- BLI_filelist_entry_duplicate(dst, src);
- }
+ unsigned int i;
+
+ *dest_filelist = MEM_mallocN(sizeof(**dest_filelist) * (size_t)(nrentries), __func__);
+ for (i = 0; i < nrentries; ++i) {
+ struct direntry *const src = &src_filelist[i];
+ struct direntry *dst = &(*dest_filelist)[i];
+ BLI_filelist_entry_duplicate(dst, src);
+ }
}
/**
@@ -402,12 +429,12 @@ void BLI_filelist_duplicate(
*/
void BLI_filelist_entry_free(struct direntry *entry)
{
- if (entry->relname) {
- MEM_freeN((void *)entry->relname);
- }
- if (entry->path) {
- MEM_freeN((void *)entry->path);
- }
+ if (entry->relname) {
+ MEM_freeN((void *)entry->relname);
+ }
+ if (entry->path) {
+ MEM_freeN((void *)entry->path);
+ }
}
/**
@@ -415,12 +442,12 @@ void BLI_filelist_entry_free(struct direntry *entry)
*/
void BLI_filelist_free(struct direntry *filelist, const unsigned int nrentries)
{
- unsigned int i;
- for (i = 0; i < nrentries; ++i) {
- BLI_filelist_entry_free(&filelist[i]);
- }
-
- if (filelist != NULL) {
- MEM_freeN(filelist);
- }
+ unsigned int i;
+ for (i = 0; i < nrentries; ++i) {
+ BLI_filelist_entry_free(&filelist[i]);
+ }
+
+ if (filelist != NULL) {
+ MEM_freeN(filelist);
+ }
}
diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c
index ae1c6e0ba0b..c0ec1eba9c0 100644
--- a/source/blender/blenlib/intern/BLI_ghash.c
+++ b/source/blender/blenlib/intern/BLI_ghash.c
@@ -33,12 +33,12 @@
#include "MEM_guardedalloc.h"
-#include "BLI_sys_types.h" /* for intptr_t support */
+#include "BLI_sys_types.h" /* for intptr_t support */
#include "BLI_utildefines.h"
#include "BLI_mempool.h"
#define GHASH_INTERNAL_API
-#include "BLI_ghash.h" /* own include */
+#include "BLI_ghash.h" /* own include */
/* keep last */
#include "BLI_strict_flags.h"
@@ -54,12 +54,11 @@
*
* \note Also used by: `BLI_edgehash` & `BLI_smallhash`.
*/
-extern const uint BLI_ghash_hash_sizes[]; /* Quiet warning, this is only used by smallhash.c */
+extern const uint BLI_ghash_hash_sizes[]; /* Quiet warning, this is only used by smallhash.c */
const uint BLI_ghash_hash_sizes[] = {
- 5, 11, 17, 37, 67, 131, 257, 521, 1031, 2053, 4099, 8209,
- 16411, 32771, 65537, 131101, 262147, 524309, 1048583, 2097169,
- 4194319, 8388617, 16777259, 33554467, 67108879, 134217757,
- 268435459,
+ 5, 11, 17, 37, 67, 131, 257, 521, 1031,
+ 2053, 4099, 8209, 16411, 32771, 65537, 131101, 262147, 524309,
+ 1048583, 2097169, 4194319, 8388617, 16777259, 33554467, 67108879, 134217757, 268435459,
};
#define hashsizes BLI_ghash_hash_sizes
@@ -68,7 +67,7 @@ const uint BLI_ghash_hash_sizes[] = {
BLI_STATIC_ASSERT(ARRAY_SIZE(hashsizes) == GHASH_MAX_SIZE, "Invalid 'hashsizes' size");
#else
# define GHASH_BUCKET_BIT_MIN 2
-# define GHASH_BUCKET_BIT_MAX 28 /* About 268M of buckets... */
+# define GHASH_BUCKET_BIT_MAX 28 /* About 268M of buckets... */
#endif
/**
@@ -78,43 +77,42 @@ BLI_STATIC_ASSERT(ARRAY_SIZE(hashsizes) == GHASH_MAX_SIZE, "Invalid 'hashsizes'
* about 25% - 30% quicker 'dynamic-topology' stroke drawing e.g.).
* Min load #GHASH_LIMIT_SHRINK is a quarter of max load, to avoid resizing to quickly.
*/
-#define GHASH_LIMIT_GROW(_nbkt) (((_nbkt) * 3) / 4)
-#define GHASH_LIMIT_SHRINK(_nbkt) (((_nbkt) * 3) / 16)
+#define GHASH_LIMIT_GROW(_nbkt) (((_nbkt)*3) / 4)
+#define GHASH_LIMIT_SHRINK(_nbkt) (((_nbkt)*3) / 16)
/* WARNING! Keep in sync with ugly _gh_Entry in header!!! */
typedef struct Entry {
- struct Entry *next;
+ struct Entry *next;
- void *key;
+ void *key;
} Entry;
typedef struct GHashEntry {
- Entry e;
+ Entry e;
- void *val;
+ void *val;
} GHashEntry;
typedef Entry GSetEntry;
-#define GHASH_ENTRY_SIZE(_is_gset) \
- ((_is_gset) ? sizeof(GSetEntry) : sizeof(GHashEntry))
+#define GHASH_ENTRY_SIZE(_is_gset) ((_is_gset) ? sizeof(GSetEntry) : sizeof(GHashEntry))
struct GHash {
- GHashHashFP hashfp;
- GHashCmpFP cmpfp;
+ GHashHashFP hashfp;
+ GHashCmpFP cmpfp;
- Entry **buckets;
- struct BLI_mempool *entrypool;
- uint nbuckets;
- uint limit_grow, limit_shrink;
+ Entry **buckets;
+ struct BLI_mempool *entrypool;
+ uint nbuckets;
+ uint limit_grow, limit_shrink;
#ifdef GHASH_USE_MODULO_BUCKETS
- uint cursize, size_min;
+ uint cursize, size_min;
#else
- uint bucket_mask, bucket_bit, bucket_bit_min;
+ uint bucket_mask, bucket_bit, bucket_bit_min;
#endif
- uint nentries;
- uint flag;
+ uint nentries;
+ uint flag;
};
/** \} */
@@ -123,20 +121,24 @@ struct GHash {
/** \name Internal Utility API
* \{ */
-BLI_INLINE void ghash_entry_copy(
- GHash *gh_dst, Entry *dst, GHash *gh_src, Entry *src,
- GHashKeyCopyFP keycopyfp, GHashValCopyFP valcopyfp)
+BLI_INLINE void ghash_entry_copy(GHash *gh_dst,
+ Entry *dst,
+ GHash *gh_src,
+ Entry *src,
+ GHashKeyCopyFP keycopyfp,
+ GHashValCopyFP valcopyfp)
{
- dst->key = (keycopyfp) ? keycopyfp(src->key) : src->key;
+ dst->key = (keycopyfp) ? keycopyfp(src->key) : src->key;
- if ((gh_dst->flag & GHASH_FLAG_IS_GSET) == 0) {
- if ((gh_src->flag & GHASH_FLAG_IS_GSET) == 0) {
- ((GHashEntry *)dst)->val = (valcopyfp) ? valcopyfp(((GHashEntry *)src)->val) : ((GHashEntry *)src)->val;
- }
- else {
- ((GHashEntry *)dst)->val = NULL;
- }
- }
+ if ((gh_dst->flag & GHASH_FLAG_IS_GSET) == 0) {
+ if ((gh_src->flag & GHASH_FLAG_IS_GSET) == 0) {
+ ((GHashEntry *)dst)->val = (valcopyfp) ? valcopyfp(((GHashEntry *)src)->val) :
+ ((GHashEntry *)src)->val;
+ }
+ else {
+ ((GHashEntry *)dst)->val = NULL;
+ }
+ }
}
/**
@@ -144,7 +146,7 @@ BLI_INLINE void ghash_entry_copy(
*/
BLI_INLINE uint ghash_keyhash(GHash *gh, const void *key)
{
- return gh->hashfp(key);
+ return gh->hashfp(key);
}
/**
@@ -152,7 +154,7 @@ BLI_INLINE uint ghash_keyhash(GHash *gh, const void *key)
*/
BLI_INLINE uint ghash_entryhash(GHash *gh, const Entry *e)
{
- return gh->hashfp(e->key);
+ return gh->hashfp(e->key);
}
/**
@@ -161,9 +163,9 @@ BLI_INLINE uint ghash_entryhash(GHash *gh, const Entry *e)
BLI_INLINE uint ghash_bucket_index(GHash *gh, const uint hash)
{
#ifdef GHASH_USE_MODULO_BUCKETS
- return hash % gh->nbuckets;
+ return hash % gh->nbuckets;
#else
- return hash & gh->bucket_mask;
+ return hash & gh->bucket_mask;
#endif
}
@@ -172,24 +174,24 @@ BLI_INLINE uint ghash_bucket_index(GHash *gh, const uint hash)
*/
BLI_INLINE uint ghash_find_next_bucket_index(GHash *gh, uint curr_bucket)
{
- if (curr_bucket >= gh->nbuckets) {
- curr_bucket = 0;
- }
- if (gh->buckets[curr_bucket]) {
- return curr_bucket;
- }
- for (; curr_bucket < gh->nbuckets; curr_bucket++) {
- if (gh->buckets[curr_bucket]) {
- return curr_bucket;
- }
- }
- for (curr_bucket = 0; curr_bucket < gh->nbuckets; curr_bucket++) {
- if (gh->buckets[curr_bucket]) {
- return curr_bucket;
- }
- }
- BLI_assert(0);
- return 0;
+ if (curr_bucket >= gh->nbuckets) {
+ curr_bucket = 0;
+ }
+ if (gh->buckets[curr_bucket]) {
+ return curr_bucket;
+ }
+ for (; curr_bucket < gh->nbuckets; curr_bucket++) {
+ if (gh->buckets[curr_bucket]) {
+ return curr_bucket;
+ }
+ }
+ for (curr_bucket = 0; curr_bucket < gh->nbuckets; curr_bucket++) {
+ if (gh->buckets[curr_bucket]) {
+ return curr_bucket;
+ }
+ }
+ BLI_assert(0);
+ return 0;
}
/**
@@ -197,162 +199,156 @@ BLI_INLINE uint ghash_find_next_bucket_index(GHash *gh, uint curr_bucket)
*/
static void ghash_buckets_resize(GHash *gh, const uint nbuckets)
{
- Entry **buckets_old = gh->buckets;
- Entry **buckets_new;
- const uint nbuckets_old = gh->nbuckets;
- uint i;
+ Entry **buckets_old = gh->buckets;
+ Entry **buckets_new;
+ const uint nbuckets_old = gh->nbuckets;
+ uint i;
- BLI_assert((gh->nbuckets != nbuckets) || !gh->buckets);
-// printf("%s: %d -> %d\n", __func__, nbuckets_old, nbuckets);
+ BLI_assert((gh->nbuckets != nbuckets) || !gh->buckets);
+ // printf("%s: %d -> %d\n", __func__, nbuckets_old, nbuckets);
- gh->nbuckets = nbuckets;
+ gh->nbuckets = nbuckets;
#ifdef GHASH_USE_MODULO_BUCKETS
#else
- gh->bucket_mask = nbuckets - 1;
+ gh->bucket_mask = nbuckets - 1;
#endif
- buckets_new = (Entry **)MEM_callocN(sizeof(*gh->buckets) * gh->nbuckets, __func__);
-
- if (buckets_old) {
- if (nbuckets > nbuckets_old) {
- for (i = 0; i < nbuckets_old; i++) {
- for (Entry *e = buckets_old[i], *e_next; e; e = e_next) {
- const unsigned hash = ghash_entryhash(gh, e);
- const unsigned bucket_index = ghash_bucket_index(gh, hash);
- e_next = e->next;
- e->next = buckets_new[bucket_index];
- buckets_new[bucket_index] = e;
- }
- }
- }
- else {
- for (i = 0; i < nbuckets_old; i++) {
+ buckets_new = (Entry **)MEM_callocN(sizeof(*gh->buckets) * gh->nbuckets, __func__);
+
+ if (buckets_old) {
+ if (nbuckets > nbuckets_old) {
+ for (i = 0; i < nbuckets_old; i++) {
+ for (Entry *e = buckets_old[i], *e_next; e; e = e_next) {
+ const unsigned hash = ghash_entryhash(gh, e);
+ const unsigned bucket_index = ghash_bucket_index(gh, hash);
+ e_next = e->next;
+ e->next = buckets_new[bucket_index];
+ buckets_new[bucket_index] = e;
+ }
+ }
+ }
+ else {
+ for (i = 0; i < nbuckets_old; i++) {
#ifdef GHASH_USE_MODULO_BUCKETS
- for (Entry *e = buckets_old[i], *e_next; e; e = e_next) {
- const unsigned hash = ghash_entryhash(gh, e);
- const unsigned bucket_index = ghash_bucket_index(gh, hash);
- e_next = e->next;
- e->next = buckets_new[bucket_index];
- buckets_new[bucket_index] = e;
- }
+ for (Entry *e = buckets_old[i], *e_next; e; e = e_next) {
+ const unsigned hash = ghash_entryhash(gh, e);
+ const unsigned bucket_index = ghash_bucket_index(gh, hash);
+ e_next = e->next;
+ e->next = buckets_new[bucket_index];
+ buckets_new[bucket_index] = e;
+ }
#else
- /* No need to recompute hashes in this case, since our mask is just smaller,
- * all items in old bucket 'i' will go in same new bucket (i & new_mask)! */
- const unsigned bucket_index = ghash_bucket_index(gh, i);
- BLI_assert(!buckets_old[i] || (bucket_index == ghash_bucket_index(gh, ghash_entryhash(gh, buckets_old[i]))));
- Entry *e;
- for (e = buckets_old[i]; e && e->next; e = e->next) {
- /* pass */
- }
- if (e) {
- e->next = buckets_new[bucket_index];
- buckets_new[bucket_index] = buckets_old[i];
- }
+ /* No need to recompute hashes in this case, since our mask is just smaller,
+ * all items in old bucket 'i' will go in same new bucket (i & new_mask)! */
+ const unsigned bucket_index = ghash_bucket_index(gh, i);
+ BLI_assert(!buckets_old[i] ||
+ (bucket_index == ghash_bucket_index(gh, ghash_entryhash(gh, buckets_old[i]))));
+ Entry *e;
+ for (e = buckets_old[i]; e && e->next; e = e->next) {
+ /* pass */
+ }
+ if (e) {
+ e->next = buckets_new[bucket_index];
+ buckets_new[bucket_index] = buckets_old[i];
+ }
#endif
- }
- }
- }
+ }
+ }
+ }
- gh->buckets = buckets_new;
- if (buckets_old) {
- MEM_freeN(buckets_old);
- }
+ gh->buckets = buckets_new;
+ if (buckets_old) {
+ MEM_freeN(buckets_old);
+ }
}
/**
* Check if the number of items in the GHash is large enough to require more buckets,
* or small enough to require less buckets, and resize \a gh accordingly.
*/
-static void ghash_buckets_expand(
- GHash *gh, const uint nentries, const bool user_defined)
+static void ghash_buckets_expand(GHash *gh, const uint nentries, const bool user_defined)
{
- uint new_nbuckets;
+ uint new_nbuckets;
- if (LIKELY(gh->buckets && (nentries < gh->limit_grow))) {
- return;
- }
+ if (LIKELY(gh->buckets && (nentries < gh->limit_grow))) {
+ return;
+ }
- new_nbuckets = gh->nbuckets;
+ new_nbuckets = gh->nbuckets;
#ifdef GHASH_USE_MODULO_BUCKETS
- while ((nentries > gh->limit_grow) &&
- (gh->cursize < GHASH_MAX_SIZE - 1))
- {
- new_nbuckets = hashsizes[++gh->cursize];
- gh->limit_grow = GHASH_LIMIT_GROW(new_nbuckets);
- }
+ while ((nentries > gh->limit_grow) && (gh->cursize < GHASH_MAX_SIZE - 1)) {
+ new_nbuckets = hashsizes[++gh->cursize];
+ gh->limit_grow = GHASH_LIMIT_GROW(new_nbuckets);
+ }
#else
- while ((nentries > gh->limit_grow) &&
- (gh->bucket_bit < GHASH_BUCKET_BIT_MAX))
- {
- new_nbuckets = 1u << ++gh->bucket_bit;
- gh->limit_grow = GHASH_LIMIT_GROW(new_nbuckets);
- }
+ while ((nentries > gh->limit_grow) && (gh->bucket_bit < GHASH_BUCKET_BIT_MAX)) {
+ new_nbuckets = 1u << ++gh->bucket_bit;
+ gh->limit_grow = GHASH_LIMIT_GROW(new_nbuckets);
+ }
#endif
- if (user_defined) {
+ if (user_defined) {
#ifdef GHASH_USE_MODULO_BUCKETS
- gh->size_min = gh->cursize;
+ gh->size_min = gh->cursize;
#else
- gh->bucket_bit_min = gh->bucket_bit;
+ gh->bucket_bit_min = gh->bucket_bit;
#endif
- }
+ }
- if ((new_nbuckets == gh->nbuckets) && gh->buckets) {
- return;
- }
+ if ((new_nbuckets == gh->nbuckets) && gh->buckets) {
+ return;
+ }
- gh->limit_grow = GHASH_LIMIT_GROW(new_nbuckets);
- gh->limit_shrink = GHASH_LIMIT_SHRINK(new_nbuckets);
- ghash_buckets_resize(gh, new_nbuckets);
+ gh->limit_grow = GHASH_LIMIT_GROW(new_nbuckets);
+ gh->limit_shrink = GHASH_LIMIT_SHRINK(new_nbuckets);
+ ghash_buckets_resize(gh, new_nbuckets);
}
-static void ghash_buckets_contract(
- GHash *gh, const uint nentries, const bool user_defined, const bool force_shrink)
+static void ghash_buckets_contract(GHash *gh,
+ const uint nentries,
+ const bool user_defined,
+ const bool force_shrink)
{
- uint new_nbuckets;
+ uint new_nbuckets;
- if (!(force_shrink || (gh->flag & GHASH_FLAG_ALLOW_SHRINK))) {
- return;
- }
+ if (!(force_shrink || (gh->flag & GHASH_FLAG_ALLOW_SHRINK))) {
+ return;
+ }
- if (LIKELY(gh->buckets && (nentries > gh->limit_shrink))) {
- return;
- }
+ if (LIKELY(gh->buckets && (nentries > gh->limit_shrink))) {
+ return;
+ }
- new_nbuckets = gh->nbuckets;
+ new_nbuckets = gh->nbuckets;
#ifdef GHASH_USE_MODULO_BUCKETS
- while ((nentries < gh->limit_shrink) &&
- (gh->cursize > gh->size_min))
- {
- new_nbuckets = hashsizes[--gh->cursize];
- gh->limit_shrink = GHASH_LIMIT_SHRINK(new_nbuckets);
- }
+ while ((nentries < gh->limit_shrink) && (gh->cursize > gh->size_min)) {
+ new_nbuckets = hashsizes[--gh->cursize];
+ gh->limit_shrink = GHASH_LIMIT_SHRINK(new_nbuckets);
+ }
#else
- while ((nentries < gh->limit_shrink) &&
- (gh->bucket_bit > gh->bucket_bit_min))
- {
- new_nbuckets = 1u << --gh->bucket_bit;
- gh->limit_shrink = GHASH_LIMIT_SHRINK(new_nbuckets);
- }
+ while ((nentries < gh->limit_shrink) && (gh->bucket_bit > gh->bucket_bit_min)) {
+ new_nbuckets = 1u << --gh->bucket_bit;
+ gh->limit_shrink = GHASH_LIMIT_SHRINK(new_nbuckets);
+ }
#endif
- if (user_defined) {
+ if (user_defined) {
#ifdef GHASH_USE_MODULO_BUCKETS
- gh->size_min = gh->cursize;
+ gh->size_min = gh->cursize;
#else
- gh->bucket_bit_min = gh->bucket_bit;
+ gh->bucket_bit_min = gh->bucket_bit;
#endif
- }
+ }
- if ((new_nbuckets == gh->nbuckets) && gh->buckets) {
- return;
- }
+ if ((new_nbuckets == gh->nbuckets) && gh->buckets) {
+ return;
+ }
- gh->limit_grow = GHASH_LIMIT_GROW(new_nbuckets);
- gh->limit_shrink = GHASH_LIMIT_SHRINK(new_nbuckets);
- ghash_buckets_resize(gh, new_nbuckets);
+ gh->limit_grow = GHASH_LIMIT_GROW(new_nbuckets);
+ gh->limit_shrink = GHASH_LIMIT_SHRINK(new_nbuckets);
+ ghash_buckets_resize(gh, new_nbuckets);
}
/**
@@ -360,44 +356,43 @@ static void ghash_buckets_contract(
*/
BLI_INLINE void ghash_buckets_reset(GHash *gh, const uint nentries)
{
- MEM_SAFE_FREE(gh->buckets);
+ MEM_SAFE_FREE(gh->buckets);
#ifdef GHASH_USE_MODULO_BUCKETS
- gh->cursize = 0;
- gh->size_min = 0;
- gh->nbuckets = hashsizes[gh->cursize];
+ gh->cursize = 0;
+ gh->size_min = 0;
+ gh->nbuckets = hashsizes[gh->cursize];
#else
- gh->bucket_bit = GHASH_BUCKET_BIT_MIN;
- gh->bucket_bit_min = GHASH_BUCKET_BIT_MIN;
- gh->nbuckets = 1u << gh->bucket_bit;
- gh->bucket_mask = gh->nbuckets - 1;
+ gh->bucket_bit = GHASH_BUCKET_BIT_MIN;
+ gh->bucket_bit_min = GHASH_BUCKET_BIT_MIN;
+ gh->nbuckets = 1u << gh->bucket_bit;
+ gh->bucket_mask = gh->nbuckets - 1;
#endif
- gh->limit_grow = GHASH_LIMIT_GROW(gh->nbuckets);
- gh->limit_shrink = GHASH_LIMIT_SHRINK(gh->nbuckets);
+ gh->limit_grow = GHASH_LIMIT_GROW(gh->nbuckets);
+ gh->limit_shrink = GHASH_LIMIT_SHRINK(gh->nbuckets);
- gh->nentries = 0;
+ gh->nentries = 0;
- ghash_buckets_expand(gh, nentries, (nentries != 0));
+ ghash_buckets_expand(gh, nentries, (nentries != 0));
}
/**
* Internal lookup function.
* Takes hash and bucket_index arguments to avoid calling #ghash_keyhash and #ghash_bucket_index multiple times.
*/
-BLI_INLINE Entry *ghash_lookup_entry_ex(
- GHash *gh, const void *key, const uint bucket_index)
+BLI_INLINE Entry *ghash_lookup_entry_ex(GHash *gh, const void *key, const uint bucket_index)
{
- Entry *e;
- /* If we do not store GHash, not worth computing it for each entry here!
- * Typically, comparison function will be quicker, and since it's needed in the end anyway... */
- for (e = gh->buckets[bucket_index]; e; e = e->next) {
- if (UNLIKELY(gh->cmpfp(key, e->key) == false)) {
- return e;
- }
- }
+ Entry *e;
+ /* If we do not store GHash, not worth computing it for each entry here!
+ * Typically, comparison function will be quicker, and since it's needed in the end anyway... */
+ for (e = gh->buckets[bucket_index]; e; e = e->next) {
+ if (UNLIKELY(gh->cmpfp(key, e->key) == false)) {
+ return e;
+ }
+ }
- return NULL;
+ return NULL;
}
/**
@@ -405,21 +400,22 @@ BLI_INLINE Entry *ghash_lookup_entry_ex(
* Takes bucket_index argument to avoid calling #ghash_keyhash and #ghash_bucket_index multiple times.
* Useful when modifying buckets somehow (like removing an entry...).
*/
-BLI_INLINE Entry *ghash_lookup_entry_prev_ex(
- GHash *gh, const void *key,
- Entry **r_e_prev, const uint bucket_index)
+BLI_INLINE Entry *ghash_lookup_entry_prev_ex(GHash *gh,
+ const void *key,
+ Entry **r_e_prev,
+ const uint bucket_index)
{
- /* If we do not store GHash, not worth computing it for each entry here!
- * Typically, comparison function will be quicker, and since it's needed in the end anyway... */
- for (Entry *e_prev = NULL, *e = gh->buckets[bucket_index]; e; e_prev = e, e = e->next) {
- if (UNLIKELY(gh->cmpfp(key, e->key) == false)) {
- *r_e_prev = e_prev;
- return e;
- }
- }
+ /* If we do not store GHash, not worth computing it for each entry here!
+ * Typically, comparison function will be quicker, and since it's needed in the end anyway... */
+ for (Entry *e_prev = NULL, *e = gh->buckets[bucket_index]; e; e_prev = e, e = e->next) {
+ if (UNLIKELY(gh->cmpfp(key, e->key) == false)) {
+ *r_e_prev = e_prev;
+ return e;
+ }
+ }
- *r_e_prev = NULL;
- return NULL;
+ *r_e_prev = NULL;
+ return NULL;
}
/**
@@ -427,177 +423,184 @@ BLI_INLINE Entry *ghash_lookup_entry_prev_ex(
*/
BLI_INLINE Entry *ghash_lookup_entry(GHash *gh, const void *key)
{
- const uint hash = ghash_keyhash(gh, key);
- const uint bucket_index = ghash_bucket_index(gh, hash);
- return ghash_lookup_entry_ex(gh, key, bucket_index);
+ const uint hash = ghash_keyhash(gh, key);
+ const uint bucket_index = ghash_bucket_index(gh, hash);
+ return ghash_lookup_entry_ex(gh, key, bucket_index);
}
-static GHash *ghash_new(
- GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info,
- const uint nentries_reserve, const uint flag)
+static GHash *ghash_new(GHashHashFP hashfp,
+ GHashCmpFP cmpfp,
+ const char *info,
+ const uint nentries_reserve,
+ const uint flag)
{
- GHash *gh = MEM_mallocN(sizeof(*gh), info);
+ GHash *gh = MEM_mallocN(sizeof(*gh), info);
- gh->hashfp = hashfp;
- gh->cmpfp = cmpfp;
+ gh->hashfp = hashfp;
+ gh->cmpfp = cmpfp;
- gh->buckets = NULL;
- gh->flag = flag;
+ gh->buckets = NULL;
+ gh->flag = flag;
- ghash_buckets_reset(gh, nentries_reserve);
- gh->entrypool = BLI_mempool_create(GHASH_ENTRY_SIZE(flag & GHASH_FLAG_IS_GSET), 64, 64, BLI_MEMPOOL_NOP);
+ ghash_buckets_reset(gh, nentries_reserve);
+ gh->entrypool = BLI_mempool_create(
+ GHASH_ENTRY_SIZE(flag & GHASH_FLAG_IS_GSET), 64, 64, BLI_MEMPOOL_NOP);
- return gh;
+ return gh;
}
/**
* Internal insert function.
* Takes hash and bucket_index arguments to avoid calling #ghash_keyhash and #ghash_bucket_index multiple times.
*/
-BLI_INLINE void ghash_insert_ex(
- GHash *gh, void *key, void *val, const uint bucket_index)
+BLI_INLINE void ghash_insert_ex(GHash *gh, void *key, void *val, const uint bucket_index)
{
- GHashEntry *e = BLI_mempool_alloc(gh->entrypool);
+ GHashEntry *e = BLI_mempool_alloc(gh->entrypool);
- BLI_assert((gh->flag & GHASH_FLAG_ALLOW_DUPES) || (BLI_ghash_haskey(gh, key) == 0));
- BLI_assert(!(gh->flag & GHASH_FLAG_IS_GSET));
+ BLI_assert((gh->flag & GHASH_FLAG_ALLOW_DUPES) || (BLI_ghash_haskey(gh, key) == 0));
+ BLI_assert(!(gh->flag & GHASH_FLAG_IS_GSET));
- e->e.next = gh->buckets[bucket_index];
- e->e.key = key;
- e->val = val;
- gh->buckets[bucket_index] = (Entry *)e;
+ e->e.next = gh->buckets[bucket_index];
+ e->e.key = key;
+ e->val = val;
+ gh->buckets[bucket_index] = (Entry *)e;
- ghash_buckets_expand(gh, ++gh->nentries, false);
+ ghash_buckets_expand(gh, ++gh->nentries, false);
}
/**
* Insert function that takes a pre-allocated entry.
*/
-BLI_INLINE void ghash_insert_ex_keyonly_entry(
- GHash *gh, void *key, const uint bucket_index,
- Entry *e)
+BLI_INLINE void ghash_insert_ex_keyonly_entry(GHash *gh,
+ void *key,
+ const uint bucket_index,
+ Entry *e)
{
- BLI_assert((gh->flag & GHASH_FLAG_ALLOW_DUPES) || (BLI_ghash_haskey(gh, key) == 0));
+ BLI_assert((gh->flag & GHASH_FLAG_ALLOW_DUPES) || (BLI_ghash_haskey(gh, key) == 0));
- e->next = gh->buckets[bucket_index];
- e->key = key;
- gh->buckets[bucket_index] = e;
+ e->next = gh->buckets[bucket_index];
+ e->key = key;
+ gh->buckets[bucket_index] = e;
- ghash_buckets_expand(gh, ++gh->nentries, false);
+ ghash_buckets_expand(gh, ++gh->nentries, false);
}
/**
* Insert function that doesn't set the value (use for GSet)
*/
-BLI_INLINE void ghash_insert_ex_keyonly(
- GHash *gh, void *key, const uint bucket_index)
+BLI_INLINE void ghash_insert_ex_keyonly(GHash *gh, void *key, const uint bucket_index)
{
- Entry *e = BLI_mempool_alloc(gh->entrypool);
+ Entry *e = BLI_mempool_alloc(gh->entrypool);
- BLI_assert((gh->flag & GHASH_FLAG_ALLOW_DUPES) || (BLI_ghash_haskey(gh, key) == 0));
- BLI_assert((gh->flag & GHASH_FLAG_IS_GSET) != 0);
+ BLI_assert((gh->flag & GHASH_FLAG_ALLOW_DUPES) || (BLI_ghash_haskey(gh, key) == 0));
+ BLI_assert((gh->flag & GHASH_FLAG_IS_GSET) != 0);
- e->next = gh->buckets[bucket_index];
- e->key = key;
- gh->buckets[bucket_index] = e;
+ e->next = gh->buckets[bucket_index];
+ e->key = key;
+ gh->buckets[bucket_index] = e;
- ghash_buckets_expand(gh, ++gh->nentries, false);
+ ghash_buckets_expand(gh, ++gh->nentries, false);
}
BLI_INLINE void ghash_insert(GHash *gh, void *key, void *val)
{
- const uint hash = ghash_keyhash(gh, key);
- const uint bucket_index = ghash_bucket_index(gh, hash);
-
- ghash_insert_ex(gh, key, val, bucket_index);
-}
-
-BLI_INLINE bool ghash_insert_safe(
- GHash *gh, void *key, void *val, const bool override,
- GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
-{
- const uint hash = ghash_keyhash(gh, key);
- const uint bucket_index = ghash_bucket_index(gh, hash);
- GHashEntry *e = (GHashEntry *)ghash_lookup_entry_ex(gh, key, bucket_index);
-
- BLI_assert(!(gh->flag & GHASH_FLAG_IS_GSET));
-
- if (e) {
- if (override) {
- if (keyfreefp) {
- keyfreefp(e->e.key);
- }
- if (valfreefp) {
- valfreefp(e->val);
- }
- e->e.key = key;
- e->val = val;
- }
- return false;
- }
- else {
- ghash_insert_ex(gh, key, val, bucket_index);
- return true;
- }
-}
-
-BLI_INLINE bool ghash_insert_safe_keyonly(
- GHash *gh, void *key, const bool override,
- GHashKeyFreeFP keyfreefp)
-{
- const uint hash = ghash_keyhash(gh, key);
- const uint bucket_index = ghash_bucket_index(gh, hash);
- Entry *e = ghash_lookup_entry_ex(gh, key, bucket_index);
-
- BLI_assert((gh->flag & GHASH_FLAG_IS_GSET) != 0);
-
- if (e) {
- if (override) {
- if (keyfreefp) {
- keyfreefp(e->key);
- }
- e->key = key;
- }
- return false;
- }
- else {
- ghash_insert_ex_keyonly(gh, key, bucket_index);
- return true;
- }
+ const uint hash = ghash_keyhash(gh, key);
+ const uint bucket_index = ghash_bucket_index(gh, hash);
+
+ ghash_insert_ex(gh, key, val, bucket_index);
+}
+
+BLI_INLINE bool ghash_insert_safe(GHash *gh,
+ void *key,
+ void *val,
+ const bool override,
+ GHashKeyFreeFP keyfreefp,
+ GHashValFreeFP valfreefp)
+{
+ const uint hash = ghash_keyhash(gh, key);
+ const uint bucket_index = ghash_bucket_index(gh, hash);
+ GHashEntry *e = (GHashEntry *)ghash_lookup_entry_ex(gh, key, bucket_index);
+
+ BLI_assert(!(gh->flag & GHASH_FLAG_IS_GSET));
+
+ if (e) {
+ if (override) {
+ if (keyfreefp) {
+ keyfreefp(e->e.key);
+ }
+ if (valfreefp) {
+ valfreefp(e->val);
+ }
+ e->e.key = key;
+ e->val = val;
+ }
+ return false;
+ }
+ else {
+ ghash_insert_ex(gh, key, val, bucket_index);
+ return true;
+ }
+}
+
+BLI_INLINE bool ghash_insert_safe_keyonly(GHash *gh,
+ void *key,
+ const bool override,
+ GHashKeyFreeFP keyfreefp)
+{
+ const uint hash = ghash_keyhash(gh, key);
+ const uint bucket_index = ghash_bucket_index(gh, hash);
+ Entry *e = ghash_lookup_entry_ex(gh, key, bucket_index);
+
+ BLI_assert((gh->flag & GHASH_FLAG_IS_GSET) != 0);
+
+ if (e) {
+ if (override) {
+ if (keyfreefp) {
+ keyfreefp(e->key);
+ }
+ e->key = key;
+ }
+ return false;
+ }
+ else {
+ ghash_insert_ex_keyonly(gh, key, bucket_index);
+ return true;
+ }
}
/**
* Remove the entry and return it, caller must free from gh->entrypool.
*/
-static Entry *ghash_remove_ex(
- GHash *gh, const void *key,
- GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp,
- const uint bucket_index)
+static Entry *ghash_remove_ex(GHash *gh,
+ const void *key,
+ GHashKeyFreeFP keyfreefp,
+ GHashValFreeFP valfreefp,
+ const uint bucket_index)
{
- Entry *e_prev;
- Entry *e = ghash_lookup_entry_prev_ex(gh, key, &e_prev, bucket_index);
+ Entry *e_prev;
+ Entry *e = ghash_lookup_entry_prev_ex(gh, key, &e_prev, bucket_index);
- BLI_assert(!valfreefp || !(gh->flag & GHASH_FLAG_IS_GSET));
+ BLI_assert(!valfreefp || !(gh->flag & GHASH_FLAG_IS_GSET));
- if (e) {
- if (keyfreefp) {
- keyfreefp(e->key);
- }
- if (valfreefp) {
- valfreefp(((GHashEntry *)e)->val);
- }
+ if (e) {
+ if (keyfreefp) {
+ keyfreefp(e->key);
+ }
+ if (valfreefp) {
+ valfreefp(((GHashEntry *)e)->val);
+ }
- if (e_prev) {
- e_prev->next = e->next;
- }
- else {
- gh->buckets[bucket_index] = e->next;
- }
+ if (e_prev) {
+ e_prev->next = e->next;
+ }
+ else {
+ gh->buckets[bucket_index] = e->next;
+ }
- ghash_buckets_contract(gh, --gh->nentries, false, false);
- }
+ ghash_buckets_contract(gh, --gh->nentries, false, false);
+ }
- return e;
+ return e;
}
/**
@@ -605,49 +608,47 @@ static Entry *ghash_remove_ex(
*/
static Entry *ghash_pop(GHash *gh, GHashIterState *state)
{
- uint curr_bucket = state->curr_bucket;
- if (gh->nentries == 0) {
- return NULL;
- }
+ uint curr_bucket = state->curr_bucket;
+ if (gh->nentries == 0) {
+ return NULL;
+ }
- /* Note: using first_bucket_index here allows us to avoid potential
- * huge number of loops over buckets,
- * in case we are popping from a large ghash with few items in it... */
- curr_bucket = ghash_find_next_bucket_index(gh, curr_bucket);
+ /* Note: using first_bucket_index here allows us to avoid potential
+ * huge number of loops over buckets,
+ * in case we are popping from a large ghash with few items in it... */
+ curr_bucket = ghash_find_next_bucket_index(gh, curr_bucket);
- Entry *e = gh->buckets[curr_bucket];
- BLI_assert(e);
+ Entry *e = gh->buckets[curr_bucket];
+ BLI_assert(e);
- ghash_remove_ex(gh, e->key, NULL, NULL, curr_bucket);
+ ghash_remove_ex(gh, e->key, NULL, NULL, curr_bucket);
- state->curr_bucket = curr_bucket;
- return e;
+ state->curr_bucket = curr_bucket;
+ return e;
}
/**
* Run free callbacks for freeing entries.
*/
-static void ghash_free_cb(
- GHash *gh,
- GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
+static void ghash_free_cb(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
{
- uint i;
+ uint i;
- BLI_assert(keyfreefp || valfreefp);
- BLI_assert(!valfreefp || !(gh->flag & GHASH_FLAG_IS_GSET));
+ BLI_assert(keyfreefp || valfreefp);
+ BLI_assert(!valfreefp || !(gh->flag & GHASH_FLAG_IS_GSET));
- for (i = 0; i < gh->nbuckets; i++) {
- Entry *e;
+ for (i = 0; i < gh->nbuckets; i++) {
+ Entry *e;
- for (e = gh->buckets[i]; e; e = e->next) {
- if (keyfreefp) {
- keyfreefp(e->key);
- }
- if (valfreefp) {
- valfreefp(((GHashEntry *)e)->val);
- }
- }
- }
+ for (e = gh->buckets[i]; e; e = e->next) {
+ if (keyfreefp) {
+ keyfreefp(e->key);
+ }
+ if (valfreefp) {
+ valfreefp(((GHashEntry *)e)->val);
+ }
+ }
+ }
}
/**
@@ -655,38 +656,38 @@ static void ghash_free_cb(
*/
static GHash *ghash_copy(GHash *gh, GHashKeyCopyFP keycopyfp, GHashValCopyFP valcopyfp)
{
- GHash *gh_new;
- uint i;
- /* This allows us to be sure to get the same number of buckets in gh_new as in ghash. */
- const uint reserve_nentries_new = MAX2(GHASH_LIMIT_GROW(gh->nbuckets) - 1, gh->nentries);
+ GHash *gh_new;
+ uint i;
+ /* This allows us to be sure to get the same number of buckets in gh_new as in ghash. */
+ const uint reserve_nentries_new = MAX2(GHASH_LIMIT_GROW(gh->nbuckets) - 1, gh->nentries);
- BLI_assert(!valcopyfp || !(gh->flag & GHASH_FLAG_IS_GSET));
+ BLI_assert(!valcopyfp || !(gh->flag & GHASH_FLAG_IS_GSET));
- gh_new = ghash_new(gh->hashfp, gh->cmpfp, __func__, 0, gh->flag);
- ghash_buckets_expand(gh_new, reserve_nentries_new, false);
+ gh_new = ghash_new(gh->hashfp, gh->cmpfp, __func__, 0, gh->flag);
+ ghash_buckets_expand(gh_new, reserve_nentries_new, false);
- BLI_assert(gh_new->nbuckets == gh->nbuckets);
+ BLI_assert(gh_new->nbuckets == gh->nbuckets);
- for (i = 0; i < gh->nbuckets; i++) {
- Entry *e;
+ for (i = 0; i < gh->nbuckets; i++) {
+ Entry *e;
- for (e = gh->buckets[i]; e; e = e->next) {
- Entry *e_new = BLI_mempool_alloc(gh_new->entrypool);
- ghash_entry_copy(gh_new, e_new, gh, e, keycopyfp, valcopyfp);
+ for (e = gh->buckets[i]; e; e = e->next) {
+ Entry *e_new = BLI_mempool_alloc(gh_new->entrypool);
+ ghash_entry_copy(gh_new, e_new, gh, e, keycopyfp, valcopyfp);
- /* Warning!
- * This means entries in buckets in new copy will be in reversed order!
- * This shall not be an issue though, since order should never be assumed in ghash. */
+ /* Warning!
+ * This means entries in buckets in new copy will be in reversed order!
+ * This shall not be an issue though, since order should never be assumed in ghash. */
- /* Note: We can use 'i' here, since we are sure that
- * 'gh' and 'gh_new' have the same number of buckets! */
- e_new->next = gh_new->buckets[i];
- gh_new->buckets[i] = e_new;
- }
- }
- gh_new->nentries = gh->nentries;
+ /* Note: We can use 'i' here, since we are sure that
+ * 'gh' and 'gh_new' have the same number of buckets! */
+ e_new->next = gh_new->buckets[i];
+ gh_new->buckets[i] = e_new;
+ }
+ }
+ gh_new->nentries = gh->nentries;
- return gh_new;
+ return gh_new;
}
/** \} */
@@ -705,11 +706,12 @@ static GHash *ghash_copy(GHash *gh, GHashKeyCopyFP keycopyfp, GHashValCopyFP val
* Use this to avoid resizing buckets if the size is known or can be closely approximated.
* \return An empty GHash.
*/
-GHash *BLI_ghash_new_ex(
- GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info,
- const uint nentries_reserve)
+GHash *BLI_ghash_new_ex(GHashHashFP hashfp,
+ GHashCmpFP cmpfp,
+ const char *info,
+ const uint nentries_reserve)
{
- return ghash_new(hashfp, cmpfp, info, nentries_reserve, 0);
+ return ghash_new(hashfp, cmpfp, info, nentries_reserve, 0);
}
/**
@@ -717,7 +719,7 @@ GHash *BLI_ghash_new_ex(
*/
GHash *BLI_ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info)
{
- return BLI_ghash_new_ex(hashfp, cmpfp, info, 0);
+ return BLI_ghash_new_ex(hashfp, cmpfp, info, 0);
}
/**
@@ -725,7 +727,7 @@ GHash *BLI_ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info)
*/
GHash *BLI_ghash_copy(GHash *gh, GHashKeyCopyFP keycopyfp, GHashValCopyFP valcopyfp)
{
- return ghash_copy(gh, keycopyfp, valcopyfp);
+ return ghash_copy(gh, keycopyfp, valcopyfp);
}
/**
@@ -733,8 +735,8 @@ GHash *BLI_ghash_copy(GHash *gh, GHashKeyCopyFP keycopyfp, GHashValCopyFP valcop
*/
void BLI_ghash_reserve(GHash *gh, const uint nentries_reserve)
{
- ghash_buckets_expand(gh, nentries_reserve, true);
- ghash_buckets_contract(gh, nentries_reserve, true, false);
+ ghash_buckets_expand(gh, nentries_reserve, true);
+ ghash_buckets_contract(gh, nentries_reserve, true, false);
}
/**
@@ -742,7 +744,7 @@ void BLI_ghash_reserve(GHash *gh, const uint nentries_reserve)
*/
uint BLI_ghash_len(GHash *gh)
{
- return gh->nentries;
+ return gh->nentries;
}
/**
@@ -754,7 +756,7 @@ uint BLI_ghash_len(GHash *gh)
*/
void BLI_ghash_insert(GHash *gh, void *key, void *val)
{
- ghash_insert(gh, key, val);
+ ghash_insert(gh, key, val);
}
/**
@@ -764,9 +766,10 @@ void BLI_ghash_insert(GHash *gh, void *key, void *val)
*
* \returns true if a new key has been added.
*/
-bool BLI_ghash_reinsert(GHash *gh, void *key, void *val, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
+bool BLI_ghash_reinsert(
+ GHash *gh, void *key, void *val, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
{
- return ghash_insert_safe(gh, key, val, true, keyfreefp, valfreefp);
+ return ghash_insert_safe(gh, key, val, true, keyfreefp, valfreefp);
}
/**
@@ -778,17 +781,17 @@ bool BLI_ghash_reinsert(GHash *gh, void *key, void *val, GHashKeyFreeFP keyfreef
*/
void *BLI_ghash_replace_key(GHash *gh, void *key)
{
- const uint hash = ghash_keyhash(gh, key);
- const uint bucket_index = ghash_bucket_index(gh, hash);
- GHashEntry *e = (GHashEntry *)ghash_lookup_entry_ex(gh, key, bucket_index);
- if (e != NULL) {
- void *key_prev = e->e.key;
- e->e.key = key;
- return key_prev;
- }
- else {
- return NULL;
- }
+ const uint hash = ghash_keyhash(gh, key);
+ const uint bucket_index = ghash_bucket_index(gh, hash);
+ GHashEntry *e = (GHashEntry *)ghash_lookup_entry_ex(gh, key, bucket_index);
+ if (e != NULL) {
+ void *key_prev = e->e.key;
+ e->e.key = key;
+ return key_prev;
+ }
+ else {
+ return NULL;
+ }
}
/**
@@ -802,9 +805,9 @@ void *BLI_ghash_replace_key(GHash *gh, void *key)
*/
void *BLI_ghash_lookup(GHash *gh, const void *key)
{
- GHashEntry *e = (GHashEntry *)ghash_lookup_entry(gh, key);
- BLI_assert(!(gh->flag & GHASH_FLAG_IS_GSET));
- return e ? e->val : NULL;
+ GHashEntry *e = (GHashEntry *)ghash_lookup_entry(gh, key);
+ BLI_assert(!(gh->flag & GHASH_FLAG_IS_GSET));
+ return e ? e->val : NULL;
}
/**
@@ -812,9 +815,9 @@ void *BLI_ghash_lookup(GHash *gh, const void *key)
*/
void *BLI_ghash_lookup_default(GHash *gh, const void *key, void *val_default)
{
- GHashEntry *e = (GHashEntry *)ghash_lookup_entry(gh, key);
- BLI_assert(!(gh->flag & GHASH_FLAG_IS_GSET));
- return e ? e->val : val_default;
+ GHashEntry *e = (GHashEntry *)ghash_lookup_entry(gh, key);
+ BLI_assert(!(gh->flag & GHASH_FLAG_IS_GSET));
+ return e ? e->val : val_default;
}
/**
@@ -829,9 +832,9 @@ void *BLI_ghash_lookup_default(GHash *gh, const void *key, void *val_default)
*/
void **BLI_ghash_lookup_p(GHash *gh, const void *key)
{
- GHashEntry *e = (GHashEntry *)ghash_lookup_entry(gh, key);
- BLI_assert(!(gh->flag & GHASH_FLAG_IS_GSET));
- return e ? &e->val : NULL;
+ GHashEntry *e = (GHashEntry *)ghash_lookup_entry(gh, key);
+ BLI_assert(!(gh->flag & GHASH_FLAG_IS_GSET));
+ return e ? &e->val : NULL;
}
/**
@@ -850,18 +853,18 @@ void **BLI_ghash_lookup_p(GHash *gh, const void *key)
*/
bool BLI_ghash_ensure_p(GHash *gh, void *key, void ***r_val)
{
- const uint hash = ghash_keyhash(gh, key);
- const uint bucket_index = ghash_bucket_index(gh, hash);
- GHashEntry *e = (GHashEntry *)ghash_lookup_entry_ex(gh, key, bucket_index);
- const bool haskey = (e != NULL);
+ const uint hash = ghash_keyhash(gh, key);
+ const uint bucket_index = ghash_bucket_index(gh, hash);
+ GHashEntry *e = (GHashEntry *)ghash_lookup_entry_ex(gh, key, bucket_index);
+ const bool haskey = (e != NULL);
- if (!haskey) {
- e = BLI_mempool_alloc(gh->entrypool);
- ghash_insert_ex_keyonly_entry(gh, key, bucket_index, (Entry *)e);
- }
+ if (!haskey) {
+ e = BLI_mempool_alloc(gh->entrypool);
+ ghash_insert_ex_keyonly_entry(gh, key, bucket_index, (Entry *)e);
+ }
- *r_val = &e->val;
- return haskey;
+ *r_val = &e->val;
+ return haskey;
}
/**
@@ -870,24 +873,23 @@ bool BLI_ghash_ensure_p(GHash *gh, void *key, void ***r_val)
*
* \warning Caller _must_ write to \a r_key when returning false.
*/
-bool BLI_ghash_ensure_p_ex(
- GHash *gh, const void *key, void ***r_key, void ***r_val)
+bool BLI_ghash_ensure_p_ex(GHash *gh, const void *key, void ***r_key, void ***r_val)
{
- const uint hash = ghash_keyhash(gh, key);
- const uint bucket_index = ghash_bucket_index(gh, hash);
- GHashEntry *e = (GHashEntry *)ghash_lookup_entry_ex(gh, key, bucket_index);
- const bool haskey = (e != NULL);
+ const uint hash = ghash_keyhash(gh, key);
+ const uint bucket_index = ghash_bucket_index(gh, hash);
+ GHashEntry *e = (GHashEntry *)ghash_lookup_entry_ex(gh, key, bucket_index);
+ const bool haskey = (e != NULL);
- if (!haskey) {
- /* pass 'key' incase we resize */
- e = BLI_mempool_alloc(gh->entrypool);
- ghash_insert_ex_keyonly_entry(gh, (void *)key, bucket_index, (Entry *)e);
- e->e.key = NULL; /* caller must re-assign */
- }
+ if (!haskey) {
+ /* pass 'key' incase we resize */
+ e = BLI_mempool_alloc(gh->entrypool);
+ ghash_insert_ex_keyonly_entry(gh, (void *)key, bucket_index, (Entry *)e);
+ e->e.key = NULL; /* caller must re-assign */
+ }
- *r_key = &e->e.key;
- *r_val = &e->val;
- return haskey;
+ *r_key = &e->e.key;
+ *r_val = &e->val;
+ return haskey;
}
/**
@@ -898,18 +900,21 @@ bool BLI_ghash_ensure_p_ex(
* \param valfreefp: Optional callback to free the value.
* \return true if \a key was removed from \a gh.
*/
-bool BLI_ghash_remove(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
-{
- const uint hash = ghash_keyhash(gh, key);
- const uint bucket_index = ghash_bucket_index(gh, hash);
- Entry *e = ghash_remove_ex(gh, key, keyfreefp, valfreefp, bucket_index);
- if (e) {
- BLI_mempool_free(gh->entrypool, e);
- return true;
- }
- else {
- return false;
- }
+bool BLI_ghash_remove(GHash *gh,
+ const void *key,
+ GHashKeyFreeFP keyfreefp,
+ GHashValFreeFP valfreefp)
+{
+ const uint hash = ghash_keyhash(gh, key);
+ const uint bucket_index = ghash_bucket_index(gh, hash);
+ Entry *e = ghash_remove_ex(gh, key, keyfreefp, valfreefp, bucket_index);
+ if (e) {
+ BLI_mempool_free(gh->entrypool, e);
+ return true;
+ }
+ else {
+ return false;
+ }
}
/* same as above but return the value,
@@ -923,18 +928,18 @@ bool BLI_ghash_remove(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp, GHas
*/
void *BLI_ghash_popkey(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp)
{
- const uint hash = ghash_keyhash(gh, key);
- const uint bucket_index = ghash_bucket_index(gh, hash);
- GHashEntry *e = (GHashEntry *)ghash_remove_ex(gh, key, keyfreefp, NULL, bucket_index);
- BLI_assert(!(gh->flag & GHASH_FLAG_IS_GSET));
- if (e) {
- void *val = e->val;
- BLI_mempool_free(gh->entrypool, e);
- return val;
- }
- else {
- return NULL;
- }
+ const uint hash = ghash_keyhash(gh, key);
+ const uint bucket_index = ghash_bucket_index(gh, hash);
+ GHashEntry *e = (GHashEntry *)ghash_remove_ex(gh, key, keyfreefp, NULL, bucket_index);
+ BLI_assert(!(gh->flag & GHASH_FLAG_IS_GSET));
+ if (e) {
+ void *val = e->val;
+ BLI_mempool_free(gh->entrypool, e);
+ return val;
+ }
+ else {
+ return NULL;
+ }
}
/**
@@ -942,7 +947,7 @@ void *BLI_ghash_popkey(GHash *gh, const void *key, GHashKeyFreeFP keyfreefp)
*/
bool BLI_ghash_haskey(GHash *gh, const void *key)
{
- return (ghash_lookup_entry(gh, key) != NULL);
+ return (ghash_lookup_entry(gh, key) != NULL);
}
/**
@@ -953,25 +958,23 @@ bool BLI_ghash_haskey(GHash *gh, const void *key)
* \param state: Used for efficient removal.
* \return true if there was something to pop, false if ghash was already empty.
*/
-bool BLI_ghash_pop(
- GHash *gh, GHashIterState *state,
- void **r_key, void **r_val)
+bool BLI_ghash_pop(GHash *gh, GHashIterState *state, void **r_key, void **r_val)
{
- GHashEntry *e = (GHashEntry *)ghash_pop(gh, state);
+ GHashEntry *e = (GHashEntry *)ghash_pop(gh, state);
- BLI_assert(!(gh->flag & GHASH_FLAG_IS_GSET));
+ BLI_assert(!(gh->flag & GHASH_FLAG_IS_GSET));
- if (e) {
- *r_key = e->e.key;
- *r_val = e->val;
+ if (e) {
+ *r_key = e->e.key;
+ *r_val = e->val;
- BLI_mempool_free(gh->entrypool, e);
- return true;
- }
- else {
- *r_key = *r_val = NULL;
- return false;
- }
+ BLI_mempool_free(gh->entrypool, e);
+ return true;
+ }
+ else {
+ *r_key = *r_val = NULL;
+ return false;
+ }
}
/**
@@ -981,16 +984,17 @@ bool BLI_ghash_pop(
* \param valfreefp: Optional callback to free the value.
* \param nentries_reserve: Optionally reserve the number of members that the hash will hold.
*/
-void BLI_ghash_clear_ex(
- GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp,
- const uint nentries_reserve)
+void BLI_ghash_clear_ex(GHash *gh,
+ GHashKeyFreeFP keyfreefp,
+ GHashValFreeFP valfreefp,
+ const uint nentries_reserve)
{
- if (keyfreefp || valfreefp) {
- ghash_free_cb(gh, keyfreefp, valfreefp);
- }
+ if (keyfreefp || valfreefp) {
+ ghash_free_cb(gh, keyfreefp, valfreefp);
+ }
- ghash_buckets_reset(gh, nentries_reserve);
- BLI_mempool_clear_ex(gh->entrypool, nentries_reserve ? (int)nentries_reserve : -1);
+ ghash_buckets_reset(gh, nentries_reserve);
+ BLI_mempool_clear_ex(gh->entrypool, nentries_reserve ? (int)nentries_reserve : -1);
}
/**
@@ -998,7 +1002,7 @@ void BLI_ghash_clear_ex(
*/
void BLI_ghash_clear(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
{
- BLI_ghash_clear_ex(gh, keyfreefp, valfreefp, 0);
+ BLI_ghash_clear_ex(gh, keyfreefp, valfreefp, 0);
}
/**
@@ -1010,14 +1014,14 @@ void BLI_ghash_clear(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfree
*/
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
{
- BLI_assert((int)gh->nentries == BLI_mempool_len(gh->entrypool));
- if (keyfreefp || valfreefp) {
- ghash_free_cb(gh, keyfreefp, valfreefp);
- }
+ BLI_assert((int)gh->nentries == BLI_mempool_len(gh->entrypool));
+ if (keyfreefp || valfreefp) {
+ ghash_free_cb(gh, keyfreefp, valfreefp);
+ }
- MEM_freeN(gh->buckets);
- BLI_mempool_destroy(gh->entrypool);
- MEM_freeN(gh);
+ MEM_freeN(gh->buckets);
+ BLI_mempool_destroy(gh->entrypool);
+ MEM_freeN(gh);
}
/**
@@ -1025,7 +1029,7 @@ void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreef
*/
void BLI_ghash_flag_set(GHash *gh, uint flag)
{
- gh->flag |= flag;
+ gh->flag |= flag;
}
/**
@@ -1033,7 +1037,7 @@ void BLI_ghash_flag_set(GHash *gh, uint flag)
*/
void BLI_ghash_flag_clear(GHash *gh, uint flag)
{
- gh->flag &= ~flag;
+ gh->flag &= ~flag;
}
/** \} */
@@ -1052,9 +1056,9 @@ void BLI_ghash_flag_clear(GHash *gh, uint flag)
*/
GHashIterator *BLI_ghashIterator_new(GHash *gh)
{
- GHashIterator *ghi = MEM_mallocN(sizeof(*ghi), "ghash iterator");
- BLI_ghashIterator_init(ghi, gh);
- return ghi;
+ GHashIterator *ghi = MEM_mallocN(sizeof(*ghi), "ghash iterator");
+ BLI_ghashIterator_init(ghi, gh);
+ return ghi;
}
/**
@@ -1067,18 +1071,18 @@ GHashIterator *BLI_ghashIterator_new(GHash *gh)
*/
void BLI_ghashIterator_init(GHashIterator *ghi, GHash *gh)
{
- ghi->gh = gh;
- ghi->curEntry = NULL;
- ghi->curBucket = UINT_MAX; /* wraps to zero */
- if (gh->nentries) {
- do {
- ghi->curBucket++;
- if (UNLIKELY(ghi->curBucket == ghi->gh->nbuckets)) {
- break;
- }
- ghi->curEntry = ghi->gh->buckets[ghi->curBucket];
- } while (!ghi->curEntry);
- }
+ ghi->gh = gh;
+ ghi->curEntry = NULL;
+ ghi->curBucket = UINT_MAX; /* wraps to zero */
+ if (gh->nentries) {
+ do {
+ ghi->curBucket++;
+ if (UNLIKELY(ghi->curBucket == ghi->gh->nbuckets)) {
+ break;
+ }
+ ghi->curEntry = ghi->gh->buckets[ghi->curBucket];
+ } while (!ghi->curEntry);
+ }
}
/**
@@ -1088,16 +1092,16 @@ void BLI_ghashIterator_init(GHashIterator *ghi, GHash *gh)
*/
void BLI_ghashIterator_step(GHashIterator *ghi)
{
- if (ghi->curEntry) {
- ghi->curEntry = ghi->curEntry->next;
- while (!ghi->curEntry) {
- ghi->curBucket++;
- if (ghi->curBucket == ghi->gh->nbuckets) {
- break;
- }
- ghi->curEntry = ghi->gh->buckets[ghi->curBucket];
- }
- }
+ if (ghi->curEntry) {
+ ghi->curEntry = ghi->curEntry->next;
+ while (!ghi->curEntry) {
+ ghi->curBucket++;
+ if (ghi->curBucket == ghi->gh->nbuckets) {
+ break;
+ }
+ ghi->curEntry = ghi->gh->buckets[ghi->curBucket];
+ }
+ }
}
/**
@@ -1107,7 +1111,7 @@ void BLI_ghashIterator_step(GHashIterator *ghi)
*/
void BLI_ghashIterator_free(GHashIterator *ghi)
{
- MEM_freeN(ghi);
+ MEM_freeN(ghi);
}
/** \} */
@@ -1117,16 +1121,17 @@ void BLI_ghashIterator_free(GHashIterator *ghi)
*
* Use ghash API to give 'set' functionality
* \{ */
-GSet *BLI_gset_new_ex(
- GSetHashFP hashfp, GSetCmpFP cmpfp, const char *info,
- const uint nentries_reserve)
+GSet *BLI_gset_new_ex(GSetHashFP hashfp,
+ GSetCmpFP cmpfp,
+ const char *info,
+ const uint nentries_reserve)
{
- return (GSet *)ghash_new(hashfp, cmpfp, info, nentries_reserve, GHASH_FLAG_IS_GSET);
+ return (GSet *)ghash_new(hashfp, cmpfp, info, nentries_reserve, GHASH_FLAG_IS_GSET);
}
GSet *BLI_gset_new(GSetHashFP hashfp, GSetCmpFP cmpfp, const char *info)
{
- return BLI_gset_new_ex(hashfp, cmpfp, info, 0);
+ return BLI_gset_new_ex(hashfp, cmpfp, info, 0);
}
/**
@@ -1134,12 +1139,12 @@ GSet *BLI_gset_new(GSetHashFP hashfp, GSetCmpFP cmpfp, const char *info)
*/
GSet *BLI_gset_copy(GSet *gs, GHashKeyCopyFP keycopyfp)
{
- return (GSet *)ghash_copy((GHash *)gs, keycopyfp, NULL);
+ return (GSet *)ghash_copy((GHash *)gs, keycopyfp, NULL);
}
uint BLI_gset_len(GSet *gs)
{
- return ((GHash *)gs)->nentries;
+ return ((GHash *)gs)->nentries;
}
/**
@@ -1148,9 +1153,9 @@ uint BLI_gset_len(GSet *gs)
*/
void BLI_gset_insert(GSet *gs, void *key)
{
- const uint hash = ghash_keyhash((GHash *)gs, key);
- const uint bucket_index = ghash_bucket_index((GHash *)gs, hash);
- ghash_insert_ex_keyonly((GHash *)gs, key, bucket_index);
+ const uint hash = ghash_keyhash((GHash *)gs, key);
+ const uint bucket_index = ghash_bucket_index((GHash *)gs, hash);
+ ghash_insert_ex_keyonly((GHash *)gs, key, bucket_index);
}
/**
@@ -1161,7 +1166,7 @@ void BLI_gset_insert(GSet *gs, void *key)
*/
bool BLI_gset_add(GSet *gs, void *key)
{
- return ghash_insert_safe_keyonly((GHash *)gs, key, false, NULL);
+ return ghash_insert_safe_keyonly((GHash *)gs, key, false, NULL);
}
/**
@@ -1172,20 +1177,20 @@ bool BLI_gset_add(GSet *gs, void *key)
*/
bool BLI_gset_ensure_p_ex(GSet *gs, const void *key, void ***r_key)
{
- const uint hash = ghash_keyhash((GHash *)gs, key);
- const uint bucket_index = ghash_bucket_index((GHash *)gs, hash);
- GSetEntry *e = (GSetEntry *)ghash_lookup_entry_ex((GHash *)gs, key, bucket_index);
- const bool haskey = (e != NULL);
+ const uint hash = ghash_keyhash((GHash *)gs, key);
+ const uint bucket_index = ghash_bucket_index((GHash *)gs, hash);
+ GSetEntry *e = (GSetEntry *)ghash_lookup_entry_ex((GHash *)gs, key, bucket_index);
+ const bool haskey = (e != NULL);
- if (!haskey) {
- /* pass 'key' incase we resize */
- e = BLI_mempool_alloc(((GHash *)gs)->entrypool);
- ghash_insert_ex_keyonly_entry((GHash *)gs, (void *)key, bucket_index, (Entry *)e);
- e->key = NULL; /* caller must re-assign */
- }
+ if (!haskey) {
+ /* pass 'key' incase we resize */
+ e = BLI_mempool_alloc(((GHash *)gs)->entrypool);
+ ghash_insert_ex_keyonly_entry((GHash *)gs, (void *)key, bucket_index, (Entry *)e);
+ e->key = NULL; /* caller must re-assign */
+ }
- *r_key = &e->key;
- return haskey;
+ *r_key = &e->key;
+ return haskey;
}
/**
@@ -1196,7 +1201,7 @@ bool BLI_gset_ensure_p_ex(GSet *gs, const void *key, void ***r_key)
*/
bool BLI_gset_reinsert(GSet *gs, void *key, GSetKeyFreeFP keyfreefp)
{
- return ghash_insert_safe_keyonly((GHash *)gs, key, true, keyfreefp);
+ return ghash_insert_safe_keyonly((GHash *)gs, key, true, keyfreefp);
}
/**
@@ -1207,19 +1212,17 @@ bool BLI_gset_reinsert(GSet *gs, void *key, GSetKeyFreeFP keyfreefp)
*/
void *BLI_gset_replace_key(GSet *gs, void *key)
{
- return BLI_ghash_replace_key((GHash *)gs, key);
+ return BLI_ghash_replace_key((GHash *)gs, key);
}
-
bool BLI_gset_remove(GSet *gs, const void *key, GSetKeyFreeFP keyfreefp)
{
- return BLI_ghash_remove((GHash *)gs, key, keyfreefp, NULL);
+ return BLI_ghash_remove((GHash *)gs, key, keyfreefp, NULL);
}
-
bool BLI_gset_haskey(GSet *gs, const void *key)
{
- return (ghash_lookup_entry((GHash *)gs, key) != NULL);
+ return (ghash_lookup_entry((GHash *)gs, key) != NULL);
}
/**
@@ -1229,51 +1232,45 @@ bool BLI_gset_haskey(GSet *gs, const void *key)
* \param state: Used for efficient removal.
* \return true if there was something to pop, false if gset was already empty.
*/
-bool BLI_gset_pop(
- GSet *gs, GSetIterState *state,
- void **r_key)
+bool BLI_gset_pop(GSet *gs, GSetIterState *state, void **r_key)
{
- GSetEntry *e = (GSetEntry *)ghash_pop((GHash *)gs, (GHashIterState *)state);
+ GSetEntry *e = (GSetEntry *)ghash_pop((GHash *)gs, (GHashIterState *)state);
- if (e) {
- *r_key = e->key;
+ if (e) {
+ *r_key = e->key;
- BLI_mempool_free(((GHash *)gs)->entrypool, e);
- return true;
- }
- else {
- *r_key = NULL;
- return false;
- }
+ BLI_mempool_free(((GHash *)gs)->entrypool, e);
+ return true;
+ }
+ else {
+ *r_key = NULL;
+ return false;
+ }
}
-void BLI_gset_clear_ex(
- GSet *gs, GSetKeyFreeFP keyfreefp,
- const uint nentries_reserve)
+void BLI_gset_clear_ex(GSet *gs, GSetKeyFreeFP keyfreefp, const uint nentries_reserve)
{
- BLI_ghash_clear_ex(
- (GHash *)gs, keyfreefp, NULL,
- nentries_reserve);
+ BLI_ghash_clear_ex((GHash *)gs, keyfreefp, NULL, nentries_reserve);
}
void BLI_gset_clear(GSet *gs, GSetKeyFreeFP keyfreefp)
{
- BLI_ghash_clear((GHash *)gs, keyfreefp, NULL);
+ BLI_ghash_clear((GHash *)gs, keyfreefp, NULL);
}
void BLI_gset_free(GSet *gs, GSetKeyFreeFP keyfreefp)
{
- BLI_ghash_free((GHash *)gs, keyfreefp, NULL);
+ BLI_ghash_free((GHash *)gs, keyfreefp, NULL);
}
void BLI_gset_flag_set(GSet *gs, uint flag)
{
- ((GHash *)gs)->flag |= flag;
+ ((GHash *)gs)->flag |= flag;
}
void BLI_gset_flag_clear(GSet *gs, uint flag)
{
- ((GHash *)gs)->flag &= ~flag;
+ ((GHash *)gs)->flag &= ~flag;
}
/** \} */
@@ -1290,8 +1287,8 @@ void BLI_gset_flag_clear(GSet *gs, uint flag)
*/
void *BLI_gset_lookup(GSet *gs, const void *key)
{
- Entry *e = ghash_lookup_entry((GHash *)gs, key);
- return e ? e->key : NULL;
+ Entry *e = ghash_lookup_entry((GHash *)gs, key);
+ return e ? e->key : NULL;
}
/**
@@ -1300,17 +1297,17 @@ void *BLI_gset_lookup(GSet *gs, const void *key)
*/
void *BLI_gset_pop_key(GSet *gs, const void *key)
{
- const uint hash = ghash_keyhash((GHash *)gs, key);
- const uint bucket_index = ghash_bucket_index((GHash *)gs, hash);
- Entry *e = ghash_remove_ex((GHash *)gs, key, NULL, NULL, bucket_index);
- if (e) {
- void *key_ret = e->key;
- BLI_mempool_free(((GHash *)gs)->entrypool, e);
- return key_ret;
- }
- else {
- return NULL;
- }
+ const uint hash = ghash_keyhash((GHash *)gs, key);
+ const uint bucket_index = ghash_bucket_index((GHash *)gs, hash);
+ Entry *e = ghash_remove_ex((GHash *)gs, key, NULL, NULL, bucket_index);
+ if (e) {
+ void *key_ret = e->key;
+ BLI_mempool_free(((GHash *)gs)->entrypool, e);
+ return key_ret;
+ }
+ else {
+ return NULL;
+ }
}
/** \} */
@@ -1326,11 +1323,11 @@ void *BLI_gset_pop_key(GSet *gs, const void *key)
*/
int BLI_ghash_buckets_len(GHash *gh)
{
- return (int)gh->nbuckets;
+ return (int)gh->nbuckets;
}
int BLI_gset_buckets_len(GSet *gs)
{
- return BLI_ghash_buckets_len((GHash *)gs);
+ return BLI_ghash_buckets_len((GHash *)gs);
}
/**
@@ -1339,106 +1336,115 @@ int BLI_gset_buckets_len(GSet *gs)
*
* Smaller is better!
*/
-double BLI_ghash_calc_quality_ex(
- GHash *gh, double *r_load, double *r_variance,
- double *r_prop_empty_buckets, double *r_prop_overloaded_buckets, int *r_biggest_bucket)
-{
- double mean;
- uint i;
-
- if (gh->nentries == 0) {
- if (r_load) {
- *r_load = 0.0;
- }
- if (r_variance) {
- *r_variance = 0.0;
- }
- if (r_prop_empty_buckets) {
- *r_prop_empty_buckets = 1.0;
- }
- if (r_prop_overloaded_buckets) {
- *r_prop_overloaded_buckets = 0.0;
- }
- if (r_biggest_bucket) {
- *r_biggest_bucket = 0;
- }
-
- return 0.0;
- }
-
- mean = (double)gh->nentries / (double)gh->nbuckets;
- if (r_load) {
- *r_load = mean;
- }
- if (r_biggest_bucket) {
- *r_biggest_bucket = 0;
- }
-
- if (r_variance) {
- /* We already know our mean (i.e. load factor), easy to compute variance.
- * See https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Two-pass_algorithm
- */
- double sum = 0.0;
- for (i = 0; i < gh->nbuckets; i++) {
- int count = 0;
- Entry *e;
- for (e = gh->buckets[i]; e; e = e->next) {
- count++;
- }
- sum += ((double)count - mean) * ((double)count - mean);
- }
- *r_variance = sum / (double)(gh->nbuckets - 1);
- }
-
- {
- uint64_t sum = 0;
- uint64_t overloaded_buckets_threshold = (uint64_t)max_ii(GHASH_LIMIT_GROW(1), 1);
- uint64_t sum_overloaded = 0;
- uint64_t sum_empty = 0;
-
- for (i = 0; i < gh->nbuckets; i++) {
- uint64_t count = 0;
- Entry *e;
- for (e = gh->buckets[i]; e; e = e->next) {
- count++;
- }
- if (r_biggest_bucket) {
- *r_biggest_bucket = max_ii(*r_biggest_bucket, (int)count);
- }
- if (r_prop_overloaded_buckets && (count > overloaded_buckets_threshold)) {
- sum_overloaded++;
- }
- if (r_prop_empty_buckets && !count) {
- sum_empty++;
- }
- sum += count * (count + 1);
- }
- if (r_prop_overloaded_buckets) {
- *r_prop_overloaded_buckets = (double)sum_overloaded / (double)gh->nbuckets;
- }
- if (r_prop_empty_buckets) {
- *r_prop_empty_buckets = (double)sum_empty / (double)gh->nbuckets;
- }
- return ((double)sum * (double)gh->nbuckets /
- ((double)gh->nentries * (gh->nentries + 2 * gh->nbuckets - 1)));
- }
-}
-double BLI_gset_calc_quality_ex(
- GSet *gs, double *r_load, double *r_variance,
- double *r_prop_empty_buckets, double *r_prop_overloaded_buckets, int *r_biggest_bucket)
-{
- return BLI_ghash_calc_quality_ex(
- (GHash *)gs, r_load, r_variance,
- r_prop_empty_buckets, r_prop_overloaded_buckets, r_biggest_bucket);
+double BLI_ghash_calc_quality_ex(GHash *gh,
+ double *r_load,
+ double *r_variance,
+ double *r_prop_empty_buckets,
+ double *r_prop_overloaded_buckets,
+ int *r_biggest_bucket)
+{
+ double mean;
+ uint i;
+
+ if (gh->nentries == 0) {
+ if (r_load) {
+ *r_load = 0.0;
+ }
+ if (r_variance) {
+ *r_variance = 0.0;
+ }
+ if (r_prop_empty_buckets) {
+ *r_prop_empty_buckets = 1.0;
+ }
+ if (r_prop_overloaded_buckets) {
+ *r_prop_overloaded_buckets = 0.0;
+ }
+ if (r_biggest_bucket) {
+ *r_biggest_bucket = 0;
+ }
+
+ return 0.0;
+ }
+
+ mean = (double)gh->nentries / (double)gh->nbuckets;
+ if (r_load) {
+ *r_load = mean;
+ }
+ if (r_biggest_bucket) {
+ *r_biggest_bucket = 0;
+ }
+
+ if (r_variance) {
+ /* We already know our mean (i.e. load factor), easy to compute variance.
+ * See https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Two-pass_algorithm
+ */
+ double sum = 0.0;
+ for (i = 0; i < gh->nbuckets; i++) {
+ int count = 0;
+ Entry *e;
+ for (e = gh->buckets[i]; e; e = e->next) {
+ count++;
+ }
+ sum += ((double)count - mean) * ((double)count - mean);
+ }
+ *r_variance = sum / (double)(gh->nbuckets - 1);
+ }
+
+ {
+ uint64_t sum = 0;
+ uint64_t overloaded_buckets_threshold = (uint64_t)max_ii(GHASH_LIMIT_GROW(1), 1);
+ uint64_t sum_overloaded = 0;
+ uint64_t sum_empty = 0;
+
+ for (i = 0; i < gh->nbuckets; i++) {
+ uint64_t count = 0;
+ Entry *e;
+ for (e = gh->buckets[i]; e; e = e->next) {
+ count++;
+ }
+ if (r_biggest_bucket) {
+ *r_biggest_bucket = max_ii(*r_biggest_bucket, (int)count);
+ }
+ if (r_prop_overloaded_buckets && (count > overloaded_buckets_threshold)) {
+ sum_overloaded++;
+ }
+ if (r_prop_empty_buckets && !count) {
+ sum_empty++;
+ }
+ sum += count * (count + 1);
+ }
+ if (r_prop_overloaded_buckets) {
+ *r_prop_overloaded_buckets = (double)sum_overloaded / (double)gh->nbuckets;
+ }
+ if (r_prop_empty_buckets) {
+ *r_prop_empty_buckets = (double)sum_empty / (double)gh->nbuckets;
+ }
+ return ((double)sum * (double)gh->nbuckets /
+ ((double)gh->nentries * (gh->nentries + 2 * gh->nbuckets - 1)));
+ }
+}
+double BLI_gset_calc_quality_ex(GSet *gs,
+ double *r_load,
+ double *r_variance,
+ double *r_prop_empty_buckets,
+ double *r_prop_overloaded_buckets,
+ int *r_biggest_bucket)
+{
+ return BLI_ghash_calc_quality_ex((GHash *)gs,
+ r_load,
+ r_variance,
+ r_prop_empty_buckets,
+ r_prop_overloaded_buckets,
+ r_biggest_bucket);
}
double BLI_ghash_calc_quality(GHash *gh)
{
- return BLI_ghash_calc_quality_ex(gh, NULL, NULL, NULL, NULL, NULL);
+ return BLI_ghash_calc_quality_ex(gh, NULL, NULL, NULL, NULL, NULL);
}
double BLI_gset_calc_quality(GSet *gs)
{
- return BLI_ghash_calc_quality_ex((GHash *)gs, NULL, NULL, NULL, NULL, NULL);
+ return BLI_ghash_calc_quality_ex((GHash *)gs, NULL, NULL, NULL, NULL, NULL);
}
/** \} */
diff --git a/source/blender/blenlib/intern/BLI_ghash_utils.c b/source/blender/blenlib/intern/BLI_ghash_utils.c
index 5e271c21830..1c6484acbdf 100644
--- a/source/blender/blenlib/intern/BLI_ghash_utils.c
+++ b/source/blender/blenlib/intern/BLI_ghash_utils.c
@@ -30,7 +30,7 @@
#include "BLI_utildefines.h"
#include "BLI_hash_mm2a.h"
-#include "BLI_ghash.h" /* own include */
+#include "BLI_ghash.h" /* own include */
/* keep last */
#include "BLI_strict_flags.h"
@@ -43,94 +43,94 @@
/* works but slower */
uint BLI_ghashutil_ptrhash(const void *key)
{
- return (uint)(intptr_t)key;
+ return (uint)(intptr_t)key;
}
#else
/* Based Python3.7's pointer hashing function. */
uint BLI_ghashutil_ptrhash(const void *key)
{
- size_t y = (size_t)key;
- /* bottom 3 or 4 bits are likely to be 0; rotate y by 4 to avoid
- * excessive hash collisions for dicts and sets */
+ size_t y = (size_t)key;
+ /* bottom 3 or 4 bits are likely to be 0; rotate y by 4 to avoid
+ * excessive hash collisions for dicts and sets */
- /* Note: Unlike Python 'sizeof(uint)' is used instead of 'sizeof(void *)',
- * Otherwise casting to 'uint' ignores the upper bits on 64bit platforms. */
- return (uint)(y >> 4) | ((uint)y << (8 * sizeof(uint) - 4));
+ /* Note: Unlike Python 'sizeof(uint)' is used instead of 'sizeof(void *)',
+ * Otherwise casting to 'uint' ignores the upper bits on 64bit platforms. */
+ return (uint)(y >> 4) | ((uint)y << (8 * sizeof(uint) - 4));
}
#endif
bool BLI_ghashutil_ptrcmp(const void *a, const void *b)
{
- return (a != b);
+ return (a != b);
}
uint BLI_ghashutil_uinthash_v4(const uint key[4])
{
- uint hash;
- hash = key[0];
- hash *= 37;
- hash += key[1];
- hash *= 37;
- hash += key[2];
- hash *= 37;
- hash += key[3];
- return hash;
+ uint hash;
+ hash = key[0];
+ hash *= 37;
+ hash += key[1];
+ hash *= 37;
+ hash += key[2];
+ hash *= 37;
+ hash += key[3];
+ return hash;
}
uint BLI_ghashutil_uinthash_v4_murmur(const uint key[4])
{
- return BLI_hash_mm2((const unsigned char *)key, sizeof(int) * 4 /* sizeof(key) */, 0);
+ return BLI_hash_mm2((const unsigned char *)key, sizeof(int) * 4 /* sizeof(key) */, 0);
}
bool BLI_ghashutil_uinthash_v4_cmp(const void *a, const void *b)
{
- return (memcmp(a, b, sizeof(uint[4])) != 0);
+ return (memcmp(a, b, sizeof(uint[4])) != 0);
}
uint BLI_ghashutil_uinthash(uint key)
{
- key += ~(key << 16);
- key ^= (key >> 5);
- key += (key << 3);
- key ^= (key >> 13);
- key += ~(key << 9);
- key ^= (key >> 17);
+ key += ~(key << 16);
+ key ^= (key >> 5);
+ key += (key << 3);
+ key ^= (key >> 13);
+ key += ~(key << 9);
+ key ^= (key >> 17);
- return key;
+ return key;
}
uint BLI_ghashutil_inthash_p(const void *ptr)
{
- uintptr_t key = (uintptr_t)ptr;
+ uintptr_t key = (uintptr_t)ptr;
- key += ~(key << 16);
- key ^= (key >> 5);
- key += (key << 3);
- key ^= (key >> 13);
- key += ~(key << 9);
- key ^= (key >> 17);
+ key += ~(key << 16);
+ key ^= (key >> 5);
+ key += (key << 3);
+ key ^= (key >> 13);
+ key += ~(key << 9);
+ key ^= (key >> 17);
- return (uint)(key & 0xffffffff);
+ return (uint)(key & 0xffffffff);
}
uint BLI_ghashutil_inthash_p_murmur(const void *ptr)
{
- uintptr_t key = (uintptr_t)ptr;
+ uintptr_t key = (uintptr_t)ptr;
- return BLI_hash_mm2((const unsigned char *)&key, sizeof(key), 0);
+ return BLI_hash_mm2((const unsigned char *)&key, sizeof(key), 0);
}
uint BLI_ghashutil_inthash_p_simple(const void *ptr)
{
- return POINTER_AS_UINT(ptr);
+ return POINTER_AS_UINT(ptr);
}
bool BLI_ghashutil_intcmp(const void *a, const void *b)
{
- return (a != b);
+ return (a != b);
}
size_t BLI_ghashutil_combine_hash(size_t hash_a, size_t hash_b)
{
- return hash_a ^ (hash_b + 0x9e3779b9 + (hash_a << 6) + (hash_a >> 2));
+ return hash_a ^ (hash_b + 0x9e3779b9 + (hash_a << 6) + (hash_a >> 2));
}
/**
@@ -144,64 +144,63 @@ size_t BLI_ghashutil_combine_hash(size_t hash_a, size_t hash_b)
*/
uint BLI_ghashutil_strhash_n(const char *key, size_t n)
{
- const signed char *p;
- uint h = 5381;
+ const signed char *p;
+ uint h = 5381;
- for (p = (const signed char *)key; n-- && *p != '\0'; p++) {
- h = (uint)((h << 5) + h) + (uint)*p;
- }
+ for (p = (const signed char *)key; n-- && *p != '\0'; p++) {
+ h = (uint)((h << 5) + h) + (uint)*p;
+ }
- return h;
+ return h;
}
uint BLI_ghashutil_strhash_p(const void *ptr)
{
- const signed char *p;
- uint h = 5381;
+ const signed char *p;
+ uint h = 5381;
- for (p = ptr; *p != '\0'; p++) {
- h = (uint)((h << 5) + h) + (uint)*p;
- }
+ for (p = ptr; *p != '\0'; p++) {
+ h = (uint)((h << 5) + h) + (uint)*p;
+ }
- return h;
+ return h;
}
uint BLI_ghashutil_strhash_p_murmur(const void *ptr)
{
- const unsigned char *key = ptr;
+ const unsigned char *key = ptr;
- return BLI_hash_mm2(key, strlen((const char *)key) + 1, 0);
+ return BLI_hash_mm2(key, strlen((const char *)key) + 1, 0);
}
bool BLI_ghashutil_strcmp(const void *a, const void *b)
{
- return (a == b) ? false : !STREQ(a, b);
+ return (a == b) ? false : !STREQ(a, b);
}
GHashPair *BLI_ghashutil_pairalloc(const void *first, const void *second)
{
- GHashPair *pair = MEM_mallocN(sizeof(GHashPair), "GHashPair");
- pair->first = first;
- pair->second = second;
- return pair;
+ GHashPair *pair = MEM_mallocN(sizeof(GHashPair), "GHashPair");
+ pair->first = first;
+ pair->second = second;
+ return pair;
}
uint BLI_ghashutil_pairhash(const void *ptr)
{
- const GHashPair *pair = ptr;
- uint hash = BLI_ghashutil_ptrhash(pair->first);
- return hash ^ BLI_ghashutil_ptrhash(pair->second);
+ const GHashPair *pair = ptr;
+ uint hash = BLI_ghashutil_ptrhash(pair->first);
+ return hash ^ BLI_ghashutil_ptrhash(pair->second);
}
bool BLI_ghashutil_paircmp(const void *a, const void *b)
{
- const GHashPair *A = a;
- const GHashPair *B = b;
+ const GHashPair *A = a;
+ const GHashPair *B = b;
- return ((A->first != B->first) ||
- (A->second != B->second));
+ return ((A->first != B->first) || (A->second != B->second));
}
void BLI_ghashutil_pairfree(void *ptr)
{
- MEM_freeN(ptr);
+ MEM_freeN(ptr);
}
/** \} */
@@ -212,38 +211,38 @@ void BLI_ghashutil_pairfree(void *ptr)
GHash *BLI_ghash_ptr_new_ex(const char *info, const uint nentries_reserve)
{
- return BLI_ghash_new_ex(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, info, nentries_reserve);
+ return BLI_ghash_new_ex(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, info, nentries_reserve);
}
GHash *BLI_ghash_ptr_new(const char *info)
{
- return BLI_ghash_ptr_new_ex(info, 0);
+ return BLI_ghash_ptr_new_ex(info, 0);
}
GHash *BLI_ghash_str_new_ex(const char *info, const uint nentries_reserve)
{
- return BLI_ghash_new_ex(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, info, nentries_reserve);
+ return BLI_ghash_new_ex(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, info, nentries_reserve);
}
GHash *BLI_ghash_str_new(const char *info)
{
- return BLI_ghash_str_new_ex(info, 0);
+ return BLI_ghash_str_new_ex(info, 0);
}
GHash *BLI_ghash_int_new_ex(const char *info, const uint nentries_reserve)
{
- return BLI_ghash_new_ex(BLI_ghashutil_inthash_p, BLI_ghashutil_intcmp, info, nentries_reserve);
+ return BLI_ghash_new_ex(BLI_ghashutil_inthash_p, BLI_ghashutil_intcmp, info, nentries_reserve);
}
GHash *BLI_ghash_int_new(const char *info)
{
- return BLI_ghash_int_new_ex(info, 0);
+ return BLI_ghash_int_new_ex(info, 0);
}
GHash *BLI_ghash_pair_new_ex(const char *info, const uint nentries_reserve)
{
- return BLI_ghash_new_ex(BLI_ghashutil_pairhash, BLI_ghashutil_paircmp, info, nentries_reserve);
+ return BLI_ghash_new_ex(BLI_ghashutil_pairhash, BLI_ghashutil_paircmp, info, nentries_reserve);
}
GHash *BLI_ghash_pair_new(const char *info)
{
- return BLI_ghash_pair_new_ex(info, 0);
+ return BLI_ghash_pair_new_ex(info, 0);
}
/** \} */
@@ -254,29 +253,29 @@ GHash *BLI_ghash_pair_new(const char *info)
GSet *BLI_gset_ptr_new_ex(const char *info, const uint nentries_reserve)
{
- return BLI_gset_new_ex(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, info, nentries_reserve);
+ return BLI_gset_new_ex(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, info, nentries_reserve);
}
GSet *BLI_gset_ptr_new(const char *info)
{
- return BLI_gset_ptr_new_ex(info, 0);
+ return BLI_gset_ptr_new_ex(info, 0);
}
GSet *BLI_gset_str_new_ex(const char *info, const uint nentries_reserve)
{
- return BLI_gset_new_ex(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, info, nentries_reserve);
+ return BLI_gset_new_ex(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, info, nentries_reserve);
}
GSet *BLI_gset_str_new(const char *info)
{
- return BLI_gset_str_new_ex(info, 0);
+ return BLI_gset_str_new_ex(info, 0);
}
GSet *BLI_gset_pair_new_ex(const char *info, const uint nentries_reserve)
{
- return BLI_gset_new_ex(BLI_ghashutil_pairhash, BLI_ghashutil_paircmp, info, nentries_reserve);
+ return BLI_gset_new_ex(BLI_ghashutil_pairhash, BLI_ghashutil_paircmp, info, nentries_reserve);
}
GSet *BLI_gset_pair_new(const char *info)
{
- return BLI_gset_pair_new_ex(info, 0);
+ return BLI_gset_pair_new_ex(info, 0);
}
/** \} */
diff --git a/source/blender/blenlib/intern/BLI_heap.c b/source/blender/blenlib/intern/BLI_heap.c
index 0e5cfd02939..836b11baa85 100644
--- a/source/blender/blenlib/intern/BLI_heap.c
+++ b/source/blender/blenlib/intern/BLI_heap.c
@@ -32,16 +32,16 @@
/***/
struct HeapNode {
- float value;
- uint index;
- void *ptr;
+ float value;
+ uint index;
+ void *ptr;
};
struct HeapNode_Chunk {
- struct HeapNode_Chunk *prev;
- uint size;
- uint bufsize;
- struct HeapNode buf[0];
+ struct HeapNode_Chunk *prev;
+ uint size;
+ uint bufsize;
+ struct HeapNode buf[0];
};
/**
@@ -52,143 +52,141 @@ struct HeapNode_Chunk {
* \note keep type in sync with tot_nodes in heap_node_alloc_chunk.
*/
#define HEAP_CHUNK_DEFAULT_NUM \
- ((uint)((MEM_SIZE_OPTIMAL((1 << 16) - sizeof(struct HeapNode_Chunk))) / sizeof(HeapNode)))
+ ((uint)((MEM_SIZE_OPTIMAL((1 << 16) - sizeof(struct HeapNode_Chunk))) / sizeof(HeapNode)))
struct Heap {
- uint size;
- uint bufsize;
- HeapNode **tree;
-
- struct {
- /* Always keep at least one chunk (never NULL) */
- struct HeapNode_Chunk *chunk;
- /* when NULL, allocate a new chunk */
- HeapNode *free;
- } nodes;
+ uint size;
+ uint bufsize;
+ HeapNode **tree;
+
+ struct {
+ /* Always keep at least one chunk (never NULL) */
+ struct HeapNode_Chunk *chunk;
+ /* when NULL, allocate a new chunk */
+ HeapNode *free;
+ } nodes;
};
/** \name Internal Functions
* \{ */
-#define HEAP_PARENT(i) (((i) - 1) >> 1)
-#define HEAP_LEFT(i) (((i) << 1) + 1)
-#define HEAP_RIGHT(i) (((i) << 1) + 2)
+#define HEAP_PARENT(i) (((i)-1) >> 1)
+#define HEAP_LEFT(i) (((i) << 1) + 1)
+#define HEAP_RIGHT(i) (((i) << 1) + 2)
#define HEAP_COMPARE(a, b) ((a)->value < (b)->value)
-#if 0 /* UNUSED */
-#define HEAP_EQUALS(a, b) ((a)->value == (b)->value)
+#if 0 /* UNUSED */
+# define HEAP_EQUALS(a, b) ((a)->value == (b)->value)
#endif
BLI_INLINE void heap_swap(Heap *heap, const uint i, const uint j)
{
#if 1
- HeapNode **tree = heap->tree;
- HeapNode *pi = tree[i], *pj = tree[j];
- pi->index = j;
- tree[j] = pi;
- pj->index = i;
- tree[i] = pj;
+ HeapNode **tree = heap->tree;
+ HeapNode *pi = tree[i], *pj = tree[j];
+ pi->index = j;
+ tree[j] = pi;
+ pj->index = i;
+ tree[i] = pj;
#elif 0
- SWAP(uint, heap->tree[i]->index, heap->tree[j]->index);
- SWAP(HeapNode *, heap->tree[i], heap->tree[j]);
+ SWAP(uint, heap->tree[i]->index, heap->tree[j]->index);
+ SWAP(HeapNode *, heap->tree[i], heap->tree[j]);
#else
- HeapNode **tree = heap->tree;
- union {
- uint index;
- HeapNode *node;
- } tmp;
- SWAP_TVAL(tmp.index, tree[i]->index, tree[j]->index);
- SWAP_TVAL(tmp.node, tree[i], tree[j]);
+ HeapNode **tree = heap->tree;
+ union {
+ uint index;
+ HeapNode *node;
+ } tmp;
+ SWAP_TVAL(tmp.index, tree[i]->index, tree[j]->index);
+ SWAP_TVAL(tmp.node, tree[i], tree[j]);
#endif
}
static void heap_down(Heap *heap, uint i)
{
- /* size won't change in the loop */
- HeapNode **const tree = heap->tree;
- const uint size = heap->size;
-
- while (1) {
- const uint l = HEAP_LEFT(i);
- const uint r = HEAP_RIGHT(i);
- uint smallest = i;
-
- if (LIKELY(l < size) && HEAP_COMPARE(tree[l], tree[smallest])) {
- smallest = l;
- }
- if (LIKELY(r < size) && HEAP_COMPARE(tree[r], tree[smallest])) {
- smallest = r;
- }
-
- if (UNLIKELY(smallest == i)) {
- break;
- }
-
- heap_swap(heap, i, smallest);
- i = smallest;
- }
+ /* size won't change in the loop */
+ HeapNode **const tree = heap->tree;
+ const uint size = heap->size;
+
+ while (1) {
+ const uint l = HEAP_LEFT(i);
+ const uint r = HEAP_RIGHT(i);
+ uint smallest = i;
+
+ if (LIKELY(l < size) && HEAP_COMPARE(tree[l], tree[smallest])) {
+ smallest = l;
+ }
+ if (LIKELY(r < size) && HEAP_COMPARE(tree[r], tree[smallest])) {
+ smallest = r;
+ }
+
+ if (UNLIKELY(smallest == i)) {
+ break;
+ }
+
+ heap_swap(heap, i, smallest);
+ i = smallest;
+ }
}
static void heap_up(Heap *heap, uint i)
{
- HeapNode **const tree = heap->tree;
+ HeapNode **const tree = heap->tree;
- while (LIKELY(i > 0)) {
- const uint p = HEAP_PARENT(i);
+ while (LIKELY(i > 0)) {
+ const uint p = HEAP_PARENT(i);
- if (HEAP_COMPARE(tree[p], tree[i])) {
- break;
- }
- heap_swap(heap, p, i);
- i = p;
- }
+ if (HEAP_COMPARE(tree[p], tree[i])) {
+ break;
+ }
+ heap_swap(heap, p, i);
+ i = p;
+ }
}
/** \} */
-
/** \name Internal Memory Management
* \{ */
-static struct HeapNode_Chunk *heap_node_alloc_chunk(
- uint tot_nodes, struct HeapNode_Chunk *chunk_prev)
+static struct HeapNode_Chunk *heap_node_alloc_chunk(uint tot_nodes,
+ struct HeapNode_Chunk *chunk_prev)
{
- struct HeapNode_Chunk *chunk = MEM_mallocN(
- sizeof(struct HeapNode_Chunk) + (sizeof(HeapNode) * tot_nodes), __func__);
- chunk->prev = chunk_prev;
- chunk->bufsize = tot_nodes;
- chunk->size = 0;
- return chunk;
+ struct HeapNode_Chunk *chunk = MEM_mallocN(
+ sizeof(struct HeapNode_Chunk) + (sizeof(HeapNode) * tot_nodes), __func__);
+ chunk->prev = chunk_prev;
+ chunk->bufsize = tot_nodes;
+ chunk->size = 0;
+ return chunk;
}
static struct HeapNode *heap_node_alloc(Heap *heap)
{
- HeapNode *node;
-
- if (heap->nodes.free) {
- node = heap->nodes.free;
- heap->nodes.free = heap->nodes.free->ptr;
- }
- else {
- struct HeapNode_Chunk *chunk = heap->nodes.chunk;
- if (UNLIKELY(chunk->size == chunk->bufsize)) {
- chunk = heap->nodes.chunk = heap_node_alloc_chunk(HEAP_CHUNK_DEFAULT_NUM, chunk);
- }
- node = &chunk->buf[chunk->size++];
- }
-
- return node;
+ HeapNode *node;
+
+ if (heap->nodes.free) {
+ node = heap->nodes.free;
+ heap->nodes.free = heap->nodes.free->ptr;
+ }
+ else {
+ struct HeapNode_Chunk *chunk = heap->nodes.chunk;
+ if (UNLIKELY(chunk->size == chunk->bufsize)) {
+ chunk = heap->nodes.chunk = heap_node_alloc_chunk(HEAP_CHUNK_DEFAULT_NUM, chunk);
+ }
+ node = &chunk->buf[chunk->size++];
+ }
+
+ return node;
}
static void heap_node_free(Heap *heap, HeapNode *node)
{
- node->ptr = heap->nodes.free;
- heap->nodes.free = node;
+ node->ptr = heap->nodes.free;
+ heap->nodes.free = node;
}
/** \} */
-
/** \name Public Heap API
* \{ */
@@ -199,64 +197,65 @@ static void heap_node_free(Heap *heap, HeapNode *node)
*/
Heap *BLI_heap_new_ex(uint tot_reserve)
{
- Heap *heap = MEM_mallocN(sizeof(Heap), __func__);
- /* ensure we have at least one so we can keep doubling it */
- heap->size = 0;
- heap->bufsize = MAX2(1u, tot_reserve);
- heap->tree = MEM_mallocN(heap->bufsize * sizeof(HeapNode *), "BLIHeapTree");
+ Heap *heap = MEM_mallocN(sizeof(Heap), __func__);
+ /* ensure we have at least one so we can keep doubling it */
+ heap->size = 0;
+ heap->bufsize = MAX2(1u, tot_reserve);
+ heap->tree = MEM_mallocN(heap->bufsize * sizeof(HeapNode *), "BLIHeapTree");
- heap->nodes.chunk = heap_node_alloc_chunk((tot_reserve > 1) ? tot_reserve : HEAP_CHUNK_DEFAULT_NUM, NULL);
- heap->nodes.free = NULL;
+ heap->nodes.chunk = heap_node_alloc_chunk(
+ (tot_reserve > 1) ? tot_reserve : HEAP_CHUNK_DEFAULT_NUM, NULL);
+ heap->nodes.free = NULL;
- return heap;
+ return heap;
}
Heap *BLI_heap_new(void)
{
- return BLI_heap_new_ex(1);
+ return BLI_heap_new_ex(1);
}
void BLI_heap_free(Heap *heap, HeapFreeFP ptrfreefp)
{
- if (ptrfreefp) {
- uint i;
-
- for (i = 0; i < heap->size; i++) {
- ptrfreefp(heap->tree[i]->ptr);
- }
- }
-
- struct HeapNode_Chunk *chunk = heap->nodes.chunk;
- do {
- struct HeapNode_Chunk *chunk_prev;
- chunk_prev = chunk->prev;
- MEM_freeN(chunk);
- chunk = chunk_prev;
- } while (chunk);
-
- MEM_freeN(heap->tree);
- MEM_freeN(heap);
+ if (ptrfreefp) {
+ uint i;
+
+ for (i = 0; i < heap->size; i++) {
+ ptrfreefp(heap->tree[i]->ptr);
+ }
+ }
+
+ struct HeapNode_Chunk *chunk = heap->nodes.chunk;
+ do {
+ struct HeapNode_Chunk *chunk_prev;
+ chunk_prev = chunk->prev;
+ MEM_freeN(chunk);
+ chunk = chunk_prev;
+ } while (chunk);
+
+ MEM_freeN(heap->tree);
+ MEM_freeN(heap);
}
void BLI_heap_clear(Heap *heap, HeapFreeFP ptrfreefp)
{
- if (ptrfreefp) {
- uint i;
-
- for (i = 0; i < heap->size; i++) {
- ptrfreefp(heap->tree[i]->ptr);
- }
- }
- heap->size = 0;
-
- /* Remove all except the last chunk */
- while (heap->nodes.chunk->prev) {
- struct HeapNode_Chunk *chunk_prev = heap->nodes.chunk->prev;
- MEM_freeN(heap->nodes.chunk);
- heap->nodes.chunk = chunk_prev;
- }
- heap->nodes.chunk->size = 0;
- heap->nodes.free = NULL;
+ if (ptrfreefp) {
+ uint i;
+
+ for (i = 0; i < heap->size; i++) {
+ ptrfreefp(heap->tree[i]->ptr);
+ }
+ }
+ heap->size = 0;
+
+ /* Remove all except the last chunk */
+ while (heap->nodes.chunk->prev) {
+ struct HeapNode_Chunk *chunk_prev = heap->nodes.chunk->prev;
+ MEM_freeN(heap->nodes.chunk);
+ heap->nodes.chunk = chunk_prev;
+ }
+ heap->nodes.chunk->size = 0;
+ heap->nodes.free = NULL;
}
/**
@@ -265,26 +264,26 @@ void BLI_heap_clear(Heap *heap, HeapFreeFP ptrfreefp)
*/
HeapNode *BLI_heap_insert(Heap *heap, float value, void *ptr)
{
- HeapNode *node;
+ HeapNode *node;
- if (UNLIKELY(heap->size >= heap->bufsize)) {
- heap->bufsize *= 2;
- heap->tree = MEM_reallocN(heap->tree, heap->bufsize * sizeof(*heap->tree));
- }
+ if (UNLIKELY(heap->size >= heap->bufsize)) {
+ heap->bufsize *= 2;
+ heap->tree = MEM_reallocN(heap->tree, heap->bufsize * sizeof(*heap->tree));
+ }
- node = heap_node_alloc(heap);
+ node = heap_node_alloc(heap);
- node->ptr = ptr;
- node->value = value;
- node->index = heap->size;
+ node->ptr = ptr;
+ node->value = value;
+ node->index = heap->size;
- heap->tree[node->index] = node;
+ heap->tree[node->index] = node;
- heap->size++;
+ heap->size++;
- heap_up(heap, node->index);
+ heap_up(heap, node->index);
- return node;
+ return node;
}
/**
@@ -292,23 +291,22 @@ HeapNode *BLI_heap_insert(Heap *heap, float value, void *ptr)
*/
void BLI_heap_insert_or_update(Heap *heap, HeapNode **node_p, float value, void *ptr)
{
- if (*node_p == NULL) {
- *node_p = BLI_heap_insert(heap, value, ptr);
- }
- else {
- BLI_heap_node_value_update_ptr(heap, *node_p, value, ptr);
- }
+ if (*node_p == NULL) {
+ *node_p = BLI_heap_insert(heap, value, ptr);
+ }
+ else {
+ BLI_heap_node_value_update_ptr(heap, *node_p, value, ptr);
+ }
}
-
bool BLI_heap_is_empty(const Heap *heap)
{
- return (heap->size == 0);
+ return (heap->size == 0);
}
uint BLI_heap_len(const Heap *heap)
{
- return heap->size;
+ return heap->size;
}
/**
@@ -317,7 +315,7 @@ uint BLI_heap_len(const Heap *heap)
*/
HeapNode *BLI_heap_top(const Heap *heap)
{
- return heap->tree[0];
+ return heap->tree[0];
}
/**
@@ -326,9 +324,9 @@ HeapNode *BLI_heap_top(const Heap *heap)
*/
float BLI_heap_top_value(const Heap *heap)
{
- BLI_assert(heap->size != 0);
+ BLI_assert(heap->size != 0);
- return heap->tree[0]->value;
+ return heap->tree[0]->value;
}
/**
@@ -336,33 +334,33 @@ float BLI_heap_top_value(const Heap *heap)
*/
void *BLI_heap_pop_min(Heap *heap)
{
- BLI_assert(heap->size != 0);
+ BLI_assert(heap->size != 0);
- void *ptr = heap->tree[0]->ptr;
+ void *ptr = heap->tree[0]->ptr;
- heap_node_free(heap, heap->tree[0]);
+ heap_node_free(heap, heap->tree[0]);
- if (--heap->size) {
- heap_swap(heap, 0, heap->size);
- heap_down(heap, 0);
- }
+ if (--heap->size) {
+ heap_swap(heap, 0, heap->size);
+ heap_down(heap, 0);
+ }
- return ptr;
+ return ptr;
}
void BLI_heap_remove(Heap *heap, HeapNode *node)
{
- BLI_assert(heap->size != 0);
+ BLI_assert(heap->size != 0);
- uint i = node->index;
+ uint i = node->index;
- while (i > 0) {
- uint p = HEAP_PARENT(i);
- heap_swap(heap, p, i);
- i = p;
- }
+ while (i > 0) {
+ uint p = HEAP_PARENT(i);
+ heap_swap(heap, p, i);
+ i = p;
+ }
- BLI_heap_pop_min(heap);
+ BLI_heap_pop_min(heap);
}
/**
@@ -372,66 +370,66 @@ void BLI_heap_remove(Heap *heap, HeapNode *node)
*/
void BLI_heap_node_value_update(Heap *heap, HeapNode *node, float value)
{
- if (value < node->value) {
- node->value = value;
- heap_up(heap, node->index);
- }
- else if (value > node->value) {
- node->value = value;
- heap_down(heap, node->index);
- }
+ if (value < node->value) {
+ node->value = value;
+ heap_up(heap, node->index);
+ }
+ else if (value > node->value) {
+ node->value = value;
+ heap_down(heap, node->index);
+ }
}
void BLI_heap_node_value_update_ptr(Heap *heap, HeapNode *node, float value, void *ptr)
{
- node->ptr = ptr; /* only difference */
- if (value < node->value) {
- node->value = value;
- heap_up(heap, node->index);
- }
- else if (value > node->value) {
- node->value = value;
- heap_down(heap, node->index);
- }
+ node->ptr = ptr; /* only difference */
+ if (value < node->value) {
+ node->value = value;
+ heap_up(heap, node->index);
+ }
+ else if (value > node->value) {
+ node->value = value;
+ heap_down(heap, node->index);
+ }
}
float BLI_heap_node_value(const HeapNode *node)
{
- return node->value;
+ return node->value;
}
void *BLI_heap_node_ptr(const HeapNode *node)
{
- return node->ptr;
+ return node->ptr;
}
static bool heap_is_minheap(const Heap *heap, uint root)
{
- if (root < heap->size) {
- if (heap->tree[root]->index != root) {
- return false;
- }
- const uint l = HEAP_LEFT(root);
- if (l < heap->size) {
- if (HEAP_COMPARE(heap->tree[l], heap->tree[root]) || !heap_is_minheap(heap, l)) {
- return false;
- }
- }
- const uint r = HEAP_RIGHT(root);
- if (r < heap->size) {
- if (HEAP_COMPARE(heap->tree[r], heap->tree[root]) || !heap_is_minheap(heap, r)) {
- return false;
- }
- }
- }
- return true;
+ if (root < heap->size) {
+ if (heap->tree[root]->index != root) {
+ return false;
+ }
+ const uint l = HEAP_LEFT(root);
+ if (l < heap->size) {
+ if (HEAP_COMPARE(heap->tree[l], heap->tree[root]) || !heap_is_minheap(heap, l)) {
+ return false;
+ }
+ }
+ const uint r = HEAP_RIGHT(root);
+ if (r < heap->size) {
+ if (HEAP_COMPARE(heap->tree[r], heap->tree[root]) || !heap_is_minheap(heap, r)) {
+ return false;
+ }
+ }
+ }
+ return true;
}
/**
* Only for checking internal errors (gtest).
*/
bool BLI_heap_is_valid(const Heap *heap)
{
- return heap_is_minheap(heap, 0);
+ return heap_is_minheap(heap, 0);
}
/** \} */
diff --git a/source/blender/blenlib/intern/BLI_heap_simple.c b/source/blender/blenlib/intern/BLI_heap_simple.c
index 50eb06e5d5d..6b27799b808 100644
--- a/source/blender/blenlib/intern/BLI_heap_simple.c
+++ b/source/blender/blenlib/intern/BLI_heap_simple.c
@@ -33,21 +33,21 @@
#include "BLI_heap_simple.h"
#include "BLI_strict_flags.h"
-#define HEAP_PARENT(i) (((i) - 1) >> 1)
+#define HEAP_PARENT(i) (((i)-1) >> 1)
/* -------------------------------------------------------------------- */
/** \name HeapSimple Internal Structs
* \{ */
typedef struct HeapSimpleNode {
- float value;
- void *ptr;
+ float value;
+ void *ptr;
} HeapSimpleNode;
struct HeapSimple {
- uint size;
- uint bufsize;
- HeapSimpleNode *tree;
+ uint size;
+ uint bufsize;
+ HeapSimpleNode *tree;
};
/** \} */
@@ -59,63 +59,63 @@ struct HeapSimple {
static void heapsimple_down(HeapSimple *heap, uint start_i, const HeapSimpleNode *init)
{
#if 1
- /* The compiler isn't smart enough to realize that all computations
- * using index here can be modified to work with byte offset. */
- uint8_t * const tree_buf = (uint8_t *)heap->tree;
+ /* The compiler isn't smart enough to realize that all computations
+ * using index here can be modified to work with byte offset. */
+ uint8_t *const tree_buf = (uint8_t *)heap->tree;
-#define OFFSET(i) (i * (uint)sizeof(HeapSimpleNode))
-#define NODE(offset) (*(HeapSimpleNode*)(tree_buf + (offset)))
+# define OFFSET(i) (i * (uint)sizeof(HeapSimpleNode))
+# define NODE(offset) (*(HeapSimpleNode *)(tree_buf + (offset)))
#else
- HeapSimpleNode *const tree = heap->tree;
+ HeapSimpleNode *const tree = heap->tree;
-#define OFFSET(i) (i)
-#define NODE(i) tree[i]
+# define OFFSET(i) (i)
+# define NODE(i) tree[i]
#endif
#define HEAP_LEFT_OFFSET(i) (((i) << 1) + OFFSET(1))
- const uint size = OFFSET(heap->size);
+ const uint size = OFFSET(heap->size);
- /* Pull the active node values into locals. This allows spilling
- * the data from registers instead of literally swapping nodes. */
- float active_val = init->value;
- void *active_ptr = init->ptr;
+ /* Pull the active node values into locals. This allows spilling
+ * the data from registers instead of literally swapping nodes. */
+ float active_val = init->value;
+ void *active_ptr = init->ptr;
- /* Prepare the first iteration and spill value. */
- uint i = OFFSET(start_i);
+ /* Prepare the first iteration and spill value. */
+ uint i = OFFSET(start_i);
- NODE(i).value = active_val;
+ NODE(i).value = active_val;
- for (;;) {
- const uint l = HEAP_LEFT_OFFSET(i);
- const uint r = l + OFFSET(1); /* right */
+ for (;;) {
+ const uint l = HEAP_LEFT_OFFSET(i);
+ const uint r = l + OFFSET(1); /* right */
- /* Find the child with the smallest value. */
- uint smallest = i;
+ /* Find the child with the smallest value. */
+ uint smallest = i;
- if (LIKELY(l < size) && NODE(l).value < active_val) {
- smallest = l;
- }
- if (LIKELY(r < size) && NODE(r).value < NODE(smallest).value) {
- smallest = r;
- }
+ if (LIKELY(l < size) && NODE(l).value < active_val) {
+ smallest = l;
+ }
+ if (LIKELY(r < size) && NODE(r).value < NODE(smallest).value) {
+ smallest = r;
+ }
- if (UNLIKELY(smallest == i)) {
- break;
- }
+ if (UNLIKELY(smallest == i)) {
+ break;
+ }
- /* Move the smallest child into the current node.
- * Skip padding: for some reason that makes it faster here. */
- NODE(i).value = NODE(smallest).value;
- NODE(i).ptr = NODE(smallest).ptr;
+ /* Move the smallest child into the current node.
+ * Skip padding: for some reason that makes it faster here. */
+ NODE(i).value = NODE(smallest).value;
+ NODE(i).ptr = NODE(smallest).ptr;
- /* Proceed to next iteration and spill value. */
- i = smallest;
- NODE(i).value = active_val;
- }
+ /* Proceed to next iteration and spill value. */
+ i = smallest;
+ NODE(i).value = active_val;
+ }
- /* Spill the pointer into the final position of the node. */
- NODE(i).ptr = active_ptr;
+ /* Spill the pointer into the final position of the node. */
+ NODE(i).ptr = active_ptr;
#undef NODE
#undef OFFSET
@@ -124,21 +124,21 @@ static void heapsimple_down(HeapSimple *heap, uint start_i, const HeapSimpleNode
static void heapsimple_up(HeapSimple *heap, uint i, float active_val, void *active_ptr)
{
- HeapSimpleNode *const tree = heap->tree;
+ HeapSimpleNode *const tree = heap->tree;
- while (LIKELY(i > 0)) {
- const uint p = HEAP_PARENT(i);
+ while (LIKELY(i > 0)) {
+ const uint p = HEAP_PARENT(i);
- if (active_val >= tree[p].value) {
- break;
- }
+ if (active_val >= tree[p].value) {
+ break;
+ }
- tree[i] = tree[p];
- i = p;
- }
+ tree[i] = tree[p];
+ i = p;
+ }
- tree[i].value = active_val;
- tree[i].ptr = active_ptr;
+ tree[i].value = active_val;
+ tree[i].ptr = active_ptr;
}
/** \} */
@@ -154,40 +154,40 @@ static void heapsimple_up(HeapSimple *heap, uint i, float active_val, void *acti
*/
HeapSimple *BLI_heapsimple_new_ex(uint tot_reserve)
{
- HeapSimple *heap = MEM_mallocN(sizeof(HeapSimple), __func__);
- /* ensure we have at least one so we can keep doubling it */
- heap->size = 0;
- heap->bufsize = MAX2(1u, tot_reserve);
- heap->tree = MEM_mallocN(heap->bufsize * sizeof(HeapSimpleNode), "BLIHeapSimpleTree");
- return heap;
+ HeapSimple *heap = MEM_mallocN(sizeof(HeapSimple), __func__);
+ /* ensure we have at least one so we can keep doubling it */
+ heap->size = 0;
+ heap->bufsize = MAX2(1u, tot_reserve);
+ heap->tree = MEM_mallocN(heap->bufsize * sizeof(HeapSimpleNode), "BLIHeapSimpleTree");
+ return heap;
}
HeapSimple *BLI_heapsimple_new(void)
{
- return BLI_heapsimple_new_ex(1);
+ return BLI_heapsimple_new_ex(1);
}
void BLI_heapsimple_free(HeapSimple *heap, HeapSimpleFreeFP ptrfreefp)
{
- if (ptrfreefp) {
- for (uint i = 0; i < heap->size; i++) {
- ptrfreefp(heap->tree[i].ptr);
- }
- }
-
- MEM_freeN(heap->tree);
- MEM_freeN(heap);
+ if (ptrfreefp) {
+ for (uint i = 0; i < heap->size; i++) {
+ ptrfreefp(heap->tree[i].ptr);
+ }
+ }
+
+ MEM_freeN(heap->tree);
+ MEM_freeN(heap);
}
void BLI_heapsimple_clear(HeapSimple *heap, HeapSimpleFreeFP ptrfreefp)
{
- if (ptrfreefp) {
- for (uint i = 0; i < heap->size; i++) {
- ptrfreefp(heap->tree[i].ptr);
- }
- }
+ if (ptrfreefp) {
+ for (uint i = 0; i < heap->size; i++) {
+ ptrfreefp(heap->tree[i].ptr);
+ }
+ }
- heap->size = 0;
+ heap->size = 0;
}
/**
@@ -196,22 +196,22 @@ void BLI_heapsimple_clear(HeapSimple *heap, HeapSimpleFreeFP ptrfreefp)
*/
void BLI_heapsimple_insert(HeapSimple *heap, float value, void *ptr)
{
- if (UNLIKELY(heap->size >= heap->bufsize)) {
- heap->bufsize *= 2;
- heap->tree = MEM_reallocN(heap->tree, heap->bufsize * sizeof(*heap->tree));
- }
+ if (UNLIKELY(heap->size >= heap->bufsize)) {
+ heap->bufsize *= 2;
+ heap->tree = MEM_reallocN(heap->tree, heap->bufsize * sizeof(*heap->tree));
+ }
- heapsimple_up(heap, heap->size++, value, ptr);
+ heapsimple_up(heap, heap->size++, value, ptr);
}
bool BLI_heapsimple_is_empty(const HeapSimple *heap)
{
- return (heap->size == 0);
+ return (heap->size == 0);
}
uint BLI_heapsimple_len(const HeapSimple *heap)
{
- return heap->size;
+ return heap->size;
}
/**
@@ -219,9 +219,9 @@ uint BLI_heapsimple_len(const HeapSimple *heap)
*/
float BLI_heapsimple_top_value(const HeapSimple *heap)
{
- BLI_assert(heap->size != 0);
+ BLI_assert(heap->size != 0);
- return heap->tree[0].value;
+ return heap->tree[0].value;
}
/**
@@ -229,15 +229,15 @@ float BLI_heapsimple_top_value(const HeapSimple *heap)
*/
void *BLI_heapsimple_pop_min(HeapSimple *heap)
{
- BLI_assert(heap->size != 0);
+ BLI_assert(heap->size != 0);
- void *ptr = heap->tree[0].ptr;
+ void *ptr = heap->tree[0].ptr;
- if (--heap->size) {
- heapsimple_down(heap, 0, &heap->tree[heap->size]);
- }
+ if (--heap->size) {
+ heapsimple_down(heap, 0, &heap->tree[heap->size]);
+ }
- return ptr;
+ return ptr;
}
/** \} */
diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c
index 7887c55a907..22e64d6717b 100644
--- a/source/blender/blenlib/intern/BLI_kdopbvh.c
+++ b/source/blender/blenlib/intern/BLI_kdopbvh.c
@@ -61,7 +61,6 @@
/* Check tree is valid. */
// #define USE_VERIFY_TREE
-
#define MAX_TREETYPE 32
/* Setting zero so we can catch bugs in BLI_task/KDOPBVH.
@@ -73,7 +72,6 @@
# define KDOPBVH_THREAD_LEAF_THRESHOLD 1024
#endif
-
/* -------------------------------------------------------------------- */
/** \name Struct Definitions
* \{ */
@@ -81,99 +79,97 @@
typedef unsigned char axis_t;
typedef struct BVHNode {
- struct BVHNode **children;
- struct BVHNode *parent; /* some user defined traversed need that */
+ struct BVHNode **children;
+ struct BVHNode *parent; /* some user defined traversed need that */
#ifdef USE_SKIP_LINKS
- struct BVHNode *skip[2];
+ struct BVHNode *skip[2];
#endif
- float *bv; /* Bounding volume of all nodes, max 13 axis */
- int index; /* face, edge, vertex index */
- char totnode; /* how many nodes are used, used for speedup */
- char main_axis; /* Axis used to split this node */
+ float *bv; /* Bounding volume of all nodes, max 13 axis */
+ int index; /* face, edge, vertex index */
+ char totnode; /* how many nodes are used, used for speedup */
+ char main_axis; /* Axis used to split this node */
} BVHNode;
/* keep under 26 bytes for speed purposes */
struct BVHTree {
- BVHNode **nodes;
- BVHNode *nodearray; /* pre-alloc branch nodes */
- BVHNode **nodechild; /* pre-alloc childs for nodes */
- float *nodebv; /* pre-alloc bounding-volumes for nodes */
- float epsilon; /* epslion is used for inflation of the k-dop */
- int totleaf; /* leafs */
- int totbranch;
- axis_t start_axis, stop_axis; /* bvhtree_kdop_axes array indices according to axis */
- axis_t axis; /* kdop type (6 => OBB, 7 => AABB, ...) */
- char tree_type; /* type of tree (4 => quadtree) */
+ BVHNode **nodes;
+ BVHNode *nodearray; /* pre-alloc branch nodes */
+ BVHNode **nodechild; /* pre-alloc childs for nodes */
+ float *nodebv; /* pre-alloc bounding-volumes for nodes */
+ float epsilon; /* epslion is used for inflation of the k-dop */
+ int totleaf; /* leafs */
+ int totbranch;
+ axis_t start_axis, stop_axis; /* bvhtree_kdop_axes array indices according to axis */
+ axis_t axis; /* kdop type (6 => OBB, 7 => AABB, ...) */
+ char tree_type; /* type of tree (4 => quadtree) */
};
/* optimization, ensure we stay small */
BLI_STATIC_ASSERT((sizeof(void *) == 8 && sizeof(BVHTree) <= 48) ||
- (sizeof(void *) == 4 && sizeof(BVHTree) <= 32),
+ (sizeof(void *) == 4 && sizeof(BVHTree) <= 32),
"over sized")
/* avoid duplicating vars in BVHOverlapData_Thread */
typedef struct BVHOverlapData_Shared {
- const BVHTree *tree1, *tree2;
- axis_t start_axis, stop_axis;
+ const BVHTree *tree1, *tree2;
+ axis_t start_axis, stop_axis;
- /* use for callbacks */
- BVHTree_OverlapCallback callback;
- void *userdata;
+ /* use for callbacks */
+ BVHTree_OverlapCallback callback;
+ void *userdata;
} BVHOverlapData_Shared;
typedef struct BVHOverlapData_Thread {
- BVHOverlapData_Shared *shared;
- struct BLI_Stack *overlap; /* store BVHTreeOverlap */
- /* use for callbacks */
- int thread;
+ BVHOverlapData_Shared *shared;
+ struct BLI_Stack *overlap; /* store BVHTreeOverlap */
+ /* use for callbacks */
+ int thread;
} BVHOverlapData_Thread;
typedef struct BVHNearestData {
- const BVHTree *tree;
- const float *co;
- BVHTree_NearestPointCallback callback;
- void *userdata;
- float proj[13]; /* coordinates projection over axis */
- BVHTreeNearest nearest;
+ const BVHTree *tree;
+ const float *co;
+ BVHTree_NearestPointCallback callback;
+ void *userdata;
+ float proj[13]; /* coordinates projection over axis */
+ BVHTreeNearest nearest;
} BVHNearestData;
typedef struct BVHRayCastData {
- const BVHTree *tree;
+ const BVHTree *tree;
- BVHTree_RayCastCallback callback;
- void *userdata;
+ BVHTree_RayCastCallback callback;
+ void *userdata;
-
- BVHTreeRay ray;
+ BVHTreeRay ray;
#ifdef USE_KDOPBVH_WATERTIGHT
- struct IsectRayPrecalc isect_precalc;
+ struct IsectRayPrecalc isect_precalc;
#endif
- /* initialized by bvhtree_ray_cast_data_precalc */
- float ray_dot_axis[13];
- float idot_axis[13];
- int index[6];
+ /* initialized by bvhtree_ray_cast_data_precalc */
+ float ray_dot_axis[13];
+ float idot_axis[13];
+ int index[6];
- BVHTreeRayHit hit;
+ BVHTreeRayHit hit;
} BVHRayCastData;
typedef struct BVHNearestProjectedData {
- const BVHTree *tree;
- struct DistProjectedAABBPrecalc precalc;
- bool closest_axis[3];
- float clip_plane[6][4];
- int clip_plane_len;
- BVHTree_NearestProjectedCallback callback;
- void *userdata;
- BVHTreeNearest nearest;
+ const BVHTree *tree;
+ struct DistProjectedAABBPrecalc precalc;
+ bool closest_axis[3];
+ float clip_plane[6][4];
+ int clip_plane_len;
+ BVHTree_NearestProjectedCallback callback;
+ void *userdata;
+ BVHTreeNearest nearest;
} BVHNearestProjectedData;
/** \} */
-
/**
* Bounding Volume Hierarchy Definition
*
@@ -183,24 +179,33 @@ typedef struct BVHNearestProjectedData {
*/
const float bvhtree_kdop_axes[13][3] = {
- {1.0, 0, 0}, {0, 1.0, 0}, {0, 0, 1.0},
- {1.0, 1.0, 1.0}, {1.0, -1.0, 1.0}, {1.0, 1.0, -1.0}, {1.0, -1.0, -1.0},
- {1.0, 1.0, 0}, {1.0, 0, 1.0}, {0, 1.0, 1.0}, {1.0, -1.0, 0}, {1.0, 0, -1.0}, {0, 1.0, -1.0},
+ {1.0, 0, 0},
+ {0, 1.0, 0},
+ {0, 0, 1.0},
+ {1.0, 1.0, 1.0},
+ {1.0, -1.0, 1.0},
+ {1.0, 1.0, -1.0},
+ {1.0, -1.0, -1.0},
+ {1.0, 1.0, 0},
+ {1.0, 0, 1.0},
+ {0, 1.0, 1.0},
+ {1.0, -1.0, 0},
+ {1.0, 0, -1.0},
+ {0, 1.0, -1.0},
};
-
/* -------------------------------------------------------------------- */
/** \name Utility Functions
* \{ */
MINLINE axis_t min_axis(axis_t a, axis_t b)
{
- return (a < b) ? a : b;
+ return (a < b) ? a : b;
}
#if 0
MINLINE axis_t max_axis(axis_t a, axis_t b)
{
- return (b < a) ? a : b;
+ return (b < a) ? a : b;
}
#endif
@@ -211,22 +216,19 @@ MINLINE axis_t max_axis(axis_t a, axis_t b)
* and he derived it from the SUN STL
*/
-
-
static void node_minmax_init(const BVHTree *tree, BVHNode *node)
{
- axis_t axis_iter;
- float (*bv)[2] = (float (*)[2])node->bv;
+ axis_t axis_iter;
+ float(*bv)[2] = (float(*)[2])node->bv;
- for (axis_iter = tree->start_axis; axis_iter != tree->stop_axis; axis_iter++) {
- bv[axis_iter][0] = FLT_MAX;
- bv[axis_iter][1] = -FLT_MAX;
- }
+ for (axis_iter = tree->start_axis; axis_iter != tree->stop_axis; axis_iter++) {
+ bv[axis_iter][0] = FLT_MAX;
+ bv[axis_iter][1] = -FLT_MAX;
+ }
}
/** \} */
-
/* -------------------------------------------------------------------- */
/** \name Balance Utility Functions
* \{ */
@@ -236,67 +238,67 @@ static void node_minmax_init(const BVHTree *tree, BVHNode *node)
*/
static void bvh_insertionsort(BVHNode **a, int lo, int hi, int axis)
{
- int i, j;
- BVHNode *t;
- for (i = lo; i < hi; i++) {
- j = i;
- t = a[i];
- while ((j != lo) && (t->bv[axis] < (a[j - 1])->bv[axis])) {
- a[j] = a[j - 1];
- j--;
- }
- a[j] = t;
- }
+ int i, j;
+ BVHNode *t;
+ for (i = lo; i < hi; i++) {
+ j = i;
+ t = a[i];
+ while ((j != lo) && (t->bv[axis] < (a[j - 1])->bv[axis])) {
+ a[j] = a[j - 1];
+ j--;
+ }
+ a[j] = t;
+ }
}
static int bvh_partition(BVHNode **a, int lo, int hi, BVHNode *x, int axis)
{
- int i = lo, j = hi;
- while (1) {
- while (a[i]->bv[axis] < x->bv[axis]) {
- i++;
- }
- j--;
- while (x->bv[axis] < a[j]->bv[axis]) {
- j--;
- }
- if (!(i < j)) {
- return i;
- }
- SWAP(BVHNode *, a[i], a[j]);
- i++;
- }
+ int i = lo, j = hi;
+ while (1) {
+ while (a[i]->bv[axis] < x->bv[axis]) {
+ i++;
+ }
+ j--;
+ while (x->bv[axis] < a[j]->bv[axis]) {
+ j--;
+ }
+ if (!(i < j)) {
+ return i;
+ }
+ SWAP(BVHNode *, a[i], a[j]);
+ i++;
+ }
}
/* returns Sortable */
static BVHNode *bvh_medianof3(BVHNode **a, int lo, int mid, int hi, int axis)
{
- if ((a[mid])->bv[axis] < (a[lo])->bv[axis]) {
- if ((a[hi])->bv[axis] < (a[mid])->bv[axis]) {
- return a[mid];
- }
- else {
- if ((a[hi])->bv[axis] < (a[lo])->bv[axis]) {
- return a[hi];
- }
- else {
- return a[lo];
- }
- }
- }
- else {
- if ((a[hi])->bv[axis] < (a[mid])->bv[axis]) {
- if ((a[hi])->bv[axis] < (a[lo])->bv[axis]) {
- return a[lo];
- }
- else {
- return a[hi];
- }
- }
- else {
- return a[mid];
- }
- }
+ if ((a[mid])->bv[axis] < (a[lo])->bv[axis]) {
+ if ((a[hi])->bv[axis] < (a[mid])->bv[axis]) {
+ return a[mid];
+ }
+ else {
+ if ((a[hi])->bv[axis] < (a[lo])->bv[axis]) {
+ return a[hi];
+ }
+ else {
+ return a[lo];
+ }
+ }
+ }
+ else {
+ if ((a[hi])->bv[axis] < (a[mid])->bv[axis]) {
+ if ((a[hi])->bv[axis] < (a[lo])->bv[axis]) {
+ return a[lo];
+ }
+ else {
+ return a[hi];
+ }
+ }
+ else {
+ return a[mid];
+ }
+ }
}
/**
@@ -305,66 +307,68 @@ static BVHNode *bvh_medianof3(BVHNode **a, int lo, int mid, int hi, int axis)
* - every node to the right of a[n] are greater or equal to it */
static void partition_nth_element(BVHNode **a, int begin, int end, const int n, const int axis)
{
- while (end - begin > 3) {
- const int cut = bvh_partition(a, begin, end, bvh_medianof3(a, begin, (begin + end) / 2, end - 1, axis), axis);
- if (cut <= n) {
- begin = cut;
- }
- else {
- end = cut;
- }
- }
- bvh_insertionsort(a, begin, end, axis);
+ while (end - begin > 3) {
+ const int cut = bvh_partition(
+ a, begin, end, bvh_medianof3(a, begin, (begin + end) / 2, end - 1, axis), axis);
+ if (cut <= n) {
+ begin = cut;
+ }
+ else {
+ end = cut;
+ }
+ }
+ bvh_insertionsort(a, begin, end, axis);
}
#ifdef USE_SKIP_LINKS
static void build_skip_links(BVHTree *tree, BVHNode *node, BVHNode *left, BVHNode *right)
{
- int i;
+ int i;
- node->skip[0] = left;
- node->skip[1] = right;
+ node->skip[0] = left;
+ node->skip[1] = right;
- for (i = 0; i < node->totnode; i++) {
- if (i + 1 < node->totnode) {
- build_skip_links(tree, node->children[i], left, node->children[i + 1]);
- }
- else {
- build_skip_links(tree, node->children[i], left, right);
- }
+ for (i = 0; i < node->totnode; i++) {
+ if (i + 1 < node->totnode) {
+ build_skip_links(tree, node->children[i], left, node->children[i + 1]);
+ }
+ else {
+ build_skip_links(tree, node->children[i], left, right);
+ }
- left = node->children[i];
- }
+ left = node->children[i];
+ }
}
#endif
/*
* BVHTree bounding volumes functions
*/
-static void create_kdop_hull(const BVHTree *tree, BVHNode *node, const float *co, int numpoints, int moving)
+static void create_kdop_hull(
+ const BVHTree *tree, BVHNode *node, const float *co, int numpoints, int moving)
{
- float newminmax;
- float *bv = node->bv;
- int k;
- axis_t axis_iter;
-
- /* don't init boudings for the moving case */
- if (!moving) {
- node_minmax_init(tree, node);
- }
-
- for (k = 0; k < numpoints; k++) {
- /* for all Axes. */
- for (axis_iter = tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) {
- newminmax = dot_v3v3(&co[k * 3], bvhtree_kdop_axes[axis_iter]);
- if (newminmax < bv[2 * axis_iter]) {
- bv[2 * axis_iter] = newminmax;
- }
- if (newminmax > bv[(2 * axis_iter) + 1]) {
- bv[(2 * axis_iter) + 1] = newminmax;
- }
- }
- }
+ float newminmax;
+ float *bv = node->bv;
+ int k;
+ axis_t axis_iter;
+
+ /* don't init boudings for the moving case */
+ if (!moving) {
+ node_minmax_init(tree, node);
+ }
+
+ for (k = 0; k < numpoints; k++) {
+ /* for all Axes. */
+ for (axis_iter = tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) {
+ newminmax = dot_v3v3(&co[k * 3], bvhtree_kdop_axes[axis_iter]);
+ if (newminmax < bv[2 * axis_iter]) {
+ bv[2 * axis_iter] = newminmax;
+ }
+ if (newminmax > bv[(2 * axis_iter) + 1]) {
+ bv[(2 * axis_iter) + 1] = newminmax;
+ }
+ }
+ }
}
/**
@@ -372,30 +376,29 @@ static void create_kdop_hull(const BVHTree *tree, BVHNode *node, const float *co
*/
static void refit_kdop_hull(const BVHTree *tree, BVHNode *node, int start, int end)
{
- float newmin, newmax;
- float *__restrict bv = node->bv;
- int j;
- axis_t axis_iter;
-
- node_minmax_init(tree, node);
-
- for (j = start; j < end; j++) {
- float *__restrict node_bv = tree->nodes[j]->bv;
-
- /* for all Axes. */
- for (axis_iter = tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) {
- newmin = node_bv[(2 * axis_iter)];
- if ((newmin < bv[(2 * axis_iter)])) {
- bv[(2 * axis_iter)] = newmin;
- }
-
- newmax = node_bv[(2 * axis_iter) + 1];
- if ((newmax > bv[(2 * axis_iter) + 1])) {
- bv[(2 * axis_iter) + 1] = newmax;
- }
- }
- }
-
+ float newmin, newmax;
+ float *__restrict bv = node->bv;
+ int j;
+ axis_t axis_iter;
+
+ node_minmax_init(tree, node);
+
+ for (j = start; j < end; j++) {
+ float *__restrict node_bv = tree->nodes[j]->bv;
+
+ /* for all Axes. */
+ for (axis_iter = tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) {
+ newmin = node_bv[(2 * axis_iter)];
+ if ((newmin < bv[(2 * axis_iter)])) {
+ bv[(2 * axis_iter)] = newmin;
+ }
+
+ newmax = node_bv[(2 * axis_iter) + 1];
+ if ((newmax > bv[(2 * axis_iter) + 1])) {
+ bv[(2 * axis_iter) + 1] = newmax;
+ }
+ }
+ }
}
/**
@@ -403,27 +406,27 @@ static void refit_kdop_hull(const BVHTree *tree, BVHNode *node, int start, int e
* but we should use a plain and simple function here for speed sake */
static char get_largest_axis(const float *bv)
{
- float middle_point[3];
-
- middle_point[0] = (bv[1]) - (bv[0]); /* x axis */
- middle_point[1] = (bv[3]) - (bv[2]); /* y axis */
- middle_point[2] = (bv[5]) - (bv[4]); /* z axis */
- if (middle_point[0] > middle_point[1]) {
- if (middle_point[0] > middle_point[2]) {
- return 1; /* max x axis */
- }
- else {
- return 5; /* max z axis */
- }
- }
- else {
- if (middle_point[1] > middle_point[2]) {
- return 3; /* max y axis */
- }
- else {
- return 5; /* max z axis */
- }
- }
+ float middle_point[3];
+
+ middle_point[0] = (bv[1]) - (bv[0]); /* x axis */
+ middle_point[1] = (bv[3]) - (bv[2]); /* y axis */
+ middle_point[2] = (bv[5]) - (bv[4]); /* z axis */
+ if (middle_point[0] > middle_point[1]) {
+ if (middle_point[0] > middle_point[2]) {
+ return 1; /* max x axis */
+ }
+ else {
+ return 5; /* max z axis */
+ }
+ }
+ else {
+ if (middle_point[1] > middle_point[2]) {
+ return 3; /* max y axis */
+ }
+ else {
+ return 5; /* max z axis */
+ }
+ }
}
/**
@@ -431,29 +434,29 @@ static char get_largest_axis(const float *bv)
* join the children on the parent BV */
static void node_join(BVHTree *tree, BVHNode *node)
{
- int i;
- axis_t axis_iter;
-
- node_minmax_init(tree, node);
-
- for (i = 0; i < tree->tree_type; i++) {
- if (node->children[i]) {
- for (axis_iter = tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) {
- /* update minimum */
- if (node->children[i]->bv[(2 * axis_iter)] < node->bv[(2 * axis_iter)]) {
- node->bv[(2 * axis_iter)] = node->children[i]->bv[(2 * axis_iter)];
- }
-
- /* update maximum */
- if (node->children[i]->bv[(2 * axis_iter) + 1] > node->bv[(2 * axis_iter) + 1]) {
- node->bv[(2 * axis_iter) + 1] = node->children[i]->bv[(2 * axis_iter) + 1];
- }
- }
- }
- else {
- break;
- }
- }
+ int i;
+ axis_t axis_iter;
+
+ node_minmax_init(tree, node);
+
+ for (i = 0; i < tree->tree_type; i++) {
+ if (node->children[i]) {
+ for (axis_iter = tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) {
+ /* update minimum */
+ if (node->children[i]->bv[(2 * axis_iter)] < node->bv[(2 * axis_iter)]) {
+ node->bv[(2 * axis_iter)] = node->children[i]->bv[(2 * axis_iter)];
+ }
+
+ /* update maximum */
+ if (node->children[i]->bv[(2 * axis_iter) + 1] > node->bv[(2 * axis_iter) + 1]) {
+ node->bv[(2 * axis_iter) + 1] = node->children[i]->bv[(2 * axis_iter) + 1];
+ }
+ }
+ }
+ else {
+ break;
+ }
+ }
}
#ifdef USE_PRINT_TREE
@@ -464,156 +467,156 @@ static void node_join(BVHTree *tree, BVHNode *node)
static void bvhtree_print_tree(BVHTree *tree, BVHNode *node, int depth)
{
- int i;
- axis_t axis_iter;
-
- for (i = 0; i < depth; i++) {
- printf(" ");
- }
- printf(" - %d (%ld): ", node->index, (long int)(node - tree->nodearray));
- for (axis_iter = (axis_t)(2 * tree->start_axis);
- axis_iter < (axis_t)(2 * tree->stop_axis);
- axis_iter++)
- {
- printf("%.3f ", node->bv[axis_iter]);
- }
- printf("\n");
-
- for (i = 0; i < tree->tree_type; i++) {
- if (node->children[i]) {
- bvhtree_print_tree(tree, node->children[i], depth + 1);
- }
- }
+ int i;
+ axis_t axis_iter;
+
+ for (i = 0; i < depth; i++) {
+ printf(" ");
+ }
+ printf(" - %d (%ld): ", node->index, (long int)(node - tree->nodearray));
+ for (axis_iter = (axis_t)(2 * tree->start_axis); axis_iter < (axis_t)(2 * tree->stop_axis);
+ axis_iter++) {
+ printf("%.3f ", node->bv[axis_iter]);
+ }
+ printf("\n");
+
+ for (i = 0; i < tree->tree_type; i++) {
+ if (node->children[i]) {
+ bvhtree_print_tree(tree, node->children[i], depth + 1);
+ }
+ }
}
static void bvhtree_info(BVHTree *tree)
{
- printf("BVHTree Info: tree_type = %d, axis = %d, epsilon = %f\n",
- tree->tree_type, tree->axis, tree->epsilon);
- printf("nodes = %d, branches = %d, leafs = %d\n",
- tree->totbranch + tree->totleaf, tree->totbranch, tree->totleaf);
- printf("Memory per node = %ubytes\n",
- (uint)(sizeof(BVHNode) + sizeof(BVHNode *) * tree->tree_type + sizeof(float) * tree->axis));
- printf("BV memory = %ubytes\n",
- (uint)MEM_allocN_len(tree->nodebv));
-
- printf("Total memory = %ubytes\n",
- (uint)(sizeof(BVHTree) +
- MEM_allocN_len(tree->nodes) +
- MEM_allocN_len(tree->nodearray) +
- MEM_allocN_len(tree->nodechild) +
- MEM_allocN_len(tree->nodebv)));
-
- bvhtree_print_tree(tree, tree->nodes[tree->totleaf], 0);
+ printf("BVHTree Info: tree_type = %d, axis = %d, epsilon = %f\n",
+ tree->tree_type,
+ tree->axis,
+ tree->epsilon);
+ printf("nodes = %d, branches = %d, leafs = %d\n",
+ tree->totbranch + tree->totleaf,
+ tree->totbranch,
+ tree->totleaf);
+ printf(
+ "Memory per node = %ubytes\n",
+ (uint)(sizeof(BVHNode) + sizeof(BVHNode *) * tree->tree_type + sizeof(float) * tree->axis));
+ printf("BV memory = %ubytes\n", (uint)MEM_allocN_len(tree->nodebv));
+
+ printf("Total memory = %ubytes\n",
+ (uint)(sizeof(BVHTree) + MEM_allocN_len(tree->nodes) + MEM_allocN_len(tree->nodearray) +
+ MEM_allocN_len(tree->nodechild) + MEM_allocN_len(tree->nodebv)));
+
+ bvhtree_print_tree(tree, tree->nodes[tree->totleaf], 0);
}
-#endif /* USE_PRINT_TREE */
+#endif /* USE_PRINT_TREE */
#ifdef USE_VERIFY_TREE
static void bvhtree_verify(BVHTree *tree)
{
- int i, j, check = 0;
-
- /* check the pointer list */
- for (i = 0; i < tree->totleaf; i++) {
- if (tree->nodes[i]->parent == NULL) {
- printf("Leaf has no parent: %d\n", i);
- }
- else {
- for (j = 0; j < tree->tree_type; j++) {
- if (tree->nodes[i]->parent->children[j] == tree->nodes[i]) {
- check = 1;
- }
- }
- if (!check) {
- printf("Parent child relationship doesn't match: %d\n", i);
- }
- check = 0;
- }
- }
-
- /* check the leaf list */
- for (i = 0; i < tree->totleaf; i++) {
- if (tree->nodearray[i].parent == NULL) {
- printf("Leaf has no parent: %d\n", i);
- }
- else {
- for (j = 0; j < tree->tree_type; j++) {
- if (tree->nodearray[i].parent->children[j] == &tree->nodearray[i]) {
- check = 1;
- }
- }
- if (!check) {
- printf("Parent child relationship doesn't match: %d\n", i);
- }
- check = 0;
- }
- }
-
- printf("branches: %d, leafs: %d, total: %d\n",
- tree->totbranch, tree->totleaf, tree->totbranch + tree->totleaf);
+ int i, j, check = 0;
+
+ /* check the pointer list */
+ for (i = 0; i < tree->totleaf; i++) {
+ if (tree->nodes[i]->parent == NULL) {
+ printf("Leaf has no parent: %d\n", i);
+ }
+ else {
+ for (j = 0; j < tree->tree_type; j++) {
+ if (tree->nodes[i]->parent->children[j] == tree->nodes[i]) {
+ check = 1;
+ }
+ }
+ if (!check) {
+ printf("Parent child relationship doesn't match: %d\n", i);
+ }
+ check = 0;
+ }
+ }
+
+ /* check the leaf list */
+ for (i = 0; i < tree->totleaf; i++) {
+ if (tree->nodearray[i].parent == NULL) {
+ printf("Leaf has no parent: %d\n", i);
+ }
+ else {
+ for (j = 0; j < tree->tree_type; j++) {
+ if (tree->nodearray[i].parent->children[j] == &tree->nodearray[i]) {
+ check = 1;
+ }
+ }
+ if (!check) {
+ printf("Parent child relationship doesn't match: %d\n", i);
+ }
+ check = 0;
+ }
+ }
+
+ printf("branches: %d, leafs: %d, total: %d\n",
+ tree->totbranch,
+ tree->totleaf,
+ tree->totbranch + tree->totleaf);
}
-#endif /* USE_VERIFY_TREE */
+#endif /* USE_VERIFY_TREE */
/* Helper data and structures to build a min-leaf generalized implicit tree
* This code can be easily reduced
* (basicly this is only method to calculate pow(k, n) in O(1).. and stuff like that) */
typedef struct BVHBuildHelper {
- int tree_type;
- int totleafs;
+ int tree_type;
+ int totleafs;
- /** Min number of leafs that are archievable from a node at depth N */
- int leafs_per_child[32];
- /** Number of nodes at depth N (tree_type^N) */
- int branches_on_level[32];
+ /** Min number of leafs that are archievable from a node at depth N */
+ int leafs_per_child[32];
+ /** Number of nodes at depth N (tree_type^N) */
+ int branches_on_level[32];
- /** Number of leafs that are placed on the level that is not 100% filled */
- int remain_leafs;
+ /** Number of leafs that are placed on the level that is not 100% filled */
+ int remain_leafs;
} BVHBuildHelper;
static void build_implicit_tree_helper(const BVHTree *tree, BVHBuildHelper *data)
{
- int depth = 0;
- int remain;
- int nnodes;
-
- data->totleafs = tree->totleaf;
- data->tree_type = tree->tree_type;
-
- /* Calculate the smallest tree_type^n such that tree_type^n >= num_leafs */
- for (data->leafs_per_child[0] = 1;
- data->leafs_per_child[0] < data->totleafs;
- data->leafs_per_child[0] *= data->tree_type)
- {
- /* pass */
- }
-
- data->branches_on_level[0] = 1;
-
- for (depth = 1; (depth < 32) && data->leafs_per_child[depth - 1]; depth++) {
- data->branches_on_level[depth] = data->branches_on_level[depth - 1] * data->tree_type;
- data->leafs_per_child[depth] = data->leafs_per_child[depth - 1] / data->tree_type;
- }
-
- remain = data->totleafs - data->leafs_per_child[1];
- nnodes = (remain + data->tree_type - 2) / (data->tree_type - 1);
- data->remain_leafs = remain + nnodes;
+ int depth = 0;
+ int remain;
+ int nnodes;
+
+ data->totleafs = tree->totleaf;
+ data->tree_type = tree->tree_type;
+
+ /* Calculate the smallest tree_type^n such that tree_type^n >= num_leafs */
+ for (data->leafs_per_child[0] = 1; data->leafs_per_child[0] < data->totleafs;
+ data->leafs_per_child[0] *= data->tree_type) {
+ /* pass */
+ }
+
+ data->branches_on_level[0] = 1;
+
+ for (depth = 1; (depth < 32) && data->leafs_per_child[depth - 1]; depth++) {
+ data->branches_on_level[depth] = data->branches_on_level[depth - 1] * data->tree_type;
+ data->leafs_per_child[depth] = data->leafs_per_child[depth - 1] / data->tree_type;
+ }
+
+ remain = data->totleafs - data->leafs_per_child[1];
+ nnodes = (remain + data->tree_type - 2) / (data->tree_type - 1);
+ data->remain_leafs = remain + nnodes;
}
// return the min index of all the leafs archivable with the given branch
static int implicit_leafs_index(const BVHBuildHelper *data, const int depth, const int child_index)
{
- int min_leaf_index = child_index * data->leafs_per_child[depth - 1];
- if (min_leaf_index <= data->remain_leafs) {
- return min_leaf_index;
- }
- else if (data->leafs_per_child[depth]) {
- return data->totleafs - (data->branches_on_level[depth - 1] - child_index) * data->leafs_per_child[depth];
- }
- else {
- return data->remain_leafs;
- }
+ int min_leaf_index = child_index * data->leafs_per_child[depth - 1];
+ if (min_leaf_index <= data->remain_leafs) {
+ return min_leaf_index;
+ }
+ else if (data->leafs_per_child[depth]) {
+ return data->totleafs -
+ (data->branches_on_level[depth - 1] - child_index) * data->leafs_per_child[depth];
+ }
+ else {
+ return data->remain_leafs;
+ }
}
/**
@@ -645,7 +648,7 @@ static int implicit_leafs_index(const BVHBuildHelper *data, const int depth, con
/* This functions returns the number of branches needed to have the requested number of leafs. */
static int implicit_needed_branches(int tree_type, int leafs)
{
- return max_ii(1, (leafs + tree_type - 3) / (tree_type - 1));
+ return max_ii(1, (leafs + tree_type - 3) / (tree_type - 1));
}
/**
@@ -660,96 +663,100 @@ static int implicit_needed_branches(int tree_type, int leafs)
*
* TODO: This can be optimized a bit by doing a specialized nth_element instead of K nth_elements
*/
-static void split_leafs(BVHNode **leafs_array, const int nth[], const int partitions, const int split_axis)
+static void split_leafs(BVHNode **leafs_array,
+ const int nth[],
+ const int partitions,
+ const int split_axis)
{
- int i;
- for (i = 0; i < partitions - 1; i++) {
- if (nth[i] >= nth[partitions]) {
- break;
- }
-
- partition_nth_element(leafs_array, nth[i], nth[partitions], nth[i + 1], split_axis);
- }
+ int i;
+ for (i = 0; i < partitions - 1; i++) {
+ if (nth[i] >= nth[partitions]) {
+ break;
+ }
+
+ partition_nth_element(leafs_array, nth[i], nth[partitions], nth[i + 1], split_axis);
+ }
}
typedef struct BVHDivNodesData {
- const BVHTree *tree;
- BVHNode *branches_array;
- BVHNode **leafs_array;
+ const BVHTree *tree;
+ BVHNode *branches_array;
+ BVHNode **leafs_array;
- int tree_type;
- int tree_offset;
+ int tree_type;
+ int tree_offset;
- const BVHBuildHelper *data;
+ const BVHBuildHelper *data;
- int depth;
- int i;
- int first_of_next_level;
+ int depth;
+ int i;
+ int first_of_next_level;
} BVHDivNodesData;
-static void non_recursive_bvh_div_nodes_task_cb(
- void *__restrict userdata,
- const int j,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+static void non_recursive_bvh_div_nodes_task_cb(void *__restrict userdata,
+ const int j,
+ const ParallelRangeTLS *__restrict UNUSED(tls))
{
- BVHDivNodesData *data = userdata;
-
- int k;
- const int parent_level_index = j - data->i;
- BVHNode *parent = &data->branches_array[j];
- int nth_positions[MAX_TREETYPE + 1];
- char split_axis;
-
- int parent_leafs_begin = implicit_leafs_index(data->data, data->depth, parent_level_index);
- int parent_leafs_end = implicit_leafs_index(data->data, data->depth, parent_level_index + 1);
-
- /* This calculates the bounding box of this branch
- * and chooses the largest axis as the axis to divide leafs */
- refit_kdop_hull(data->tree, parent, parent_leafs_begin, parent_leafs_end);
- split_axis = get_largest_axis(parent->bv);
-
- /* Save split axis (this can be used on raytracing to speedup the query time) */
- parent->main_axis = split_axis / 2;
-
- /* Split the childs along the split_axis, note: its not needed to sort the whole leafs array
- * Only to assure that the elements are partitioned on a way that each child takes the elements
- * it would take in case the whole array was sorted.
- * Split_leafs takes care of that "sort" problem. */
- nth_positions[0] = parent_leafs_begin;
- nth_positions[data->tree_type] = parent_leafs_end;
- for (k = 1; k < data->tree_type; k++) {
- const int child_index = j * data->tree_type + data->tree_offset + k;
- /* child level index */
- const int child_level_index = child_index - data->first_of_next_level;
- nth_positions[k] = implicit_leafs_index(data->data, data->depth + 1, child_level_index);
- }
-
- split_leafs(data->leafs_array, nth_positions, data->tree_type, split_axis);
-
- /* Setup children and totnode counters
- * Not really needed but currently most of BVH code
- * relies on having an explicit children structure */
- for (k = 0; k < data->tree_type; k++) {
- const int child_index = j * data->tree_type + data->tree_offset + k;
- /* child level index */
- const int child_level_index = child_index - data->first_of_next_level;
-
- const int child_leafs_begin = implicit_leafs_index(data->data, data->depth + 1, child_level_index);
- const int child_leafs_end = implicit_leafs_index(data->data, data->depth + 1, child_level_index + 1);
-
- if (child_leafs_end - child_leafs_begin > 1) {
- parent->children[k] = &data->branches_array[child_index];
- parent->children[k]->parent = parent;
- }
- else if (child_leafs_end - child_leafs_begin == 1) {
- parent->children[k] = data->leafs_array[child_leafs_begin];
- parent->children[k]->parent = parent;
- }
- else {
- break;
- }
- }
- parent->totnode = (char)k;
+ BVHDivNodesData *data = userdata;
+
+ int k;
+ const int parent_level_index = j - data->i;
+ BVHNode *parent = &data->branches_array[j];
+ int nth_positions[MAX_TREETYPE + 1];
+ char split_axis;
+
+ int parent_leafs_begin = implicit_leafs_index(data->data, data->depth, parent_level_index);
+ int parent_leafs_end = implicit_leafs_index(data->data, data->depth, parent_level_index + 1);
+
+ /* This calculates the bounding box of this branch
+ * and chooses the largest axis as the axis to divide leafs */
+ refit_kdop_hull(data->tree, parent, parent_leafs_begin, parent_leafs_end);
+ split_axis = get_largest_axis(parent->bv);
+
+ /* Save split axis (this can be used on raytracing to speedup the query time) */
+ parent->main_axis = split_axis / 2;
+
+ /* Split the childs along the split_axis, note: its not needed to sort the whole leafs array
+ * Only to assure that the elements are partitioned on a way that each child takes the elements
+ * it would take in case the whole array was sorted.
+ * Split_leafs takes care of that "sort" problem. */
+ nth_positions[0] = parent_leafs_begin;
+ nth_positions[data->tree_type] = parent_leafs_end;
+ for (k = 1; k < data->tree_type; k++) {
+ const int child_index = j * data->tree_type + data->tree_offset + k;
+ /* child level index */
+ const int child_level_index = child_index - data->first_of_next_level;
+ nth_positions[k] = implicit_leafs_index(data->data, data->depth + 1, child_level_index);
+ }
+
+ split_leafs(data->leafs_array, nth_positions, data->tree_type, split_axis);
+
+ /* Setup children and totnode counters
+ * Not really needed but currently most of BVH code
+ * relies on having an explicit children structure */
+ for (k = 0; k < data->tree_type; k++) {
+ const int child_index = j * data->tree_type + data->tree_offset + k;
+ /* child level index */
+ const int child_level_index = child_index - data->first_of_next_level;
+
+ const int child_leafs_begin = implicit_leafs_index(
+ data->data, data->depth + 1, child_level_index);
+ const int child_leafs_end = implicit_leafs_index(
+ data->data, data->depth + 1, child_level_index + 1);
+
+ if (child_leafs_end - child_leafs_begin > 1) {
+ parent->children[k] = &data->branches_array[child_index];
+ parent->children[k]->parent = parent;
+ }
+ else if (child_leafs_end - child_leafs_begin == 1) {
+ parent->children[k] = data->leafs_array[child_leafs_begin];
+ parent->children[k]->parent = parent;
+ }
+ else {
+ break;
+ }
+ }
+ parent->totnode = (char)k;
}
/**
@@ -768,79 +775,82 @@ static void non_recursive_bvh_div_nodes_task_cb(
* To archive this is necessary to find how much leafs are accessible from a certain branch, BVHBuildHelper
* #implicit_needed_branches and #implicit_leafs_index are auxiliary functions to solve that "optimal-split".
*/
-static void non_recursive_bvh_div_nodes(
- const BVHTree *tree, BVHNode *branches_array, BVHNode **leafs_array, int num_leafs)
+static void non_recursive_bvh_div_nodes(const BVHTree *tree,
+ BVHNode *branches_array,
+ BVHNode **leafs_array,
+ int num_leafs)
{
- int i;
-
- const int tree_type = tree->tree_type;
- /* this value is 0 (on binary trees) and negative on the others */
- const int tree_offset = 2 - tree->tree_type;
-
- const int num_branches = implicit_needed_branches(tree_type, num_leafs);
-
- BVHBuildHelper data;
- int depth;
-
- {
- /* set parent from root node to NULL */
- BVHNode *root = &branches_array[1];
- root->parent = NULL;
-
- /* Most of bvhtree code relies on 1-leaf trees having at least one branch
- * We handle that special case here */
- if (num_leafs == 1) {
- refit_kdop_hull(tree, root, 0, num_leafs);
- root->main_axis = get_largest_axis(root->bv) / 2;
- root->totnode = 1;
- root->children[0] = leafs_array[0];
- root->children[0]->parent = root;
- return;
- }
- }
-
- build_implicit_tree_helper(tree, &data);
-
- BVHDivNodesData cb_data = {
- .tree = tree, .branches_array = branches_array, .leafs_array = leafs_array,
- .tree_type = tree_type, .tree_offset = tree_offset, .data = &data,
- .first_of_next_level = 0, .depth = 0, .i = 0,
- };
-
- /* Loop tree levels (log N) loops */
- for (i = 1, depth = 1; i <= num_branches; i = i * tree_type + tree_offset, depth++) {
- const int first_of_next_level = i * tree_type + tree_offset;
- /* index of last branch on this level */
- const int i_stop = min_ii(first_of_next_level, num_branches + 1);
-
- /* Loop all branches on this level */
- cb_data.first_of_next_level = first_of_next_level;
- cb_data.i = i;
- cb_data.depth = depth;
-
- if (true) {
- ParallelRangeSettings settings;
- BLI_parallel_range_settings_defaults(&settings);
- settings.use_threading = (num_leafs > KDOPBVH_THREAD_LEAF_THRESHOLD);
- BLI_task_parallel_range(
- i, i_stop,
- &cb_data,
- non_recursive_bvh_div_nodes_task_cb,
- &settings);
- }
- else {
- /* Less hassle for debugging. */
- ParallelRangeTLS tls = {0};
- for (int i_task = i; i_task < i_stop; i_task++) {
- non_recursive_bvh_div_nodes_task_cb(&cb_data, i_task, &tls);
- }
- }
- }
+ int i;
+
+ const int tree_type = tree->tree_type;
+ /* this value is 0 (on binary trees) and negative on the others */
+ const int tree_offset = 2 - tree->tree_type;
+
+ const int num_branches = implicit_needed_branches(tree_type, num_leafs);
+
+ BVHBuildHelper data;
+ int depth;
+
+ {
+ /* set parent from root node to NULL */
+ BVHNode *root = &branches_array[1];
+ root->parent = NULL;
+
+ /* Most of bvhtree code relies on 1-leaf trees having at least one branch
+ * We handle that special case here */
+ if (num_leafs == 1) {
+ refit_kdop_hull(tree, root, 0, num_leafs);
+ root->main_axis = get_largest_axis(root->bv) / 2;
+ root->totnode = 1;
+ root->children[0] = leafs_array[0];
+ root->children[0]->parent = root;
+ return;
+ }
+ }
+
+ build_implicit_tree_helper(tree, &data);
+
+ BVHDivNodesData cb_data = {
+ .tree = tree,
+ .branches_array = branches_array,
+ .leafs_array = leafs_array,
+ .tree_type = tree_type,
+ .tree_offset = tree_offset,
+ .data = &data,
+ .first_of_next_level = 0,
+ .depth = 0,
+ .i = 0,
+ };
+
+ /* Loop tree levels (log N) loops */
+ for (i = 1, depth = 1; i <= num_branches; i = i * tree_type + tree_offset, depth++) {
+ const int first_of_next_level = i * tree_type + tree_offset;
+ /* index of last branch on this level */
+ const int i_stop = min_ii(first_of_next_level, num_branches + 1);
+
+ /* Loop all branches on this level */
+ cb_data.first_of_next_level = first_of_next_level;
+ cb_data.i = i;
+ cb_data.depth = depth;
+
+ if (true) {
+ ParallelRangeSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ settings.use_threading = (num_leafs > KDOPBVH_THREAD_LEAF_THRESHOLD);
+ BLI_task_parallel_range(i, i_stop, &cb_data, non_recursive_bvh_div_nodes_task_cb, &settings);
+ }
+ else {
+ /* Less hassle for debugging. */
+ ParallelRangeTLS tls = {0};
+ for (int i_task = i; i_task < i_stop; i_task++) {
+ non_recursive_bvh_div_nodes_task_cb(&cb_data, i_task, &tls);
+ }
+ }
+ }
}
/** \} */
-
/* -------------------------------------------------------------------- */
/** \name BLI_bvhtree API
* \{ */
@@ -850,189 +860,183 @@ static void non_recursive_bvh_div_nodes(
*/
BVHTree *BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis)
{
- BVHTree *tree;
- int numnodes, i;
-
- BLI_assert(tree_type >= 2 && tree_type <= MAX_TREETYPE);
-
- tree = MEM_callocN(sizeof(BVHTree), "BVHTree");
-
- /* tree epsilon must be >= FLT_EPSILON
- * so that tangent rays can still hit a bounding volume..
- * this bug would show up when casting a ray aligned with a kdop-axis
- * and with an edge of 2 faces */
- epsilon = max_ff(FLT_EPSILON, epsilon);
-
- if (tree) {
- tree->epsilon = epsilon;
- tree->tree_type = tree_type;
- tree->axis = axis;
-
- if (axis == 26) {
- tree->start_axis = 0;
- tree->stop_axis = 13;
- }
- else if (axis == 18) {
- tree->start_axis = 7;
- tree->stop_axis = 13;
- }
- else if (axis == 14) {
- tree->start_axis = 0;
- tree->stop_axis = 7;
- }
- else if (axis == 8) { /* AABB */
- tree->start_axis = 0;
- tree->stop_axis = 4;
- }
- else if (axis == 6) { /* OBB */
- tree->start_axis = 0;
- tree->stop_axis = 3;
- }
- else {
- /* should never happen! */
- BLI_assert(0);
-
- goto fail;
- }
-
-
- /* Allocate arrays */
- numnodes = maxsize + implicit_needed_branches(tree_type, maxsize) + tree_type;
-
- tree->nodes = MEM_callocN(sizeof(BVHNode *) * (size_t)numnodes, "BVHNodes");
- tree->nodebv = MEM_callocN(sizeof(float) * (size_t)(axis * numnodes), "BVHNodeBV");
- tree->nodechild = MEM_callocN(sizeof(BVHNode *) * (size_t)(tree_type * numnodes), "BVHNodeBV");
- tree->nodearray = MEM_callocN(sizeof(BVHNode) * (size_t)numnodes, "BVHNodeArray");
-
- if (UNLIKELY((!tree->nodes) ||
- (!tree->nodebv) ||
- (!tree->nodechild) ||
- (!tree->nodearray)))
- {
- goto fail;
- }
-
- /* link the dynamic bv and child links */
- for (i = 0; i < numnodes; i++) {
- tree->nodearray[i].bv = &tree->nodebv[i * axis];
- tree->nodearray[i].children = &tree->nodechild[i * tree_type];
- }
-
- }
- return tree;
-
+ BVHTree *tree;
+ int numnodes, i;
+
+ BLI_assert(tree_type >= 2 && tree_type <= MAX_TREETYPE);
+
+ tree = MEM_callocN(sizeof(BVHTree), "BVHTree");
+
+ /* tree epsilon must be >= FLT_EPSILON
+ * so that tangent rays can still hit a bounding volume..
+ * this bug would show up when casting a ray aligned with a kdop-axis
+ * and with an edge of 2 faces */
+ epsilon = max_ff(FLT_EPSILON, epsilon);
+
+ if (tree) {
+ tree->epsilon = epsilon;
+ tree->tree_type = tree_type;
+ tree->axis = axis;
+
+ if (axis == 26) {
+ tree->start_axis = 0;
+ tree->stop_axis = 13;
+ }
+ else if (axis == 18) {
+ tree->start_axis = 7;
+ tree->stop_axis = 13;
+ }
+ else if (axis == 14) {
+ tree->start_axis = 0;
+ tree->stop_axis = 7;
+ }
+ else if (axis == 8) { /* AABB */
+ tree->start_axis = 0;
+ tree->stop_axis = 4;
+ }
+ else if (axis == 6) { /* OBB */
+ tree->start_axis = 0;
+ tree->stop_axis = 3;
+ }
+ else {
+ /* should never happen! */
+ BLI_assert(0);
+
+ goto fail;
+ }
+
+ /* Allocate arrays */
+ numnodes = maxsize + implicit_needed_branches(tree_type, maxsize) + tree_type;
+
+ tree->nodes = MEM_callocN(sizeof(BVHNode *) * (size_t)numnodes, "BVHNodes");
+ tree->nodebv = MEM_callocN(sizeof(float) * (size_t)(axis * numnodes), "BVHNodeBV");
+ tree->nodechild = MEM_callocN(sizeof(BVHNode *) * (size_t)(tree_type * numnodes), "BVHNodeBV");
+ tree->nodearray = MEM_callocN(sizeof(BVHNode) * (size_t)numnodes, "BVHNodeArray");
+
+ if (UNLIKELY((!tree->nodes) || (!tree->nodebv) || (!tree->nodechild) || (!tree->nodearray))) {
+ goto fail;
+ }
+
+ /* link the dynamic bv and child links */
+ for (i = 0; i < numnodes; i++) {
+ tree->nodearray[i].bv = &tree->nodebv[i * axis];
+ tree->nodearray[i].children = &tree->nodechild[i * tree_type];
+ }
+ }
+ return tree;
fail:
- BLI_bvhtree_free(tree);
- return NULL;
+ BLI_bvhtree_free(tree);
+ return NULL;
}
void BLI_bvhtree_free(BVHTree *tree)
{
- if (tree) {
- MEM_SAFE_FREE(tree->nodes);
- MEM_SAFE_FREE(tree->nodearray);
- MEM_SAFE_FREE(tree->nodebv);
- MEM_SAFE_FREE(tree->nodechild);
- MEM_freeN(tree);
- }
+ if (tree) {
+ MEM_SAFE_FREE(tree->nodes);
+ MEM_SAFE_FREE(tree->nodearray);
+ MEM_SAFE_FREE(tree->nodebv);
+ MEM_SAFE_FREE(tree->nodechild);
+ MEM_freeN(tree);
+ }
}
void BLI_bvhtree_balance(BVHTree *tree)
{
- BVHNode **leafs_array = tree->nodes;
+ BVHNode **leafs_array = tree->nodes;
- /* This function should only be called once
- * (some big bug goes here if its being called more than once per tree) */
- BLI_assert(tree->totbranch == 0);
+ /* This function should only be called once
+ * (some big bug goes here if its being called more than once per tree) */
+ BLI_assert(tree->totbranch == 0);
- /* Build the implicit tree */
- non_recursive_bvh_div_nodes(tree, tree->nodearray + (tree->totleaf - 1), leafs_array, tree->totleaf);
+ /* Build the implicit tree */
+ non_recursive_bvh_div_nodes(
+ tree, tree->nodearray + (tree->totleaf - 1), leafs_array, tree->totleaf);
- /* current code expects the branches to be linked to the nodes array
- * we perform that linkage here */
- tree->totbranch = implicit_needed_branches(tree->tree_type, tree->totleaf);
- for (int i = 0; i < tree->totbranch; i++) {
- tree->nodes[tree->totleaf + i] = &tree->nodearray[tree->totleaf + i];
- }
+ /* current code expects the branches to be linked to the nodes array
+ * we perform that linkage here */
+ tree->totbranch = implicit_needed_branches(tree->tree_type, tree->totleaf);
+ for (int i = 0; i < tree->totbranch; i++) {
+ tree->nodes[tree->totleaf + i] = &tree->nodearray[tree->totleaf + i];
+ }
#ifdef USE_SKIP_LINKS
- build_skip_links(tree, tree->nodes[tree->totleaf], NULL, NULL);
+ build_skip_links(tree, tree->nodes[tree->totleaf], NULL, NULL);
#endif
#ifdef USE_VERIFY_TREE
- bvhtree_verify(tree);
+ bvhtree_verify(tree);
#endif
#ifdef USE_PRINT_TREE
- bvhtree_info(tree);
+ bvhtree_info(tree);
#endif
}
void BLI_bvhtree_insert(BVHTree *tree, int index, const float co[3], int numpoints)
{
- axis_t axis_iter;
- BVHNode *node = NULL;
+ axis_t axis_iter;
+ BVHNode *node = NULL;
- /* insert should only possible as long as tree->totbranch is 0 */
- BLI_assert(tree->totbranch <= 0);
- BLI_assert((size_t)tree->totleaf < MEM_allocN_len(tree->nodes) / sizeof(*(tree->nodes)));
+ /* insert should only possible as long as tree->totbranch is 0 */
+ BLI_assert(tree->totbranch <= 0);
+ BLI_assert((size_t)tree->totleaf < MEM_allocN_len(tree->nodes) / sizeof(*(tree->nodes)));
- node = tree->nodes[tree->totleaf] = &(tree->nodearray[tree->totleaf]);
- tree->totleaf++;
+ node = tree->nodes[tree->totleaf] = &(tree->nodearray[tree->totleaf]);
+ tree->totleaf++;
- create_kdop_hull(tree, node, co, numpoints, 0);
- node->index = index;
+ create_kdop_hull(tree, node, co, numpoints, 0);
+ node->index = index;
- /* inflate the bv with some epsilon */
- for (axis_iter = tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) {
- node->bv[(2 * axis_iter)] -= tree->epsilon; /* minimum */
- node->bv[(2 * axis_iter) + 1] += tree->epsilon; /* maximum */
- }
+ /* inflate the bv with some epsilon */
+ for (axis_iter = tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) {
+ node->bv[(2 * axis_iter)] -= tree->epsilon; /* minimum */
+ node->bv[(2 * axis_iter) + 1] += tree->epsilon; /* maximum */
+ }
}
-
/* call before BLI_bvhtree_update_tree() */
-bool BLI_bvhtree_update_node(BVHTree *tree, int index, const float co[3], const float co_moving[3], int numpoints)
+bool BLI_bvhtree_update_node(
+ BVHTree *tree, int index, const float co[3], const float co_moving[3], int numpoints)
{
- BVHNode *node = NULL;
- axis_t axis_iter;
+ BVHNode *node = NULL;
+ axis_t axis_iter;
- /* check if index exists */
- if (index > tree->totleaf) {
- return false;
- }
+ /* check if index exists */
+ if (index > tree->totleaf) {
+ return false;
+ }
- node = tree->nodearray + index;
+ node = tree->nodearray + index;
- create_kdop_hull(tree, node, co, numpoints, 0);
+ create_kdop_hull(tree, node, co, numpoints, 0);
- if (co_moving) {
- create_kdop_hull(tree, node, co_moving, numpoints, 1);
- }
+ if (co_moving) {
+ create_kdop_hull(tree, node, co_moving, numpoints, 1);
+ }
- /* inflate the bv with some epsilon */
- for (axis_iter = tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) {
- node->bv[(2 * axis_iter)] -= tree->epsilon; /* minimum */
- node->bv[(2 * axis_iter) + 1] += tree->epsilon; /* maximum */
- }
+ /* inflate the bv with some epsilon */
+ for (axis_iter = tree->start_axis; axis_iter < tree->stop_axis; axis_iter++) {
+ node->bv[(2 * axis_iter)] -= tree->epsilon; /* minimum */
+ node->bv[(2 * axis_iter) + 1] += tree->epsilon; /* maximum */
+ }
- return true;
+ return true;
}
/* call BLI_bvhtree_update_node() first for every node/point/triangle */
void BLI_bvhtree_update_tree(BVHTree *tree)
{
- /* Update bottom=>top
- * TRICKY: the way we build the tree all the childs have an index greater than the parent
- * This allows us todo a bottom up update by starting on the bigger numbered branch */
+ /* Update bottom=>top
+ * TRICKY: the way we build the tree all the childs have an index greater than the parent
+ * This allows us todo a bottom up update by starting on the bigger numbered branch */
- BVHNode **root = tree->nodes + tree->totleaf;
- BVHNode **index = tree->nodes + tree->totleaf + tree->totbranch - 1;
+ BVHNode **root = tree->nodes + tree->totleaf;
+ BVHNode **index = tree->nodes + tree->totleaf + tree->totbranch - 1;
- for (; index >= root; index--) {
- node_join(tree, *index);
- }
+ for (; index >= root; index--) {
+ node_join(tree, *index);
+ }
}
/**
* Number of times #BLI_bvhtree_insert has been called.
@@ -1040,7 +1044,7 @@ void BLI_bvhtree_update_tree(BVHTree *tree)
*/
int BLI_bvhtree_get_len(const BVHTree *tree)
{
- return tree->totleaf;
+ return tree->totleaf;
}
/**
@@ -1048,17 +1052,16 @@ int BLI_bvhtree_get_len(const BVHTree *tree)
*/
int BLI_bvhtree_get_tree_type(const BVHTree *tree)
{
- return tree->tree_type;
+ return tree->tree_type;
}
float BLI_bvhtree_get_epsilon(const BVHTree *tree)
{
- return tree->epsilon;
+ return tree->epsilon;
}
/** \} */
-
/* -------------------------------------------------------------------- */
/** \name BLI_bvhtree_overlap
* \{ */
@@ -1066,108 +1069,111 @@ float BLI_bvhtree_get_epsilon(const BVHTree *tree)
/**
* overlap - is it possible for 2 bv's to collide ?
*/
-static bool tree_overlap_test(const BVHNode *node1, const BVHNode *node2, axis_t start_axis, axis_t stop_axis)
+static bool tree_overlap_test(const BVHNode *node1,
+ const BVHNode *node2,
+ axis_t start_axis,
+ axis_t stop_axis)
{
- const float *bv1 = node1->bv + (start_axis << 1);
- const float *bv2 = node2->bv + (start_axis << 1);
- const float *bv1_end = node1->bv + (stop_axis << 1);
-
- /* test all axis if min + max overlap */
- for (; bv1 != bv1_end; bv1 += 2, bv2 += 2) {
- if ((bv1[0] > bv2[1]) || (bv2[0] > bv1[1])) {
- return 0;
- }
- }
-
- return 1;
+ const float *bv1 = node1->bv + (start_axis << 1);
+ const float *bv2 = node2->bv + (start_axis << 1);
+ const float *bv1_end = node1->bv + (stop_axis << 1);
+
+ /* test all axis if min + max overlap */
+ for (; bv1 != bv1_end; bv1 += 2, bv2 += 2) {
+ if ((bv1[0] > bv2[1]) || (bv2[0] > bv1[1])) {
+ return 0;
+ }
+ }
+
+ return 1;
}
-static void tree_overlap_traverse(
- BVHOverlapData_Thread *data_thread,
- const BVHNode *node1, const BVHNode *node2)
+static void tree_overlap_traverse(BVHOverlapData_Thread *data_thread,
+ const BVHNode *node1,
+ const BVHNode *node2)
{
- BVHOverlapData_Shared *data = data_thread->shared;
- int j;
-
- if (tree_overlap_test(node1, node2, data->start_axis, data->stop_axis)) {
- /* check if node1 is a leaf */
- if (!node1->totnode) {
- /* check if node2 is a leaf */
- if (!node2->totnode) {
- BVHTreeOverlap *overlap;
-
- if (UNLIKELY(node1 == node2)) {
- return;
- }
-
- /* both leafs, insert overlap! */
- overlap = BLI_stack_push_r(data_thread->overlap);
- overlap->indexA = node1->index;
- overlap->indexB = node2->index;
- }
- else {
- for (j = 0; j < data->tree2->tree_type; j++) {
- if (node2->children[j]) {
- tree_overlap_traverse(data_thread, node1, node2->children[j]);
- }
- }
- }
- }
- else {
- for (j = 0; j < data->tree2->tree_type; j++) {
- if (node1->children[j]) {
- tree_overlap_traverse(data_thread, node1->children[j], node2);
- }
- }
- }
- }
+ BVHOverlapData_Shared *data = data_thread->shared;
+ int j;
+
+ if (tree_overlap_test(node1, node2, data->start_axis, data->stop_axis)) {
+ /* check if node1 is a leaf */
+ if (!node1->totnode) {
+ /* check if node2 is a leaf */
+ if (!node2->totnode) {
+ BVHTreeOverlap *overlap;
+
+ if (UNLIKELY(node1 == node2)) {
+ return;
+ }
+
+ /* both leafs, insert overlap! */
+ overlap = BLI_stack_push_r(data_thread->overlap);
+ overlap->indexA = node1->index;
+ overlap->indexB = node2->index;
+ }
+ else {
+ for (j = 0; j < data->tree2->tree_type; j++) {
+ if (node2->children[j]) {
+ tree_overlap_traverse(data_thread, node1, node2->children[j]);
+ }
+ }
+ }
+ }
+ else {
+ for (j = 0; j < data->tree2->tree_type; j++) {
+ if (node1->children[j]) {
+ tree_overlap_traverse(data_thread, node1->children[j], node2);
+ }
+ }
+ }
+ }
}
/**
* a version of #tree_overlap_traverse that runs a callback to check if the nodes really intersect.
*/
-static void tree_overlap_traverse_cb(
- BVHOverlapData_Thread *data_thread,
- const BVHNode *node1, const BVHNode *node2)
+static void tree_overlap_traverse_cb(BVHOverlapData_Thread *data_thread,
+ const BVHNode *node1,
+ const BVHNode *node2)
{
- BVHOverlapData_Shared *data = data_thread->shared;
- int j;
-
- if (tree_overlap_test(node1, node2, data->start_axis, data->stop_axis)) {
- /* check if node1 is a leaf */
- if (!node1->totnode) {
- /* check if node2 is a leaf */
- if (!node2->totnode) {
- BVHTreeOverlap *overlap;
-
- if (UNLIKELY(node1 == node2)) {
- return;
- }
-
- /* only difference to tree_overlap_traverse! */
- if (data->callback(data->userdata, node1->index, node2->index, data_thread->thread)) {
- /* both leafs, insert overlap! */
- overlap = BLI_stack_push_r(data_thread->overlap);
- overlap->indexA = node1->index;
- overlap->indexB = node2->index;
- }
- }
- else {
- for (j = 0; j < data->tree2->tree_type; j++) {
- if (node2->children[j]) {
- tree_overlap_traverse_cb(data_thread, node1, node2->children[j]);
- }
- }
- }
- }
- else {
- for (j = 0; j < data->tree2->tree_type; j++) {
- if (node1->children[j]) {
- tree_overlap_traverse_cb(data_thread, node1->children[j], node2);
- }
- }
- }
- }
+ BVHOverlapData_Shared *data = data_thread->shared;
+ int j;
+
+ if (tree_overlap_test(node1, node2, data->start_axis, data->stop_axis)) {
+ /* check if node1 is a leaf */
+ if (!node1->totnode) {
+ /* check if node2 is a leaf */
+ if (!node2->totnode) {
+ BVHTreeOverlap *overlap;
+
+ if (UNLIKELY(node1 == node2)) {
+ return;
+ }
+
+ /* only difference to tree_overlap_traverse! */
+ if (data->callback(data->userdata, node1->index, node2->index, data_thread->thread)) {
+ /* both leafs, insert overlap! */
+ overlap = BLI_stack_push_r(data_thread->overlap);
+ overlap->indexA = node1->index;
+ overlap->indexB = node2->index;
+ }
+ }
+ else {
+ for (j = 0; j < data->tree2->tree_type; j++) {
+ if (node2->children[j]) {
+ tree_overlap_traverse_cb(data_thread, node1, node2->children[j]);
+ }
+ }
+ }
+ }
+ else {
+ for (j = 0; j < data->tree2->tree_type; j++) {
+ if (node1->children[j]) {
+ tree_overlap_traverse_cb(data_thread, node1->children[j], node2);
+ }
+ }
+ }
+ }
}
/**
@@ -1177,106 +1183,102 @@ static void tree_overlap_traverse_cb(
*/
int BLI_bvhtree_overlap_thread_num(const BVHTree *tree)
{
- return (int)MIN2(tree->tree_type, tree->nodes[tree->totleaf]->totnode);
+ return (int)MIN2(tree->tree_type, tree->nodes[tree->totleaf]->totnode);
}
-static void bvhtree_overlap_task_cb(
- void *__restrict userdata,
- const int j,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+static void bvhtree_overlap_task_cb(void *__restrict userdata,
+ const int j,
+ const ParallelRangeTLS *__restrict UNUSED(tls))
{
- BVHOverlapData_Thread *data = &((BVHOverlapData_Thread *)userdata)[j];
- BVHOverlapData_Shared *data_shared = data->shared;
-
- if (data_shared->callback) {
- tree_overlap_traverse_cb(
- data, data_shared->tree1->nodes[data_shared->tree1->totleaf]->children[j],
- data_shared->tree2->nodes[data_shared->tree2->totleaf]);
- }
- else {
- tree_overlap_traverse(
- data, data_shared->tree1->nodes[data_shared->tree1->totleaf]->children[j],
- data_shared->tree2->nodes[data_shared->tree2->totleaf]);
- }
+ BVHOverlapData_Thread *data = &((BVHOverlapData_Thread *)userdata)[j];
+ BVHOverlapData_Shared *data_shared = data->shared;
+
+ if (data_shared->callback) {
+ tree_overlap_traverse_cb(data,
+ data_shared->tree1->nodes[data_shared->tree1->totleaf]->children[j],
+ data_shared->tree2->nodes[data_shared->tree2->totleaf]);
+ }
+ else {
+ tree_overlap_traverse(data,
+ data_shared->tree1->nodes[data_shared->tree1->totleaf]->children[j],
+ data_shared->tree2->nodes[data_shared->tree2->totleaf]);
+ }
}
BVHTreeOverlap *BLI_bvhtree_overlap(
- const BVHTree *tree1, const BVHTree *tree2, uint *r_overlap_tot,
- /* optional callback to test the overlap before adding (must be thread-safe!) */
- BVHTree_OverlapCallback callback, void *userdata)
+ const BVHTree *tree1,
+ const BVHTree *tree2,
+ uint *r_overlap_tot,
+ /* optional callback to test the overlap before adding (must be thread-safe!) */
+ BVHTree_OverlapCallback callback,
+ void *userdata)
{
- const int thread_num = BLI_bvhtree_overlap_thread_num(tree1);
- int j;
- size_t total = 0;
- BVHTreeOverlap *overlap = NULL, *to = NULL;
- BVHOverlapData_Shared data_shared;
- BVHOverlapData_Thread *data = BLI_array_alloca(data, (size_t)thread_num);
- axis_t start_axis, stop_axis;
-
- /* check for compatibility of both trees (can't compare 14-DOP with 18-DOP) */
- if (UNLIKELY((tree1->axis != tree2->axis) &&
- (tree1->axis == 14 || tree2->axis == 14) &&
- (tree1->axis == 18 || tree2->axis == 18)))
- {
- BLI_assert(0);
- return NULL;
- }
-
- start_axis = min_axis(tree1->start_axis, tree2->start_axis);
- stop_axis = min_axis(tree1->stop_axis, tree2->stop_axis);
-
- /* fast check root nodes for collision before doing big splitting + traversal */
- if (!tree_overlap_test(tree1->nodes[tree1->totleaf], tree2->nodes[tree2->totleaf], start_axis, stop_axis)) {
- return NULL;
- }
-
- data_shared.tree1 = tree1;
- data_shared.tree2 = tree2;
- data_shared.start_axis = start_axis;
- data_shared.stop_axis = stop_axis;
-
- /* can be NULL */
- data_shared.callback = callback;
- data_shared.userdata = userdata;
-
- for (j = 0; j < thread_num; j++) {
- /* init BVHOverlapData_Thread */
- data[j].shared = &data_shared;
- data[j].overlap = BLI_stack_new(sizeof(BVHTreeOverlap), __func__);
-
- /* for callback */
- data[j].thread = j;
- }
-
- ParallelRangeSettings settings;
- BLI_parallel_range_settings_defaults(&settings);
- settings.use_threading = (tree1->totleaf > KDOPBVH_THREAD_LEAF_THRESHOLD);
- BLI_task_parallel_range(
- 0, thread_num,
- data,
- bvhtree_overlap_task_cb,
- &settings);
-
- for (j = 0; j < thread_num; j++) {
- total += BLI_stack_count(data[j].overlap);
- }
-
- to = overlap = MEM_mallocN(sizeof(BVHTreeOverlap) * total, "BVHTreeOverlap");
-
- for (j = 0; j < thread_num; j++) {
- uint count = (uint)BLI_stack_count(data[j].overlap);
- BLI_stack_pop_n(data[j].overlap, to, count);
- BLI_stack_free(data[j].overlap);
- to += count;
- }
-
- *r_overlap_tot = (uint)total;
- return overlap;
+ const int thread_num = BLI_bvhtree_overlap_thread_num(tree1);
+ int j;
+ size_t total = 0;
+ BVHTreeOverlap *overlap = NULL, *to = NULL;
+ BVHOverlapData_Shared data_shared;
+ BVHOverlapData_Thread *data = BLI_array_alloca(data, (size_t)thread_num);
+ axis_t start_axis, stop_axis;
+
+ /* check for compatibility of both trees (can't compare 14-DOP with 18-DOP) */
+ if (UNLIKELY((tree1->axis != tree2->axis) && (tree1->axis == 14 || tree2->axis == 14) &&
+ (tree1->axis == 18 || tree2->axis == 18))) {
+ BLI_assert(0);
+ return NULL;
+ }
+
+ start_axis = min_axis(tree1->start_axis, tree2->start_axis);
+ stop_axis = min_axis(tree1->stop_axis, tree2->stop_axis);
+
+ /* fast check root nodes for collision before doing big splitting + traversal */
+ if (!tree_overlap_test(
+ tree1->nodes[tree1->totleaf], tree2->nodes[tree2->totleaf], start_axis, stop_axis)) {
+ return NULL;
+ }
+
+ data_shared.tree1 = tree1;
+ data_shared.tree2 = tree2;
+ data_shared.start_axis = start_axis;
+ data_shared.stop_axis = stop_axis;
+
+ /* can be NULL */
+ data_shared.callback = callback;
+ data_shared.userdata = userdata;
+
+ for (j = 0; j < thread_num; j++) {
+ /* init BVHOverlapData_Thread */
+ data[j].shared = &data_shared;
+ data[j].overlap = BLI_stack_new(sizeof(BVHTreeOverlap), __func__);
+
+ /* for callback */
+ data[j].thread = j;
+ }
+
+ ParallelRangeSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ settings.use_threading = (tree1->totleaf > KDOPBVH_THREAD_LEAF_THRESHOLD);
+ BLI_task_parallel_range(0, thread_num, data, bvhtree_overlap_task_cb, &settings);
+
+ for (j = 0; j < thread_num; j++) {
+ total += BLI_stack_count(data[j].overlap);
+ }
+
+ to = overlap = MEM_mallocN(sizeof(BVHTreeOverlap) * total, "BVHTreeOverlap");
+
+ for (j = 0; j < thread_num; j++) {
+ uint count = (uint)BLI_stack_count(data[j].overlap);
+ BLI_stack_pop_n(data[j].overlap, to, count);
+ BLI_stack_free(data[j].overlap);
+ to += count;
+ }
+
+ *r_overlap_tot = (uint)total;
+ return overlap;
}
/** \} */
-
/* -------------------------------------------------------------------- */
/** \name BLI_bvhtree_find_nearest
* \{ */
@@ -1285,172 +1287,178 @@ BVHTreeOverlap *BLI_bvhtree_overlap(
* Returns the squared distance to that point. */
static float calc_nearest_point_squared(const float proj[3], BVHNode *node, float nearest[3])
{
- int i;
- const float *bv = node->bv;
-
- /* nearest on AABB hull */
- for (i = 0; i != 3; i++, bv += 2) {
- float val = proj[i];
- if (bv[0] > val) {
- val = bv[0];
- }
- if (bv[1] < val) {
- val = bv[1];
- }
- nearest[i] = val;
- }
-
- return len_squared_v3v3(proj, nearest);
+ int i;
+ const float *bv = node->bv;
+
+ /* nearest on AABB hull */
+ for (i = 0; i != 3; i++, bv += 2) {
+ float val = proj[i];
+ if (bv[0] > val) {
+ val = bv[0];
+ }
+ if (bv[1] < val) {
+ val = bv[1];
+ }
+ nearest[i] = val;
+ }
+
+ return len_squared_v3v3(proj, nearest);
}
/* Depth first search method */
static void dfs_find_nearest_dfs(BVHNearestData *data, BVHNode *node)
{
- if (node->totnode == 0) {
- if (data->callback) {
- data->callback(data->userdata, node->index, data->co, &data->nearest);
- }
- else {
- data->nearest.index = node->index;
- data->nearest.dist_sq = calc_nearest_point_squared(data->proj, node, data->nearest.co);
- }
- }
- else {
- /* Better heuristic to pick the closest node to dive on */
- int i;
- float nearest[3];
-
- if (data->proj[node->main_axis] <= node->children[0]->bv[node->main_axis * 2 + 1]) {
-
- for (i = 0; i != node->totnode; i++) {
- if (calc_nearest_point_squared(data->proj, node->children[i], nearest) >= data->nearest.dist_sq) {
- continue;
- }
- dfs_find_nearest_dfs(data, node->children[i]);
- }
- }
- else {
- for (i = node->totnode - 1; i >= 0; i--) {
- if (calc_nearest_point_squared(data->proj, node->children[i], nearest) >= data->nearest.dist_sq) {
- continue;
- }
- dfs_find_nearest_dfs(data, node->children[i]);
- }
- }
- }
+ if (node->totnode == 0) {
+ if (data->callback) {
+ data->callback(data->userdata, node->index, data->co, &data->nearest);
+ }
+ else {
+ data->nearest.index = node->index;
+ data->nearest.dist_sq = calc_nearest_point_squared(data->proj, node, data->nearest.co);
+ }
+ }
+ else {
+ /* Better heuristic to pick the closest node to dive on */
+ int i;
+ float nearest[3];
+
+ if (data->proj[node->main_axis] <= node->children[0]->bv[node->main_axis * 2 + 1]) {
+
+ for (i = 0; i != node->totnode; i++) {
+ if (calc_nearest_point_squared(data->proj, node->children[i], nearest) >=
+ data->nearest.dist_sq) {
+ continue;
+ }
+ dfs_find_nearest_dfs(data, node->children[i]);
+ }
+ }
+ else {
+ for (i = node->totnode - 1; i >= 0; i--) {
+ if (calc_nearest_point_squared(data->proj, node->children[i], nearest) >=
+ data->nearest.dist_sq) {
+ continue;
+ }
+ dfs_find_nearest_dfs(data, node->children[i]);
+ }
+ }
+ }
}
static void dfs_find_nearest_begin(BVHNearestData *data, BVHNode *node)
{
- float nearest[3], dist_sq;
- dist_sq = calc_nearest_point_squared(data->proj, node, nearest);
- if (dist_sq >= data->nearest.dist_sq) {
- return;
- }
- dfs_find_nearest_dfs(data, node);
+ float nearest[3], dist_sq;
+ dist_sq = calc_nearest_point_squared(data->proj, node, nearest);
+ if (dist_sq >= data->nearest.dist_sq) {
+ return;
+ }
+ dfs_find_nearest_dfs(data, node);
}
/* Priority queue method */
static void heap_find_nearest_inner(BVHNearestData *data, HeapSimple *heap, BVHNode *node)
{
- if (node->totnode == 0) {
- if (data->callback) {
- data->callback(data->userdata, node->index, data->co, &data->nearest);
- }
- else {
- data->nearest.index = node->index;
- data->nearest.dist_sq = calc_nearest_point_squared(data->proj, node, data->nearest.co);
- }
- }
- else {
- float nearest[3];
-
- for (int i = 0; i != node->totnode; i++) {
- float dist_sq = calc_nearest_point_squared(data->proj, node->children[i], nearest);
-
- if (dist_sq < data->nearest.dist_sq) {
- BLI_heapsimple_insert(heap, dist_sq, node->children[i]);
- }
- }
- }
+ if (node->totnode == 0) {
+ if (data->callback) {
+ data->callback(data->userdata, node->index, data->co, &data->nearest);
+ }
+ else {
+ data->nearest.index = node->index;
+ data->nearest.dist_sq = calc_nearest_point_squared(data->proj, node, data->nearest.co);
+ }
+ }
+ else {
+ float nearest[3];
+
+ for (int i = 0; i != node->totnode; i++) {
+ float dist_sq = calc_nearest_point_squared(data->proj, node->children[i], nearest);
+
+ if (dist_sq < data->nearest.dist_sq) {
+ BLI_heapsimple_insert(heap, dist_sq, node->children[i]);
+ }
+ }
+ }
}
static void heap_find_nearest_begin(BVHNearestData *data, BVHNode *root)
{
- float nearest[3];
- float dist_sq = calc_nearest_point_squared(data->proj, root, nearest);
+ float nearest[3];
+ float dist_sq = calc_nearest_point_squared(data->proj, root, nearest);
- if (dist_sq < data->nearest.dist_sq) {
- HeapSimple *heap = BLI_heapsimple_new_ex(32);
+ if (dist_sq < data->nearest.dist_sq) {
+ HeapSimple *heap = BLI_heapsimple_new_ex(32);
- heap_find_nearest_inner(data, heap, root);
+ heap_find_nearest_inner(data, heap, root);
- while (!BLI_heapsimple_is_empty(heap) && BLI_heapsimple_top_value(heap) < data->nearest.dist_sq) {
- BVHNode *node = BLI_heapsimple_pop_min(heap);
- heap_find_nearest_inner(data, heap, node);
- }
+ while (!BLI_heapsimple_is_empty(heap) &&
+ BLI_heapsimple_top_value(heap) < data->nearest.dist_sq) {
+ BVHNode *node = BLI_heapsimple_pop_min(heap);
+ heap_find_nearest_inner(data, heap, node);
+ }
- BLI_heapsimple_free(heap, NULL);
- }
+ BLI_heapsimple_free(heap, NULL);
+ }
}
-int BLI_bvhtree_find_nearest_ex(
- BVHTree *tree, const float co[3], BVHTreeNearest *nearest,
- BVHTree_NearestPointCallback callback, void *userdata,
- int flag)
+int BLI_bvhtree_find_nearest_ex(BVHTree *tree,
+ const float co[3],
+ BVHTreeNearest *nearest,
+ BVHTree_NearestPointCallback callback,
+ void *userdata,
+ int flag)
{
- axis_t axis_iter;
-
- BVHNearestData data;
- BVHNode *root = tree->nodes[tree->totleaf];
-
- /* init data to search */
- data.tree = tree;
- data.co = co;
-
- data.callback = callback;
- data.userdata = userdata;
-
- for (axis_iter = data.tree->start_axis; axis_iter != data.tree->stop_axis; axis_iter++) {
- data.proj[axis_iter] = dot_v3v3(data.co, bvhtree_kdop_axes[axis_iter]);
- }
-
- if (nearest) {
- memcpy(&data.nearest, nearest, sizeof(*nearest));
- }
- else {
- data.nearest.index = -1;
- data.nearest.dist_sq = FLT_MAX;
- }
-
- /* dfs search */
- if (root) {
- if (flag & BVH_NEAREST_OPTIMAL_ORDER) {
- heap_find_nearest_begin(&data, root);
- }
- else {
- dfs_find_nearest_begin(&data, root);
- }
- }
-
- /* copy back results */
- if (nearest) {
- memcpy(nearest, &data.nearest, sizeof(*nearest));
- }
-
- return data.nearest.index;
+ axis_t axis_iter;
+
+ BVHNearestData data;
+ BVHNode *root = tree->nodes[tree->totleaf];
+
+ /* init data to search */
+ data.tree = tree;
+ data.co = co;
+
+ data.callback = callback;
+ data.userdata = userdata;
+
+ for (axis_iter = data.tree->start_axis; axis_iter != data.tree->stop_axis; axis_iter++) {
+ data.proj[axis_iter] = dot_v3v3(data.co, bvhtree_kdop_axes[axis_iter]);
+ }
+
+ if (nearest) {
+ memcpy(&data.nearest, nearest, sizeof(*nearest));
+ }
+ else {
+ data.nearest.index = -1;
+ data.nearest.dist_sq = FLT_MAX;
+ }
+
+ /* dfs search */
+ if (root) {
+ if (flag & BVH_NEAREST_OPTIMAL_ORDER) {
+ heap_find_nearest_begin(&data, root);
+ }
+ else {
+ dfs_find_nearest_begin(&data, root);
+ }
+ }
+
+ /* copy back results */
+ if (nearest) {
+ memcpy(nearest, &data.nearest, sizeof(*nearest));
+ }
+
+ return data.nearest.index;
}
-int BLI_bvhtree_find_nearest(
- BVHTree *tree, const float co[3], BVHTreeNearest *nearest,
- BVHTree_NearestPointCallback callback, void *userdata)
+int BLI_bvhtree_find_nearest(BVHTree *tree,
+ const float co[3],
+ BVHTreeNearest *nearest,
+ BVHTree_NearestPointCallback callback,
+ void *userdata)
{
- return BLI_bvhtree_find_nearest_ex(tree, co, nearest, callback, userdata, 0);
+ return BLI_bvhtree_find_nearest_ex(tree, co, nearest, callback, userdata, 0);
}
/** \} */
-
/* -------------------------------------------------------------------- */
/** \name BLI_bvhtree_ray_cast
*
@@ -1458,50 +1466,48 @@ int BLI_bvhtree_find_nearest(
*
* \{ */
-
/* Determines the distance that the ray must travel to hit the bounding volume of the given node */
static float ray_nearest_hit(const BVHRayCastData *data, const float bv[6])
{
- int i;
-
- float low = 0, upper = data->hit.dist;
-
- for (i = 0; i != 3; i++, bv += 2) {
- if (data->ray_dot_axis[i] == 0.0f) {
- /* axis aligned ray */
- if (data->ray.origin[i] < bv[0] - data->ray.radius ||
- data->ray.origin[i] > bv[1] + data->ray.radius)
- {
- return FLT_MAX;
- }
- }
- else {
- float ll = (bv[0] - data->ray.radius - data->ray.origin[i]) / data->ray_dot_axis[i];
- float lu = (bv[1] + data->ray.radius - data->ray.origin[i]) / data->ray_dot_axis[i];
-
- if (data->ray_dot_axis[i] > 0.0f) {
- if (ll > low) {
- low = ll;
- }
- if (lu < upper) {
- upper = lu;
- }
- }
- else {
- if (lu > low) {
- low = lu;
- }
- if (ll < upper) {
- upper = ll;
- }
- }
-
- if (low > upper) {
- return FLT_MAX;
- }
- }
- }
- return low;
+ int i;
+
+ float low = 0, upper = data->hit.dist;
+
+ for (i = 0; i != 3; i++, bv += 2) {
+ if (data->ray_dot_axis[i] == 0.0f) {
+ /* axis aligned ray */
+ if (data->ray.origin[i] < bv[0] - data->ray.radius ||
+ data->ray.origin[i] > bv[1] + data->ray.radius) {
+ return FLT_MAX;
+ }
+ }
+ else {
+ float ll = (bv[0] - data->ray.radius - data->ray.origin[i]) / data->ray_dot_axis[i];
+ float lu = (bv[1] + data->ray.radius - data->ray.origin[i]) / data->ray_dot_axis[i];
+
+ if (data->ray_dot_axis[i] > 0.0f) {
+ if (ll > low) {
+ low = ll;
+ }
+ if (lu < upper) {
+ upper = lu;
+ }
+ }
+ else {
+ if (lu > low) {
+ low = lu;
+ }
+ if (ll < upper) {
+ upper = ll;
+ }
+ }
+
+ if (low > upper) {
+ return FLT_MAX;
+ }
+ }
+ }
+ return low;
}
/**
@@ -1512,61 +1518,61 @@ static float ray_nearest_hit(const BVHRayCastData *data, const float bv[6])
* TODO this doesn't take data->ray.radius into consideration */
static float fast_ray_nearest_hit(const BVHRayCastData *data, const BVHNode *node)
{
- const float *bv = node->bv;
-
- float t1x = (bv[data->index[0]] - data->ray.origin[0]) * data->idot_axis[0];
- float t2x = (bv[data->index[1]] - data->ray.origin[0]) * data->idot_axis[0];
- float t1y = (bv[data->index[2]] - data->ray.origin[1]) * data->idot_axis[1];
- float t2y = (bv[data->index[3]] - data->ray.origin[1]) * data->idot_axis[1];
- float t1z = (bv[data->index[4]] - data->ray.origin[2]) * data->idot_axis[2];
- float t2z = (bv[data->index[5]] - data->ray.origin[2]) * data->idot_axis[2];
-
- if ((t1x > t2y || t2x < t1y || t1x > t2z || t2x < t1z || t1y > t2z || t2y < t1z) ||
- (t2x < 0.0f || t2y < 0.0f || t2z < 0.0f) ||
- (t1x > data->hit.dist || t1y > data->hit.dist || t1z > data->hit.dist))
- {
- return FLT_MAX;
- }
- else {
- return max_fff(t1x, t1y, t1z);
- }
+ const float *bv = node->bv;
+
+ float t1x = (bv[data->index[0]] - data->ray.origin[0]) * data->idot_axis[0];
+ float t2x = (bv[data->index[1]] - data->ray.origin[0]) * data->idot_axis[0];
+ float t1y = (bv[data->index[2]] - data->ray.origin[1]) * data->idot_axis[1];
+ float t2y = (bv[data->index[3]] - data->ray.origin[1]) * data->idot_axis[1];
+ float t1z = (bv[data->index[4]] - data->ray.origin[2]) * data->idot_axis[2];
+ float t2z = (bv[data->index[5]] - data->ray.origin[2]) * data->idot_axis[2];
+
+ if ((t1x > t2y || t2x < t1y || t1x > t2z || t2x < t1z || t1y > t2z || t2y < t1z) ||
+ (t2x < 0.0f || t2y < 0.0f || t2z < 0.0f) ||
+ (t1x > data->hit.dist || t1y > data->hit.dist || t1z > data->hit.dist)) {
+ return FLT_MAX;
+ }
+ else {
+ return max_fff(t1x, t1y, t1z);
+ }
}
static void dfs_raycast(BVHRayCastData *data, BVHNode *node)
{
- int i;
-
- /* ray-bv is really fast.. and simple tests revealed its worth to test it
- * before calling the ray-primitive functions */
- /* XXX: temporary solution for particles until fast_ray_nearest_hit supports ray.radius */
- float dist = (data->ray.radius == 0.0f) ? fast_ray_nearest_hit(data, node) : ray_nearest_hit(data, node->bv);
- if (dist >= data->hit.dist) {
- return;
- }
-
- if (node->totnode == 0) {
- if (data->callback) {
- data->callback(data->userdata, node->index, &data->ray, &data->hit);
- }
- else {
- data->hit.index = node->index;
- data->hit.dist = dist;
- madd_v3_v3v3fl(data->hit.co, data->ray.origin, data->ray.direction, dist);
- }
- }
- else {
- /* pick loop direction to dive into the tree (based on ray direction and split axis) */
- if (data->ray_dot_axis[node->main_axis] > 0.0f) {
- for (i = 0; i != node->totnode; i++) {
- dfs_raycast(data, node->children[i]);
- }
- }
- else {
- for (i = node->totnode - 1; i >= 0; i--) {
- dfs_raycast(data, node->children[i]);
- }
- }
- }
+ int i;
+
+ /* ray-bv is really fast.. and simple tests revealed its worth to test it
+ * before calling the ray-primitive functions */
+ /* XXX: temporary solution for particles until fast_ray_nearest_hit supports ray.radius */
+ float dist = (data->ray.radius == 0.0f) ? fast_ray_nearest_hit(data, node) :
+ ray_nearest_hit(data, node->bv);
+ if (dist >= data->hit.dist) {
+ return;
+ }
+
+ if (node->totnode == 0) {
+ if (data->callback) {
+ data->callback(data->userdata, node->index, &data->ray, &data->hit);
+ }
+ else {
+ data->hit.index = node->index;
+ data->hit.dist = dist;
+ madd_v3_v3v3fl(data->hit.co, data->ray.origin, data->ray.direction, dist);
+ }
+ }
+ else {
+ /* pick loop direction to dive into the tree (based on ray direction and split axis) */
+ if (data->ray_dot_axis[node->main_axis] > 0.0f) {
+ for (i = 0; i != node->totnode; i++) {
+ dfs_raycast(data, node->children[i]);
+ }
+ }
+ else {
+ for (i = node->totnode - 1; i >= 0; i--) {
+ dfs_raycast(data, node->children[i]);
+ }
+ }
+ }
}
/**
@@ -1574,140 +1580,151 @@ static void dfs_raycast(BVHRayCastData *data, BVHNode *node)
*/
static void dfs_raycast_all(BVHRayCastData *data, BVHNode *node)
{
- int i;
-
- /* ray-bv is really fast.. and simple tests revealed its worth to test it
- * before calling the ray-primitive functions */
- /* XXX: temporary solution for particles until fast_ray_nearest_hit supports ray.radius */
- float dist = (data->ray.radius == 0.0f) ? fast_ray_nearest_hit(data, node) : ray_nearest_hit(data, node->bv);
- if (dist >= data->hit.dist) {
- return;
- }
-
- if (node->totnode == 0) {
- /* no need to check for 'data->callback' (using 'all' only makes sense with a callback). */
- dist = data->hit.dist;
- data->callback(data->userdata, node->index, &data->ray, &data->hit);
- data->hit.index = -1;
- data->hit.dist = dist;
- }
- else {
- /* pick loop direction to dive into the tree (based on ray direction and split axis) */
- if (data->ray_dot_axis[node->main_axis] > 0.0f) {
- for (i = 0; i != node->totnode; i++) {
- dfs_raycast_all(data, node->children[i]);
- }
- }
- else {
- for (i = node->totnode - 1; i >= 0; i--) {
- dfs_raycast_all(data, node->children[i]);
- }
- }
- }
+ int i;
+
+ /* ray-bv is really fast.. and simple tests revealed its worth to test it
+ * before calling the ray-primitive functions */
+ /* XXX: temporary solution for particles until fast_ray_nearest_hit supports ray.radius */
+ float dist = (data->ray.radius == 0.0f) ? fast_ray_nearest_hit(data, node) :
+ ray_nearest_hit(data, node->bv);
+ if (dist >= data->hit.dist) {
+ return;
+ }
+
+ if (node->totnode == 0) {
+ /* no need to check for 'data->callback' (using 'all' only makes sense with a callback). */
+ dist = data->hit.dist;
+ data->callback(data->userdata, node->index, &data->ray, &data->hit);
+ data->hit.index = -1;
+ data->hit.dist = dist;
+ }
+ else {
+ /* pick loop direction to dive into the tree (based on ray direction and split axis) */
+ if (data->ray_dot_axis[node->main_axis] > 0.0f) {
+ for (i = 0; i != node->totnode; i++) {
+ dfs_raycast_all(data, node->children[i]);
+ }
+ }
+ else {
+ for (i = node->totnode - 1; i >= 0; i--) {
+ dfs_raycast_all(data, node->children[i]);
+ }
+ }
+ }
}
static void bvhtree_ray_cast_data_precalc(BVHRayCastData *data, int flag)
{
- int i;
+ int i;
- for (i = 0; i < 3; i++) {
- data->ray_dot_axis[i] = dot_v3v3(data->ray.direction, bvhtree_kdop_axes[i]);
- data->idot_axis[i] = 1.0f / data->ray_dot_axis[i];
+ for (i = 0; i < 3; i++) {
+ data->ray_dot_axis[i] = dot_v3v3(data->ray.direction, bvhtree_kdop_axes[i]);
+ data->idot_axis[i] = 1.0f / data->ray_dot_axis[i];
- if (fabsf(data->ray_dot_axis[i]) < FLT_EPSILON) {
- data->ray_dot_axis[i] = 0.0;
- }
- data->index[2 * i] = data->idot_axis[i] < 0.0f ? 1 : 0;
- data->index[2 * i + 1] = 1 - data->index[2 * i];
- data->index[2 * i] += 2 * i;
- data->index[2 * i + 1] += 2 * i;
- }
+ if (fabsf(data->ray_dot_axis[i]) < FLT_EPSILON) {
+ data->ray_dot_axis[i] = 0.0;
+ }
+ data->index[2 * i] = data->idot_axis[i] < 0.0f ? 1 : 0;
+ data->index[2 * i + 1] = 1 - data->index[2 * i];
+ data->index[2 * i] += 2 * i;
+ data->index[2 * i + 1] += 2 * i;
+ }
#ifdef USE_KDOPBVH_WATERTIGHT
- if (flag & BVH_RAYCAST_WATERTIGHT) {
- isect_ray_tri_watertight_v3_precalc(&data->isect_precalc, data->ray.direction);
- data->ray.isect_precalc = &data->isect_precalc;
- }
- else {
- data->ray.isect_precalc = NULL;
- }
+ if (flag & BVH_RAYCAST_WATERTIGHT) {
+ isect_ray_tri_watertight_v3_precalc(&data->isect_precalc, data->ray.direction);
+ data->ray.isect_precalc = &data->isect_precalc;
+ }
+ else {
+ data->ray.isect_precalc = NULL;
+ }
#else
- UNUSED_VARS(flag);
+ UNUSED_VARS(flag);
#endif
}
-int BLI_bvhtree_ray_cast_ex(
- BVHTree *tree, const float co[3], const float dir[3], float radius, BVHTreeRayHit *hit,
- BVHTree_RayCastCallback callback, void *userdata,
- int flag)
+int BLI_bvhtree_ray_cast_ex(BVHTree *tree,
+ const float co[3],
+ const float dir[3],
+ float radius,
+ BVHTreeRayHit *hit,
+ BVHTree_RayCastCallback callback,
+ void *userdata,
+ int flag)
{
- BVHRayCastData data;
- BVHNode *root = tree->nodes[tree->totleaf];
-
- BLI_ASSERT_UNIT_V3(dir);
+ BVHRayCastData data;
+ BVHNode *root = tree->nodes[tree->totleaf];
- data.tree = tree;
+ BLI_ASSERT_UNIT_V3(dir);
- data.callback = callback;
- data.userdata = userdata;
+ data.tree = tree;
- copy_v3_v3(data.ray.origin, co);
- copy_v3_v3(data.ray.direction, dir);
- data.ray.radius = radius;
+ data.callback = callback;
+ data.userdata = userdata;
- bvhtree_ray_cast_data_precalc(&data, flag);
+ copy_v3_v3(data.ray.origin, co);
+ copy_v3_v3(data.ray.direction, dir);
+ data.ray.radius = radius;
- if (hit) {
- memcpy(&data.hit, hit, sizeof(*hit));
- }
- else {
- data.hit.index = -1;
- data.hit.dist = BVH_RAYCAST_DIST_MAX;
- }
+ bvhtree_ray_cast_data_precalc(&data, flag);
- if (root) {
- dfs_raycast(&data, root);
-// iterative_raycast(&data, root);
- }
+ if (hit) {
+ memcpy(&data.hit, hit, sizeof(*hit));
+ }
+ else {
+ data.hit.index = -1;
+ data.hit.dist = BVH_RAYCAST_DIST_MAX;
+ }
+ if (root) {
+ dfs_raycast(&data, root);
+ // iterative_raycast(&data, root);
+ }
- if (hit) {
- memcpy(hit, &data.hit, sizeof(*hit));
- }
+ if (hit) {
+ memcpy(hit, &data.hit, sizeof(*hit));
+ }
- return data.hit.index;
+ return data.hit.index;
}
-int BLI_bvhtree_ray_cast(
- BVHTree *tree, const float co[3], const float dir[3], float radius, BVHTreeRayHit *hit,
- BVHTree_RayCastCallback callback, void *userdata)
+int BLI_bvhtree_ray_cast(BVHTree *tree,
+ const float co[3],
+ const float dir[3],
+ float radius,
+ BVHTreeRayHit *hit,
+ BVHTree_RayCastCallback callback,
+ void *userdata)
{
- return BLI_bvhtree_ray_cast_ex(tree, co, dir, radius, hit, callback, userdata, BVH_RAYCAST_DEFAULT);
+ return BLI_bvhtree_ray_cast_ex(
+ tree, co, dir, radius, hit, callback, userdata, BVH_RAYCAST_DEFAULT);
}
-float BLI_bvhtree_bb_raycast(const float bv[6], const float light_start[3], const float light_end[3], float pos[3])
+float BLI_bvhtree_bb_raycast(const float bv[6],
+ const float light_start[3],
+ const float light_end[3],
+ float pos[3])
{
- BVHRayCastData data;
- float dist;
-
- data.hit.dist = BVH_RAYCAST_DIST_MAX;
+ BVHRayCastData data;
+ float dist;
- /* get light direction */
- sub_v3_v3v3(data.ray.direction, light_end, light_start);
+ data.hit.dist = BVH_RAYCAST_DIST_MAX;
- data.ray.radius = 0.0;
+ /* get light direction */
+ sub_v3_v3v3(data.ray.direction, light_end, light_start);
- copy_v3_v3(data.ray.origin, light_start);
+ data.ray.radius = 0.0;
- normalize_v3(data.ray.direction);
- copy_v3_v3(data.ray_dot_axis, data.ray.direction);
+ copy_v3_v3(data.ray.origin, light_start);
- dist = ray_nearest_hit(&data, bv);
+ normalize_v3(data.ray.direction);
+ copy_v3_v3(data.ray_dot_axis, data.ray.direction);
- madd_v3_v3v3fl(pos, light_start, data.ray.direction, dist);
+ dist = ray_nearest_hit(&data, bv);
- return dist;
+ madd_v3_v3v3fl(pos, light_start, data.ray.direction, dist);
+ return dist;
}
/**
@@ -1718,41 +1735,50 @@ float BLI_bvhtree_bb_raycast(const float bv[6], const float light_start[3], cons
* having to handle resetting the hit beforehand.
* It also avoid redundant argument and return value which aren't meaningful when collecting multiple hits.
*/
-void BLI_bvhtree_ray_cast_all_ex(
- BVHTree *tree, const float co[3], const float dir[3], float radius, float hit_dist,
- BVHTree_RayCastCallback callback, void *userdata,
- int flag)
+void BLI_bvhtree_ray_cast_all_ex(BVHTree *tree,
+ const float co[3],
+ const float dir[3],
+ float radius,
+ float hit_dist,
+ BVHTree_RayCastCallback callback,
+ void *userdata,
+ int flag)
{
- BVHRayCastData data;
- BVHNode *root = tree->nodes[tree->totleaf];
+ BVHRayCastData data;
+ BVHNode *root = tree->nodes[tree->totleaf];
- BLI_ASSERT_UNIT_V3(dir);
- BLI_assert(callback != NULL);
+ BLI_ASSERT_UNIT_V3(dir);
+ BLI_assert(callback != NULL);
- data.tree = tree;
+ data.tree = tree;
- data.callback = callback;
- data.userdata = userdata;
+ data.callback = callback;
+ data.userdata = userdata;
- copy_v3_v3(data.ray.origin, co);
- copy_v3_v3(data.ray.direction, dir);
- data.ray.radius = radius;
+ copy_v3_v3(data.ray.origin, co);
+ copy_v3_v3(data.ray.direction, dir);
+ data.ray.radius = radius;
- bvhtree_ray_cast_data_precalc(&data, flag);
+ bvhtree_ray_cast_data_precalc(&data, flag);
- data.hit.index = -1;
- data.hit.dist = hit_dist;
+ data.hit.index = -1;
+ data.hit.dist = hit_dist;
- if (root) {
- dfs_raycast_all(&data, root);
- }
+ if (root) {
+ dfs_raycast_all(&data, root);
+ }
}
-void BLI_bvhtree_ray_cast_all(
- BVHTree *tree, const float co[3], const float dir[3], float radius, float hit_dist,
- BVHTree_RayCastCallback callback, void *userdata)
+void BLI_bvhtree_ray_cast_all(BVHTree *tree,
+ const float co[3],
+ const float dir[3],
+ float radius,
+ float hit_dist,
+ BVHTree_RayCastCallback callback,
+ void *userdata)
{
- BLI_bvhtree_ray_cast_all_ex(tree, co, dir, radius, hit_dist, callback, userdata, BVH_RAYCAST_DEFAULT);
+ BLI_bvhtree_ray_cast_all_ex(
+ tree, co, dir, radius, hit_dist, callback, userdata, BVH_RAYCAST_DEFAULT);
}
/** \} */
@@ -1766,284 +1792,274 @@ void BLI_bvhtree_ray_cast_all(
* \{ */
typedef struct RangeQueryData {
- BVHTree *tree;
- const float *center;
- float radius_sq; /* squared radius */
+ BVHTree *tree;
+ const float *center;
+ float radius_sq; /* squared radius */
- int hits;
+ int hits;
- BVHTree_RangeQuery callback;
- void *userdata;
+ BVHTree_RangeQuery callback;
+ void *userdata;
} RangeQueryData;
-
static void dfs_range_query(RangeQueryData *data, BVHNode *node)
{
- if (node->totnode == 0) {
-#if 0 /*UNUSED*/
- /* Calculate the node min-coords
- * (if the node was a point then this is the point coordinates) */
- float co[3];
- co[0] = node->bv[0];
- co[1] = node->bv[2];
- co[2] = node->bv[4];
+ if (node->totnode == 0) {
+#if 0 /*UNUSED*/
+ /* Calculate the node min-coords
+ * (if the node was a point then this is the point coordinates) */
+ float co[3];
+ co[0] = node->bv[0];
+ co[1] = node->bv[2];
+ co[2] = node->bv[4];
#endif
- }
- else {
- int i;
- for (i = 0; i != node->totnode; i++) {
- float nearest[3];
- float dist_sq = calc_nearest_point_squared(data->center, node->children[i], nearest);
- if (dist_sq < data->radius_sq) {
- /* Its a leaf.. call the callback */
- if (node->children[i]->totnode == 0) {
- data->hits++;
- data->callback(data->userdata, node->children[i]->index, data->center, dist_sq);
- }
- else {
- dfs_range_query(data, node->children[i]);
- }
- }
- }
- }
+ }
+ else {
+ int i;
+ for (i = 0; i != node->totnode; i++) {
+ float nearest[3];
+ float dist_sq = calc_nearest_point_squared(data->center, node->children[i], nearest);
+ if (dist_sq < data->radius_sq) {
+ /* Its a leaf.. call the callback */
+ if (node->children[i]->totnode == 0) {
+ data->hits++;
+ data->callback(data->userdata, node->children[i]->index, data->center, dist_sq);
+ }
+ else {
+ dfs_range_query(data, node->children[i]);
+ }
+ }
+ }
+ }
}
int BLI_bvhtree_range_query(
- BVHTree *tree, const float co[3], float radius,
- BVHTree_RangeQuery callback, void *userdata)
+ BVHTree *tree, const float co[3], float radius, BVHTree_RangeQuery callback, void *userdata)
{
- BVHNode *root = tree->nodes[tree->totleaf];
-
- RangeQueryData data;
- data.tree = tree;
- data.center = co;
- data.radius_sq = radius * radius;
- data.hits = 0;
-
- data.callback = callback;
- data.userdata = userdata;
-
- if (root != NULL) {
- float nearest[3];
- float dist_sq = calc_nearest_point_squared(data.center, root, nearest);
- if (dist_sq < data.radius_sq) {
- /* Its a leaf.. call the callback */
- if (root->totnode == 0) {
- data.hits++;
- data.callback(data.userdata, root->index, co, dist_sq);
- }
- else {
- dfs_range_query(&data, root);
- }
- }
- }
-
- return data.hits;
+ BVHNode *root = tree->nodes[tree->totleaf];
+
+ RangeQueryData data;
+ data.tree = tree;
+ data.center = co;
+ data.radius_sq = radius * radius;
+ data.hits = 0;
+
+ data.callback = callback;
+ data.userdata = userdata;
+
+ if (root != NULL) {
+ float nearest[3];
+ float dist_sq = calc_nearest_point_squared(data.center, root, nearest);
+ if (dist_sq < data.radius_sq) {
+ /* Its a leaf.. call the callback */
+ if (root->totnode == 0) {
+ data.hits++;
+ data.callback(data.userdata, root->index, co, dist_sq);
+ }
+ else {
+ dfs_range_query(&data, root);
+ }
+ }
+ }
+
+ return data.hits;
}
/** \} */
-
/* -------------------------------------------------------------------- */
/** \name BLI_bvhtree_nearest_projected
* \{ */
-static void bvhtree_nearest_projected_dfs_recursive(
- BVHNearestProjectedData *__restrict data, const BVHNode *node)
+static void bvhtree_nearest_projected_dfs_recursive(BVHNearestProjectedData *__restrict data,
+ const BVHNode *node)
{
- if (node->totnode == 0) {
- if (data->callback) {
- data->callback(
- data->userdata, node->index, &data->precalc,
- NULL, 0,
- &data->nearest);
- }
- else {
- data->nearest.index = node->index;
- data->nearest.dist_sq = dist_squared_to_projected_aabb(
- &data->precalc,
- (float[3]) {node->bv[0], node->bv[2], node->bv[4]},
- (float[3]) {node->bv[1], node->bv[3], node->bv[5]},
- data->closest_axis);
- }
- }
- else {
- /* First pick the closest node to recurse into */
- if (data->closest_axis[node->main_axis]) {
- for (int i = 0; i != node->totnode; i++) {
- const float *bv = node->children[i]->bv;
-
- if (dist_squared_to_projected_aabb(
- &data->precalc,
- (float[3]) {bv[0], bv[2], bv[4]},
- (float[3]) {bv[1], bv[3], bv[5]},
- data->closest_axis) <= data->nearest.dist_sq)
- {
- bvhtree_nearest_projected_dfs_recursive(data, node->children[i]);
- }
- }
- }
- else {
- for (int i = node->totnode; i--;) {
- const float *bv = node->children[i]->bv;
-
- if (dist_squared_to_projected_aabb(
- &data->precalc,
- (float[3]) {bv[0], bv[2], bv[4]},
- (float[3]) {bv[1], bv[3], bv[5]},
- data->closest_axis) <= data->nearest.dist_sq)
- {
- bvhtree_nearest_projected_dfs_recursive(data, node->children[i]);
- }
- }
- }
- }
+ if (node->totnode == 0) {
+ if (data->callback) {
+ data->callback(data->userdata, node->index, &data->precalc, NULL, 0, &data->nearest);
+ }
+ else {
+ data->nearest.index = node->index;
+ data->nearest.dist_sq = dist_squared_to_projected_aabb(
+ &data->precalc,
+ (float[3]){node->bv[0], node->bv[2], node->bv[4]},
+ (float[3]){node->bv[1], node->bv[3], node->bv[5]},
+ data->closest_axis);
+ }
+ }
+ else {
+ /* First pick the closest node to recurse into */
+ if (data->closest_axis[node->main_axis]) {
+ for (int i = 0; i != node->totnode; i++) {
+ const float *bv = node->children[i]->bv;
+
+ if (dist_squared_to_projected_aabb(&data->precalc,
+ (float[3]){bv[0], bv[2], bv[4]},
+ (float[3]){bv[1], bv[3], bv[5]},
+ data->closest_axis) <= data->nearest.dist_sq) {
+ bvhtree_nearest_projected_dfs_recursive(data, node->children[i]);
+ }
+ }
+ }
+ else {
+ for (int i = node->totnode; i--;) {
+ const float *bv = node->children[i]->bv;
+
+ if (dist_squared_to_projected_aabb(&data->precalc,
+ (float[3]){bv[0], bv[2], bv[4]},
+ (float[3]){bv[1], bv[3], bv[5]},
+ data->closest_axis) <= data->nearest.dist_sq) {
+ bvhtree_nearest_projected_dfs_recursive(data, node->children[i]);
+ }
+ }
+ }
+ }
}
static void bvhtree_nearest_projected_with_clipplane_test_dfs_recursive(
- BVHNearestProjectedData *__restrict data, const BVHNode *node)
+ BVHNearestProjectedData *__restrict data, const BVHNode *node)
{
- if (node->totnode == 0) {
- if (data->callback) {
- data->callback(
- data->userdata, node->index, &data->precalc,
- data->clip_plane, data->clip_plane_len,
- &data->nearest);
- }
- else {
- data->nearest.index = node->index;
- data->nearest.dist_sq = dist_squared_to_projected_aabb(
- &data->precalc,
- (float[3]) {node->bv[0], node->bv[2], node->bv[4]},
- (float[3]) {node->bv[1], node->bv[3], node->bv[5]},
- data->closest_axis);
- }
- }
- else {
- /* First pick the closest node to recurse into */
- if (data->closest_axis[node->main_axis]) {
- for (int i = 0; i != node->totnode; i++) {
- const float *bv = node->children[i]->bv;
- const float bb_min[3] = {bv[0], bv[2], bv[4]};
- const float bb_max[3] = {bv[1], bv[3], bv[5]};
-
- int isect_type = isect_aabb_planes_v3(data->clip_plane, data->clip_plane_len, bb_min, bb_max);
-
- if ((isect_type != ISECT_AABB_PLANE_BEHIND_ANY) && dist_squared_to_projected_aabb(
- &data->precalc, bb_min, bb_max,
- data->closest_axis) <= data->nearest.dist_sq)
- {
- if (isect_type == ISECT_AABB_PLANE_CROSS_ANY) {
- bvhtree_nearest_projected_with_clipplane_test_dfs_recursive(data, node->children[i]);
- }
- else {
- /* ISECT_AABB_PLANE_IN_FRONT_ALL */
- bvhtree_nearest_projected_dfs_recursive(data, node->children[i]);
- }
- }
- }
- }
- else {
- for (int i = node->totnode; i--;) {
- const float *bv = node->children[i]->bv;
- const float bb_min[3] = {bv[0], bv[2], bv[4]};
- const float bb_max[3] = {bv[1], bv[3], bv[5]};
-
- int isect_type = isect_aabb_planes_v3(data->clip_plane, data->clip_plane_len, bb_min, bb_max);
-
- if (isect_type != ISECT_AABB_PLANE_BEHIND_ANY && dist_squared_to_projected_aabb(
- &data->precalc, bb_min, bb_max,
- data->closest_axis) <= data->nearest.dist_sq)
- {
- if (isect_type == ISECT_AABB_PLANE_CROSS_ANY) {
- bvhtree_nearest_projected_with_clipplane_test_dfs_recursive(data, node->children[i]);
- }
- else {
- /* ISECT_AABB_PLANE_IN_FRONT_ALL */
- bvhtree_nearest_projected_dfs_recursive(data, node->children[i]);
- }
- }
- }
- }
- }
+ if (node->totnode == 0) {
+ if (data->callback) {
+ data->callback(data->userdata,
+ node->index,
+ &data->precalc,
+ data->clip_plane,
+ data->clip_plane_len,
+ &data->nearest);
+ }
+ else {
+ data->nearest.index = node->index;
+ data->nearest.dist_sq = dist_squared_to_projected_aabb(
+ &data->precalc,
+ (float[3]){node->bv[0], node->bv[2], node->bv[4]},
+ (float[3]){node->bv[1], node->bv[3], node->bv[5]},
+ data->closest_axis);
+ }
+ }
+ else {
+ /* First pick the closest node to recurse into */
+ if (data->closest_axis[node->main_axis]) {
+ for (int i = 0; i != node->totnode; i++) {
+ const float *bv = node->children[i]->bv;
+ const float bb_min[3] = {bv[0], bv[2], bv[4]};
+ const float bb_max[3] = {bv[1], bv[3], bv[5]};
+
+ int isect_type = isect_aabb_planes_v3(
+ data->clip_plane, data->clip_plane_len, bb_min, bb_max);
+
+ if ((isect_type != ISECT_AABB_PLANE_BEHIND_ANY) &&
+ dist_squared_to_projected_aabb(&data->precalc, bb_min, bb_max, data->closest_axis) <=
+ data->nearest.dist_sq) {
+ if (isect_type == ISECT_AABB_PLANE_CROSS_ANY) {
+ bvhtree_nearest_projected_with_clipplane_test_dfs_recursive(data, node->children[i]);
+ }
+ else {
+ /* ISECT_AABB_PLANE_IN_FRONT_ALL */
+ bvhtree_nearest_projected_dfs_recursive(data, node->children[i]);
+ }
+ }
+ }
+ }
+ else {
+ for (int i = node->totnode; i--;) {
+ const float *bv = node->children[i]->bv;
+ const float bb_min[3] = {bv[0], bv[2], bv[4]};
+ const float bb_max[3] = {bv[1], bv[3], bv[5]};
+
+ int isect_type = isect_aabb_planes_v3(
+ data->clip_plane, data->clip_plane_len, bb_min, bb_max);
+
+ if (isect_type != ISECT_AABB_PLANE_BEHIND_ANY &&
+ dist_squared_to_projected_aabb(&data->precalc, bb_min, bb_max, data->closest_axis) <=
+ data->nearest.dist_sq) {
+ if (isect_type == ISECT_AABB_PLANE_CROSS_ANY) {
+ bvhtree_nearest_projected_with_clipplane_test_dfs_recursive(data, node->children[i]);
+ }
+ else {
+ /* ISECT_AABB_PLANE_IN_FRONT_ALL */
+ bvhtree_nearest_projected_dfs_recursive(data, node->children[i]);
+ }
+ }
+ }
+ }
+ }
}
-int BLI_bvhtree_find_nearest_projected(
- BVHTree *tree, float projmat[4][4], float winsize[2], float mval[2],
- float clip_plane[6][4], int clip_plane_len,
- BVHTreeNearest *nearest,
- BVHTree_NearestProjectedCallback callback, void *userdata)
+int BLI_bvhtree_find_nearest_projected(BVHTree *tree,
+ float projmat[4][4],
+ float winsize[2],
+ float mval[2],
+ float clip_plane[6][4],
+ int clip_plane_len,
+ BVHTreeNearest *nearest,
+ BVHTree_NearestProjectedCallback callback,
+ void *userdata)
{
- BVHNode *root = tree->nodes[tree->totleaf];
- if (root != NULL) {
- BVHNearestProjectedData data;
- dist_squared_to_projected_aabb_precalc(
- &data.precalc, projmat, winsize, mval);
-
- data.callback = callback;
- data.userdata = userdata;
-
- if (clip_plane) {
- data.clip_plane_len = clip_plane_len;
- for (int i = 0; i < data.clip_plane_len; i++) {
- copy_v4_v4(data.clip_plane[i], clip_plane[i]);
- }
- }
- else {
- data.clip_plane_len = 1;
- planes_from_projmat(
- projmat,
- NULL, NULL, NULL, NULL,
- data.clip_plane[0], NULL);
- }
-
- if (nearest) {
- memcpy(&data.nearest, nearest, sizeof(*nearest));
- }
- else {
- data.nearest.index = -1;
- data.nearest.dist_sq = FLT_MAX;
- }
- {
- const float bb_min[3] = {root->bv[0], root->bv[2], root->bv[4]};
- const float bb_max[3] = {root->bv[1], root->bv[3], root->bv[5]};
-
- int isect_type = isect_aabb_planes_v3(data.clip_plane, data.clip_plane_len, bb_min, bb_max);
-
- if (isect_type != 0 && dist_squared_to_projected_aabb(
- &data.precalc, bb_min, bb_max,
- data.closest_axis) <= data.nearest.dist_sq)
- {
- if (isect_type == 1) {
- bvhtree_nearest_projected_with_clipplane_test_dfs_recursive(&data, root);
- }
- else {
- bvhtree_nearest_projected_dfs_recursive(&data, root);
- }
- }
- }
-
- if (nearest) {
- memcpy(nearest, &data.nearest, sizeof(*nearest));
- }
-
- return data.nearest.index;
- }
- return -1;
+ BVHNode *root = tree->nodes[tree->totleaf];
+ if (root != NULL) {
+ BVHNearestProjectedData data;
+ dist_squared_to_projected_aabb_precalc(&data.precalc, projmat, winsize, mval);
+
+ data.callback = callback;
+ data.userdata = userdata;
+
+ if (clip_plane) {
+ data.clip_plane_len = clip_plane_len;
+ for (int i = 0; i < data.clip_plane_len; i++) {
+ copy_v4_v4(data.clip_plane[i], clip_plane[i]);
+ }
+ }
+ else {
+ data.clip_plane_len = 1;
+ planes_from_projmat(projmat, NULL, NULL, NULL, NULL, data.clip_plane[0], NULL);
+ }
+
+ if (nearest) {
+ memcpy(&data.nearest, nearest, sizeof(*nearest));
+ }
+ else {
+ data.nearest.index = -1;
+ data.nearest.dist_sq = FLT_MAX;
+ }
+ {
+ const float bb_min[3] = {root->bv[0], root->bv[2], root->bv[4]};
+ const float bb_max[3] = {root->bv[1], root->bv[3], root->bv[5]};
+
+ int isect_type = isect_aabb_planes_v3(data.clip_plane, data.clip_plane_len, bb_min, bb_max);
+
+ if (isect_type != 0 &&
+ dist_squared_to_projected_aabb(&data.precalc, bb_min, bb_max, data.closest_axis) <=
+ data.nearest.dist_sq) {
+ if (isect_type == 1) {
+ bvhtree_nearest_projected_with_clipplane_test_dfs_recursive(&data, root);
+ }
+ else {
+ bvhtree_nearest_projected_dfs_recursive(&data, root);
+ }
+ }
+ }
+
+ if (nearest) {
+ memcpy(nearest, &data.nearest, sizeof(*nearest));
+ }
+
+ return data.nearest.index;
+ }
+ return -1;
}
/** \} */
-
/* -------------------------------------------------------------------- */
/** \name BLI_bvhtree_walk_dfs
* \{ */
typedef struct BVHTree_WalkData {
- BVHTree_WalkParentCallback walk_parent_cb;
- BVHTree_WalkLeafCallback walk_leaf_cb;
- BVHTree_WalkOrderCallback walk_order_cb;
- void *userdata;
+ BVHTree_WalkParentCallback walk_parent_cb;
+ BVHTree_WalkLeafCallback walk_leaf_cb;
+ BVHTree_WalkOrderCallback walk_order_cb;
+ void *userdata;
} BVHTree_WalkData;
/**
@@ -2051,35 +2067,37 @@ typedef struct BVHTree_WalkData {
*
* \return false to break out of the search early.
*/
-static bool bvhtree_walk_dfs_recursive(
- BVHTree_WalkData *walk_data,
- const BVHNode *node)
+static bool bvhtree_walk_dfs_recursive(BVHTree_WalkData *walk_data, const BVHNode *node)
{
- if (node->totnode == 0) {
- return walk_data->walk_leaf_cb((const BVHTreeAxisRange *)node->bv, node->index, walk_data->userdata);
- }
- else {
- /* First pick the closest node to recurse into */
- if (walk_data->walk_order_cb((const BVHTreeAxisRange *)node->bv, node->main_axis, walk_data->userdata)) {
- for (int i = 0; i != node->totnode; i++) {
- if (walk_data->walk_parent_cb((const BVHTreeAxisRange *)node->children[i]->bv, walk_data->userdata)) {
- if (!bvhtree_walk_dfs_recursive(walk_data, node->children[i])) {
- return false;
- }
- }
- }
- }
- else {
- for (int i = node->totnode - 1; i >= 0; i--) {
- if (walk_data->walk_parent_cb((const BVHTreeAxisRange *)node->children[i]->bv, walk_data->userdata)) {
- if (!bvhtree_walk_dfs_recursive(walk_data, node->children[i])) {
- return false;
- }
- }
- }
- }
- }
- return true;
+ if (node->totnode == 0) {
+ return walk_data->walk_leaf_cb(
+ (const BVHTreeAxisRange *)node->bv, node->index, walk_data->userdata);
+ }
+ else {
+ /* First pick the closest node to recurse into */
+ if (walk_data->walk_order_cb(
+ (const BVHTreeAxisRange *)node->bv, node->main_axis, walk_data->userdata)) {
+ for (int i = 0; i != node->totnode; i++) {
+ if (walk_data->walk_parent_cb((const BVHTreeAxisRange *)node->children[i]->bv,
+ walk_data->userdata)) {
+ if (!bvhtree_walk_dfs_recursive(walk_data, node->children[i])) {
+ return false;
+ }
+ }
+ }
+ }
+ else {
+ for (int i = node->totnode - 1; i >= 0; i--) {
+ if (walk_data->walk_parent_cb((const BVHTreeAxisRange *)node->children[i]->bv,
+ walk_data->userdata)) {
+ if (!bvhtree_walk_dfs_recursive(walk_data, node->children[i])) {
+ return false;
+ }
+ }
+ }
+ }
+ }
+ return true;
}
/**
@@ -2094,20 +2112,20 @@ static bool bvhtree_walk_dfs_recursive(
* either from the node with the lower or higher k-dop axis value.
* \param userdata: Argument passed to all callbacks.
*/
-void BLI_bvhtree_walk_dfs(
- BVHTree *tree,
- BVHTree_WalkParentCallback walk_parent_cb,
- BVHTree_WalkLeafCallback walk_leaf_cb,
- BVHTree_WalkOrderCallback walk_order_cb, void *userdata)
+void BLI_bvhtree_walk_dfs(BVHTree *tree,
+ BVHTree_WalkParentCallback walk_parent_cb,
+ BVHTree_WalkLeafCallback walk_leaf_cb,
+ BVHTree_WalkOrderCallback walk_order_cb,
+ void *userdata)
{
- const BVHNode *root = tree->nodes[tree->totleaf];
- if (root != NULL) {
- BVHTree_WalkData walk_data = {walk_parent_cb, walk_leaf_cb, walk_order_cb, userdata};
- /* first make sure the bv of root passes in the test too */
- if (walk_parent_cb((const BVHTreeAxisRange *)root->bv, userdata)) {
- bvhtree_walk_dfs_recursive(&walk_data, root);
- }
- }
+ const BVHNode *root = tree->nodes[tree->totleaf];
+ if (root != NULL) {
+ BVHTree_WalkData walk_data = {walk_parent_cb, walk_leaf_cb, walk_order_cb, userdata};
+ /* first make sure the bv of root passes in the test too */
+ if (walk_parent_cb((const BVHTreeAxisRange *)root->bv, userdata)) {
+ bvhtree_walk_dfs_recursive(&walk_data, root);
+ }
+ }
}
/** \} */
diff --git a/source/blender/blenlib/intern/BLI_linklist.c b/source/blender/blenlib/intern/BLI_linklist.c
index 3f99f65703f..ae4f5dcebcf 100644
--- a/source/blender/blenlib/intern/BLI_linklist.c
+++ b/source/blender/blenlib/intern/BLI_linklist.c
@@ -39,55 +39,55 @@
int BLI_linklist_count(const LinkNode *list)
{
- int len;
+ int len;
- for (len = 0; list; list = list->next) {
- len++;
- }
+ for (len = 0; list; list = list->next) {
+ len++;
+ }
- return len;
+ return len;
}
int BLI_linklist_index(const LinkNode *list, void *ptr)
{
- int index;
+ int index;
- for (index = 0; list; list = list->next, index++) {
- if (list->link == ptr) {
- return index;
- }
- }
+ for (index = 0; list; list = list->next, index++) {
+ if (list->link == ptr) {
+ return index;
+ }
+ }
- return -1;
+ return -1;
}
LinkNode *BLI_linklist_find(LinkNode *list, int index)
{
- int i;
+ int i;
- for (i = 0; list; list = list->next, i++) {
- if (i == index) {
- return list;
- }
- }
+ for (i = 0; list; list = list->next, i++) {
+ if (i == index) {
+ return list;
+ }
+ }
- return NULL;
+ return NULL;
}
void BLI_linklist_reverse(LinkNode **listp)
{
- LinkNode *rhead = NULL, *cur = *listp;
+ LinkNode *rhead = NULL, *cur = *listp;
- while (cur) {
- LinkNode *next = cur->next;
+ while (cur) {
+ LinkNode *next = cur->next;
- cur->next = rhead;
- rhead = cur;
+ cur->next = rhead;
+ rhead = cur;
- cur = next;
- }
+ cur = next;
+ }
- *listp = rhead;
+ *listp = rhead;
}
/**
@@ -96,69 +96,69 @@ void BLI_linklist_reverse(LinkNode **listp)
*/
void BLI_linklist_move_item(LinkNode **listp, int curr_index, int new_index)
{
- LinkNode *lnk, *lnk_psrc = NULL, *lnk_pdst = NULL;
- int i;
-
- if (new_index == curr_index) {
- return;
- }
-
- if (new_index < curr_index) {
- for (lnk = *listp, i = 0; lnk; lnk = lnk->next, i++) {
- if (i == new_index - 1) {
- lnk_pdst = lnk;
- }
- else if (i == curr_index - 1) {
- lnk_psrc = lnk;
- break;
- }
- }
-
- if (!(lnk_psrc && lnk_psrc->next && (!lnk_pdst || lnk_pdst->next))) {
- /* Invalid indices, abort. */
- return;
- }
-
- lnk = lnk_psrc->next;
- lnk_psrc->next = lnk->next;
- if (lnk_pdst) {
- lnk->next = lnk_pdst->next;
- lnk_pdst->next = lnk;
- }
- else {
- /* destination is first element of the list... */
- lnk->next = *listp;
- *listp = lnk;
- }
- }
- else {
- for (lnk = *listp, i = 0; lnk; lnk = lnk->next, i++) {
- if (i == new_index) {
- lnk_pdst = lnk;
- break;
- }
- else if (i == curr_index - 1) {
- lnk_psrc = lnk;
- }
- }
-
- if (!(lnk_pdst && (!lnk_psrc || lnk_psrc->next))) {
- /* Invalid indices, abort. */
- return;
- }
-
- if (lnk_psrc) {
- lnk = lnk_psrc->next;
- lnk_psrc->next = lnk->next;
- }
- else {
- /* source is first element of the list... */
- lnk = *listp;
- *listp = lnk->next;
- }
- lnk->next = lnk_pdst->next;
- lnk_pdst->next = lnk;
- }
+ LinkNode *lnk, *lnk_psrc = NULL, *lnk_pdst = NULL;
+ int i;
+
+ if (new_index == curr_index) {
+ return;
+ }
+
+ if (new_index < curr_index) {
+ for (lnk = *listp, i = 0; lnk; lnk = lnk->next, i++) {
+ if (i == new_index - 1) {
+ lnk_pdst = lnk;
+ }
+ else if (i == curr_index - 1) {
+ lnk_psrc = lnk;
+ break;
+ }
+ }
+
+ if (!(lnk_psrc && lnk_psrc->next && (!lnk_pdst || lnk_pdst->next))) {
+ /* Invalid indices, abort. */
+ return;
+ }
+
+ lnk = lnk_psrc->next;
+ lnk_psrc->next = lnk->next;
+ if (lnk_pdst) {
+ lnk->next = lnk_pdst->next;
+ lnk_pdst->next = lnk;
+ }
+ else {
+ /* destination is first element of the list... */
+ lnk->next = *listp;
+ *listp = lnk;
+ }
+ }
+ else {
+ for (lnk = *listp, i = 0; lnk; lnk = lnk->next, i++) {
+ if (i == new_index) {
+ lnk_pdst = lnk;
+ break;
+ }
+ else if (i == curr_index - 1) {
+ lnk_psrc = lnk;
+ }
+ }
+
+ if (!(lnk_pdst && (!lnk_psrc || lnk_psrc->next))) {
+ /* Invalid indices, abort. */
+ return;
+ }
+
+ if (lnk_psrc) {
+ lnk = lnk_psrc->next;
+ lnk_psrc->next = lnk->next;
+ }
+ else {
+ /* source is first element of the list... */
+ lnk = *listp;
+ *listp = lnk->next;
+ }
+ lnk->next = lnk_pdst->next;
+ lnk_pdst->next = lnk;
+ }
}
/**
@@ -166,27 +166,27 @@ void BLI_linklist_move_item(LinkNode **listp, int curr_index, int new_index)
*/
void BLI_linklist_prepend_nlink(LinkNode **listp, void *ptr, LinkNode *nlink)
{
- nlink->link = ptr;
- nlink->next = *listp;
- *listp = nlink;
+ nlink->link = ptr;
+ nlink->next = *listp;
+ *listp = nlink;
}
void BLI_linklist_prepend(LinkNode **listp, void *ptr)
{
- LinkNode *nlink = MEM_mallocN(sizeof(*nlink), __func__);
- BLI_linklist_prepend_nlink(listp, ptr, nlink);
+ LinkNode *nlink = MEM_mallocN(sizeof(*nlink), __func__);
+ BLI_linklist_prepend_nlink(listp, ptr, nlink);
}
void BLI_linklist_prepend_arena(LinkNode **listp, void *ptr, MemArena *ma)
{
- LinkNode *nlink = BLI_memarena_alloc(ma, sizeof(*nlink));
- BLI_linklist_prepend_nlink(listp, ptr, nlink);
+ LinkNode *nlink = BLI_memarena_alloc(ma, sizeof(*nlink));
+ BLI_linklist_prepend_nlink(listp, ptr, nlink);
}
void BLI_linklist_prepend_pool(LinkNode **listp, void *ptr, BLI_mempool *mempool)
{
- LinkNode *nlink = BLI_mempool_alloc(mempool);
- BLI_linklist_prepend_nlink(listp, ptr, nlink);
+ LinkNode *nlink = BLI_mempool_alloc(mempool);
+ BLI_linklist_prepend_nlink(listp, ptr, nlink);
}
/**
@@ -194,125 +194,125 @@ void BLI_linklist_prepend_pool(LinkNode **listp, void *ptr, BLI_mempool *mempool
*/
void BLI_linklist_append_nlink(LinkNodePair *list_pair, void *ptr, LinkNode *nlink)
{
- nlink->link = ptr;
- nlink->next = NULL;
-
- if (list_pair->list) {
- BLI_assert((list_pair->last_node != NULL) && (list_pair->last_node->next == NULL));
- list_pair->last_node->next = nlink;
- }
- else {
- BLI_assert(list_pair->last_node == NULL);
- list_pair->list = nlink;
- }
-
- list_pair->last_node = nlink;
+ nlink->link = ptr;
+ nlink->next = NULL;
+
+ if (list_pair->list) {
+ BLI_assert((list_pair->last_node != NULL) && (list_pair->last_node->next == NULL));
+ list_pair->last_node->next = nlink;
+ }
+ else {
+ BLI_assert(list_pair->last_node == NULL);
+ list_pair->list = nlink;
+ }
+
+ list_pair->last_node = nlink;
}
void BLI_linklist_append(LinkNodePair *list_pair, void *ptr)
{
- LinkNode *nlink = MEM_mallocN(sizeof(*nlink), __func__);
- BLI_linklist_append_nlink(list_pair, ptr, nlink);
+ LinkNode *nlink = MEM_mallocN(sizeof(*nlink), __func__);
+ BLI_linklist_append_nlink(list_pair, ptr, nlink);
}
void BLI_linklist_append_arena(LinkNodePair *list_pair, void *ptr, MemArena *ma)
{
- LinkNode *nlink = BLI_memarena_alloc(ma, sizeof(*nlink));
- BLI_linklist_append_nlink(list_pair, ptr, nlink);
+ LinkNode *nlink = BLI_memarena_alloc(ma, sizeof(*nlink));
+ BLI_linklist_append_nlink(list_pair, ptr, nlink);
}
void BLI_linklist_append_pool(LinkNodePair *list_pair, void *ptr, BLI_mempool *mempool)
{
- LinkNode *nlink = BLI_mempool_alloc(mempool);
- BLI_linklist_append_nlink(list_pair, ptr, nlink);
+ LinkNode *nlink = BLI_mempool_alloc(mempool);
+ BLI_linklist_append_nlink(list_pair, ptr, nlink);
}
void *BLI_linklist_pop(struct LinkNode **listp)
{
- /* intentionally no NULL check */
- void *link = (*listp)->link;
- void *next = (*listp)->next;
+ /* intentionally no NULL check */
+ void *link = (*listp)->link;
+ void *next = (*listp)->next;
- MEM_freeN(*listp);
+ MEM_freeN(*listp);
- *listp = next;
- return link;
+ *listp = next;
+ return link;
}
void *BLI_linklist_pop_pool(struct LinkNode **listp, struct BLI_mempool *mempool)
{
- /* intentionally no NULL check */
- void *link = (*listp)->link;
- void *next = (*listp)->next;
+ /* intentionally no NULL check */
+ void *link = (*listp)->link;
+ void *next = (*listp)->next;
- BLI_mempool_free(mempool, (*listp));
+ BLI_mempool_free(mempool, (*listp));
- *listp = next;
- return link;
+ *listp = next;
+ return link;
}
void BLI_linklist_insert_after(LinkNode **listp, void *ptr)
{
- LinkNode *nlink = MEM_mallocN(sizeof(*nlink), __func__);
- LinkNode *node = *listp;
-
- nlink->link = ptr;
-
- if (node) {
- nlink->next = node->next;
- node->next = nlink;
- }
- else {
- nlink->next = NULL;
- *listp = nlink;
- }
+ LinkNode *nlink = MEM_mallocN(sizeof(*nlink), __func__);
+ LinkNode *node = *listp;
+
+ nlink->link = ptr;
+
+ if (node) {
+ nlink->next = node->next;
+ node->next = nlink;
+ }
+ else {
+ nlink->next = NULL;
+ *listp = nlink;
+ }
}
void BLI_linklist_free(LinkNode *list, LinkNodeFreeFP freefunc)
{
- while (list) {
- LinkNode *next = list->next;
+ while (list) {
+ LinkNode *next = list->next;
- if (freefunc) {
- freefunc(list->link);
- }
- MEM_freeN(list);
+ if (freefunc) {
+ freefunc(list->link);
+ }
+ MEM_freeN(list);
- list = next;
- }
+ list = next;
+ }
}
void BLI_linklist_free_pool(LinkNode *list, LinkNodeFreeFP freefunc, struct BLI_mempool *mempool)
{
- while (list) {
- LinkNode *next = list->next;
+ while (list) {
+ LinkNode *next = list->next;
- if (freefunc) {
- freefunc(list->link);
- }
- BLI_mempool_free(mempool, list);
+ if (freefunc) {
+ freefunc(list->link);
+ }
+ BLI_mempool_free(mempool, list);
- list = next;
- }
+ list = next;
+ }
}
void BLI_linklist_freeN(LinkNode *list)
{
- while (list) {
- LinkNode *next = list->next;
+ while (list) {
+ LinkNode *next = list->next;
- MEM_freeN(list->link);
- MEM_freeN(list);
+ MEM_freeN(list->link);
+ MEM_freeN(list);
- list = next;
- }
+ list = next;
+ }
}
void BLI_linklist_apply(LinkNode *list, LinkNodeApplyFP applyfunc, void *userdata)
{
- for (; list; list = list->next) {
- applyfunc(list->link, userdata);
- }
+ for (; list; list = list->next) {
+ applyfunc(list->link, userdata);
+ }
}
/* -------------------------------------------------------------------- */
@@ -335,19 +335,20 @@ void BLI_linklist_apply(LinkNode *list, LinkNodeApplyFP applyfunc, void *userdat
#undef SORT_IMPL_LINKTYPE
#undef SORT_IMPL_LINKTYPE_DATA
-
LinkNode *BLI_linklist_sort(LinkNode *list, int (*cmp)(const void *, const void *))
{
- if (list && list->next) {
- list = linklist_sort_fn(list, cmp);
- }
- return list;
+ if (list && list->next) {
+ list = linklist_sort_fn(list, cmp);
+ }
+ return list;
}
-LinkNode *BLI_linklist_sort_r(LinkNode *list, int (*cmp)(void *, const void *, const void *), void *thunk)
+LinkNode *BLI_linklist_sort_r(LinkNode *list,
+ int (*cmp)(void *, const void *, const void *),
+ void *thunk)
{
- if (list && list->next) {
- list = linklist_sort_fn_r(list, cmp, thunk);
- }
- return list;
+ if (list && list->next) {
+ list = linklist_sort_fn_r(list, cmp, thunk);
+ }
+ return list;
}
diff --git a/source/blender/blenlib/intern/BLI_linklist_lockfree.c b/source/blender/blenlib/intern/BLI_linklist_lockfree.c
index d5dca86ae50..d27e65af778 100644
--- a/source/blender/blenlib/intern/BLI_linklist_lockfree.c
+++ b/source/blender/blenlib/intern/BLI_linklist_lockfree.c
@@ -30,56 +30,52 @@
void BLI_linklist_lockfree_init(LockfreeLinkList *list)
{
- list->dummy_node.next = NULL;
- list->head = list->tail = &list->dummy_node;
+ list->dummy_node.next = NULL;
+ list->head = list->tail = &list->dummy_node;
}
-void BLI_linklist_lockfree_free(LockfreeLinkList *list,
- LockfreeeLinkNodeFreeFP free_func)
+void BLI_linklist_lockfree_free(LockfreeLinkList *list, LockfreeeLinkNodeFreeFP free_func)
{
- if (free_func != NULL) {
- /* NOTE: We start from a first user-added node. */
- LockfreeLinkNode *node = list->head->next;
- while (node != NULL) {
- LockfreeLinkNode *node_next = node->next;
- free_func(node);
- node = node_next;
- }
- }
+ if (free_func != NULL) {
+ /* NOTE: We start from a first user-added node. */
+ LockfreeLinkNode *node = list->head->next;
+ while (node != NULL) {
+ LockfreeLinkNode *node_next = node->next;
+ free_func(node);
+ node = node_next;
+ }
+ }
}
-void BLI_linklist_lockfree_clear(LockfreeLinkList *list,
- LockfreeeLinkNodeFreeFP free_func)
+void BLI_linklist_lockfree_clear(LockfreeLinkList *list, LockfreeeLinkNodeFreeFP free_func)
{
- BLI_linklist_lockfree_free(list, free_func);
- BLI_linklist_lockfree_init(list);
+ BLI_linklist_lockfree_free(list, free_func);
+ BLI_linklist_lockfree_init(list);
}
-void BLI_linklist_lockfree_insert(LockfreeLinkList *list,
- LockfreeLinkNode *node)
+void BLI_linklist_lockfree_insert(LockfreeLinkList *list, LockfreeLinkNode *node)
{
- /* Based on:
- *
- * John D. Valois
- * Implementing Lock-Free Queues
- *
- * http://people.csail.mit.edu/bushl2/rpi/portfolio/lockfree-grape/documents/lock-free-linked-lists.pdf
- */
- bool keep_working;
- LockfreeLinkNode *tail_node;
- node->next = NULL;
- do {
- tail_node = list->tail;
- keep_working =
- (atomic_cas_ptr((void **)&tail_node->next, NULL, node) != NULL);
- if (keep_working) {
- atomic_cas_ptr((void **)&list->tail, tail_node, tail_node->next);
- }
- } while (keep_working);
- atomic_cas_ptr((void **)&list->tail, tail_node, node);
+ /* Based on:
+ *
+ * John D. Valois
+ * Implementing Lock-Free Queues
+ *
+ * http://people.csail.mit.edu/bushl2/rpi/portfolio/lockfree-grape/documents/lock-free-linked-lists.pdf
+ */
+ bool keep_working;
+ LockfreeLinkNode *tail_node;
+ node->next = NULL;
+ do {
+ tail_node = list->tail;
+ keep_working = (atomic_cas_ptr((void **)&tail_node->next, NULL, node) != NULL);
+ if (keep_working) {
+ atomic_cas_ptr((void **)&list->tail, tail_node, tail_node->next);
+ }
+ } while (keep_working);
+ atomic_cas_ptr((void **)&list->tail, tail_node, node);
}
LockfreeLinkNode *BLI_linklist_lockfree_begin(LockfreeLinkList *list)
{
- return list->head->next;
+ return list->head->next;
}
diff --git a/source/blender/blenlib/intern/BLI_memarena.c b/source/blender/blenlib/intern/BLI_memarena.c
index 8be64a44d2c..b5815f7b503 100644
--- a/source/blender/blenlib/intern/BLI_memarena.c
+++ b/source/blender/blenlib/intern/BLI_memarena.c
@@ -58,129 +58,130 @@
#endif
struct MemBuf {
- struct MemBuf *next;
- uchar data[0];
+ struct MemBuf *next;
+ uchar data[0];
};
struct MemArena {
- unsigned char *curbuf;
- const char *name;
- struct MemBuf *bufs;
+ unsigned char *curbuf;
+ const char *name;
+ struct MemBuf *bufs;
- size_t bufsize, cursize;
- size_t align;
+ size_t bufsize, cursize;
+ size_t align;
- bool use_calloc;
+ bool use_calloc;
};
static void memarena_buf_free_all(struct MemBuf *mb)
{
- while (mb != NULL) {
- struct MemBuf *mb_next = mb->next;
- MEM_freeN(mb);
- mb = mb_next;
- }
+ while (mb != NULL) {
+ struct MemBuf *mb_next = mb->next;
+ MEM_freeN(mb);
+ mb = mb_next;
+ }
}
MemArena *BLI_memarena_new(const size_t bufsize, const char *name)
{
- MemArena *ma = MEM_callocN(sizeof(*ma), "memarena");
- ma->bufsize = bufsize;
- ma->align = 8;
- ma->name = name;
+ MemArena *ma = MEM_callocN(sizeof(*ma), "memarena");
+ ma->bufsize = bufsize;
+ ma->align = 8;
+ ma->name = name;
- VALGRIND_CREATE_MEMPOOL(ma, 0, false);
+ VALGRIND_CREATE_MEMPOOL(ma, 0, false);
- return ma;
+ return ma;
}
void BLI_memarena_use_calloc(MemArena *ma)
{
- ma->use_calloc = 1;
+ ma->use_calloc = 1;
}
void BLI_memarena_use_malloc(MemArena *ma)
{
- ma->use_calloc = 0;
+ ma->use_calloc = 0;
}
void BLI_memarena_use_align(struct MemArena *ma, const size_t align)
{
- /* Align must be a power of two. */
- BLI_assert((align & (align - 1)) == 0);
+ /* Align must be a power of two. */
+ BLI_assert((align & (align - 1)) == 0);
- ma->align = align;
+ ma->align = align;
}
void BLI_memarena_free(MemArena *ma)
{
- memarena_buf_free_all(ma->bufs);
+ memarena_buf_free_all(ma->bufs);
- VALGRIND_DESTROY_MEMPOOL(ma);
+ VALGRIND_DESTROY_MEMPOOL(ma);
- MEM_freeN(ma);
+ MEM_freeN(ma);
}
/** Pad num up by \a amt (must be power of two). */
-#define PADUP(num, amt) (((num) + ((amt) - 1)) & ~((amt) - 1))
+#define PADUP(num, amt) (((num) + ((amt)-1)) & ~((amt)-1))
/** Align alloc'ed memory (needed if `align > 8`). */
static void memarena_curbuf_align(MemArena *ma)
{
- unsigned char *tmp;
+ unsigned char *tmp;
- tmp = (unsigned char *)PADUP((intptr_t)ma->curbuf, (int)ma->align);
- ma->cursize -= (size_t)(tmp - ma->curbuf);
- ma->curbuf = tmp;
+ tmp = (unsigned char *)PADUP((intptr_t)ma->curbuf, (int)ma->align);
+ ma->cursize -= (size_t)(tmp - ma->curbuf);
+ ma->curbuf = tmp;
}
void *BLI_memarena_alloc(MemArena *ma, size_t size)
{
- void *ptr;
+ void *ptr;
- /* Ensure proper alignment by rounding size up to multiple of 8. */
- size = PADUP(size, ma->align);
+ /* Ensure proper alignment by rounding size up to multiple of 8. */
+ size = PADUP(size, ma->align);
- if (UNLIKELY(size > ma->cursize)) {
- if (size > ma->bufsize - (ma->align - 1)) {
- ma->cursize = PADUP(size + 1, ma->align);
- }
- else {
- ma->cursize = ma->bufsize;
- }
+ if (UNLIKELY(size > ma->cursize)) {
+ if (size > ma->bufsize - (ma->align - 1)) {
+ ma->cursize = PADUP(size + 1, ma->align);
+ }
+ else {
+ ma->cursize = ma->bufsize;
+ }
- struct MemBuf *mb = (ma->use_calloc ? MEM_callocN : MEM_mallocN)(sizeof(*mb) + ma->cursize, ma->name);
- ma->curbuf = mb->data;
- mb->next = ma->bufs;
- ma->bufs = mb;
+ struct MemBuf *mb = (ma->use_calloc ? MEM_callocN : MEM_mallocN)(sizeof(*mb) + ma->cursize,
+ ma->name);
+ ma->curbuf = mb->data;
+ mb->next = ma->bufs;
+ ma->bufs = mb;
- ASAN_POISON_MEMORY_REGION(ma->curbuf, ma->cursize);
+ ASAN_POISON_MEMORY_REGION(ma->curbuf, ma->cursize);
- memarena_curbuf_align(ma);
- }
+ memarena_curbuf_align(ma);
+ }
- ptr = ma->curbuf;
- ma->curbuf += size;
- ma->cursize -= size;
+ ptr = ma->curbuf;
+ ma->curbuf += size;
+ ma->cursize -= size;
- VALGRIND_MEMPOOL_ALLOC(ma, ptr, size);
+ VALGRIND_MEMPOOL_ALLOC(ma, ptr, size);
- ASAN_UNPOISON_MEMORY_REGION(ptr, size);
+ ASAN_UNPOISON_MEMORY_REGION(ptr, size);
- return ptr;
+ return ptr;
}
void *BLI_memarena_calloc(MemArena *ma, size_t size)
{
- void *ptr;
+ void *ptr;
- /* No need to use this function call if we're calloc'ing by default. */
- BLI_assert(ma->use_calloc == false);
+ /* No need to use this function call if we're calloc'ing by default. */
+ BLI_assert(ma->use_calloc == false);
- ptr = BLI_memarena_alloc(ma, size);
- memset(ptr, 0, size);
+ ptr = BLI_memarena_alloc(ma, size);
+ memset(ptr, 0, size);
- return ptr;
+ return ptr;
}
/**
@@ -189,29 +190,29 @@ void *BLI_memarena_calloc(MemArena *ma, size_t size)
*/
void BLI_memarena_clear(MemArena *ma)
{
- if (ma->bufs) {
- unsigned char *curbuf_prev;
- size_t curbuf_used;
-
- if (ma->bufs->next) {
- memarena_buf_free_all(ma->bufs->next);
- ma->bufs->next = NULL;
- }
-
- curbuf_prev = ma->curbuf;
- ma->curbuf = ma->bufs->data;
- memarena_curbuf_align(ma);
-
- /* restore to original size */
- curbuf_used = (size_t)(curbuf_prev - ma->curbuf);
- ma->cursize += curbuf_used;
-
- if (ma->use_calloc) {
- memset(ma->curbuf, 0, curbuf_used);
- }
- ASAN_POISON_MEMORY_REGION(ma->curbuf, ma->cursize);
- }
-
- VALGRIND_DESTROY_MEMPOOL(ma);
- VALGRIND_CREATE_MEMPOOL(ma, 0, false);
+ if (ma->bufs) {
+ unsigned char *curbuf_prev;
+ size_t curbuf_used;
+
+ if (ma->bufs->next) {
+ memarena_buf_free_all(ma->bufs->next);
+ ma->bufs->next = NULL;
+ }
+
+ curbuf_prev = ma->curbuf;
+ ma->curbuf = ma->bufs->data;
+ memarena_curbuf_align(ma);
+
+ /* restore to original size */
+ curbuf_used = (size_t)(curbuf_prev - ma->curbuf);
+ ma->cursize += curbuf_used;
+
+ if (ma->use_calloc) {
+ memset(ma->curbuf, 0, curbuf_used);
+ }
+ ASAN_POISON_MEMORY_REGION(ma->curbuf, ma->cursize);
+ }
+
+ VALGRIND_DESTROY_MEMPOOL(ma);
+ VALGRIND_CREATE_MEMPOOL(ma, 0, false);
}
diff --git a/source/blender/blenlib/intern/BLI_memiter.c b/source/blender/blenlib/intern/BLI_memiter.c
index df8a1de84e4..c7df7d5fdd4 100644
--- a/source/blender/blenlib/intern/BLI_memiter.c
+++ b/source/blender/blenlib/intern/BLI_memiter.c
@@ -69,66 +69,65 @@ typedef intptr_t offset_t;
// #define USE_TERMINATE_PARANOID
/* Currently totalloc isnt used. */
- // #define USE_TOTALLOC
+// #define USE_TOTALLOC
/* pad must be power of two */
-#define PADUP(num, pad) (((num) + ((pad) - 1)) & ~((pad) - 1))
+#define PADUP(num, pad) (((num) + ((pad)-1)) & ~((pad)-1))
typedef struct BLI_memiter_elem {
- offset_t size;
- data_t data[0];
+ offset_t size;
+ data_t data[0];
} BLI_memiter_elem;
typedef struct BLI_memiter_chunk {
- struct BLI_memiter_chunk *next;
- /**
- * internal format is:
- * ``[next_pointer, size:data, size:data, ..., negative_offset]``
- *
- * Where negative offset rewinds to the start.
- */
- data_t data[0];
+ struct BLI_memiter_chunk *next;
+ /**
+ * internal format is:
+ * ``[next_pointer, size:data, size:data, ..., negative_offset]``
+ *
+ * Where negative offset rewinds to the start.
+ */
+ data_t data[0];
} BLI_memiter_chunk;
typedef struct BLI_memiter {
- /* A pointer to 'head' is needed so we can iterate in the order allocated. */
- struct BLI_memiter_chunk *head, *tail;
- data_t *data_curr;
- data_t *data_last;
- /* Used unless a large element is requested.
- * (which should be very rare!). */
- uint chunk_size_in_bytes_min;
- uint count;
+ /* A pointer to 'head' is needed so we can iterate in the order allocated. */
+ struct BLI_memiter_chunk *head, *tail;
+ data_t *data_curr;
+ data_t *data_last;
+ /* Used unless a large element is requested.
+ * (which should be very rare!). */
+ uint chunk_size_in_bytes_min;
+ uint count;
#ifdef USE_TOTALLOC
- uint totalloc;
+ uint totalloc;
#endif
} BLI_memiter;
-
BLI_INLINE uint data_offset_from_size(uint size)
{
- return (PADUP(size, (uint)sizeof(data_t))) / (uint)sizeof(data_t);
+ return (PADUP(size, (uint)sizeof(data_t))) / (uint)sizeof(data_t);
}
static void memiter_set_rewind_offset(BLI_memiter *mi)
{
- BLI_memiter_elem *elem = (BLI_memiter_elem *)mi->data_curr;
+ BLI_memiter_elem *elem = (BLI_memiter_elem *)mi->data_curr;
- ASAN_UNPOISON_MEMORY_REGION(elem, sizeof(BLI_memiter_elem));
+ ASAN_UNPOISON_MEMORY_REGION(elem, sizeof(BLI_memiter_elem));
- elem->size = (offset_t)(((data_t *)mi->tail) - mi->data_curr);
- BLI_assert(elem->size < 0);
+ elem->size = (offset_t)(((data_t *)mi->tail) - mi->data_curr);
+ BLI_assert(elem->size < 0);
}
static void memiter_init(BLI_memiter *mi)
{
- mi->head = NULL;
- mi->tail = NULL;
- mi->data_curr = NULL;
- mi->data_last = NULL;
- mi->count = 0;
+ mi->head = NULL;
+ mi->tail = NULL;
+ mi->data_curr = NULL;
+ mi->data_last = NULL;
+ mi->count = 0;
#ifdef USE_TOTALLOC
- mi->totalloc = 0;
+ mi->totalloc = 0;
#endif
}
@@ -147,126 +146,123 @@ static void memiter_init(BLI_memiter *mi)
*/
BLI_memiter *BLI_memiter_create(uint chunk_size_min)
{
- BLI_memiter *mi = MEM_mallocN(sizeof(BLI_memiter), "BLI_memiter");
- memiter_init(mi);
-
- /* Small values are used for tests to check for correctness,
- * but otherwise not that useful. */
- const uint slop_space = (sizeof(BLI_memiter_chunk) + MEM_SIZE_OVERHEAD);
- if (chunk_size_min >= 1024) {
- /* As long as the input is a power of 2, this will give efficient sizes. */
- chunk_size_min -= slop_space;
- }
-
- mi->chunk_size_in_bytes_min = chunk_size_min;
- return mi;
+ BLI_memiter *mi = MEM_mallocN(sizeof(BLI_memiter), "BLI_memiter");
+ memiter_init(mi);
+
+ /* Small values are used for tests to check for correctness,
+ * but otherwise not that useful. */
+ const uint slop_space = (sizeof(BLI_memiter_chunk) + MEM_SIZE_OVERHEAD);
+ if (chunk_size_min >= 1024) {
+ /* As long as the input is a power of 2, this will give efficient sizes. */
+ chunk_size_min -= slop_space;
+ }
+
+ mi->chunk_size_in_bytes_min = chunk_size_min;
+ return mi;
}
void *BLI_memiter_alloc(BLI_memiter *mi, uint elem_size)
{
- const uint data_offset = data_offset_from_size(elem_size);
- data_t *data_curr_next = mi->data_curr + (1 + data_offset);
+ const uint data_offset = data_offset_from_size(elem_size);
+ data_t *data_curr_next = mi->data_curr + (1 + data_offset);
- if (UNLIKELY(mi->data_curr == NULL) || (data_curr_next > mi->data_last)) {
+ if (UNLIKELY(mi->data_curr == NULL) || (data_curr_next > mi->data_last)) {
#ifndef USE_TERMINATE_PARANOID
- if (mi->data_curr != NULL) {
- memiter_set_rewind_offset(mi);
- }
+ if (mi->data_curr != NULL) {
+ memiter_set_rewind_offset(mi);
+ }
#endif
- uint chunk_size_in_bytes = mi->chunk_size_in_bytes_min;
- if (UNLIKELY(chunk_size_in_bytes < elem_size + (uint)sizeof(data_t[2]))) {
- chunk_size_in_bytes = elem_size + (uint)sizeof(data_t[2]);
- }
- uint chunk_size = data_offset_from_size(chunk_size_in_bytes);
- BLI_memiter_chunk *chunk = MEM_mallocN(
- sizeof(BLI_memiter_chunk) +
- (chunk_size * sizeof(data_t)),
- "BLI_memiter_chunk");
+ uint chunk_size_in_bytes = mi->chunk_size_in_bytes_min;
+ if (UNLIKELY(chunk_size_in_bytes < elem_size + (uint)sizeof(data_t[2]))) {
+ chunk_size_in_bytes = elem_size + (uint)sizeof(data_t[2]);
+ }
+ uint chunk_size = data_offset_from_size(chunk_size_in_bytes);
+ BLI_memiter_chunk *chunk = MEM_mallocN(
+ sizeof(BLI_memiter_chunk) + (chunk_size * sizeof(data_t)), "BLI_memiter_chunk");
- if (mi->head == NULL) {
- BLI_assert(mi->tail == NULL);
- mi->head = chunk;
- }
- else {
- mi->tail->next = chunk;
- }
- mi->tail = chunk;
- chunk->next = NULL;
+ if (mi->head == NULL) {
+ BLI_assert(mi->tail == NULL);
+ mi->head = chunk;
+ }
+ else {
+ mi->tail->next = chunk;
+ }
+ mi->tail = chunk;
+ chunk->next = NULL;
- mi->data_curr = chunk->data;
- mi->data_last = chunk->data + (chunk_size - 1);
- data_curr_next = mi->data_curr + (1 + data_offset);
+ mi->data_curr = chunk->data;
+ mi->data_last = chunk->data + (chunk_size - 1);
+ data_curr_next = mi->data_curr + (1 + data_offset);
- ASAN_POISON_MEMORY_REGION(chunk->data, chunk_size * sizeof(data_t));
- }
+ ASAN_POISON_MEMORY_REGION(chunk->data, chunk_size * sizeof(data_t));
+ }
- BLI_assert(data_curr_next <= mi->data_last);
+ BLI_assert(data_curr_next <= mi->data_last);
- BLI_memiter_elem *elem = (BLI_memiter_elem *)mi->data_curr;
+ BLI_memiter_elem *elem = (BLI_memiter_elem *)mi->data_curr;
- ASAN_UNPOISON_MEMORY_REGION(elem, sizeof(BLI_memiter_elem) + elem_size);
+ ASAN_UNPOISON_MEMORY_REGION(elem, sizeof(BLI_memiter_elem) + elem_size);
- elem->size = (offset_t)elem_size;
- mi->data_curr = data_curr_next;
+ elem->size = (offset_t)elem_size;
+ mi->data_curr = data_curr_next;
#ifdef USE_TERMINATE_PARANOID
- memiter_set_rewind_offset(mi);
+ memiter_set_rewind_offset(mi);
#endif
- mi->count += 1;
+ mi->count += 1;
#ifdef USE_TOTALLOC
- mi->totalloc += elem_size;
+ mi->totalloc += elem_size;
#endif
- return elem->data;
+ return elem->data;
}
void *BLI_memiter_calloc(BLI_memiter *mi, uint elem_size)
{
- void *data = BLI_memiter_alloc(mi, elem_size);
- memset(data, 0, elem_size);
- return data;
+ void *data = BLI_memiter_alloc(mi, elem_size);
+ memset(data, 0, elem_size);
+ return data;
}
void BLI_memiter_alloc_from(BLI_memiter *mi, uint elem_size, const void *data_from)
{
- void *data = BLI_memiter_alloc(mi, elem_size);
- memcpy(data, data_from, elem_size);
+ void *data = BLI_memiter_alloc(mi, elem_size);
+ memcpy(data, data_from, elem_size);
}
static void memiter_free_data(BLI_memiter *mi)
{
- BLI_memiter_chunk *chunk = mi->head;
- while (chunk) {
- BLI_memiter_chunk *chunk_next = chunk->next;
- MEM_freeN(chunk);
- chunk = chunk_next;
- }
+ BLI_memiter_chunk *chunk = mi->head;
+ while (chunk) {
+ BLI_memiter_chunk *chunk_next = chunk->next;
+ MEM_freeN(chunk);
+ chunk = chunk_next;
+ }
}
void BLI_memiter_destroy(BLI_memiter *mi)
{
- memiter_free_data(mi);
- MEM_freeN(mi);
+ memiter_free_data(mi);
+ MEM_freeN(mi);
}
void BLI_memiter_clear(BLI_memiter *mi)
{
- memiter_free_data(mi);
- memiter_init(mi);
+ memiter_free_data(mi);
+ memiter_init(mi);
}
uint BLI_memiter_count(const BLI_memiter *mi)
{
- return mi->count;
+ return mi->count;
}
/** \} */
-
/* -------------------------------------------------------------------- */
/** \name Helper API's
* \{ */
@@ -274,32 +270,31 @@ uint BLI_memiter_count(const BLI_memiter *mi)
/* Support direct lookup for first. */
void *BLI_memiter_elem_first(BLI_memiter *mi)
{
- if (mi->head != NULL) {
- BLI_memiter_chunk *chunk = mi->head;
- BLI_memiter_elem *elem = (BLI_memiter_elem *)chunk->data;
- return elem->data;
- }
- else {
- return NULL;
- }
+ if (mi->head != NULL) {
+ BLI_memiter_chunk *chunk = mi->head;
+ BLI_memiter_elem *elem = (BLI_memiter_elem *)chunk->data;
+ return elem->data;
+ }
+ else {
+ return NULL;
+ }
}
void *BLI_memiter_elem_first_size(BLI_memiter *mi, uint *r_size)
{
- if (mi->head != NULL) {
- BLI_memiter_chunk *chunk = mi->head;
- BLI_memiter_elem *elem = (BLI_memiter_elem *)chunk->data;
- *r_size = (uint)elem->size;
- return elem->data;
- }
- else {
- return NULL;
- }
+ if (mi->head != NULL) {
+ BLI_memiter_chunk *chunk = mi->head;
+ BLI_memiter_elem *elem = (BLI_memiter_elem *)chunk->data;
+ *r_size = (uint)elem->size;
+ return elem->data;
+ }
+ else {
+ return NULL;
+ }
}
/** \} */
-
/* -------------------------------------------------------------------- */
/** \name Iterator API's
*
@@ -313,59 +308,59 @@ void *BLI_memiter_elem_first_size(BLI_memiter *mi, uint *r_size)
void BLI_memiter_iter_init(BLI_memiter *mi, BLI_memiter_handle *iter)
{
- iter->elem = mi->head ? (BLI_memiter_elem *)mi->head->data : NULL;
- iter->elem_left = mi->count;
+ iter->elem = mi->head ? (BLI_memiter_elem *)mi->head->data : NULL;
+ iter->elem_left = mi->count;
}
bool BLI_memiter_iter_done(const BLI_memiter_handle *iter)
{
- return iter->elem_left != 0;
+ return iter->elem_left != 0;
}
BLI_INLINE void memiter_chunk_step(BLI_memiter_handle *iter)
{
- BLI_assert(iter->elem->size < 0);
- BLI_memiter_chunk *chunk = (BLI_memiter_chunk *)(((data_t *)iter->elem) + iter->elem->size);
- chunk = chunk->next;
- iter->elem = chunk ? (BLI_memiter_elem *)chunk->data : NULL;
- BLI_assert(iter->elem == NULL || iter->elem->size >= 0);
+ BLI_assert(iter->elem->size < 0);
+ BLI_memiter_chunk *chunk = (BLI_memiter_chunk *)(((data_t *)iter->elem) + iter->elem->size);
+ chunk = chunk->next;
+ iter->elem = chunk ? (BLI_memiter_elem *)chunk->data : NULL;
+ BLI_assert(iter->elem == NULL || iter->elem->size >= 0);
}
void *BLI_memiter_iter_step_size(BLI_memiter_handle *iter, uint *r_size)
{
- if (iter->elem_left != 0) {
- iter->elem_left -= 1;
- if (UNLIKELY(iter->elem->size < 0)) {
- memiter_chunk_step(iter);
- }
- BLI_assert(iter->elem->size >= 0);
- uint size = (uint)iter->elem->size;
- *r_size = size; /* <-- only difference */
- data_t *data = iter->elem->data;
- iter->elem = (BLI_memiter_elem *)&data[data_offset_from_size(size)];
- return (void *)data;
- }
- else {
- return NULL;
- }
+ if (iter->elem_left != 0) {
+ iter->elem_left -= 1;
+ if (UNLIKELY(iter->elem->size < 0)) {
+ memiter_chunk_step(iter);
+ }
+ BLI_assert(iter->elem->size >= 0);
+ uint size = (uint)iter->elem->size;
+ *r_size = size; /* <-- only difference */
+ data_t *data = iter->elem->data;
+ iter->elem = (BLI_memiter_elem *)&data[data_offset_from_size(size)];
+ return (void *)data;
+ }
+ else {
+ return NULL;
+ }
}
void *BLI_memiter_iter_step(BLI_memiter_handle *iter)
{
- if (iter->elem_left != 0) {
- iter->elem_left -= 1;
- if (UNLIKELY(iter->elem->size < 0)) {
- memiter_chunk_step(iter);
- }
- BLI_assert(iter->elem->size >= 0);
- uint size = (uint)iter->elem->size;
- data_t *data = iter->elem->data;
- iter->elem = (BLI_memiter_elem *)&data[data_offset_from_size(size)];
- return (void *)data;
- }
- else {
- return NULL;
- }
+ if (iter->elem_left != 0) {
+ iter->elem_left -= 1;
+ if (UNLIKELY(iter->elem->size < 0)) {
+ memiter_chunk_step(iter);
+ }
+ BLI_assert(iter->elem->size >= 0);
+ uint size = (uint)iter->elem->size;
+ data_t *data = iter->elem->data;
+ iter->elem = (BLI_memiter_elem *)&data[data_offset_from_size(size)];
+ return (void *)data;
+ }
+ else {
+ return NULL;
+ }
}
/** \} */
diff --git a/source/blender/blenlib/intern/BLI_mempool.c b/source/blender/blenlib/intern/BLI_mempool.c
index 24e3f22172e..0f65f8ecbf0 100644
--- a/source/blender/blenlib/intern/BLI_mempool.c
+++ b/source/blender/blenlib/intern/BLI_mempool.c
@@ -40,7 +40,7 @@
#include "MEM_guardedalloc.h"
-#include "BLI_strict_flags.h" /* keep last */
+#include "BLI_strict_flags.h" /* keep last */
#ifdef WITH_MEM_VALGRIND
# include "valgrind/memcheck.h"
@@ -49,16 +49,16 @@
/* note: copied from BLO_blend_defs.h, don't use here because we're in BLI */
#ifdef __BIG_ENDIAN__
/* Big Endian */
-# define MAKE_ID(a, b, c, d) ( (int)(a) << 24 | (int)(b) << 16 | (c) << 8 | (d) )
+# define MAKE_ID(a, b, c, d) ((int)(a) << 24 | (int)(b) << 16 | (c) << 8 | (d))
# define MAKE_ID_8(a, b, c, d, e, f, g, h) \
- ((int64_t)(a) << 56 | (int64_t)(b) << 48 | (int64_t)(c) << 40 | (int64_t)(d) << 32 | \
- (int64_t)(e) << 24 | (int64_t)(f) << 16 | (int64_t)(g) << 8 | (h) )
+ ((int64_t)(a) << 56 | (int64_t)(b) << 48 | (int64_t)(c) << 40 | (int64_t)(d) << 32 | \
+ (int64_t)(e) << 24 | (int64_t)(f) << 16 | (int64_t)(g) << 8 | (h))
#else
/* Little Endian */
-# define MAKE_ID(a, b, c, d) ( (int)(d) << 24 | (int)(c) << 16 | (b) << 8 | (a) )
+# define MAKE_ID(a, b, c, d) ((int)(d) << 24 | (int)(c) << 16 | (b) << 8 | (a))
# define MAKE_ID_8(a, b, c, d, e, f, g, h) \
- ((int64_t)(h) << 56 | (int64_t)(g) << 48 | (int64_t)(f) << 40 | (int64_t)(e) << 32 | \
- (int64_t)(d) << 24 | (int64_t)(c) << 16 | (int64_t)(b) << 8 | (a) )
+ ((int64_t)(h) << 56 | (int64_t)(g) << 48 | (int64_t)(f) << 40 | (int64_t)(e) << 32 | \
+ (int64_t)(d) << 24 | (int64_t)(c) << 16 | (int64_t)(b) << 8 | (a))
#endif
/**
@@ -66,9 +66,9 @@
* So having a pointer to 2/4/8... aligned memory is enough to ensure the freeword will never be used.
* To be safe, use a word thats the same in both directions.
*/
-#define FREEWORD ((sizeof(void *) > sizeof(int32_t)) ? \
- MAKE_ID_8('e', 'e', 'r', 'f', 'f', 'r', 'e', 'e') : \
- MAKE_ID('e', 'f', 'f', 'e'))
+#define FREEWORD \
+ ((sizeof(void *) > sizeof(int32_t)) ? MAKE_ID_8('e', 'e', 'r', 'f', 'f', 'r', 'e', 'e') : \
+ MAKE_ID('e', 'f', 'f', 'e'))
/**
* The 'used' word just needs to be set to something besides FREEWORD.
@@ -81,7 +81,6 @@
/* optimize pool size */
#define USE_CHUNK_POW2
-
#ifndef NDEBUG
static bool mempool_debug_memset = false;
#endif
@@ -93,9 +92,9 @@ static bool mempool_debug_memset = false;
* Each element represents a block which BLI_mempool_alloc may return.
*/
typedef struct BLI_freenode {
- struct BLI_freenode *next;
- /** Used to identify this as a freed node. */
- intptr_t freeword;
+ struct BLI_freenode *next;
+ /** Used to identify this as a freed node. */
+ intptr_t freeword;
} BLI_freenode;
/**
@@ -103,37 +102,37 @@ typedef struct BLI_freenode {
* #BLI_mempool.chunks as a double linked list.
*/
typedef struct BLI_mempool_chunk {
- struct BLI_mempool_chunk *next;
+ struct BLI_mempool_chunk *next;
} BLI_mempool_chunk;
/**
* The mempool, stores and tracks memory \a chunks and elements within those chunks \a free.
*/
struct BLI_mempool {
- /** Single linked list of allocated chunks. */
- BLI_mempool_chunk *chunks;
- /** Keep a pointer to the last, so we can append new chunks there
- * this is needed for iteration so we can loop over chunks in the order added. */
- BLI_mempool_chunk *chunk_tail;
-
- /** Element size in bytes. */
- uint esize;
- /** Chunk size in bytes. */
- uint csize;
- /** Number of elements per chunk. */
- uint pchunk;
- uint flag;
- /* keeps aligned to 16 bits */
-
- /** Free element list. Interleaved into chunk datas. */
- BLI_freenode *free;
- /** Use to know how many chunks to keep for #BLI_mempool_clear. */
- uint maxchunks;
- /** Number of elements currently in use. */
- uint totused;
+ /** Single linked list of allocated chunks. */
+ BLI_mempool_chunk *chunks;
+ /** Keep a pointer to the last, so we can append new chunks there
+ * this is needed for iteration so we can loop over chunks in the order added. */
+ BLI_mempool_chunk *chunk_tail;
+
+ /** Element size in bytes. */
+ uint esize;
+ /** Chunk size in bytes. */
+ uint csize;
+ /** Number of elements per chunk. */
+ uint pchunk;
+ uint flag;
+ /* keeps aligned to 16 bits */
+
+ /** Free element list. Interleaved into chunk datas. */
+ BLI_freenode *free;
+ /** Use to know how many chunks to keep for #BLI_mempool_clear. */
+ uint maxchunks;
+ /** Number of elements currently in use. */
+ uint totused;
#ifdef USE_TOTALLOC
- /** Number of elements allocated in total. */
- uint totalloc;
+ /** Number of elements allocated in total. */
+ uint totalloc;
#endif
};
@@ -141,8 +140,8 @@ struct BLI_mempool {
#define CHUNK_DATA(chunk) (CHECK_TYPE_INLINE(chunk, BLI_mempool_chunk *), (void *)((chunk) + 1))
-#define NODE_STEP_NEXT(node) ((void *)((char *)(node) + esize))
-#define NODE_STEP_PREV(node) ((void *)((char *)(node) - esize))
+#define NODE_STEP_NEXT(node) ((void *)((char *)(node) + esize))
+#define NODE_STEP_PREV(node) ((void *)((char *)(node)-esize))
/** Extra bytes implicitly used for every chunk alloc. */
#define CHUNK_OVERHEAD (uint)(MEM_SIZE_OVERHEAD + sizeof(BLI_mempool_chunk))
@@ -150,22 +149,22 @@ struct BLI_mempool {
#ifdef USE_CHUNK_POW2
static uint power_of_2_max_u(uint x)
{
- x -= 1;
- x = x | (x >> 1);
- x = x | (x >> 2);
- x = x | (x >> 4);
- x = x | (x >> 8);
- x = x | (x >> 16);
- return x + 1;
+ x -= 1;
+ x = x | (x >> 1);
+ x = x | (x >> 2);
+ x = x | (x >> 4);
+ x = x | (x >> 8);
+ x = x | (x >> 16);
+ return x + 1;
}
#endif
BLI_INLINE BLI_mempool_chunk *mempool_chunk_find(BLI_mempool_chunk *head, uint index)
{
- while (index-- && head) {
- head = head->next;
- }
- return head;
+ while (index-- && head) {
+ head = head->next;
+ }
+ return head;
}
/**
@@ -176,12 +175,12 @@ BLI_INLINE BLI_mempool_chunk *mempool_chunk_find(BLI_mempool_chunk *head, uint i
*/
BLI_INLINE uint mempool_maxchunks(const uint totelem, const uint pchunk)
{
- return (totelem <= pchunk) ? 1 : ((totelem / pchunk) + 1);
+ return (totelem <= pchunk) ? 1 : ((totelem / pchunk) + 1);
}
static BLI_mempool_chunk *mempool_chunk_alloc(BLI_mempool *pool)
{
- return MEM_mallocN(sizeof(BLI_mempool_chunk) + (size_t)pool->csize, "BLI_Mempool Chunk");
+ return MEM_mallocN(sizeof(BLI_mempool_chunk) + (size_t)pool->csize, "BLI_Mempool Chunk");
}
/**
@@ -193,179 +192,177 @@ static BLI_mempool_chunk *mempool_chunk_alloc(BLI_mempool *pool)
* (used when building free chunks initially)
* \return The last chunk,
*/
-static BLI_freenode *mempool_chunk_add(
- BLI_mempool *pool, BLI_mempool_chunk *mpchunk,
- BLI_freenode *last_tail)
+static BLI_freenode *mempool_chunk_add(BLI_mempool *pool,
+ BLI_mempool_chunk *mpchunk,
+ BLI_freenode *last_tail)
{
- const uint esize = pool->esize;
- BLI_freenode *curnode = CHUNK_DATA(mpchunk);
- uint j;
-
- /* append */
- if (pool->chunk_tail) {
- pool->chunk_tail->next = mpchunk;
- }
- else {
- BLI_assert(pool->chunks == NULL);
- pool->chunks = mpchunk;
- }
-
- mpchunk->next = NULL;
- pool->chunk_tail = mpchunk;
-
- if (UNLIKELY(pool->free == NULL)) {
- pool->free = curnode;
- }
-
- /* loop through the allocated data, building the pointer structures */
- j = pool->pchunk;
- if (pool->flag & BLI_MEMPOOL_ALLOW_ITER) {
- while (j--) {
- curnode->next = NODE_STEP_NEXT(curnode);
- curnode->freeword = FREEWORD;
- curnode = curnode->next;
- }
- }
- else {
- while (j--) {
- curnode->next = NODE_STEP_NEXT(curnode);
- curnode = curnode->next;
- }
- }
-
- /* terminate the list (rewind one)
- * will be overwritten if 'curnode' gets passed in again as 'last_tail' */
- curnode = NODE_STEP_PREV(curnode);
- curnode->next = NULL;
+ const uint esize = pool->esize;
+ BLI_freenode *curnode = CHUNK_DATA(mpchunk);
+ uint j;
+
+ /* append */
+ if (pool->chunk_tail) {
+ pool->chunk_tail->next = mpchunk;
+ }
+ else {
+ BLI_assert(pool->chunks == NULL);
+ pool->chunks = mpchunk;
+ }
+
+ mpchunk->next = NULL;
+ pool->chunk_tail = mpchunk;
+
+ if (UNLIKELY(pool->free == NULL)) {
+ pool->free = curnode;
+ }
+
+ /* loop through the allocated data, building the pointer structures */
+ j = pool->pchunk;
+ if (pool->flag & BLI_MEMPOOL_ALLOW_ITER) {
+ while (j--) {
+ curnode->next = NODE_STEP_NEXT(curnode);
+ curnode->freeword = FREEWORD;
+ curnode = curnode->next;
+ }
+ }
+ else {
+ while (j--) {
+ curnode->next = NODE_STEP_NEXT(curnode);
+ curnode = curnode->next;
+ }
+ }
+
+ /* terminate the list (rewind one)
+ * will be overwritten if 'curnode' gets passed in again as 'last_tail' */
+ curnode = NODE_STEP_PREV(curnode);
+ curnode->next = NULL;
#ifdef USE_TOTALLOC
- pool->totalloc += pool->pchunk;
+ pool->totalloc += pool->pchunk;
#endif
- /* final pointer in the previously allocated chunk is wrong */
- if (last_tail) {
- last_tail->next = CHUNK_DATA(mpchunk);
- }
+ /* final pointer in the previously allocated chunk is wrong */
+ if (last_tail) {
+ last_tail->next = CHUNK_DATA(mpchunk);
+ }
- return curnode;
+ return curnode;
}
static void mempool_chunk_free(BLI_mempool_chunk *mpchunk)
{
- MEM_freeN(mpchunk);
+ MEM_freeN(mpchunk);
}
static void mempool_chunk_free_all(BLI_mempool_chunk *mpchunk)
{
- BLI_mempool_chunk *mpchunk_next;
+ BLI_mempool_chunk *mpchunk_next;
- for (; mpchunk; mpchunk = mpchunk_next) {
- mpchunk_next = mpchunk->next;
- mempool_chunk_free(mpchunk);
- }
+ for (; mpchunk; mpchunk = mpchunk_next) {
+ mpchunk_next = mpchunk->next;
+ mempool_chunk_free(mpchunk);
+ }
}
-BLI_mempool *BLI_mempool_create(
- uint esize, uint totelem,
- uint pchunk, uint flag)
+BLI_mempool *BLI_mempool_create(uint esize, uint totelem, uint pchunk, uint flag)
{
- BLI_mempool *pool;
- BLI_freenode *last_tail = NULL;
- uint i, maxchunks;
+ BLI_mempool *pool;
+ BLI_freenode *last_tail = NULL;
+ uint i, maxchunks;
- /* allocate the pool structure */
- pool = MEM_mallocN(sizeof(BLI_mempool), "memory pool");
+ /* allocate the pool structure */
+ pool = MEM_mallocN(sizeof(BLI_mempool), "memory pool");
- /* set the elem size */
- if (esize < (int)MEMPOOL_ELEM_SIZE_MIN) {
- esize = (int)MEMPOOL_ELEM_SIZE_MIN;
- }
+ /* set the elem size */
+ if (esize < (int)MEMPOOL_ELEM_SIZE_MIN) {
+ esize = (int)MEMPOOL_ELEM_SIZE_MIN;
+ }
- if (flag & BLI_MEMPOOL_ALLOW_ITER) {
- esize = MAX2(esize, (uint)sizeof(BLI_freenode));
- }
+ if (flag & BLI_MEMPOOL_ALLOW_ITER) {
+ esize = MAX2(esize, (uint)sizeof(BLI_freenode));
+ }
- maxchunks = mempool_maxchunks(totelem, pchunk);
+ maxchunks = mempool_maxchunks(totelem, pchunk);
- pool->chunks = NULL;
- pool->chunk_tail = NULL;
- pool->esize = esize;
+ pool->chunks = NULL;
+ pool->chunk_tail = NULL;
+ pool->esize = esize;
- /* Optimize chunk size to powers of 2, accounting for slop-space. */
+ /* Optimize chunk size to powers of 2, accounting for slop-space. */
#ifdef USE_CHUNK_POW2
- {
- BLI_assert(power_of_2_max_u(pchunk * esize) > CHUNK_OVERHEAD);
- pchunk = (power_of_2_max_u(pchunk * esize) - CHUNK_OVERHEAD) / esize;
- }
+ {
+ BLI_assert(power_of_2_max_u(pchunk * esize) > CHUNK_OVERHEAD);
+ pchunk = (power_of_2_max_u(pchunk * esize) - CHUNK_OVERHEAD) / esize;
+ }
#endif
- pool->csize = esize * pchunk;
+ pool->csize = esize * pchunk;
- /* Ensure this is a power of 2, minus the rounding by element size. */
+ /* Ensure this is a power of 2, minus the rounding by element size. */
#if defined(USE_CHUNK_POW2) && !defined(NDEBUG)
- {
- uint final_size = (uint)MEM_SIZE_OVERHEAD + (uint)sizeof(BLI_mempool_chunk) + pool->csize;
- BLI_assert(((uint)power_of_2_max_u(final_size) - final_size) < pool->esize);
- }
+ {
+ uint final_size = (uint)MEM_SIZE_OVERHEAD + (uint)sizeof(BLI_mempool_chunk) + pool->csize;
+ BLI_assert(((uint)power_of_2_max_u(final_size) - final_size) < pool->esize);
+ }
#endif
- pool->pchunk = pchunk;
- pool->flag = flag;
- pool->free = NULL; /* mempool_chunk_add assigns */
- pool->maxchunks = maxchunks;
+ pool->pchunk = pchunk;
+ pool->flag = flag;
+ pool->free = NULL; /* mempool_chunk_add assigns */
+ pool->maxchunks = maxchunks;
#ifdef USE_TOTALLOC
- pool->totalloc = 0;
+ pool->totalloc = 0;
#endif
- pool->totused = 0;
+ pool->totused = 0;
- if (totelem) {
- /* Allocate the actual chunks. */
- for (i = 0; i < maxchunks; i++) {
- BLI_mempool_chunk *mpchunk = mempool_chunk_alloc(pool);
- last_tail = mempool_chunk_add(pool, mpchunk, last_tail);
- }
- }
+ if (totelem) {
+ /* Allocate the actual chunks. */
+ for (i = 0; i < maxchunks; i++) {
+ BLI_mempool_chunk *mpchunk = mempool_chunk_alloc(pool);
+ last_tail = mempool_chunk_add(pool, mpchunk, last_tail);
+ }
+ }
#ifdef WITH_MEM_VALGRIND
- VALGRIND_CREATE_MEMPOOL(pool, 0, false);
+ VALGRIND_CREATE_MEMPOOL(pool, 0, false);
#endif
- return pool;
+ return pool;
}
void *BLI_mempool_alloc(BLI_mempool *pool)
{
- BLI_freenode *free_pop;
+ BLI_freenode *free_pop;
- if (UNLIKELY(pool->free == NULL)) {
- /* Need to allocate a new chunk. */
- BLI_mempool_chunk *mpchunk = mempool_chunk_alloc(pool);
- mempool_chunk_add(pool, mpchunk, NULL);
- }
+ if (UNLIKELY(pool->free == NULL)) {
+ /* Need to allocate a new chunk. */
+ BLI_mempool_chunk *mpchunk = mempool_chunk_alloc(pool);
+ mempool_chunk_add(pool, mpchunk, NULL);
+ }
- free_pop = pool->free;
+ free_pop = pool->free;
- BLI_assert(pool->chunk_tail->next == NULL);
+ BLI_assert(pool->chunk_tail->next == NULL);
- if (pool->flag & BLI_MEMPOOL_ALLOW_ITER) {
- free_pop->freeword = USEDWORD;
- }
+ if (pool->flag & BLI_MEMPOOL_ALLOW_ITER) {
+ free_pop->freeword = USEDWORD;
+ }
- pool->free = free_pop->next;
- pool->totused++;
+ pool->free = free_pop->next;
+ pool->totused++;
#ifdef WITH_MEM_VALGRIND
- VALGRIND_MEMPOOL_ALLOC(pool, free_pop, pool->esize);
+ VALGRIND_MEMPOOL_ALLOC(pool, free_pop, pool->esize);
#endif
- return (void *)free_pop;
+ return (void *)free_pop;
}
void *BLI_mempool_calloc(BLI_mempool *pool)
{
- void *retval = BLI_mempool_alloc(pool);
- memset(retval, 0, (size_t)pool->esize);
- return retval;
+ void *retval = BLI_mempool_alloc(pool);
+ memset(retval, 0, (size_t)pool->esize);
+ return retval;
}
/**
@@ -375,107 +372,105 @@ void *BLI_mempool_calloc(BLI_mempool *pool)
*/
void BLI_mempool_free(BLI_mempool *pool, void *addr)
{
- BLI_freenode *newhead = addr;
+ BLI_freenode *newhead = addr;
#ifndef NDEBUG
- {
- BLI_mempool_chunk *chunk;
- bool found = false;
- for (chunk = pool->chunks; chunk; chunk = chunk->next) {
- if (ARRAY_HAS_ITEM((char *)addr, (char *)CHUNK_DATA(chunk), pool->csize)) {
- found = true;
- break;
- }
- }
- if (!found) {
- BLI_assert(!"Attempt to free data which is not in pool.\n");
- }
- }
-
- /* Enable for debugging. */
- if (UNLIKELY(mempool_debug_memset)) {
- memset(addr, 255, pool->esize);
- }
+ {
+ BLI_mempool_chunk *chunk;
+ bool found = false;
+ for (chunk = pool->chunks; chunk; chunk = chunk->next) {
+ if (ARRAY_HAS_ITEM((char *)addr, (char *)CHUNK_DATA(chunk), pool->csize)) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ BLI_assert(!"Attempt to free data which is not in pool.\n");
+ }
+ }
+
+ /* Enable for debugging. */
+ if (UNLIKELY(mempool_debug_memset)) {
+ memset(addr, 255, pool->esize);
+ }
#endif
- if (pool->flag & BLI_MEMPOOL_ALLOW_ITER) {
+ if (pool->flag & BLI_MEMPOOL_ALLOW_ITER) {
#ifndef NDEBUG
- /* This will detect double free's. */
- BLI_assert(newhead->freeword != FREEWORD);
+ /* This will detect double free's. */
+ BLI_assert(newhead->freeword != FREEWORD);
#endif
- newhead->freeword = FREEWORD;
- }
+ newhead->freeword = FREEWORD;
+ }
- newhead->next = pool->free;
- pool->free = newhead;
+ newhead->next = pool->free;
+ pool->free = newhead;
- pool->totused--;
+ pool->totused--;
#ifdef WITH_MEM_VALGRIND
- VALGRIND_MEMPOOL_FREE(pool, addr);
+ VALGRIND_MEMPOOL_FREE(pool, addr);
#endif
- /* Nothing is in use; free all the chunks except the first. */
- if (UNLIKELY(pool->totused == 0) &&
- (pool->chunks->next))
- {
- const uint esize = pool->esize;
- BLI_freenode *curnode;
- uint j;
- BLI_mempool_chunk *first;
+ /* Nothing is in use; free all the chunks except the first. */
+ if (UNLIKELY(pool->totused == 0) && (pool->chunks->next)) {
+ const uint esize = pool->esize;
+ BLI_freenode *curnode;
+ uint j;
+ BLI_mempool_chunk *first;
- first = pool->chunks;
- mempool_chunk_free_all(first->next);
- first->next = NULL;
- pool->chunk_tail = first;
+ first = pool->chunks;
+ mempool_chunk_free_all(first->next);
+ first->next = NULL;
+ pool->chunk_tail = first;
#ifdef USE_TOTALLOC
- pool->totalloc = pool->pchunk;
+ pool->totalloc = pool->pchunk;
#endif
- /* Temp alloc so valgrind doesn't complain when setting free'd blocks 'next'. */
+ /* Temp alloc so valgrind doesn't complain when setting free'd blocks 'next'. */
#ifdef WITH_MEM_VALGRIND
- VALGRIND_MEMPOOL_ALLOC(pool, CHUNK_DATA(first), pool->csize);
+ VALGRIND_MEMPOOL_ALLOC(pool, CHUNK_DATA(first), pool->csize);
#endif
- curnode = CHUNK_DATA(first);
- pool->free = curnode;
+ curnode = CHUNK_DATA(first);
+ pool->free = curnode;
- j = pool->pchunk;
- while (j--) {
- curnode->next = NODE_STEP_NEXT(curnode);
- curnode = curnode->next;
- }
- curnode = NODE_STEP_PREV(curnode);
- curnode->next = NULL; /* terminate the list */
+ j = pool->pchunk;
+ while (j--) {
+ curnode->next = NODE_STEP_NEXT(curnode);
+ curnode = curnode->next;
+ }
+ curnode = NODE_STEP_PREV(curnode);
+ curnode->next = NULL; /* terminate the list */
#ifdef WITH_MEM_VALGRIND
- VALGRIND_MEMPOOL_FREE(pool, CHUNK_DATA(first));
+ VALGRIND_MEMPOOL_FREE(pool, CHUNK_DATA(first));
#endif
- }
+ }
}
int BLI_mempool_len(BLI_mempool *pool)
{
- return (int)pool->totused;
+ return (int)pool->totused;
}
void *BLI_mempool_findelem(BLI_mempool *pool, uint index)
{
- BLI_assert(pool->flag & BLI_MEMPOOL_ALLOW_ITER);
-
- if (index < pool->totused) {
- /* We could have some faster mem chunk stepping code inline. */
- BLI_mempool_iter iter;
- void *elem;
- BLI_mempool_iternew(pool, &iter);
- for (elem = BLI_mempool_iterstep(&iter); index-- != 0; elem = BLI_mempool_iterstep(&iter)) {
- /* pass */
- }
- return elem;
- }
-
- return NULL;
+ BLI_assert(pool->flag & BLI_MEMPOOL_ALLOW_ITER);
+
+ if (index < pool->totused) {
+ /* We could have some faster mem chunk stepping code inline. */
+ BLI_mempool_iter iter;
+ void *elem;
+ BLI_mempool_iternew(pool, &iter);
+ for (elem = BLI_mempool_iterstep(&iter); index-- != 0; elem = BLI_mempool_iterstep(&iter)) {
+ /* pass */
+ }
+ return elem;
+ }
+
+ return NULL;
}
/**
@@ -487,15 +482,15 @@ void *BLI_mempool_findelem(BLI_mempool *pool, uint index)
*/
void BLI_mempool_as_table(BLI_mempool *pool, void **data)
{
- BLI_mempool_iter iter;
- void *elem;
- void **p = data;
- BLI_assert(pool->flag & BLI_MEMPOOL_ALLOW_ITER);
- BLI_mempool_iternew(pool, &iter);
- while ((elem = BLI_mempool_iterstep(&iter))) {
- *p++ = elem;
- }
- BLI_assert((uint)(p - data) == pool->totused);
+ BLI_mempool_iter iter;
+ void *elem;
+ void **p = data;
+ BLI_assert(pool->flag & BLI_MEMPOOL_ALLOW_ITER);
+ BLI_mempool_iternew(pool, &iter);
+ while ((elem = BLI_mempool_iterstep(&iter))) {
+ *p++ = elem;
+ }
+ BLI_assert((uint)(p - data) == pool->totused);
}
/**
@@ -503,9 +498,9 @@ void BLI_mempool_as_table(BLI_mempool *pool, void **data)
*/
void **BLI_mempool_as_tableN(BLI_mempool *pool, const char *allocstr)
{
- void **data = MEM_mallocN((size_t)pool->totused * sizeof(void *), allocstr);
- BLI_mempool_as_table(pool, data);
- return data;
+ void **data = MEM_mallocN((size_t)pool->totused * sizeof(void *), allocstr);
+ BLI_mempool_as_table(pool, data);
+ return data;
}
/**
@@ -513,16 +508,16 @@ void **BLI_mempool_as_tableN(BLI_mempool *pool, const char *allocstr)
*/
void BLI_mempool_as_array(BLI_mempool *pool, void *data)
{
- const uint esize = pool->esize;
- BLI_mempool_iter iter;
- char *elem, *p = data;
- BLI_assert(pool->flag & BLI_MEMPOOL_ALLOW_ITER);
- BLI_mempool_iternew(pool, &iter);
- while ((elem = BLI_mempool_iterstep(&iter))) {
- memcpy(p, elem, (size_t)esize);
- p = NODE_STEP_NEXT(p);
- }
- BLI_assert((uint)(p - (char *)data) == pool->totused * esize);
+ const uint esize = pool->esize;
+ BLI_mempool_iter iter;
+ char *elem, *p = data;
+ BLI_assert(pool->flag & BLI_MEMPOOL_ALLOW_ITER);
+ BLI_mempool_iternew(pool, &iter);
+ while ((elem = BLI_mempool_iterstep(&iter))) {
+ memcpy(p, elem, (size_t)esize);
+ p = NODE_STEP_NEXT(p);
+ }
+ BLI_assert((uint)(p - (char *)data) == pool->totused * esize);
}
/**
@@ -530,9 +525,9 @@ void BLI_mempool_as_array(BLI_mempool *pool, void *data)
*/
void *BLI_mempool_as_arrayN(BLI_mempool *pool, const char *allocstr)
{
- char *data = MEM_mallocN((size_t)(pool->totused * pool->esize), allocstr);
- BLI_mempool_as_array(pool, data);
- return data;
+ char *data = MEM_mallocN((size_t)(pool->totused * pool->esize), allocstr);
+ BLI_mempool_as_array(pool, data);
+ return data;
}
/**
@@ -540,13 +535,13 @@ void *BLI_mempool_as_arrayN(BLI_mempool *pool, const char *allocstr)
*/
void BLI_mempool_iternew(BLI_mempool *pool, BLI_mempool_iter *iter)
{
- BLI_assert(pool->flag & BLI_MEMPOOL_ALLOW_ITER);
+ BLI_assert(pool->flag & BLI_MEMPOOL_ALLOW_ITER);
- iter->pool = pool;
- iter->curchunk = pool->chunks;
- iter->curindex = 0;
+ iter->pool = pool;
+ iter->curchunk = pool->chunks;
+ iter->curindex = 0;
- iter->curchunk_threaded_shared = NULL;
+ iter->curchunk_threaded_shared = NULL;
}
/**
@@ -562,31 +557,32 @@ void BLI_mempool_iternew(BLI_mempool *pool, BLI_mempool_iter *iter)
*/
BLI_mempool_iter *BLI_mempool_iter_threadsafe_create(BLI_mempool *pool, const size_t num_iter)
{
- BLI_assert(pool->flag & BLI_MEMPOOL_ALLOW_ITER);
+ BLI_assert(pool->flag & BLI_MEMPOOL_ALLOW_ITER);
- BLI_mempool_iter *iter_arr = MEM_mallocN(sizeof(*iter_arr) * num_iter, __func__);
- BLI_mempool_chunk **curchunk_threaded_shared = MEM_mallocN(sizeof(void *), __func__);
+ BLI_mempool_iter *iter_arr = MEM_mallocN(sizeof(*iter_arr) * num_iter, __func__);
+ BLI_mempool_chunk **curchunk_threaded_shared = MEM_mallocN(sizeof(void *), __func__);
- BLI_mempool_iternew(pool, iter_arr);
+ BLI_mempool_iternew(pool, iter_arr);
- *curchunk_threaded_shared = iter_arr->curchunk;
- iter_arr->curchunk_threaded_shared = curchunk_threaded_shared;
+ *curchunk_threaded_shared = iter_arr->curchunk;
+ iter_arr->curchunk_threaded_shared = curchunk_threaded_shared;
- for (size_t i = 1; i < num_iter; i++) {
- iter_arr[i] = iter_arr[0];
- *curchunk_threaded_shared = iter_arr[i].curchunk = (
- (*curchunk_threaded_shared) ? (*curchunk_threaded_shared)->next : NULL);
- }
+ for (size_t i = 1; i < num_iter; i++) {
+ iter_arr[i] = iter_arr[0];
+ *curchunk_threaded_shared = iter_arr[i].curchunk = ((*curchunk_threaded_shared) ?
+ (*curchunk_threaded_shared)->next :
+ NULL);
+ }
- return iter_arr;
+ return iter_arr;
}
-void BLI_mempool_iter_threadsafe_free(BLI_mempool_iter *iter_arr)
+void BLI_mempool_iter_threadsafe_free(BLI_mempool_iter *iter_arr)
{
- BLI_assert(iter_arr->curchunk_threaded_shared != NULL);
+ BLI_assert(iter_arr->curchunk_threaded_shared != NULL);
- MEM_freeN(iter_arr->curchunk_threaded_shared);
- MEM_freeN(iter_arr);
+ MEM_freeN(iter_arr->curchunk_threaded_shared);
+ MEM_freeN(iter_arr);
}
#if 0
@@ -594,48 +590,48 @@ void BLI_mempool_iter_threadsafe_free(BLI_mempool_iter *iter_arr)
static void *bli_mempool_iternext(BLI_mempool_iter *iter)
{
- void *ret = NULL;
-
- if (iter->curchunk == NULL || !iter->pool->totused) {
- return ret;
- }
-
- ret = ((char *)CHUNK_DATA(iter->curchunk)) + (iter->pool->esize * iter->curindex);
-
- iter->curindex++;
-
- if (iter->curindex == iter->pool->pchunk) {
- iter->curindex = 0;
- if (iter->curchunk_threaded_shared) {
- while (1) {
- iter->curchunk = *iter->curchunk_threaded_shared;
- if (iter->curchunk == NULL) {
- return ret;
- }
- if (atomic_cas_ptr(
- (void **)iter->curchunk_threaded_shared,
- iter->curchunk,
- iter->curchunk->next) == iter->curchunk)
- {
- break;
- }
- }
- }
- iter->curchunk = iter->curchunk->next;
- }
-
- return ret;
+ void *ret = NULL;
+
+ if (iter->curchunk == NULL || !iter->pool->totused) {
+ return ret;
+ }
+
+ ret = ((char *)CHUNK_DATA(iter->curchunk)) + (iter->pool->esize * iter->curindex);
+
+ iter->curindex++;
+
+ if (iter->curindex == iter->pool->pchunk) {
+ iter->curindex = 0;
+ if (iter->curchunk_threaded_shared) {
+ while (1) {
+ iter->curchunk = *iter->curchunk_threaded_shared;
+ if (iter->curchunk == NULL) {
+ return ret;
+ }
+ if (atomic_cas_ptr(
+ (void **)iter->curchunk_threaded_shared,
+ iter->curchunk,
+ iter->curchunk->next) == iter->curchunk)
+ {
+ break;
+ }
+ }
+ }
+ iter->curchunk = iter->curchunk->next;
+ }
+
+ return ret;
}
void *BLI_mempool_iterstep(BLI_mempool_iter *iter)
{
- BLI_freenode *ret;
+ BLI_freenode *ret;
- do {
- ret = bli_mempool_iternext(iter);
- } while (ret && ret->freeword == FREEWORD);
+ do {
+ ret = bli_mempool_iternext(iter);
+ } while (ret && ret->freeword == FREEWORD);
- return ret;
+ return ret;
}
#else
@@ -647,46 +643,43 @@ void *BLI_mempool_iterstep(BLI_mempool_iter *iter)
*/
void *BLI_mempool_iterstep(BLI_mempool_iter *iter)
{
- if (UNLIKELY(iter->curchunk == NULL)) {
- return NULL;
- }
-
- const uint esize = iter->pool->esize;
- BLI_freenode *curnode = POINTER_OFFSET(CHUNK_DATA(iter->curchunk), (esize * iter->curindex));
- BLI_freenode *ret;
- do {
- ret = curnode;
-
- if (++iter->curindex != iter->pool->pchunk) {
- curnode = POINTER_OFFSET(curnode, esize);
- }
- else {
- iter->curindex = 0;
- if (iter->curchunk_threaded_shared) {
- for (iter->curchunk = *iter->curchunk_threaded_shared;
- (iter->curchunk != NULL) &&
- (atomic_cas_ptr(
- (void **)iter->curchunk_threaded_shared,
- iter->curchunk,
- iter->curchunk->next) != iter->curchunk);
- iter->curchunk = *iter->curchunk_threaded_shared)
- {
- /* pass. */
- }
-
- if (UNLIKELY(iter->curchunk == NULL)) {
- return (ret->freeword == FREEWORD) ? NULL : ret;
- }
- }
- iter->curchunk = iter->curchunk->next;
- if (UNLIKELY(iter->curchunk == NULL)) {
- return (ret->freeword == FREEWORD) ? NULL : ret;
- }
- curnode = CHUNK_DATA(iter->curchunk);
- }
- } while (ret->freeword == FREEWORD);
-
- return ret;
+ if (UNLIKELY(iter->curchunk == NULL)) {
+ return NULL;
+ }
+
+ const uint esize = iter->pool->esize;
+ BLI_freenode *curnode = POINTER_OFFSET(CHUNK_DATA(iter->curchunk), (esize * iter->curindex));
+ BLI_freenode *ret;
+ do {
+ ret = curnode;
+
+ if (++iter->curindex != iter->pool->pchunk) {
+ curnode = POINTER_OFFSET(curnode, esize);
+ }
+ else {
+ iter->curindex = 0;
+ if (iter->curchunk_threaded_shared) {
+ for (iter->curchunk = *iter->curchunk_threaded_shared;
+ (iter->curchunk != NULL) && (atomic_cas_ptr((void **)iter->curchunk_threaded_shared,
+ iter->curchunk,
+ iter->curchunk->next) != iter->curchunk);
+ iter->curchunk = *iter->curchunk_threaded_shared) {
+ /* pass. */
+ }
+
+ if (UNLIKELY(iter->curchunk == NULL)) {
+ return (ret->freeword == FREEWORD) ? NULL : ret;
+ }
+ }
+ iter->curchunk = iter->curchunk->next;
+ if (UNLIKELY(iter->curchunk == NULL)) {
+ return (ret->freeword == FREEWORD) ? NULL : ret;
+ }
+ curnode = CHUNK_DATA(iter->curchunk);
+ }
+ } while (ret->freeword == FREEWORD);
+
+ return ret;
}
#endif
@@ -699,54 +692,54 @@ void *BLI_mempool_iterstep(BLI_mempool_iter *iter)
*/
void BLI_mempool_clear_ex(BLI_mempool *pool, const int totelem_reserve)
{
- BLI_mempool_chunk *mpchunk;
- BLI_mempool_chunk *mpchunk_next;
- uint maxchunks;
+ BLI_mempool_chunk *mpchunk;
+ BLI_mempool_chunk *mpchunk_next;
+ uint maxchunks;
- BLI_mempool_chunk *chunks_temp;
- BLI_freenode *last_tail = NULL;
+ BLI_mempool_chunk *chunks_temp;
+ BLI_freenode *last_tail = NULL;
#ifdef WITH_MEM_VALGRIND
- VALGRIND_DESTROY_MEMPOOL(pool);
- VALGRIND_CREATE_MEMPOOL(pool, 0, false);
+ VALGRIND_DESTROY_MEMPOOL(pool);
+ VALGRIND_CREATE_MEMPOOL(pool, 0, false);
#endif
- if (totelem_reserve == -1) {
- maxchunks = pool->maxchunks;
- }
- else {
- maxchunks = mempool_maxchunks((uint)totelem_reserve, pool->pchunk);
- }
-
- /* Free all after 'pool->maxchunks'. */
- mpchunk = mempool_chunk_find(pool->chunks, maxchunks - 1);
- if (mpchunk && mpchunk->next) {
- /* terminate */
- mpchunk_next = mpchunk->next;
- mpchunk->next = NULL;
- mpchunk = mpchunk_next;
-
- do {
- mpchunk_next = mpchunk->next;
- mempool_chunk_free(mpchunk);
- } while ((mpchunk = mpchunk_next));
- }
-
- /* re-initialize */
- pool->free = NULL;
- pool->totused = 0;
+ if (totelem_reserve == -1) {
+ maxchunks = pool->maxchunks;
+ }
+ else {
+ maxchunks = mempool_maxchunks((uint)totelem_reserve, pool->pchunk);
+ }
+
+ /* Free all after 'pool->maxchunks'. */
+ mpchunk = mempool_chunk_find(pool->chunks, maxchunks - 1);
+ if (mpchunk && mpchunk->next) {
+ /* terminate */
+ mpchunk_next = mpchunk->next;
+ mpchunk->next = NULL;
+ mpchunk = mpchunk_next;
+
+ do {
+ mpchunk_next = mpchunk->next;
+ mempool_chunk_free(mpchunk);
+ } while ((mpchunk = mpchunk_next));
+ }
+
+ /* re-initialize */
+ pool->free = NULL;
+ pool->totused = 0;
#ifdef USE_TOTALLOC
- pool->totalloc = 0;
+ pool->totalloc = 0;
#endif
- chunks_temp = pool->chunks;
- pool->chunks = NULL;
- pool->chunk_tail = NULL;
+ chunks_temp = pool->chunks;
+ pool->chunks = NULL;
+ pool->chunk_tail = NULL;
- while ((mpchunk = chunks_temp)) {
- chunks_temp = mpchunk->next;
- last_tail = mempool_chunk_add(pool, mpchunk, last_tail);
- }
+ while ((mpchunk = chunks_temp)) {
+ chunks_temp = mpchunk->next;
+ last_tail = mempool_chunk_add(pool, mpchunk, last_tail);
+ }
}
/**
@@ -754,7 +747,7 @@ void BLI_mempool_clear_ex(BLI_mempool *pool, const int totelem_reserve)
*/
void BLI_mempool_clear(BLI_mempool *pool)
{
- BLI_mempool_clear_ex(pool, -1);
+ BLI_mempool_clear_ex(pool, -1);
}
/**
@@ -762,18 +755,18 @@ void BLI_mempool_clear(BLI_mempool *pool)
*/
void BLI_mempool_destroy(BLI_mempool *pool)
{
- mempool_chunk_free_all(pool->chunks);
+ mempool_chunk_free_all(pool->chunks);
#ifdef WITH_MEM_VALGRIND
- VALGRIND_DESTROY_MEMPOOL(pool);
+ VALGRIND_DESTROY_MEMPOOL(pool);
#endif
- MEM_freeN(pool);
+ MEM_freeN(pool);
}
#ifndef NDEBUG
void BLI_mempool_set_memory_debug(void)
{
- mempool_debug_memset = true;
+ mempool_debug_memset = true;
}
#endif
diff --git a/source/blender/blenlib/intern/BLI_timer.c b/source/blender/blenlib/intern/BLI_timer.c
index 77409015aa6..bf9fd1b57f8 100644
--- a/source/blender/blenlib/intern/BLI_timer.c
+++ b/source/blender/blenlib/intern/BLI_timer.c
@@ -31,154 +31,156 @@
#define GET_TIME() PIL_check_seconds_timer()
typedef struct TimedFunction {
- struct TimedFunction *next, *prev;
- BLI_timer_func func;
- BLI_timer_data_free user_data_free;
- void *user_data;
- double next_time;
- uintptr_t uuid;
- bool tag_removal;
- bool persistent;
+ struct TimedFunction *next, *prev;
+ BLI_timer_func func;
+ BLI_timer_data_free user_data_free;
+ void *user_data;
+ double next_time;
+ uintptr_t uuid;
+ bool tag_removal;
+ bool persistent;
} TimedFunction;
typedef struct TimerContainer {
- ListBase funcs;
- bool file_load_cb_registered;
+ ListBase funcs;
+ bool file_load_cb_registered;
} TimerContainer;
static TimerContainer GlobalTimer = {{0}};
static void ensure_callback_is_registered(void);
-void BLI_timer_register(
- uintptr_t uuid,
- BLI_timer_func func,
- void *user_data,
- BLI_timer_data_free user_data_free,
- double first_interval,
- bool persistent)
+void BLI_timer_register(uintptr_t uuid,
+ BLI_timer_func func,
+ void *user_data,
+ BLI_timer_data_free user_data_free,
+ double first_interval,
+ bool persistent)
{
- ensure_callback_is_registered();
-
- TimedFunction *timed_func = MEM_callocN(sizeof(TimedFunction), __func__);
- timed_func->func = func;
- timed_func->user_data_free = user_data_free;
- timed_func->user_data = user_data;
- timed_func->next_time = GET_TIME() + first_interval;
- timed_func->tag_removal = false;
- timed_func->persistent = persistent;
- timed_func->uuid = uuid;
-
- BLI_addtail(&GlobalTimer.funcs, timed_func);
+ ensure_callback_is_registered();
+
+ TimedFunction *timed_func = MEM_callocN(sizeof(TimedFunction), __func__);
+ timed_func->func = func;
+ timed_func->user_data_free = user_data_free;
+ timed_func->user_data = user_data;
+ timed_func->next_time = GET_TIME() + first_interval;
+ timed_func->tag_removal = false;
+ timed_func->persistent = persistent;
+ timed_func->uuid = uuid;
+
+ BLI_addtail(&GlobalTimer.funcs, timed_func);
}
static void clear_user_data(TimedFunction *timed_func)
{
- if (timed_func->user_data_free) {
- timed_func->user_data_free(timed_func->uuid, timed_func->user_data);
- timed_func->user_data_free = NULL;
- }
+ if (timed_func->user_data_free) {
+ timed_func->user_data_free(timed_func->uuid, timed_func->user_data);
+ timed_func->user_data_free = NULL;
+ }
}
bool BLI_timer_unregister(uintptr_t uuid)
{
- LISTBASE_FOREACH(TimedFunction *, timed_func, &GlobalTimer.funcs) {
- if (timed_func->uuid == uuid) {
- if (timed_func->tag_removal) {
- return false;
- }
- else {
- timed_func->tag_removal = true;
- clear_user_data(timed_func);
- return true;
- }
- }
- }
- return false;
+ LISTBASE_FOREACH (TimedFunction *, timed_func, &GlobalTimer.funcs) {
+ if (timed_func->uuid == uuid) {
+ if (timed_func->tag_removal) {
+ return false;
+ }
+ else {
+ timed_func->tag_removal = true;
+ clear_user_data(timed_func);
+ return true;
+ }
+ }
+ }
+ return false;
}
bool BLI_timer_is_registered(uintptr_t uuid)
{
- LISTBASE_FOREACH(TimedFunction *, timed_func, &GlobalTimer.funcs) {
- if (timed_func->uuid == uuid && !timed_func->tag_removal) {
- return true;
- }
- }
- return false;
+ LISTBASE_FOREACH (TimedFunction *, timed_func, &GlobalTimer.funcs) {
+ if (timed_func->uuid == uuid && !timed_func->tag_removal) {
+ return true;
+ }
+ }
+ return false;
}
static void execute_functions_if_necessary(void)
{
- double current_time = GET_TIME();
-
- LISTBASE_FOREACH(TimedFunction *, timed_func, &GlobalTimer.funcs) {
- if (timed_func->tag_removal) {
- continue;
- }
- if (timed_func->next_time > current_time) {
- continue;
- }
-
- double ret = timed_func->func(timed_func->uuid, timed_func->user_data);
-
- if (ret < 0) {
- timed_func->tag_removal = true;
- }
- else {
- timed_func->next_time = current_time + ret;
- }
- }
+ double current_time = GET_TIME();
+
+ LISTBASE_FOREACH (TimedFunction *, timed_func, &GlobalTimer.funcs) {
+ if (timed_func->tag_removal) {
+ continue;
+ }
+ if (timed_func->next_time > current_time) {
+ continue;
+ }
+
+ double ret = timed_func->func(timed_func->uuid, timed_func->user_data);
+
+ if (ret < 0) {
+ timed_func->tag_removal = true;
+ }
+ else {
+ timed_func->next_time = current_time + ret;
+ }
+ }
}
static void remove_tagged_functions(void)
{
- for (TimedFunction *timed_func = GlobalTimer.funcs.first; timed_func; ) {
- TimedFunction *next = timed_func->next;
- if (timed_func->tag_removal) {
- clear_user_data(timed_func);
- BLI_freelinkN(&GlobalTimer.funcs, timed_func);
- }
- timed_func = next;
- }
+ for (TimedFunction *timed_func = GlobalTimer.funcs.first; timed_func;) {
+ TimedFunction *next = timed_func->next;
+ if (timed_func->tag_removal) {
+ clear_user_data(timed_func);
+ BLI_freelinkN(&GlobalTimer.funcs, timed_func);
+ }
+ timed_func = next;
+ }
}
void BLI_timer_execute()
{
- execute_functions_if_necessary();
- remove_tagged_functions();
+ execute_functions_if_necessary();
+ remove_tagged_functions();
}
void BLI_timer_free()
{
- LISTBASE_FOREACH(TimedFunction *, timed_func, &GlobalTimer.funcs) {
- timed_func->tag_removal = true;
- }
+ LISTBASE_FOREACH (TimedFunction *, timed_func, &GlobalTimer.funcs) {
+ timed_func->tag_removal = true;
+ }
- remove_tagged_functions();
+ remove_tagged_functions();
}
struct ID;
struct Main;
-static void remove_non_persistent_functions(struct Main *UNUSED(_1), struct ID *UNUSED(_2), void *UNUSED(_3))
+static void remove_non_persistent_functions(struct Main *UNUSED(_1),
+ struct ID *UNUSED(_2),
+ void *UNUSED(_3))
{
- LISTBASE_FOREACH(TimedFunction *, timed_func, &GlobalTimer.funcs) {
- if (!timed_func->persistent) {
- timed_func->tag_removal = true;
- }
- }
+ LISTBASE_FOREACH (TimedFunction *, timed_func, &GlobalTimer.funcs) {
+ if (!timed_func->persistent) {
+ timed_func->tag_removal = true;
+ }
+ }
}
static bCallbackFuncStore load_pre_callback = {
- NULL, NULL, /* next, prev */
- remove_non_persistent_functions, /* func */
- NULL, /* arg */
- 0, /* alloc */
+ NULL,
+ NULL, /* next, prev */
+ remove_non_persistent_functions, /* func */
+ NULL, /* arg */
+ 0, /* alloc */
};
static void ensure_callback_is_registered()
{
- if (!GlobalTimer.file_load_cb_registered) {
- BLI_callback_add(&load_pre_callback, BLI_CB_EVT_LOAD_PRE);
- GlobalTimer.file_load_cb_registered = true;
- }
+ if (!GlobalTimer.file_load_cb_registered) {
+ BLI_callback_add(&load_pre_callback, BLI_CB_EVT_LOAD_PRE);
+ GlobalTimer.file_load_cb_registered = true;
+ }
}
diff --git a/source/blender/blenlib/intern/DLRB_tree.c b/source/blender/blenlib/intern/DLRB_tree.c
index 46818c5a1b9..59d80b45a84 100644
--- a/source/blender/blenlib/intern/DLRB_tree.c
+++ b/source/blender/blenlib/intern/DLRB_tree.c
@@ -21,7 +21,6 @@
* \ingroup bli
*/
-
#include "MEM_guardedalloc.h"
#include "BLI_listbase.h"
@@ -33,57 +32,57 @@
/* Create a new tree, and initialize as necessary */
DLRBT_Tree *BLI_dlrbTree_new(void)
{
- /* just allocate for now */
- return MEM_callocN(sizeof(DLRBT_Tree), "DLRBT_Tree");
+ /* just allocate for now */
+ return MEM_callocN(sizeof(DLRBT_Tree), "DLRBT_Tree");
}
/* Just zero out the pointers used */
void BLI_dlrbTree_init(DLRBT_Tree *tree)
{
- if (tree == NULL) {
- return;
- }
+ if (tree == NULL) {
+ return;
+ }
- tree->first = tree->last = tree->root = NULL;
+ tree->first = tree->last = tree->root = NULL;
}
/* Helper for traversing tree and freeing sub-nodes */
static void recursive_tree_free_nodes(DLRBT_Node *node)
{
- /* sanity check */
- if (node == NULL) {
- return;
- }
+ /* sanity check */
+ if (node == NULL) {
+ return;
+ }
- /* free child nodes + subtrees */
- recursive_tree_free_nodes(node->left);
- recursive_tree_free_nodes(node->right);
+ /* free child nodes + subtrees */
+ recursive_tree_free_nodes(node->left);
+ recursive_tree_free_nodes(node->right);
- /* free self */
- MEM_freeN(node);
+ /* free self */
+ MEM_freeN(node);
}
/* Free the given tree's data but not the tree itself */
void BLI_dlrbTree_free(DLRBT_Tree *tree)
{
- if (tree == NULL) {
- return;
- }
-
- /* if the list-base stuff is set, just use that (and assume its set),
- * otherwise, we'll need to traverse the tree...
- */
- if (tree->first) {
- /* free list */
- BLI_freelistN((ListBase *)tree);
- }
- else {
- /* traverse tree, freeing sub-nodes */
- recursive_tree_free_nodes(tree->root);
- }
-
- /* clear pointers */
- tree->first = tree->last = tree->root = NULL;
+ if (tree == NULL) {
+ return;
+ }
+
+ /* if the list-base stuff is set, just use that (and assume its set),
+ * otherwise, we'll need to traverse the tree...
+ */
+ if (tree->first) {
+ /* free list */
+ BLI_freelistN((ListBase *)tree);
+ }
+ else {
+ /* traverse tree, freeing sub-nodes */
+ recursive_tree_free_nodes(tree->root);
+ }
+
+ /* clear pointers */
+ tree->first = tree->last = tree->root = NULL;
}
/* ------- */
@@ -91,38 +90,38 @@ void BLI_dlrbTree_free(DLRBT_Tree *tree)
/* Helper function - used for traversing down the tree from the root to add nodes in order */
static void linkedlist_sync_add_node(DLRBT_Tree *tree, DLRBT_Node *node)
{
- /* sanity checks */
- if ((tree == NULL) || (node == NULL)) {
- return;
- }
-
- /* add left-node (and its subtree) */
- linkedlist_sync_add_node(tree, node->left);
-
- /* now add self
- * - must remove detach from other links first
- * (for now, only clear own pointers)
- */
- node->prev = node->next = NULL;
- BLI_addtail((ListBase *)tree, (Link *)node);
-
- /* finally, add right node (and its subtree) */
- linkedlist_sync_add_node(tree, node->right);
+ /* sanity checks */
+ if ((tree == NULL) || (node == NULL)) {
+ return;
+ }
+
+ /* add left-node (and its subtree) */
+ linkedlist_sync_add_node(tree, node->left);
+
+ /* now add self
+ * - must remove detach from other links first
+ * (for now, only clear own pointers)
+ */
+ node->prev = node->next = NULL;
+ BLI_addtail((ListBase *)tree, (Link *)node);
+
+ /* finally, add right node (and its subtree) */
+ linkedlist_sync_add_node(tree, node->right);
}
/* Make sure the tree's Double-Linked list representation is valid */
void BLI_dlrbTree_linkedlist_sync(DLRBT_Tree *tree)
{
- /* sanity checks */
- if (tree == NULL) {
- return;
- }
+ /* sanity checks */
+ if (tree == NULL) {
+ return;
+ }
- /* clear list-base pointers so that the new list can be added properly */
- tree->first = tree->last = NULL;
+ /* clear list-base pointers so that the new list can be added properly */
+ tree->first = tree->last = NULL;
- /* start adding items from the root */
- linkedlist_sync_add_node(tree, tree->root);
+ /* start adding items from the root */
+ linkedlist_sync_add_node(tree, tree->root);
}
/* *********************************************** */
@@ -131,159 +130,164 @@ void BLI_dlrbTree_linkedlist_sync(DLRBT_Tree *tree)
/* Find the node which matches or is the closest to the requested node */
DLRBT_Node *BLI_dlrbTree_search(DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb, void *search_data)
{
- DLRBT_Node *node = (tree) ? tree->root : NULL;
- short found = 0;
-
- /* check that there is a comparator to use */
- /* TODO: if no comparator is supplied, try using the one supplied with the tree... */
- if (cmp_cb == NULL) {
- return NULL;
- }
-
- /* iteratively perform this search */
- while (node && found == 0) {
- /* check if traverse further or not
- * NOTE: it is assumed that the values will be unit values only
- */
- switch (cmp_cb(node, search_data)) {
- case -1: /* data less than node */
- if (node->left) {
- node = node->left;
- }
- else {
- found = 1;
- }
- break;
-
- case 1: /* data greater than node */
- if (node->right) {
- node = node->right;
- }
- else {
- found = 1;
- }
- break;
-
- default: /* data equals node */
- found = 1;
- break;
- }
- }
-
- /* return the nearest matching node */
- return node;
+ DLRBT_Node *node = (tree) ? tree->root : NULL;
+ short found = 0;
+
+ /* check that there is a comparator to use */
+ /* TODO: if no comparator is supplied, try using the one supplied with the tree... */
+ if (cmp_cb == NULL) {
+ return NULL;
+ }
+
+ /* iteratively perform this search */
+ while (node && found == 0) {
+ /* check if traverse further or not
+ * NOTE: it is assumed that the values will be unit values only
+ */
+ switch (cmp_cb(node, search_data)) {
+ case -1: /* data less than node */
+ if (node->left) {
+ node = node->left;
+ }
+ else {
+ found = 1;
+ }
+ break;
+
+ case 1: /* data greater than node */
+ if (node->right) {
+ node = node->right;
+ }
+ else {
+ found = 1;
+ }
+ break;
+
+ default: /* data equals node */
+ found = 1;
+ break;
+ }
+ }
+
+ /* return the nearest matching node */
+ return node;
}
/* Find the node which exactly matches the required data */
-DLRBT_Node *BLI_dlrbTree_search_exact(DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb, void *search_data)
+DLRBT_Node *BLI_dlrbTree_search_exact(DLRBT_Tree *tree,
+ DLRBT_Comparator_FP cmp_cb,
+ void *search_data)
{
- DLRBT_Node *node = (tree) ? tree->root : NULL;
- short found = 0;
-
- /* check that there is a comparator to use */
- /* TODO: if no comparator is supplied, try using the one supplied with the tree... */
- if (cmp_cb == NULL) {
- return NULL;
- }
-
- /* iteratively perform this search */
- while (node && found == 0) {
- /* check if traverse further or not
- * NOTE: it is assumed that the values will be unit values only
- */
- switch (cmp_cb(node, search_data)) {
- case -1: /* data less than node */
- if (node->left) {
- node = node->left;
- }
- else {
- found = -1;
- }
- break;
-
- case 1: /* data greater than node */
- if (node->right) {
- node = node->right;
- }
- else {
- found = -1;
- }
- break;
-
- default: /* data equals node */
- found = 1;
- break;
- }
- }
-
- /* return the exactly matching node */
- return (found == 1) ? (node) : (NULL);
+ DLRBT_Node *node = (tree) ? tree->root : NULL;
+ short found = 0;
+
+ /* check that there is a comparator to use */
+ /* TODO: if no comparator is supplied, try using the one supplied with the tree... */
+ if (cmp_cb == NULL) {
+ return NULL;
+ }
+
+ /* iteratively perform this search */
+ while (node && found == 0) {
+ /* check if traverse further or not
+ * NOTE: it is assumed that the values will be unit values only
+ */
+ switch (cmp_cb(node, search_data)) {
+ case -1: /* data less than node */
+ if (node->left) {
+ node = node->left;
+ }
+ else {
+ found = -1;
+ }
+ break;
+
+ case 1: /* data greater than node */
+ if (node->right) {
+ node = node->right;
+ }
+ else {
+ found = -1;
+ }
+ break;
+
+ default: /* data equals node */
+ found = 1;
+ break;
+ }
+ }
+
+ /* return the exactly matching node */
+ return (found == 1) ? (node) : (NULL);
}
/* Find the node which occurs immediately before the best matching node */
-DLRBT_Node *BLI_dlrbTree_search_prev(DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb, void *search_data)
+DLRBT_Node *BLI_dlrbTree_search_prev(DLRBT_Tree *tree,
+ DLRBT_Comparator_FP cmp_cb,
+ void *search_data)
{
- DLRBT_Node *node;
-
- /* check that there is a comparator to use */
- /* TODO: if no comparator is supplied, try using the one supplied with the tree... */
- if (cmp_cb == NULL) {
- return NULL;
- }
-
- /* get the node which best matches this description */
- node = BLI_dlrbTree_search(tree, cmp_cb, search_data);
-
- if (node) {
- /* if the item we're searching for is greater than the node found, we've found the match */
- if (cmp_cb(node, search_data) > 0) {
- return node;
- }
-
- /* return the previous node otherwise */
- /* NOTE: what happens if there is no previous node? */
- return node->prev;
- }
-
- /* nothing matching was found */
- return NULL;
+ DLRBT_Node *node;
+
+ /* check that there is a comparator to use */
+ /* TODO: if no comparator is supplied, try using the one supplied with the tree... */
+ if (cmp_cb == NULL) {
+ return NULL;
+ }
+
+ /* get the node which best matches this description */
+ node = BLI_dlrbTree_search(tree, cmp_cb, search_data);
+
+ if (node) {
+ /* if the item we're searching for is greater than the node found, we've found the match */
+ if (cmp_cb(node, search_data) > 0) {
+ return node;
+ }
+
+ /* return the previous node otherwise */
+ /* NOTE: what happens if there is no previous node? */
+ return node->prev;
+ }
+
+ /* nothing matching was found */
+ return NULL;
}
/* Find the node which occurs immediately after the best matching node */
-DLRBT_Node *BLI_dlrbTree_search_next(DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb, void *search_data)
+DLRBT_Node *BLI_dlrbTree_search_next(DLRBT_Tree *tree,
+ DLRBT_Comparator_FP cmp_cb,
+ void *search_data)
{
- DLRBT_Node *node;
-
- /* check that there is a comparator to use */
- /* TODO: if no comparator is supplied, try using the one supplied with the tree... */
- if (cmp_cb == NULL) {
- return NULL;
- }
-
- /* get the node which best matches this description */
- node = BLI_dlrbTree_search(tree, cmp_cb, search_data);
-
- if (node) {
- /* if the item we're searching for is less than the node found, we've found the match */
- if (cmp_cb(node, search_data) < 0) {
- return node;
- }
-
- /* return the previous node otherwise */
- /* NOTE: what happens if there is no previous node? */
- return node->next;
- }
-
- /* nothing matching was found */
- return NULL;
+ DLRBT_Node *node;
+
+ /* check that there is a comparator to use */
+ /* TODO: if no comparator is supplied, try using the one supplied with the tree... */
+ if (cmp_cb == NULL) {
+ return NULL;
+ }
+
+ /* get the node which best matches this description */
+ node = BLI_dlrbTree_search(tree, cmp_cb, search_data);
+
+ if (node) {
+ /* if the item we're searching for is less than the node found, we've found the match */
+ if (cmp_cb(node, search_data) < 0) {
+ return node;
+ }
+
+ /* return the previous node otherwise */
+ /* NOTE: what happens if there is no previous node? */
+ return node->next;
+ }
+
+ /* nothing matching was found */
+ return NULL;
}
-
/* Check whether there is a node matching the requested node */
short BLI_dlrbTree_contains(DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb, void *search_data)
{
- /* check if an exact search throws up anything... */
- return (BLI_dlrbTree_search_exact(tree, cmp_cb, search_data) != NULL);
+ /* check if an exact search throws up anything... */
+ return (BLI_dlrbTree_search_exact(tree, cmp_cb, search_data) != NULL);
}
/* *********************************************** */
@@ -292,40 +296,40 @@ short BLI_dlrbTree_contains(DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb, void *
/* get the 'grandparent' - the parent of the parent - of the given node */
static DLRBT_Node *get_grandparent(DLRBT_Node *node)
{
- if (node && node->parent) {
- return node->parent->parent;
- }
- else {
- return NULL;
- }
+ if (node && node->parent) {
+ return node->parent->parent;
+ }
+ else {
+ return NULL;
+ }
}
/* get the sibling node (e.g. if node is left child of parent, return right child of parent) */
static DLRBT_Node *get_sibling(DLRBT_Node *node)
{
- if (node && node->parent) {
- if (node == node->parent->left) {
- return node->parent->right;
- }
- else {
- return node->parent->left;
- }
- }
-
- /* sibling not found */
- return NULL;
+ if (node && node->parent) {
+ if (node == node->parent->left) {
+ return node->parent->right;
+ }
+ else {
+ return node->parent->left;
+ }
+ }
+
+ /* sibling not found */
+ return NULL;
}
/* get the 'uncle' - the sibling of the parent - of the given node */
static DLRBT_Node *get_uncle(DLRBT_Node *node)
{
- if (node) {
- /* return the child of the grandparent which isn't the node's parent */
- return get_sibling(node->parent);
- }
+ if (node) {
+ /* return the child of the grandparent which isn't the node's parent */
+ return get_sibling(node->parent);
+ }
- /* uncle not found */
- return NULL;
+ /* uncle not found */
+ return NULL;
}
/* *********************************************** */
@@ -334,83 +338,83 @@ static DLRBT_Node *get_uncle(DLRBT_Node *node)
/* make right child of 'root' the new root */
static void rotate_left(DLRBT_Tree *tree, DLRBT_Node *root)
{
- DLRBT_Node **root_slot, *pivot;
-
- /* pivot is simply the root's right child, to become the root's parent */
- pivot = root->right;
- if (pivot == NULL) {
- return;
- }
-
- if (root->parent) {
- if (root == root->parent->left) {
- root_slot = &root->parent->left;
- }
- else {
- root_slot = &root->parent->right;
- }
- }
- else {
- root_slot = ((DLRBT_Node **)&tree->root); /* &((DLRBT_Node *)tree->root); */
- }
-
- /* - pivot's left child becomes root's right child
- * - root now becomes pivot's left child
- */
- root->right = pivot->left;
- if (pivot->left) {
- pivot->left->parent = root;
- }
-
- pivot->left = root;
- pivot->parent = root->parent;
- root->parent = pivot;
-
- /* make the pivot the new root */
- if (root_slot) {
- *root_slot = pivot;
- }
+ DLRBT_Node **root_slot, *pivot;
+
+ /* pivot is simply the root's right child, to become the root's parent */
+ pivot = root->right;
+ if (pivot == NULL) {
+ return;
+ }
+
+ if (root->parent) {
+ if (root == root->parent->left) {
+ root_slot = &root->parent->left;
+ }
+ else {
+ root_slot = &root->parent->right;
+ }
+ }
+ else {
+ root_slot = ((DLRBT_Node **)&tree->root); /* &((DLRBT_Node *)tree->root); */
+ }
+
+ /* - pivot's left child becomes root's right child
+ * - root now becomes pivot's left child
+ */
+ root->right = pivot->left;
+ if (pivot->left) {
+ pivot->left->parent = root;
+ }
+
+ pivot->left = root;
+ pivot->parent = root->parent;
+ root->parent = pivot;
+
+ /* make the pivot the new root */
+ if (root_slot) {
+ *root_slot = pivot;
+ }
}
/* make the left child of the 'root' the new root */
static void rotate_right(DLRBT_Tree *tree, DLRBT_Node *root)
{
- DLRBT_Node **root_slot, *pivot;
-
- /* pivot is simply the root's left child, to become the root's parent */
- pivot = root->left;
- if (pivot == NULL) {
- return;
- }
-
- if (root->parent) {
- if (root == root->parent->left) {
- root_slot = &root->parent->left;
- }
- else {
- root_slot = &root->parent->right;
- }
- }
- else {
- root_slot = ((DLRBT_Node **)&tree->root); /* &((DLRBT_Node *)tree->root); */
- }
-
- /* - pivot's right child becomes root's left child
- * - root now becomes pivot's right child
- */
- root->left = pivot->right;
- if (pivot->right) {
- pivot->right->parent = root;
- }
-
- pivot->right = root;
- pivot->parent = root->parent;
- root->parent = pivot;
-
- /* make the pivot the new root */
- if (root_slot) {
- *root_slot = pivot;
- }
+ DLRBT_Node **root_slot, *pivot;
+
+ /* pivot is simply the root's left child, to become the root's parent */
+ pivot = root->left;
+ if (pivot == NULL) {
+ return;
+ }
+
+ if (root->parent) {
+ if (root == root->parent->left) {
+ root_slot = &root->parent->left;
+ }
+ else {
+ root_slot = &root->parent->right;
+ }
+ }
+ else {
+ root_slot = ((DLRBT_Node **)&tree->root); /* &((DLRBT_Node *)tree->root); */
+ }
+
+ /* - pivot's right child becomes root's left child
+ * - root now becomes pivot's right child
+ */
+ root->left = pivot->right;
+ if (pivot->right) {
+ pivot->right->parent = root;
+ }
+
+ pivot->right = root;
+ pivot->parent = root->parent;
+ root->parent = pivot;
+
+ /* make the pivot the new root */
+ if (root_slot) {
+ *root_slot = pivot;
+ }
}
/* *********************************************** */
@@ -426,96 +430,96 @@ static void insert_check_3(DLRBT_Tree *tree, DLRBT_Node *node);
/* W. 1) Root must be black (so that the 2nd-generation can have a black parent) */
static void insert_check_1(DLRBT_Tree *tree, DLRBT_Node *node)
{
- if (node) {
- /* if this is the root, just ensure that it is black */
- if (node->parent == NULL) {
- node->tree_col = DLRBT_BLACK;
- }
- else {
- insert_check_2(tree, node);
- }
- }
+ if (node) {
+ /* if this is the root, just ensure that it is black */
+ if (node->parent == NULL) {
+ node->tree_col = DLRBT_BLACK;
+ }
+ else {
+ insert_check_2(tree, node);
+ }
+ }
}
/* W. 2+3) Parent of node must be black, otherwise recolor and flush */
static void insert_check_2(DLRBT_Tree *tree, DLRBT_Node *node)
{
- /* if the parent is not black, we need to change that... */
- if (node && node->parent && node->parent->tree_col) {
- DLRBT_Node *unc = get_uncle(node);
-
- /* if uncle and parent are both red, need to change them to black and make
- * the parent black in order to satisfy the criteria of each node having the
- * same number of black nodes to its leaves
- */
- if (unc && unc->tree_col) {
- DLRBT_Node *gp = get_grandparent(node);
-
- /* make the n-1 generation nodes black */
- node->parent->tree_col = unc->tree_col = DLRBT_BLACK;
-
- /* - make the grandparent red, so that we maintain alternating red/black property
- * (it must exist, so no need to check for NULL here),
- * - as the grandparent may now cause inconsistencies with the rest of the tree,
- * we must flush up the tree and perform checks/re-balancing/re-painting, using the
- * grandparent as the node of interest
- */
- gp->tree_col = DLRBT_RED;
- insert_check_1(tree, gp);
- }
- else {
- /* we've got an unbalanced branch going down the grandparent to the parent,
- * so need to perform some rotations to re-balance the tree
- */
- insert_check_3(tree, node);
- }
- }
+ /* if the parent is not black, we need to change that... */
+ if (node && node->parent && node->parent->tree_col) {
+ DLRBT_Node *unc = get_uncle(node);
+
+ /* if uncle and parent are both red, need to change them to black and make
+ * the parent black in order to satisfy the criteria of each node having the
+ * same number of black nodes to its leaves
+ */
+ if (unc && unc->tree_col) {
+ DLRBT_Node *gp = get_grandparent(node);
+
+ /* make the n-1 generation nodes black */
+ node->parent->tree_col = unc->tree_col = DLRBT_BLACK;
+
+ /* - make the grandparent red, so that we maintain alternating red/black property
+ * (it must exist, so no need to check for NULL here),
+ * - as the grandparent may now cause inconsistencies with the rest of the tree,
+ * we must flush up the tree and perform checks/re-balancing/re-painting, using the
+ * grandparent as the node of interest
+ */
+ gp->tree_col = DLRBT_RED;
+ insert_check_1(tree, gp);
+ }
+ else {
+ /* we've got an unbalanced branch going down the grandparent to the parent,
+ * so need to perform some rotations to re-balance the tree
+ */
+ insert_check_3(tree, node);
+ }
+ }
}
/* W. 4+5) Perform rotation on sub-tree containing the 'new' node, then do any */
static void insert_check_3(DLRBT_Tree *tree, DLRBT_Node *node)
{
- DLRBT_Node *gp = get_grandparent(node);
-
- /* check that grandparent and node->parent exist
- * (jut in case... really shouldn't happen on a good tree) */
- if (node && node->parent && gp) {
- /* a left rotation will switch the roles of node and its parent, assuming that
- * the parent is the left child of the grandparent... otherwise, rotation direction
- * should be swapped
- */
- if ((node == node->parent->right) && (node->parent == gp->left)) {
- rotate_left(tree, node);
- node = node->left;
- }
- else if ((node == node->parent->left) && (node->parent == gp->right)) {
- rotate_right(tree, node);
- node = node->right;
- }
-
- /* fix old parent's color-tagging, and perform rotation on the old parent in the
- * opposite direction if needed for the current situation
- * NOTE: in the code above, node pointer is changed to point to the old parent
- */
- if (node) {
- /* get 'new' grandparent (i.e. grandparent for old-parent (node)) */
- gp = get_grandparent(node);
-
- /* modify the coloring of the grandparent and parent
- * so that they still satisfy the constraints */
- node->parent->tree_col = DLRBT_BLACK;
- gp->tree_col = DLRBT_RED;
-
- /* if there are several nodes that all form a left chain, do a right rotation to correct
- * this (or a rotation in the opposite direction if they all form a right chain) */
- if ((node == node->parent->left) && (node->parent == gp->left)) {
- rotate_right(tree, gp);
- }
- else { //if ((node == node->parent->right) && (node->parent == gp->right))
- rotate_left(tree, gp);
- }
- }
- }
+ DLRBT_Node *gp = get_grandparent(node);
+
+ /* check that grandparent and node->parent exist
+ * (jut in case... really shouldn't happen on a good tree) */
+ if (node && node->parent && gp) {
+ /* a left rotation will switch the roles of node and its parent, assuming that
+ * the parent is the left child of the grandparent... otherwise, rotation direction
+ * should be swapped
+ */
+ if ((node == node->parent->right) && (node->parent == gp->left)) {
+ rotate_left(tree, node);
+ node = node->left;
+ }
+ else if ((node == node->parent->left) && (node->parent == gp->right)) {
+ rotate_right(tree, node);
+ node = node->right;
+ }
+
+ /* fix old parent's color-tagging, and perform rotation on the old parent in the
+ * opposite direction if needed for the current situation
+ * NOTE: in the code above, node pointer is changed to point to the old parent
+ */
+ if (node) {
+ /* get 'new' grandparent (i.e. grandparent for old-parent (node)) */
+ gp = get_grandparent(node);
+
+ /* modify the coloring of the grandparent and parent
+ * so that they still satisfy the constraints */
+ node->parent->tree_col = DLRBT_BLACK;
+ gp->tree_col = DLRBT_RED;
+
+ /* if there are several nodes that all form a left chain, do a right rotation to correct
+ * this (or a rotation in the opposite direction if they all form a right chain) */
+ if ((node == node->parent->left) && (node->parent == gp->left)) {
+ rotate_right(tree, gp);
+ }
+ else { //if ((node == node->parent->right) && (node->parent == gp->right))
+ rotate_left(tree, gp);
+ }
+ }
+ }
}
/* ----- */
@@ -525,16 +529,16 @@ static void insert_check_3(DLRBT_Tree *tree, DLRBT_Node *node)
*/
void BLI_dlrbTree_insert(DLRBT_Tree *tree, DLRBT_Node *node)
{
- /* sanity checks */
- if ((tree == NULL) || (node == NULL)) {
- return;
- }
+ /* sanity checks */
+ if ((tree == NULL) || (node == NULL)) {
+ return;
+ }
- /* firstly, the node we just added should be red by default */
- node->tree_col = DLRBT_RED;
+ /* firstly, the node we just added should be red by default */
+ node->tree_col = DLRBT_RED;
- /* start from case 1, an trek through the tail-recursive insertion checks */
- insert_check_1(tree, node);
+ /* start from case 1, an trek through the tail-recursive insertion checks */
+ insert_check_1(tree, node);
}
/* ----- */
@@ -542,86 +546,89 @@ void BLI_dlrbTree_insert(DLRBT_Tree *tree, DLRBT_Node *node)
/* Add the given data to the tree, and return the node added */
/* NOTE: for duplicates, the update_cb is called (if available),
* and the existing node is returned */
-DLRBT_Node *BLI_dlrbTree_add(DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb,
- DLRBT_NAlloc_FP new_cb, DLRBT_NUpdate_FP update_cb, void *data)
+DLRBT_Node *BLI_dlrbTree_add(DLRBT_Tree *tree,
+ DLRBT_Comparator_FP cmp_cb,
+ DLRBT_NAlloc_FP new_cb,
+ DLRBT_NUpdate_FP update_cb,
+ void *data)
{
- DLRBT_Node *parNode, *node = NULL;
- short new_node = 0;
-
- /* sanity checks */
- if (tree == NULL) {
- return NULL;
- }
-
- /* TODO: if no comparator is supplied, try using the one supplied with the tree... */
- if (cmp_cb == NULL) {
- return NULL;
- }
- /* TODO: if no allocator is supplied, try using the one supplied with the tree... */
- if (new_cb == NULL) {
- return NULL;
- }
- /* TODO: if no updater is supplied, try using the one supplied with the tree... */
-
- /* try to find the nearest node to this one */
- parNode = BLI_dlrbTree_search(tree, cmp_cb, data);
-
- /* add new node to the BST in the 'standard way' as appropriate
- * NOTE: we do not support duplicates in our tree...
- */
- if (parNode) {
- /* check how this new node compares with the existing ones
- * NOTE: it is assumed that the values will be unit values only
- */
- switch (cmp_cb(parNode, data)) {
- case -1: /* add new node as left child */
- {
- node = new_cb(data);
- new_node = 1;
-
- parNode->left = node;
- node->parent = parNode;
- break;
- }
- case 1: /* add new node as right child */
- {
- node = new_cb(data);
- new_node = 1;
-
- parNode->right = node;
- node->parent = parNode;
- break;
- }
- default: /* update the duplicate node as appropriate */
- {
- if (update_cb) {
- update_cb(parNode, data);
- }
- break;
- }
- }
- }
- else {
- /* no nodes in the tree yet... add a new node as the root */
- node = new_cb(data);
- new_node = 1;
-
- tree->root = node;
- }
-
- /* if a new node was added, it should be tagged as red, and then balanced as appropriate */
- if (new_node) {
- /* tag this new node as being 'red' */
- node->tree_col = DLRBT_RED;
-
- /* perform BST balancing steps:
- * start from case 1, an trek through the tail-recursive insertion checks
- */
- insert_check_1(tree, node);
- }
-
- /* return the node added */
- return node;
+ DLRBT_Node *parNode, *node = NULL;
+ short new_node = 0;
+
+ /* sanity checks */
+ if (tree == NULL) {
+ return NULL;
+ }
+
+ /* TODO: if no comparator is supplied, try using the one supplied with the tree... */
+ if (cmp_cb == NULL) {
+ return NULL;
+ }
+ /* TODO: if no allocator is supplied, try using the one supplied with the tree... */
+ if (new_cb == NULL) {
+ return NULL;
+ }
+ /* TODO: if no updater is supplied, try using the one supplied with the tree... */
+
+ /* try to find the nearest node to this one */
+ parNode = BLI_dlrbTree_search(tree, cmp_cb, data);
+
+ /* add new node to the BST in the 'standard way' as appropriate
+ * NOTE: we do not support duplicates in our tree...
+ */
+ if (parNode) {
+ /* check how this new node compares with the existing ones
+ * NOTE: it is assumed that the values will be unit values only
+ */
+ switch (cmp_cb(parNode, data)) {
+ case -1: /* add new node as left child */
+ {
+ node = new_cb(data);
+ new_node = 1;
+
+ parNode->left = node;
+ node->parent = parNode;
+ break;
+ }
+ case 1: /* add new node as right child */
+ {
+ node = new_cb(data);
+ new_node = 1;
+
+ parNode->right = node;
+ node->parent = parNode;
+ break;
+ }
+ default: /* update the duplicate node as appropriate */
+ {
+ if (update_cb) {
+ update_cb(parNode, data);
+ }
+ break;
+ }
+ }
+ }
+ else {
+ /* no nodes in the tree yet... add a new node as the root */
+ node = new_cb(data);
+ new_node = 1;
+
+ tree->root = node;
+ }
+
+ /* if a new node was added, it should be tagged as red, and then balanced as appropriate */
+ if (new_node) {
+ /* tag this new node as being 'red' */
+ node->tree_col = DLRBT_RED;
+
+ /* perform BST balancing steps:
+ * start from case 1, an trek through the tail-recursive insertion checks
+ */
+ insert_check_1(tree, node);
+ }
+
+ /* return the node added */
+ return node;
}
/* *********************************************** */
diff --git a/source/blender/blenlib/intern/array_store.c b/source/blender/blenlib/intern/array_store.c
index 477d320835e..0e7b9a29ee5 100644
--- a/source/blender/blenlib/intern/array_store.c
+++ b/source/blender/blenlib/intern/array_store.c
@@ -105,7 +105,7 @@
#include "BLI_strict_flags.h"
-#include "BLI_array_store.h" /* own include */
+#include "BLI_array_store.h" /* own include */
/* only for BLI_array_store_is_valid */
#include "BLI_ghash.h"
@@ -161,7 +161,7 @@
*/
#define USE_HASH_TABLE_KEY_CACHE
#ifdef USE_HASH_TABLE_KEY_CACHE
-# define HASH_TABLE_KEY_UNSET ((uint64_t)-1)
+# define HASH_TABLE_KEY_UNSET ((uint64_t)-1)
# define HASH_TABLE_KEY_FALLBACK ((uint64_t)-2)
#endif
@@ -192,7 +192,7 @@
* so lower only to check splitting works.
*/
# define BCHUNK_SIZE_MAX_MUL 2
-#endif /* USE_MERGE_CHUNKS */
+#endif /* USE_MERGE_CHUNKS */
/* slow (keep disabled), but handy for debugging */
// #define USE_VALIDATE_LIST_SIZE
@@ -203,50 +203,48 @@
/** \} */
-
/** \name Internal Structs
* \{ */
typedef uint64_t hash_key;
-
typedef struct BArrayInfo {
- size_t chunk_stride;
- // uint chunk_count; /* UNUSED (other values are derived from this) */
+ size_t chunk_stride;
+ // uint chunk_count; /* UNUSED (other values are derived from this) */
- /* pre-calculated */
- size_t chunk_byte_size;
- /* min/max limits (inclusive) */
- size_t chunk_byte_size_min;
- size_t chunk_byte_size_max;
+ /* pre-calculated */
+ size_t chunk_byte_size;
+ /* min/max limits (inclusive) */
+ size_t chunk_byte_size_min;
+ size_t chunk_byte_size_max;
- size_t accum_read_ahead_bytes;
+ size_t accum_read_ahead_bytes;
#ifdef USE_HASH_TABLE_ACCUMULATE
- size_t accum_steps;
- size_t accum_read_ahead_len;
+ size_t accum_steps;
+ size_t accum_read_ahead_len;
#endif
} BArrayInfo;
typedef struct BArrayMemory {
- BLI_mempool *chunk_list; /* BChunkList */
- BLI_mempool *chunk_ref; /* BChunkRef */
- BLI_mempool *chunk; /* BChunk */
+ BLI_mempool *chunk_list; /* BChunkList */
+ BLI_mempool *chunk_ref; /* BChunkRef */
+ BLI_mempool *chunk; /* BChunk */
} BArrayMemory;
/**
* Main storage for all states
*/
struct BArrayStore {
- /* static */
- BArrayInfo info;
+ /* static */
+ BArrayInfo info;
- /* memory storage */
- BArrayMemory memory;
+ /* memory storage */
+ BArrayMemory memory;
- /**
- * #BArrayState may be in any order (logic should never depend on state order).
- */
- ListBase states;
+ /**
+ * #BArrayState may be in any order (logic should never depend on state order).
+ */
+ ListBase states;
};
/**
@@ -260,31 +258,30 @@ struct BArrayStore {
* it makes it easier to trace invalid usage, so leave as-is for now.
*/
struct BArrayState {
- /** linked list in #BArrayStore.states */
- struct BArrayState *next, *prev;
-
- struct BChunkList *chunk_list; /* BChunkList's */
+ /** linked list in #BArrayStore.states */
+ struct BArrayState *next, *prev;
+ struct BChunkList *chunk_list; /* BChunkList's */
};
typedef struct BChunkList {
- ListBase chunk_refs; /* BChunkRef's */
- uint chunk_refs_len; /* BLI_listbase_count(chunks), store for reuse. */
- size_t total_size; /* size of all chunks */
+ ListBase chunk_refs; /* BChunkRef's */
+ uint chunk_refs_len; /* BLI_listbase_count(chunks), store for reuse. */
+ size_t total_size; /* size of all chunks */
- /** number of #BArrayState using this. */
- int users;
+ /** number of #BArrayState using this. */
+ int users;
} BChunkList;
/* a chunk of an array */
typedef struct BChunk {
- const uchar *data;
- size_t data_len;
- /** number of #BChunkList using this. */
- int users;
+ const uchar *data;
+ size_t data_len;
+ /** number of #BChunkList using this. */
+ int users;
#ifdef USE_HASH_TABLE_KEY_CACHE
- hash_key key;
+ hash_key key;
#endif
} BChunk;
@@ -292,8 +289,8 @@ typedef struct BChunk {
* Links to store #BChunk data in #BChunkList.chunk_refs.
*/
typedef struct BChunkRef {
- struct BChunkRef *next, *prev;
- BChunk *link;
+ struct BChunkRef *next, *prev;
+ BChunk *link;
} BChunkRef;
/**
@@ -305,100 +302,92 @@ typedef struct BChunkRef {
* this avoids having to do so many table lookups.
*/
typedef struct BTableRef {
- struct BTableRef *next;
- const BChunkRef *cref;
+ struct BTableRef *next;
+ const BChunkRef *cref;
} BTableRef;
/** \} */
-
static size_t bchunk_list_size(const BChunkList *chunk_list);
-
/** \name Internal BChunk API
* \{ */
-static BChunk *bchunk_new(
- BArrayMemory *bs_mem, const uchar *data, const size_t data_len)
+static BChunk *bchunk_new(BArrayMemory *bs_mem, const uchar *data, const size_t data_len)
{
- BChunk *chunk = BLI_mempool_alloc(bs_mem->chunk);
- chunk->data = data;
- chunk->data_len = data_len;
- chunk->users = 0;
+ BChunk *chunk = BLI_mempool_alloc(bs_mem->chunk);
+ chunk->data = data;
+ chunk->data_len = data_len;
+ chunk->users = 0;
#ifdef USE_HASH_TABLE_KEY_CACHE
- chunk->key = HASH_TABLE_KEY_UNSET;
+ chunk->key = HASH_TABLE_KEY_UNSET;
#endif
- return chunk;
+ return chunk;
}
-static BChunk *bchunk_new_copydata(
- BArrayMemory *bs_mem, const uchar *data, const size_t data_len)
+static BChunk *bchunk_new_copydata(BArrayMemory *bs_mem, const uchar *data, const size_t data_len)
{
- uchar *data_copy = MEM_mallocN(data_len, __func__);
- memcpy(data_copy, data, data_len);
- return bchunk_new(bs_mem, data_copy, data_len);
+ uchar *data_copy = MEM_mallocN(data_len, __func__);
+ memcpy(data_copy, data, data_len);
+ return bchunk_new(bs_mem, data_copy, data_len);
}
-static void bchunk_decref(
- BArrayMemory *bs_mem, BChunk *chunk)
+static void bchunk_decref(BArrayMemory *bs_mem, BChunk *chunk)
{
- BLI_assert(chunk->users > 0);
- if (chunk->users == 1) {
- MEM_freeN((void *)chunk->data);
- BLI_mempool_free(bs_mem->chunk, chunk);
- }
- else {
- chunk->users -= 1;
- }
+ BLI_assert(chunk->users > 0);
+ if (chunk->users == 1) {
+ MEM_freeN((void *)chunk->data);
+ BLI_mempool_free(bs_mem->chunk, chunk);
+ }
+ else {
+ chunk->users -= 1;
+ }
}
-static bool bchunk_data_compare(
- const BChunk *chunk,
- const uchar *data_base, const size_t data_base_len,
- const size_t offset)
+static bool bchunk_data_compare(const BChunk *chunk,
+ const uchar *data_base,
+ const size_t data_base_len,
+ const size_t offset)
{
- if (offset + (size_t)chunk->data_len <= data_base_len) {
- return (memcmp(&data_base[offset], chunk->data, chunk->data_len) == 0);
- }
- else {
- return false;
- }
+ if (offset + (size_t)chunk->data_len <= data_base_len) {
+ return (memcmp(&data_base[offset], chunk->data, chunk->data_len) == 0);
+ }
+ else {
+ return false;
+ }
}
/** \} */
-
/** \name Internal BChunkList API
* \{ */
-static BChunkList *bchunk_list_new(
- BArrayMemory *bs_mem, size_t total_size)
+static BChunkList *bchunk_list_new(BArrayMemory *bs_mem, size_t total_size)
{
- BChunkList *chunk_list = BLI_mempool_alloc(bs_mem->chunk_list);
+ BChunkList *chunk_list = BLI_mempool_alloc(bs_mem->chunk_list);
- BLI_listbase_clear(&chunk_list->chunk_refs);
- chunk_list->chunk_refs_len = 0;
- chunk_list->total_size = total_size;
- chunk_list->users = 0;
- return chunk_list;
+ BLI_listbase_clear(&chunk_list->chunk_refs);
+ chunk_list->chunk_refs_len = 0;
+ chunk_list->total_size = total_size;
+ chunk_list->users = 0;
+ return chunk_list;
}
-static void bchunk_list_decref(
- BArrayMemory *bs_mem, BChunkList *chunk_list)
+static void bchunk_list_decref(BArrayMemory *bs_mem, BChunkList *chunk_list)
{
- BLI_assert(chunk_list->users > 0);
- if (chunk_list->users == 1) {
- for (BChunkRef *cref = chunk_list->chunk_refs.first, *cref_next; cref; cref = cref_next) {
- cref_next = cref->next;
- bchunk_decref(bs_mem, cref->link);
- BLI_mempool_free(bs_mem->chunk_ref, cref);
- }
-
- BLI_mempool_free(bs_mem->chunk_list, chunk_list);
- }
- else {
- chunk_list->users -= 1;
- }
+ BLI_assert(chunk_list->users > 0);
+ if (chunk_list->users == 1) {
+ for (BChunkRef *cref = chunk_list->chunk_refs.first, *cref_next; cref; cref = cref_next) {
+ cref_next = cref->next;
+ bchunk_decref(bs_mem, cref->link);
+ BLI_mempool_free(bs_mem->chunk_ref, cref);
+ }
+
+ BLI_mempool_free(bs_mem->chunk_list, chunk_list);
+ }
+ else {
+ chunk_list->users -= 1;
+ }
}
#ifdef USE_VALIDATE_LIST_SIZE
@@ -410,113 +399,110 @@ static void bchunk_list_decref(
# define ASSERT_CHUNKLIST_SIZE(chunk_list, n) (EXPR_NOP(chunk_list), EXPR_NOP(n))
#endif
-
#ifdef USE_VALIDATE_LIST_DATA_PARTIAL
-static size_t bchunk_list_data_check(
- const BChunkList *chunk_list, const uchar *data)
+static size_t bchunk_list_data_check(const BChunkList *chunk_list, const uchar *data)
{
- size_t offset = 0;
- for (BChunkRef *cref = chunk_list->chunk_refs.first; cref; cref = cref->next) {
- if (memcmp(&data[offset], cref->link->data, cref->link->data_len) != 0) {
- return false;
- }
- offset += cref->link->data_len;
- }
- return true;
+ size_t offset = 0;
+ for (BChunkRef *cref = chunk_list->chunk_refs.first; cref; cref = cref->next) {
+ if (memcmp(&data[offset], cref->link->data, cref->link->data_len) != 0) {
+ return false;
+ }
+ offset += cref->link->data_len;
+ }
+ return true;
}
-# define ASSERT_CHUNKLIST_DATA(chunk_list, data) BLI_assert(bchunk_list_data_check(chunk_list, data))
+# define ASSERT_CHUNKLIST_DATA(chunk_list, data) \
+ BLI_assert(bchunk_list_data_check(chunk_list, data))
#else
# define ASSERT_CHUNKLIST_DATA(chunk_list, data) (EXPR_NOP(chunk_list), EXPR_NOP(data))
#endif
-
#ifdef USE_MERGE_CHUNKS
-static void bchunk_list_ensure_min_size_last(
- const BArrayInfo *info, BArrayMemory *bs_mem,
- BChunkList *chunk_list)
+static void bchunk_list_ensure_min_size_last(const BArrayInfo *info,
+ BArrayMemory *bs_mem,
+ BChunkList *chunk_list)
{
- BChunkRef *cref = chunk_list->chunk_refs.last;
- if (cref && cref->prev) {
- /* both are decref'd after use (end of this block) */
- BChunk *chunk_curr = cref->link;
- BChunk *chunk_prev = cref->prev->link;
-
- if (MIN2(chunk_prev->data_len, chunk_curr->data_len) < info->chunk_byte_size_min) {
- const size_t data_merge_len = chunk_prev->data_len + chunk_curr->data_len;
- /* we could pass, but no need */
- if (data_merge_len <= info->chunk_byte_size_max) {
- /* we have enough space to merge */
-
- /* remove last from linklist */
- BLI_assert(chunk_list->chunk_refs.last != chunk_list->chunk_refs.first);
- cref->prev->next = NULL;
- chunk_list->chunk_refs.last = cref->prev;
- chunk_list->chunk_refs_len -= 1;
-
- uchar *data_merge = MEM_mallocN(data_merge_len, __func__);
- memcpy(data_merge, chunk_prev->data, chunk_prev->data_len);
- memcpy(&data_merge[chunk_prev->data_len], chunk_curr->data, chunk_curr->data_len);
-
- cref->prev->link = bchunk_new(bs_mem, data_merge, data_merge_len);
- cref->prev->link->users += 1;
-
- BLI_mempool_free(bs_mem->chunk_ref, cref);
- }
- else {
- /* If we always merge small slices, we should _almost_
- * never end up having very large chunks.
- * Gradual expanding on contracting will cause this.
- *
- * if we do, the code below works (test by setting 'BCHUNK_SIZE_MAX_MUL = 1.2') */
-
- /* keep chunk on the left hand side a regular size */
- const size_t split = info->chunk_byte_size;
-
- /* merge and split */
- const size_t data_prev_len = split;
- const size_t data_curr_len = data_merge_len - split;
- uchar *data_prev = MEM_mallocN(data_prev_len, __func__);
- uchar *data_curr = MEM_mallocN(data_curr_len, __func__);
-
- if (data_prev_len <= chunk_prev->data_len) {
- const size_t data_curr_shrink_len = chunk_prev->data_len - data_prev_len;
-
- /* setup 'data_prev' */
- memcpy(data_prev, chunk_prev->data, data_prev_len);
-
- /* setup 'data_curr' */
- memcpy(data_curr, &chunk_prev->data[data_prev_len], data_curr_shrink_len);
- memcpy(&data_curr[data_curr_shrink_len], chunk_curr->data, chunk_curr->data_len);
- }
- else {
- BLI_assert(data_curr_len <= chunk_curr->data_len);
- BLI_assert(data_prev_len >= chunk_prev->data_len);
-
- const size_t data_prev_grow_len = data_prev_len - chunk_prev->data_len;
-
- /* setup 'data_prev' */
- memcpy(data_prev, chunk_prev->data, chunk_prev->data_len);
- memcpy(&data_prev[chunk_prev->data_len], chunk_curr->data, data_prev_grow_len);
-
- /* setup 'data_curr' */
- memcpy(data_curr, &chunk_curr->data[data_prev_grow_len], data_curr_len);
- }
-
- cref->prev->link = bchunk_new(bs_mem, data_prev, data_prev_len);
- cref->prev->link->users += 1;
-
- cref->link = bchunk_new(bs_mem, data_curr, data_curr_len);
- cref->link->users += 1;
- }
-
- /* free zero users */
- bchunk_decref(bs_mem, chunk_curr);
- bchunk_decref(bs_mem, chunk_prev);
- }
- }
+ BChunkRef *cref = chunk_list->chunk_refs.last;
+ if (cref && cref->prev) {
+ /* both are decref'd after use (end of this block) */
+ BChunk *chunk_curr = cref->link;
+ BChunk *chunk_prev = cref->prev->link;
+
+ if (MIN2(chunk_prev->data_len, chunk_curr->data_len) < info->chunk_byte_size_min) {
+ const size_t data_merge_len = chunk_prev->data_len + chunk_curr->data_len;
+ /* we could pass, but no need */
+ if (data_merge_len <= info->chunk_byte_size_max) {
+ /* we have enough space to merge */
+
+ /* remove last from linklist */
+ BLI_assert(chunk_list->chunk_refs.last != chunk_list->chunk_refs.first);
+ cref->prev->next = NULL;
+ chunk_list->chunk_refs.last = cref->prev;
+ chunk_list->chunk_refs_len -= 1;
+
+ uchar *data_merge = MEM_mallocN(data_merge_len, __func__);
+ memcpy(data_merge, chunk_prev->data, chunk_prev->data_len);
+ memcpy(&data_merge[chunk_prev->data_len], chunk_curr->data, chunk_curr->data_len);
+
+ cref->prev->link = bchunk_new(bs_mem, data_merge, data_merge_len);
+ cref->prev->link->users += 1;
+
+ BLI_mempool_free(bs_mem->chunk_ref, cref);
+ }
+ else {
+ /* If we always merge small slices, we should _almost_
+ * never end up having very large chunks.
+ * Gradual expanding on contracting will cause this.
+ *
+ * if we do, the code below works (test by setting 'BCHUNK_SIZE_MAX_MUL = 1.2') */
+
+ /* keep chunk on the left hand side a regular size */
+ const size_t split = info->chunk_byte_size;
+
+ /* merge and split */
+ const size_t data_prev_len = split;
+ const size_t data_curr_len = data_merge_len - split;
+ uchar *data_prev = MEM_mallocN(data_prev_len, __func__);
+ uchar *data_curr = MEM_mallocN(data_curr_len, __func__);
+
+ if (data_prev_len <= chunk_prev->data_len) {
+ const size_t data_curr_shrink_len = chunk_prev->data_len - data_prev_len;
+
+ /* setup 'data_prev' */
+ memcpy(data_prev, chunk_prev->data, data_prev_len);
+
+ /* setup 'data_curr' */
+ memcpy(data_curr, &chunk_prev->data[data_prev_len], data_curr_shrink_len);
+ memcpy(&data_curr[data_curr_shrink_len], chunk_curr->data, chunk_curr->data_len);
+ }
+ else {
+ BLI_assert(data_curr_len <= chunk_curr->data_len);
+ BLI_assert(data_prev_len >= chunk_prev->data_len);
+
+ const size_t data_prev_grow_len = data_prev_len - chunk_prev->data_len;
+
+ /* setup 'data_prev' */
+ memcpy(data_prev, chunk_prev->data, chunk_prev->data_len);
+ memcpy(&data_prev[chunk_prev->data_len], chunk_curr->data, data_prev_grow_len);
+
+ /* setup 'data_curr' */
+ memcpy(data_curr, &chunk_curr->data[data_prev_grow_len], data_curr_len);
+ }
+
+ cref->prev->link = bchunk_new(bs_mem, data_prev, data_prev_len);
+ cref->prev->link->users += 1;
+
+ cref->link = bchunk_new(bs_mem, data_curr, data_curr_len);
+ cref->link->users += 1;
+ }
+
+ /* free zero users */
+ bchunk_decref(bs_mem, chunk_curr);
+ bchunk_decref(bs_mem, chunk_prev);
+ }
+ }
}
-#endif /* USE_MERGE_CHUNKS */
-
+#endif /* USE_MERGE_CHUNKS */
/**
* Split length into 2 values
@@ -526,108 +512,108 @@ static void bchunk_list_ensure_min_size_last(
* \note This function ensures the size of \a r_data_last_chunk_len
* is larger than #BArrayInfo.chunk_byte_size_min.
*/
-static void bchunk_list_calc_trim_len(
- const BArrayInfo *info, const size_t data_len,
- size_t *r_data_trim_len, size_t *r_data_last_chunk_len)
+static void bchunk_list_calc_trim_len(const BArrayInfo *info,
+ const size_t data_len,
+ size_t *r_data_trim_len,
+ size_t *r_data_last_chunk_len)
{
- size_t data_last_chunk_len = 0;
- size_t data_trim_len = data_len;
+ size_t data_last_chunk_len = 0;
+ size_t data_trim_len = data_len;
#ifdef USE_MERGE_CHUNKS
- /* avoid creating too-small chunks
- * more efficient then merging after */
- if (data_len > info->chunk_byte_size) {
- data_last_chunk_len = (data_trim_len % info->chunk_byte_size);
- data_trim_len = data_trim_len - data_last_chunk_len;
- if (data_last_chunk_len) {
- if (data_last_chunk_len < info->chunk_byte_size_min) {
- /* may be zero and thats OK */
- data_trim_len -= info->chunk_byte_size;
- data_last_chunk_len += info->chunk_byte_size;
- }
- }
- }
- else {
- data_trim_len = 0;
- data_last_chunk_len = data_len;
- }
-
- BLI_assert((data_trim_len == 0) || (data_trim_len >= info->chunk_byte_size));
+ /* avoid creating too-small chunks
+ * more efficient then merging after */
+ if (data_len > info->chunk_byte_size) {
+ data_last_chunk_len = (data_trim_len % info->chunk_byte_size);
+ data_trim_len = data_trim_len - data_last_chunk_len;
+ if (data_last_chunk_len) {
+ if (data_last_chunk_len < info->chunk_byte_size_min) {
+ /* may be zero and thats OK */
+ data_trim_len -= info->chunk_byte_size;
+ data_last_chunk_len += info->chunk_byte_size;
+ }
+ }
+ }
+ else {
+ data_trim_len = 0;
+ data_last_chunk_len = data_len;
+ }
+
+ BLI_assert((data_trim_len == 0) || (data_trim_len >= info->chunk_byte_size));
#else
- data_last_chunk_len = (data_trim_len % info->chunk_byte_size);
- data_trim_len = data_trim_len - data_last_chunk_len;
+ data_last_chunk_len = (data_trim_len % info->chunk_byte_size);
+ data_trim_len = data_trim_len - data_last_chunk_len;
#endif
- BLI_assert(data_trim_len + data_last_chunk_len == data_len);
+ BLI_assert(data_trim_len + data_last_chunk_len == data_len);
- *r_data_trim_len = data_trim_len;
- *r_data_last_chunk_len = data_last_chunk_len;
+ *r_data_trim_len = data_trim_len;
+ *r_data_last_chunk_len = data_last_chunk_len;
}
/**
* Append and don't manage merging small chunks.
*/
-static void bchunk_list_append_only(
- BArrayMemory *bs_mem,
- BChunkList *chunk_list, BChunk *chunk)
+static void bchunk_list_append_only(BArrayMemory *bs_mem, BChunkList *chunk_list, BChunk *chunk)
{
- BChunkRef *cref = BLI_mempool_alloc(bs_mem->chunk_ref);
- BLI_addtail(&chunk_list->chunk_refs, cref);
- cref->link = chunk;
- chunk_list->chunk_refs_len += 1;
- chunk->users += 1;
+ BChunkRef *cref = BLI_mempool_alloc(bs_mem->chunk_ref);
+ BLI_addtail(&chunk_list->chunk_refs, cref);
+ cref->link = chunk;
+ chunk_list->chunk_refs_len += 1;
+ chunk->users += 1;
}
/**
* \note This is for writing single chunks,
* use #bchunk_list_append_data_n when writing large blocks of memory into many chunks.
*/
-static void bchunk_list_append_data(
- const BArrayInfo *info, BArrayMemory *bs_mem,
- BChunkList *chunk_list,
- const uchar *data, const size_t data_len)
+static void bchunk_list_append_data(const BArrayInfo *info,
+ BArrayMemory *bs_mem,
+ BChunkList *chunk_list,
+ const uchar *data,
+ const size_t data_len)
{
- BLI_assert(data_len != 0);
+ BLI_assert(data_len != 0);
#ifdef USE_MERGE_CHUNKS
- BLI_assert(data_len <= info->chunk_byte_size_max);
-
- if (!BLI_listbase_is_empty(&chunk_list->chunk_refs)) {
- BChunkRef *cref = chunk_list->chunk_refs.last;
- BChunk *chunk_prev = cref->link;
-
- if (MIN2(chunk_prev->data_len, data_len) < info->chunk_byte_size_min) {
- const size_t data_merge_len = chunk_prev->data_len + data_len;
- /* realloc for single user */
- if (cref->link->users == 1) {
- uchar *data_merge = MEM_reallocN((void *)cref->link->data, data_merge_len);
- memcpy(&data_merge[chunk_prev->data_len], data, data_len);
- cref->link->data = data_merge;
- cref->link->data_len = data_merge_len;
- }
- else {
- uchar *data_merge = MEM_mallocN(data_merge_len, __func__);
- memcpy(data_merge, chunk_prev->data, chunk_prev->data_len);
- memcpy(&data_merge[chunk_prev->data_len], data, data_len);
- cref->link = bchunk_new(bs_mem, data_merge, data_merge_len);
- cref->link->users += 1;
- bchunk_decref(bs_mem, chunk_prev);
- }
- return;
- }
- }
+ BLI_assert(data_len <= info->chunk_byte_size_max);
+
+ if (!BLI_listbase_is_empty(&chunk_list->chunk_refs)) {
+ BChunkRef *cref = chunk_list->chunk_refs.last;
+ BChunk *chunk_prev = cref->link;
+
+ if (MIN2(chunk_prev->data_len, data_len) < info->chunk_byte_size_min) {
+ const size_t data_merge_len = chunk_prev->data_len + data_len;
+ /* realloc for single user */
+ if (cref->link->users == 1) {
+ uchar *data_merge = MEM_reallocN((void *)cref->link->data, data_merge_len);
+ memcpy(&data_merge[chunk_prev->data_len], data, data_len);
+ cref->link->data = data_merge;
+ cref->link->data_len = data_merge_len;
+ }
+ else {
+ uchar *data_merge = MEM_mallocN(data_merge_len, __func__);
+ memcpy(data_merge, chunk_prev->data, chunk_prev->data_len);
+ memcpy(&data_merge[chunk_prev->data_len], data, data_len);
+ cref->link = bchunk_new(bs_mem, data_merge, data_merge_len);
+ cref->link->users += 1;
+ bchunk_decref(bs_mem, chunk_prev);
+ }
+ return;
+ }
+ }
#else
- UNUSED_VARS(info);
-#endif /* USE_MERGE_CHUNKS */
+ UNUSED_VARS(info);
+#endif /* USE_MERGE_CHUNKS */
- BChunk *chunk = bchunk_new_copydata(bs_mem, data, data_len);
- bchunk_list_append_only(bs_mem, chunk_list, chunk);
+ BChunk *chunk = bchunk_new_copydata(bs_mem, data, data_len);
+ bchunk_list_append_only(bs_mem, chunk_list, chunk);
- /* don't run this, instead preemptively avoid creating a chunk only to merge it (above). */
+ /* don't run this, instead preemptively avoid creating a chunk only to merge it (above). */
#if 0
-#ifdef USE_MERGE_CHUNKS
- bchunk_list_ensure_min_size_last(info, bs_mem, chunk_list);
-#endif
+# ifdef USE_MERGE_CHUNKS
+ bchunk_list_ensure_min_size_last(info, bs_mem, chunk_list);
+# endif
#endif
}
@@ -638,106 +624,109 @@ static void bchunk_list_append_data(
* \note This function takes care not to perform redundant chunk-merging checks,
* so we can write successive fixed size chunks quickly.
*/
-static void bchunk_list_append_data_n(
- const BArrayInfo *info, BArrayMemory *bs_mem,
- BChunkList *chunk_list,
- const uchar *data, size_t data_len)
+static void bchunk_list_append_data_n(const BArrayInfo *info,
+ BArrayMemory *bs_mem,
+ BChunkList *chunk_list,
+ const uchar *data,
+ size_t data_len)
{
- size_t data_trim_len, data_last_chunk_len;
- bchunk_list_calc_trim_len(info, data_len, &data_trim_len, &data_last_chunk_len);
-
- if (data_trim_len != 0) {
- size_t i_prev;
-
- {
- const size_t i = info->chunk_byte_size;
- bchunk_list_append_data(info, bs_mem, chunk_list, data, i);
- i_prev = i;
- }
-
- while (i_prev != data_trim_len) {
- const size_t i = i_prev + info->chunk_byte_size;
- BChunk *chunk = bchunk_new_copydata(bs_mem, &data[i_prev], i - i_prev);
- bchunk_list_append_only(bs_mem, chunk_list, chunk);
- i_prev = i;
- }
-
- if (data_last_chunk_len) {
- BChunk *chunk = bchunk_new_copydata(bs_mem, &data[i_prev], data_last_chunk_len);
- bchunk_list_append_only(bs_mem, chunk_list, chunk);
- // i_prev = data_len; /* UNUSED */
- }
- }
- else {
- /* if we didn't write any chunks previously,
- * we may need to merge with the last. */
- if (data_last_chunk_len) {
- bchunk_list_append_data(info, bs_mem, chunk_list, data, data_last_chunk_len);
- // i_prev = data_len; /* UNUSED */
- }
- }
+ size_t data_trim_len, data_last_chunk_len;
+ bchunk_list_calc_trim_len(info, data_len, &data_trim_len, &data_last_chunk_len);
+
+ if (data_trim_len != 0) {
+ size_t i_prev;
+
+ {
+ const size_t i = info->chunk_byte_size;
+ bchunk_list_append_data(info, bs_mem, chunk_list, data, i);
+ i_prev = i;
+ }
+
+ while (i_prev != data_trim_len) {
+ const size_t i = i_prev + info->chunk_byte_size;
+ BChunk *chunk = bchunk_new_copydata(bs_mem, &data[i_prev], i - i_prev);
+ bchunk_list_append_only(bs_mem, chunk_list, chunk);
+ i_prev = i;
+ }
+
+ if (data_last_chunk_len) {
+ BChunk *chunk = bchunk_new_copydata(bs_mem, &data[i_prev], data_last_chunk_len);
+ bchunk_list_append_only(bs_mem, chunk_list, chunk);
+ // i_prev = data_len; /* UNUSED */
+ }
+ }
+ else {
+ /* if we didn't write any chunks previously,
+ * we may need to merge with the last. */
+ if (data_last_chunk_len) {
+ bchunk_list_append_data(info, bs_mem, chunk_list, data, data_last_chunk_len);
+ // i_prev = data_len; /* UNUSED */
+ }
+ }
#ifdef USE_MERGE_CHUNKS
- if (data_len > info->chunk_byte_size) {
- BLI_assert(((BChunkRef *)chunk_list->chunk_refs.last)->link->data_len >= info->chunk_byte_size_min);
- }
+ if (data_len > info->chunk_byte_size) {
+ BLI_assert(((BChunkRef *)chunk_list->chunk_refs.last)->link->data_len >=
+ info->chunk_byte_size_min);
+ }
#endif
}
-static void bchunk_list_append(
- const BArrayInfo *info, BArrayMemory *bs_mem,
- BChunkList *chunk_list,
- BChunk *chunk)
+static void bchunk_list_append(const BArrayInfo *info,
+ BArrayMemory *bs_mem,
+ BChunkList *chunk_list,
+ BChunk *chunk)
{
- bchunk_list_append_only(bs_mem, chunk_list, chunk);
+ bchunk_list_append_only(bs_mem, chunk_list, chunk);
#ifdef USE_MERGE_CHUNKS
- bchunk_list_ensure_min_size_last(info, bs_mem, chunk_list);
+ bchunk_list_ensure_min_size_last(info, bs_mem, chunk_list);
#else
- UNUSED_VARS(info);
+ UNUSED_VARS(info);
#endif
}
-static void bchunk_list_fill_from_array(
- const BArrayInfo *info, BArrayMemory *bs_mem,
- BChunkList *chunk_list,
- const uchar *data,
- const size_t data_len)
+static void bchunk_list_fill_from_array(const BArrayInfo *info,
+ BArrayMemory *bs_mem,
+ BChunkList *chunk_list,
+ const uchar *data,
+ const size_t data_len)
{
- BLI_assert(BLI_listbase_is_empty(&chunk_list->chunk_refs));
+ BLI_assert(BLI_listbase_is_empty(&chunk_list->chunk_refs));
- size_t data_trim_len, data_last_chunk_len;
- bchunk_list_calc_trim_len(info, data_len, &data_trim_len, &data_last_chunk_len);
+ size_t data_trim_len, data_last_chunk_len;
+ bchunk_list_calc_trim_len(info, data_len, &data_trim_len, &data_last_chunk_len);
- size_t i_prev = 0;
- while (i_prev != data_trim_len) {
- const size_t i = i_prev + info->chunk_byte_size;
- BChunk *chunk = bchunk_new_copydata(bs_mem, &data[i_prev], i - i_prev);
- bchunk_list_append_only(bs_mem, chunk_list, chunk);
- i_prev = i;
- }
+ size_t i_prev = 0;
+ while (i_prev != data_trim_len) {
+ const size_t i = i_prev + info->chunk_byte_size;
+ BChunk *chunk = bchunk_new_copydata(bs_mem, &data[i_prev], i - i_prev);
+ bchunk_list_append_only(bs_mem, chunk_list, chunk);
+ i_prev = i;
+ }
- if (data_last_chunk_len) {
- BChunk *chunk = bchunk_new_copydata(bs_mem, &data[i_prev], data_last_chunk_len);
- bchunk_list_append_only(bs_mem, chunk_list, chunk);
- // i_prev = data_len;
- }
+ if (data_last_chunk_len) {
+ BChunk *chunk = bchunk_new_copydata(bs_mem, &data[i_prev], data_last_chunk_len);
+ bchunk_list_append_only(bs_mem, chunk_list, chunk);
+ // i_prev = data_len;
+ }
#ifdef USE_MERGE_CHUNKS
- if (data_len > info->chunk_byte_size) {
- BLI_assert(((BChunkRef *)chunk_list->chunk_refs.last)->link->data_len >= info->chunk_byte_size_min);
- }
+ if (data_len > info->chunk_byte_size) {
+ BLI_assert(((BChunkRef *)chunk_list->chunk_refs.last)->link->data_len >=
+ info->chunk_byte_size_min);
+ }
#endif
- /* works but better avoid redundant re-alloc */
+ /* works but better avoid redundant re-alloc */
#if 0
-#ifdef USE_MERGE_CHUNKS
- bchunk_list_ensure_min_size_last(info, bs_mem, chunk_list);
-#endif
+# ifdef USE_MERGE_CHUNKS
+ bchunk_list_ensure_min_size_last(info, bs_mem, chunk_list);
+# endif
#endif
- ASSERT_CHUNKLIST_SIZE(chunk_list, data_len);
- ASSERT_CHUNKLIST_DATA(chunk_list, data);
+ ASSERT_CHUNKLIST_SIZE(chunk_list, data_len);
+ ASSERT_CHUNKLIST_DATA(chunk_list, data);
}
/** \} */
@@ -755,86 +744,87 @@ static void bchunk_list_fill_from_array(
BLI_INLINE uint hash_data_single(const uchar p)
{
- return ((HASH_INIT << 5) + HASH_INIT) + (unsigned int)(*((signed char *)&p));
+ return ((HASH_INIT << 5) + HASH_INIT) + (unsigned int)(*((signed char *)&p));
}
/* hash bytes, from BLI_ghashutil_strhash_n */
static uint hash_data(const uchar *key, size_t n)
{
- const signed char *p;
- unsigned int h = HASH_INIT;
+ const signed char *p;
+ unsigned int h = HASH_INIT;
- for (p = (const signed char *)key; n--; p++) {
- h = ((h << 5) + h) + (unsigned int)*p;
- }
+ for (p = (const signed char *)key; n--; p++) {
+ h = ((h << 5) + h) + (unsigned int)*p;
+ }
- return h;
+ return h;
}
#undef HASH_INIT
-
#ifdef USE_HASH_TABLE_ACCUMULATE
-static void hash_array_from_data(
- const BArrayInfo *info, const uchar *data_slice, const size_t data_slice_len,
- hash_key *hash_array)
+static void hash_array_from_data(const BArrayInfo *info,
+ const uchar *data_slice,
+ const size_t data_slice_len,
+ hash_key *hash_array)
{
- if (info->chunk_stride != 1) {
- for (size_t i = 0, i_step = 0; i_step < data_slice_len; i++, i_step += info->chunk_stride) {
- hash_array[i] = hash_data(&data_slice[i_step], info->chunk_stride);
- }
- }
- else {
- /* fast-path for bytes */
- for (size_t i = 0; i < data_slice_len; i++) {
- hash_array[i] = hash_data_single(data_slice[i]);
- }
- }
+ if (info->chunk_stride != 1) {
+ for (size_t i = 0, i_step = 0; i_step < data_slice_len; i++, i_step += info->chunk_stride) {
+ hash_array[i] = hash_data(&data_slice[i_step], info->chunk_stride);
+ }
+ }
+ else {
+ /* fast-path for bytes */
+ for (size_t i = 0; i < data_slice_len; i++) {
+ hash_array[i] = hash_data_single(data_slice[i]);
+ }
+ }
}
/*
* Similar to hash_array_from_data,
* but able to step into the next chunk if we run-out of data.
*/
-static void hash_array_from_cref(
- const BArrayInfo *info, const BChunkRef *cref, const size_t data_len,
- hash_key *hash_array)
+static void hash_array_from_cref(const BArrayInfo *info,
+ const BChunkRef *cref,
+ const size_t data_len,
+ hash_key *hash_array)
{
- const size_t hash_array_len = data_len / info->chunk_stride;
- size_t i = 0;
- do {
- size_t i_next = hash_array_len - i;
- size_t data_trim_len = i_next * info->chunk_stride;
- if (data_trim_len > cref->link->data_len) {
- data_trim_len = cref->link->data_len;
- i_next = data_trim_len / info->chunk_stride;
- }
- BLI_assert(data_trim_len <= cref->link->data_len);
- hash_array_from_data(info, cref->link->data, data_trim_len, &hash_array[i]);
- i += i_next;
- cref = cref->next;
- } while ((i < hash_array_len) && (cref != NULL));
-
- /* If this isn't equal, the caller didn't properly check
- * that there was enough data left in all chunks */
- BLI_assert(i == hash_array_len);
+ const size_t hash_array_len = data_len / info->chunk_stride;
+ size_t i = 0;
+ do {
+ size_t i_next = hash_array_len - i;
+ size_t data_trim_len = i_next * info->chunk_stride;
+ if (data_trim_len > cref->link->data_len) {
+ data_trim_len = cref->link->data_len;
+ i_next = data_trim_len / info->chunk_stride;
+ }
+ BLI_assert(data_trim_len <= cref->link->data_len);
+ hash_array_from_data(info, cref->link->data, data_trim_len, &hash_array[i]);
+ i += i_next;
+ cref = cref->next;
+ } while ((i < hash_array_len) && (cref != NULL));
+
+ /* If this isn't equal, the caller didn't properly check
+ * that there was enough data left in all chunks */
+ BLI_assert(i == hash_array_len);
}
static void hash_accum(hash_key *hash_array, const size_t hash_array_len, size_t iter_steps)
{
- /* _very_ unlikely, can happen if you select a chunk-size of 1 for example. */
- if (UNLIKELY((iter_steps > hash_array_len))) {
- iter_steps = hash_array_len;
- }
-
- const size_t hash_array_search_len = hash_array_len - iter_steps;
- while (iter_steps != 0) {
- const size_t hash_offset = iter_steps;
- for (uint i = 0; i < hash_array_search_len; i++) {
- hash_array[i] += (hash_array[i + hash_offset]) * ((hash_array[i] & 0xff) + 1);
- }
- iter_steps -= 1;
- }
+ /* _very_ unlikely, can happen if you select a chunk-size of 1 for example. */
+ if (UNLIKELY((iter_steps > hash_array_len))) {
+ iter_steps = hash_array_len;
+ }
+
+ const size_t hash_array_search_len = hash_array_len - iter_steps;
+ while (iter_steps != 0) {
+ const size_t hash_offset = iter_steps;
+ for (uint i = 0; i < hash_array_search_len; i++) {
+ hash_array[i] += (hash_array[i + hash_offset]) * ((hash_array[i] & 0xff) + 1);
+ }
+ iter_steps -= 1;
+ }
}
/**
@@ -843,162 +833,173 @@ static void hash_accum(hash_key *hash_array, const size_t hash_array_len, size_t
*/
static void hash_accum_single(hash_key *hash_array, const size_t hash_array_len, size_t iter_steps)
{
- BLI_assert(iter_steps <= hash_array_len);
- if (UNLIKELY(!(iter_steps <= hash_array_len))) {
- /* while this shouldn't happen, avoid crashing */
- iter_steps = hash_array_len;
- }
- /* We can increase this value each step to avoid accumulating quite as much
- * while getting the same results as hash_accum */
- size_t iter_steps_sub = iter_steps;
-
- while (iter_steps != 0) {
- const size_t hash_array_search_len = hash_array_len - iter_steps_sub;
- const size_t hash_offset = iter_steps;
- for (uint i = 0; i < hash_array_search_len; i++) {
- hash_array[i] += (hash_array[i + hash_offset]) * ((hash_array[i] & 0xff) + 1);
- }
- iter_steps -= 1;
- iter_steps_sub += iter_steps;
- }
+ BLI_assert(iter_steps <= hash_array_len);
+ if (UNLIKELY(!(iter_steps <= hash_array_len))) {
+ /* while this shouldn't happen, avoid crashing */
+ iter_steps = hash_array_len;
+ }
+ /* We can increase this value each step to avoid accumulating quite as much
+ * while getting the same results as hash_accum */
+ size_t iter_steps_sub = iter_steps;
+
+ while (iter_steps != 0) {
+ const size_t hash_array_search_len = hash_array_len - iter_steps_sub;
+ const size_t hash_offset = iter_steps;
+ for (uint i = 0; i < hash_array_search_len; i++) {
+ hash_array[i] += (hash_array[i + hash_offset]) * ((hash_array[i] & 0xff) + 1);
+ }
+ iter_steps -= 1;
+ iter_steps_sub += iter_steps;
+ }
}
-static hash_key key_from_chunk_ref(
- const BArrayInfo *info, const BChunkRef *cref,
- /* avoid reallocating each time */
- hash_key *hash_store, const size_t hash_store_len)
+static hash_key key_from_chunk_ref(const BArrayInfo *info,
+ const BChunkRef *cref,
+ /* avoid reallocating each time */
+ hash_key *hash_store,
+ const size_t hash_store_len)
{
- /* in C, will fill in a reusable array */
- BChunk *chunk = cref->link;
- BLI_assert((info->accum_read_ahead_bytes * info->chunk_stride) != 0);
-
- if (info->accum_read_ahead_bytes <= chunk->data_len) {
- hash_key key;
-
-#ifdef USE_HASH_TABLE_KEY_CACHE
- key = chunk->key;
- if (key != HASH_TABLE_KEY_UNSET) {
- /* Using key cache!
- * avoids calculating every time */
- }
- else {
- hash_array_from_cref(info, cref, info->accum_read_ahead_bytes, hash_store);
- hash_accum_single(hash_store, hash_store_len, info->accum_steps);
- key = hash_store[0];
-
- /* cache the key */
- if (UNLIKELY(key == HASH_TABLE_KEY_UNSET)) {
- key = HASH_TABLE_KEY_FALLBACK;
- }
- chunk->key = key;
- }
-#else
- hash_array_from_cref(info, cref, info->accum_read_ahead_bytes, hash_store);
- hash_accum_single(hash_store, hash_store_len, info->accum_steps);
- key = hash_store[0];
-#endif
- return key;
- }
- else {
- /* corner case - we're too small, calculate the key each time. */
-
- hash_array_from_cref(info, cref, info->accum_read_ahead_bytes, hash_store);
- hash_accum_single(hash_store, hash_store_len, info->accum_steps);
- hash_key key = hash_store[0];
-
-#ifdef USE_HASH_TABLE_KEY_CACHE
- if (UNLIKELY(key == HASH_TABLE_KEY_UNSET)) {
- key = HASH_TABLE_KEY_FALLBACK;
- }
-#endif
- return key;
- }
+ /* in C, will fill in a reusable array */
+ BChunk *chunk = cref->link;
+ BLI_assert((info->accum_read_ahead_bytes * info->chunk_stride) != 0);
+
+ if (info->accum_read_ahead_bytes <= chunk->data_len) {
+ hash_key key;
+
+# ifdef USE_HASH_TABLE_KEY_CACHE
+ key = chunk->key;
+ if (key != HASH_TABLE_KEY_UNSET) {
+ /* Using key cache!
+ * avoids calculating every time */
+ }
+ else {
+ hash_array_from_cref(info, cref, info->accum_read_ahead_bytes, hash_store);
+ hash_accum_single(hash_store, hash_store_len, info->accum_steps);
+ key = hash_store[0];
+
+ /* cache the key */
+ if (UNLIKELY(key == HASH_TABLE_KEY_UNSET)) {
+ key = HASH_TABLE_KEY_FALLBACK;
+ }
+ chunk->key = key;
+ }
+# else
+ hash_array_from_cref(info, cref, info->accum_read_ahead_bytes, hash_store);
+ hash_accum_single(hash_store, hash_store_len, info->accum_steps);
+ key = hash_store[0];
+# endif
+ return key;
+ }
+ else {
+ /* corner case - we're too small, calculate the key each time. */
+
+ hash_array_from_cref(info, cref, info->accum_read_ahead_bytes, hash_store);
+ hash_accum_single(hash_store, hash_store_len, info->accum_steps);
+ hash_key key = hash_store[0];
+
+# ifdef USE_HASH_TABLE_KEY_CACHE
+ if (UNLIKELY(key == HASH_TABLE_KEY_UNSET)) {
+ key = HASH_TABLE_KEY_FALLBACK;
+ }
+# endif
+ return key;
+ }
}
-static const BChunkRef *table_lookup(
- const BArrayInfo *info, BTableRef **table, const size_t table_len, const size_t i_table_start,
- const uchar *data, const size_t data_len, const size_t offset, const hash_key *table_hash_array)
+static const BChunkRef *table_lookup(const BArrayInfo *info,
+ BTableRef **table,
+ const size_t table_len,
+ const size_t i_table_start,
+ const uchar *data,
+ const size_t data_len,
+ const size_t offset,
+ const hash_key *table_hash_array)
{
- size_t size_left = data_len - offset;
- hash_key key = table_hash_array[((offset - i_table_start) / info->chunk_stride)];
- size_t key_index = (size_t)(key % (hash_key)table_len);
- for (const BTableRef *tref = table[key_index]; tref; tref = tref->next) {
- const BChunkRef *cref = tref->cref;
-#ifdef USE_HASH_TABLE_KEY_CACHE
- if (cref->link->key == key)
-#endif
- {
- BChunk *chunk_test = cref->link;
- if (chunk_test->data_len <= size_left) {
- if (bchunk_data_compare(chunk_test, data, data_len, offset)) {
- /* we could remove the chunk from the table, to avoid multiple hits */
- return cref;
- }
- }
- }
- }
- return NULL;
+ size_t size_left = data_len - offset;
+ hash_key key = table_hash_array[((offset - i_table_start) / info->chunk_stride)];
+ size_t key_index = (size_t)(key % (hash_key)table_len);
+ for (const BTableRef *tref = table[key_index]; tref; tref = tref->next) {
+ const BChunkRef *cref = tref->cref;
+# ifdef USE_HASH_TABLE_KEY_CACHE
+ if (cref->link->key == key)
+# endif
+ {
+ BChunk *chunk_test = cref->link;
+ if (chunk_test->data_len <= size_left) {
+ if (bchunk_data_compare(chunk_test, data, data_len, offset)) {
+ /* we could remove the chunk from the table, to avoid multiple hits */
+ return cref;
+ }
+ }
+ }
+ }
+ return NULL;
}
-#else /* USE_HASH_TABLE_ACCUMULATE */
+#else /* USE_HASH_TABLE_ACCUMULATE */
/* NON USE_HASH_TABLE_ACCUMULATE code (simply hash each chunk) */
static hash_key key_from_chunk_ref(const BArrayInfo *info, const BChunkRef *cref)
{
- const size_t data_hash_len = BCHUNK_HASH_LEN * info->chunk_stride;
- hash_key key;
- BChunk *chunk = cref->link;
-
-#ifdef USE_HASH_TABLE_KEY_CACHE
- key = chunk->key;
- if (key != HASH_TABLE_KEY_UNSET) {
- /* Using key cache!
- * avoids calculating every time */
- }
- else {
- /* cache the key */
- key = hash_data(chunk->data, data_hash_len);
- if (key == HASH_TABLE_KEY_UNSET) {
- key = HASH_TABLE_KEY_FALLBACK;
- }
- chunk->key = key;
- }
-#else
- key = hash_data(chunk->data, data_hash_len);
-#endif
+ const size_t data_hash_len = BCHUNK_HASH_LEN * info->chunk_stride;
+ hash_key key;
+ BChunk *chunk = cref->link;
+
+# ifdef USE_HASH_TABLE_KEY_CACHE
+ key = chunk->key;
+ if (key != HASH_TABLE_KEY_UNSET) {
+ /* Using key cache!
+ * avoids calculating every time */
+ }
+ else {
+ /* cache the key */
+ key = hash_data(chunk->data, data_hash_len);
+ if (key == HASH_TABLE_KEY_UNSET) {
+ key = HASH_TABLE_KEY_FALLBACK;
+ }
+ chunk->key = key;
+ }
+# else
+ key = hash_data(chunk->data, data_hash_len);
+# endif
- return key;
+ return key;
}
-static const BChunkRef *table_lookup(
- const BArrayInfo *info, BTableRef **table, const size_t table_len, const uint UNUSED(i_table_start),
- const uchar *data, const size_t data_len, const size_t offset, const hash_key *UNUSED(table_hash_array))
+static const BChunkRef *table_lookup(const BArrayInfo *info,
+ BTableRef **table,
+ const size_t table_len,
+ const uint UNUSED(i_table_start),
+ const uchar *data,
+ const size_t data_len,
+ const size_t offset,
+ const hash_key *UNUSED(table_hash_array))
{
- const size_t data_hash_len = BCHUNK_HASH_LEN * info->chunk_stride; /* TODO, cache */
-
- size_t size_left = data_len - offset;
- hash_key key = hash_data(&data[offset], MIN2(data_hash_len, size_left));
- size_t key_index = (size_t)(key % (hash_key)table_len);
- for (BTableRef *tref = table[key_index]; tref; tref = tref->next) {
- const BChunkRef *cref = tref->cref;
-#ifdef USE_HASH_TABLE_KEY_CACHE
- if (cref->link->key == key)
-#endif
- {
- BChunk *chunk_test = cref->link;
- if (chunk_test->data_len <= size_left) {
- if (bchunk_data_compare(chunk_test, data, data_len, offset)) {
- /* we could remove the chunk from the table, to avoid multiple hits */
- return cref;
- }
- }
- }
- }
- return NULL;
+ const size_t data_hash_len = BCHUNK_HASH_LEN * info->chunk_stride; /* TODO, cache */
+
+ size_t size_left = data_len - offset;
+ hash_key key = hash_data(&data[offset], MIN2(data_hash_len, size_left));
+ size_t key_index = (size_t)(key % (hash_key)table_len);
+ for (BTableRef *tref = table[key_index]; tref; tref = tref->next) {
+ const BChunkRef *cref = tref->cref;
+# ifdef USE_HASH_TABLE_KEY_CACHE
+ if (cref->link->key == key)
+# endif
+ {
+ BChunk *chunk_test = cref->link;
+ if (chunk_test->data_len <= size_left) {
+ if (bchunk_data_compare(chunk_test, data, data_len, offset)) {
+ /* we could remove the chunk from the table, to avoid multiple hits */
+ return cref;
+ }
+ }
+ }
+ }
+ return NULL;
}
-#endif /* USE_HASH_TABLE_ACCUMULATE */
+#endif /* USE_HASH_TABLE_ACCUMULATE */
/* End Table Lookup
* ---------------- */
@@ -1015,389 +1016,386 @@ static const BChunkRef *table_lookup(
* \param chunk_list_reference: Reuse this list or chunks within it, don't modify its content.
* \note Caller is responsible for adding the user.
*/
-static BChunkList *bchunk_list_from_data_merge(
- const BArrayInfo *info, BArrayMemory *bs_mem,
- const uchar *data, const size_t data_len_original,
- const BChunkList *chunk_list_reference)
+static BChunkList *bchunk_list_from_data_merge(const BArrayInfo *info,
+ BArrayMemory *bs_mem,
+ const uchar *data,
+ const size_t data_len_original,
+ const BChunkList *chunk_list_reference)
{
- ASSERT_CHUNKLIST_SIZE(chunk_list_reference, chunk_list_reference->total_size);
+ ASSERT_CHUNKLIST_SIZE(chunk_list_reference, chunk_list_reference->total_size);
- /* -----------------------------------------------------------------------
- * Fast-Path for exact match
- * Check for exact match, if so, return the current list.
- */
+ /* -----------------------------------------------------------------------
+ * Fast-Path for exact match
+ * Check for exact match, if so, return the current list.
+ */
- const BChunkRef *cref_match_first = NULL;
+ const BChunkRef *cref_match_first = NULL;
- uint chunk_list_reference_skip_len = 0;
- size_t chunk_list_reference_skip_bytes = 0;
- size_t i_prev = 0;
+ uint chunk_list_reference_skip_len = 0;
+ size_t chunk_list_reference_skip_bytes = 0;
+ size_t i_prev = 0;
#ifdef USE_FASTPATH_CHUNKS_FIRST
- {
- bool full_match = true;
-
- const BChunkRef *cref = chunk_list_reference->chunk_refs.first;
- while (i_prev < data_len_original) {
- if (cref != NULL && bchunk_data_compare(cref->link, data, data_len_original, i_prev)) {
- cref_match_first = cref;
- chunk_list_reference_skip_len += 1;
- chunk_list_reference_skip_bytes += cref->link->data_len;
- i_prev += cref->link->data_len;
- cref = cref->next;
- }
- else {
- full_match = false;
- break;
- }
- }
-
- if (full_match) {
- if (chunk_list_reference->total_size == data_len_original) {
- return (BChunkList *)chunk_list_reference;
- }
- }
- }
-
- /* End Fast-Path (first)
- * --------------------- */
-
-#endif /* USE_FASTPATH_CHUNKS_FIRST */
-
- /* Copy until we have a mismatch */
- BChunkList *chunk_list = bchunk_list_new(bs_mem, data_len_original);
- if (cref_match_first != NULL) {
- size_t chunk_size_step = 0;
- const BChunkRef *cref = chunk_list_reference->chunk_refs.first;
- while (true) {
- BChunk *chunk = cref->link;
- chunk_size_step += chunk->data_len;
- bchunk_list_append_only(bs_mem, chunk_list, chunk);
- ASSERT_CHUNKLIST_SIZE(chunk_list, chunk_size_step);
- ASSERT_CHUNKLIST_DATA(chunk_list, data);
- if (cref == cref_match_first) {
- break;
- }
- else {
- cref = cref->next;
- }
- }
- /* happens when bytes are removed from the end of the array */
- if (chunk_size_step == data_len_original) {
- return chunk_list;
- }
-
- i_prev = chunk_size_step;
- }
- else {
- i_prev = 0;
- }
-
- /* ------------------------------------------------------------------------
- * Fast-Path for end chunks
- *
- * Check for trailing chunks
- */
-
- /* In this case use 'chunk_list_reference_last' to define the last index
- * index_match_last = -1 */
-
- /* warning, from now on don't use len(data)
- * since we want to ignore chunks already matched */
- size_t data_len = data_len_original;
+ {
+ bool full_match = true;
+
+ const BChunkRef *cref = chunk_list_reference->chunk_refs.first;
+ while (i_prev < data_len_original) {
+ if (cref != NULL && bchunk_data_compare(cref->link, data, data_len_original, i_prev)) {
+ cref_match_first = cref;
+ chunk_list_reference_skip_len += 1;
+ chunk_list_reference_skip_bytes += cref->link->data_len;
+ i_prev += cref->link->data_len;
+ cref = cref->next;
+ }
+ else {
+ full_match = false;
+ break;
+ }
+ }
+
+ if (full_match) {
+ if (chunk_list_reference->total_size == data_len_original) {
+ return (BChunkList *)chunk_list_reference;
+ }
+ }
+ }
+
+ /* End Fast-Path (first)
+ * --------------------- */
+
+#endif /* USE_FASTPATH_CHUNKS_FIRST */
+
+ /* Copy until we have a mismatch */
+ BChunkList *chunk_list = bchunk_list_new(bs_mem, data_len_original);
+ if (cref_match_first != NULL) {
+ size_t chunk_size_step = 0;
+ const BChunkRef *cref = chunk_list_reference->chunk_refs.first;
+ while (true) {
+ BChunk *chunk = cref->link;
+ chunk_size_step += chunk->data_len;
+ bchunk_list_append_only(bs_mem, chunk_list, chunk);
+ ASSERT_CHUNKLIST_SIZE(chunk_list, chunk_size_step);
+ ASSERT_CHUNKLIST_DATA(chunk_list, data);
+ if (cref == cref_match_first) {
+ break;
+ }
+ else {
+ cref = cref->next;
+ }
+ }
+ /* happens when bytes are removed from the end of the array */
+ if (chunk_size_step == data_len_original) {
+ return chunk_list;
+ }
+
+ i_prev = chunk_size_step;
+ }
+ else {
+ i_prev = 0;
+ }
+
+ /* ------------------------------------------------------------------------
+ * Fast-Path for end chunks
+ *
+ * Check for trailing chunks
+ */
+
+ /* In this case use 'chunk_list_reference_last' to define the last index
+ * index_match_last = -1 */
+
+ /* warning, from now on don't use len(data)
+ * since we want to ignore chunks already matched */
+ size_t data_len = data_len_original;
#define data_len_original invalid_usage
-#ifdef data_len_original /* quiet warning */
+#ifdef data_len_original /* quiet warning */
#endif
- const BChunkRef *chunk_list_reference_last = NULL;
+ const BChunkRef *chunk_list_reference_last = NULL;
#ifdef USE_FASTPATH_CHUNKS_LAST
- if (!BLI_listbase_is_empty(&chunk_list_reference->chunk_refs)) {
- const BChunkRef *cref = chunk_list_reference->chunk_refs.last;
- while ((cref->prev != NULL) &&
- (cref != cref_match_first) &&
- (cref->link->data_len <= data_len - i_prev))
- {
- BChunk *chunk_test = cref->link;
- size_t offset = data_len - chunk_test->data_len;
- if (bchunk_data_compare(chunk_test, data, data_len, offset)) {
- data_len = offset;
- chunk_list_reference_last = cref;
- chunk_list_reference_skip_len += 1;
- chunk_list_reference_skip_bytes += cref->link->data_len;
- cref = cref->prev;
- }
- else {
- break;
- }
- }
- }
-
- /* End Fast-Path (last)
- * -------------------- */
-#endif /* USE_FASTPATH_CHUNKS_LAST */
-
- /* -----------------------------------------------------------------------
- * Check for aligned chunks
- *
- * This saves a lot of searching, so use simple heuristics to detect aligned arrays.
- * (may need to tweak exact method).
- */
-
- bool use_aligned = false;
+ if (!BLI_listbase_is_empty(&chunk_list_reference->chunk_refs)) {
+ const BChunkRef *cref = chunk_list_reference->chunk_refs.last;
+ while ((cref->prev != NULL) && (cref != cref_match_first) &&
+ (cref->link->data_len <= data_len - i_prev)) {
+ BChunk *chunk_test = cref->link;
+ size_t offset = data_len - chunk_test->data_len;
+ if (bchunk_data_compare(chunk_test, data, data_len, offset)) {
+ data_len = offset;
+ chunk_list_reference_last = cref;
+ chunk_list_reference_skip_len += 1;
+ chunk_list_reference_skip_bytes += cref->link->data_len;
+ cref = cref->prev;
+ }
+ else {
+ break;
+ }
+ }
+ }
+
+ /* End Fast-Path (last)
+ * -------------------- */
+#endif /* USE_FASTPATH_CHUNKS_LAST */
+
+ /* -----------------------------------------------------------------------
+ * Check for aligned chunks
+ *
+ * This saves a lot of searching, so use simple heuristics to detect aligned arrays.
+ * (may need to tweak exact method).
+ */
+
+ bool use_aligned = false;
#ifdef USE_ALIGN_CHUNKS_TEST
- if (chunk_list->total_size == chunk_list_reference->total_size) {
- /* if we're already a quarter aligned */
- if (data_len - i_prev <= chunk_list->total_size / 4) {
- use_aligned = true;
- }
- else {
- /* TODO, walk over chunks and check if some arbitrary amount align */
- }
- }
-#endif /* USE_ALIGN_CHUNKS_TEST */
-
- /* End Aligned Chunk Case
- * ----------------------- */
-
- if (use_aligned) {
- /* Copy matching chunks, creates using the same 'layout' as the reference */
- const BChunkRef *cref = cref_match_first ? cref_match_first->next : chunk_list_reference->chunk_refs.first;
- while (i_prev != data_len) {
- const size_t i = i_prev + cref->link->data_len;
- BLI_assert(i != i_prev);
-
- if ((cref != chunk_list_reference_last) &&
- bchunk_data_compare(cref->link, data, data_len, i_prev))
- {
- bchunk_list_append(info, bs_mem, chunk_list, cref->link);
- ASSERT_CHUNKLIST_SIZE(chunk_list, i);
- ASSERT_CHUNKLIST_DATA(chunk_list, data);
- }
- else {
- bchunk_list_append_data(info, bs_mem, chunk_list, &data[i_prev], i - i_prev);
- ASSERT_CHUNKLIST_SIZE(chunk_list, i);
- ASSERT_CHUNKLIST_DATA(chunk_list, data);
- }
-
- cref = cref->next;
-
- i_prev = i;
- }
- }
- else if ((data_len - i_prev >= info->chunk_byte_size) &&
- (chunk_list_reference->chunk_refs_len >= chunk_list_reference_skip_len) &&
- (chunk_list_reference->chunk_refs.first != NULL))
- {
-
- /* --------------------------------------------------------------------
- * Non-Aligned Chunk De-Duplication */
-
- /* only create a table if we have at least one chunk to search
- * otherwise just make a new one.
- *
- * Support re-arranged chunks */
+ if (chunk_list->total_size == chunk_list_reference->total_size) {
+ /* if we're already a quarter aligned */
+ if (data_len - i_prev <= chunk_list->total_size / 4) {
+ use_aligned = true;
+ }
+ else {
+ /* TODO, walk over chunks and check if some arbitrary amount align */
+ }
+ }
+#endif /* USE_ALIGN_CHUNKS_TEST */
+
+ /* End Aligned Chunk Case
+ * ----------------------- */
+
+ if (use_aligned) {
+ /* Copy matching chunks, creates using the same 'layout' as the reference */
+ const BChunkRef *cref = cref_match_first ? cref_match_first->next :
+ chunk_list_reference->chunk_refs.first;
+ while (i_prev != data_len) {
+ const size_t i = i_prev + cref->link->data_len;
+ BLI_assert(i != i_prev);
+
+ if ((cref != chunk_list_reference_last) &&
+ bchunk_data_compare(cref->link, data, data_len, i_prev)) {
+ bchunk_list_append(info, bs_mem, chunk_list, cref->link);
+ ASSERT_CHUNKLIST_SIZE(chunk_list, i);
+ ASSERT_CHUNKLIST_DATA(chunk_list, data);
+ }
+ else {
+ bchunk_list_append_data(info, bs_mem, chunk_list, &data[i_prev], i - i_prev);
+ ASSERT_CHUNKLIST_SIZE(chunk_list, i);
+ ASSERT_CHUNKLIST_DATA(chunk_list, data);
+ }
+
+ cref = cref->next;
+
+ i_prev = i;
+ }
+ }
+ else if ((data_len - i_prev >= info->chunk_byte_size) &&
+ (chunk_list_reference->chunk_refs_len >= chunk_list_reference_skip_len) &&
+ (chunk_list_reference->chunk_refs.first != NULL)) {
+
+ /* --------------------------------------------------------------------
+ * Non-Aligned Chunk De-Duplication */
+
+ /* only create a table if we have at least one chunk to search
+ * otherwise just make a new one.
+ *
+ * Support re-arranged chunks */
#ifdef USE_HASH_TABLE_ACCUMULATE
- size_t i_table_start = i_prev;
- const size_t table_hash_array_len = (data_len - i_prev) / info->chunk_stride;
- hash_key *table_hash_array = MEM_mallocN(sizeof(*table_hash_array) * table_hash_array_len, __func__);
- hash_array_from_data(info, &data[i_prev], data_len - i_prev, table_hash_array);
+ size_t i_table_start = i_prev;
+ const size_t table_hash_array_len = (data_len - i_prev) / info->chunk_stride;
+ hash_key *table_hash_array = MEM_mallocN(sizeof(*table_hash_array) * table_hash_array_len,
+ __func__);
+ hash_array_from_data(info, &data[i_prev], data_len - i_prev, table_hash_array);
- hash_accum(table_hash_array, table_hash_array_len, info->accum_steps);
+ hash_accum(table_hash_array, table_hash_array_len, info->accum_steps);
#else
- /* dummy vars */
- uint i_table_start = 0;
- hash_key *table_hash_array = NULL;
+ /* dummy vars */
+ uint i_table_start = 0;
+ hash_key *table_hash_array = NULL;
#endif
- const uint chunk_list_reference_remaining_len =
- (chunk_list_reference->chunk_refs_len - chunk_list_reference_skip_len) + 1;
- BTableRef *table_ref_stack = MEM_mallocN(chunk_list_reference_remaining_len * sizeof(BTableRef), __func__);
- uint table_ref_stack_n = 0;
+ const uint chunk_list_reference_remaining_len = (chunk_list_reference->chunk_refs_len -
+ chunk_list_reference_skip_len) +
+ 1;
+ BTableRef *table_ref_stack = MEM_mallocN(
+ chunk_list_reference_remaining_len * sizeof(BTableRef), __func__);
+ uint table_ref_stack_n = 0;
- const size_t table_len = chunk_list_reference_remaining_len * BCHUNK_HASH_TABLE_MUL;
- BTableRef **table = MEM_callocN(table_len * sizeof(*table), __func__);
+ const size_t table_len = chunk_list_reference_remaining_len * BCHUNK_HASH_TABLE_MUL;
+ BTableRef **table = MEM_callocN(table_len * sizeof(*table), __func__);
- /* table_make - inline
- * include one matching chunk, to allow for repeating values */
- {
+ /* table_make - inline
+ * include one matching chunk, to allow for repeating values */
+ {
#ifdef USE_HASH_TABLE_ACCUMULATE
- const size_t hash_store_len = info->accum_read_ahead_len;
- hash_key *hash_store = MEM_mallocN(sizeof(hash_key) * hash_store_len, __func__);
+ const size_t hash_store_len = info->accum_read_ahead_len;
+ hash_key *hash_store = MEM_mallocN(sizeof(hash_key) * hash_store_len, __func__);
#endif
- const BChunkRef *cref;
- size_t chunk_list_reference_bytes_remaining =
- chunk_list_reference->total_size - chunk_list_reference_skip_bytes;
+ const BChunkRef *cref;
+ size_t chunk_list_reference_bytes_remaining = chunk_list_reference->total_size -
+ chunk_list_reference_skip_bytes;
- if (cref_match_first) {
- cref = cref_match_first;
- chunk_list_reference_bytes_remaining += cref->link->data_len;
- }
- else {
- cref = chunk_list_reference->chunk_refs.first;
- }
+ if (cref_match_first) {
+ cref = cref_match_first;
+ chunk_list_reference_bytes_remaining += cref->link->data_len;
+ }
+ else {
+ cref = chunk_list_reference->chunk_refs.first;
+ }
#ifdef USE_PARANOID_CHECKS
- {
- size_t test_bytes_len = 0;
- const BChunkRef *cr = cref;
- while (cr != chunk_list_reference_last) {
- test_bytes_len += cr->link->data_len;
- cr = cr->next;
- }
- BLI_assert(test_bytes_len == chunk_list_reference_bytes_remaining);
- }
+ {
+ size_t test_bytes_len = 0;
+ const BChunkRef *cr = cref;
+ while (cr != chunk_list_reference_last) {
+ test_bytes_len += cr->link->data_len;
+ cr = cr->next;
+ }
+ BLI_assert(test_bytes_len == chunk_list_reference_bytes_remaining);
+ }
#endif
- while ((cref != chunk_list_reference_last) &&
- (chunk_list_reference_bytes_remaining >= info->accum_read_ahead_bytes))
- {
- hash_key key = key_from_chunk_ref(info, cref
+ while ((cref != chunk_list_reference_last) &&
+ (chunk_list_reference_bytes_remaining >= info->accum_read_ahead_bytes)) {
+ hash_key key = key_from_chunk_ref(info,
+ cref
#ifdef USE_HASH_TABLE_ACCUMULATE
- , hash_store, hash_store_len
+ ,
+ hash_store,
+ hash_store_len
#endif
- );
- size_t key_index = (size_t)(key % (hash_key)table_len);
- BTableRef *tref_prev = table[key_index];
- BLI_assert(table_ref_stack_n < chunk_list_reference_remaining_len);
- BTableRef *tref = &table_ref_stack[table_ref_stack_n++];
- tref->cref = cref;
- tref->next = tref_prev;
- table[key_index] = tref;
+ );
+ size_t key_index = (size_t)(key % (hash_key)table_len);
+ BTableRef *tref_prev = table[key_index];
+ BLI_assert(table_ref_stack_n < chunk_list_reference_remaining_len);
+ BTableRef *tref = &table_ref_stack[table_ref_stack_n++];
+ tref->cref = cref;
+ tref->next = tref_prev;
+ table[key_index] = tref;
- chunk_list_reference_bytes_remaining -= cref->link->data_len;
- cref = cref->next;
- }
+ chunk_list_reference_bytes_remaining -= cref->link->data_len;
+ cref = cref->next;
+ }
- BLI_assert(table_ref_stack_n <= chunk_list_reference_remaining_len);
+ BLI_assert(table_ref_stack_n <= chunk_list_reference_remaining_len);
#ifdef USE_HASH_TABLE_ACCUMULATE
- MEM_freeN(hash_store);
+ MEM_freeN(hash_store);
#endif
- }
- /* done making the table */
-
- BLI_assert(i_prev <= data_len);
- for (size_t i = i_prev; i < data_len; ) {
- /* Assumes exiting chunk isnt a match! */
-
- const BChunkRef *cref_found = table_lookup(
- info,
- table, table_len, i_table_start,
- data, data_len, i, table_hash_array);
- if (cref_found != NULL) {
- BLI_assert(i < data_len);
- if (i != i_prev) {
- bchunk_list_append_data_n(info, bs_mem, chunk_list, &data[i_prev], i - i_prev);
- i_prev = i;
- }
-
- /* now add the reference chunk */
- {
- BChunk *chunk_found = cref_found->link;
- i += chunk_found->data_len;
- bchunk_list_append(info, bs_mem, chunk_list, chunk_found);
- }
- i_prev = i;
- BLI_assert(i_prev <= data_len);
- ASSERT_CHUNKLIST_SIZE(chunk_list, i_prev);
- ASSERT_CHUNKLIST_DATA(chunk_list, data);
-
- /* its likely that the next chunk in the list will be a match, so check it! */
- while ((cref_found->next != NULL) &&
- (cref_found->next != chunk_list_reference_last))
- {
- cref_found = cref_found->next;
- BChunk *chunk_found = cref_found->link;
-
- if (bchunk_data_compare(chunk_found, data, data_len, i_prev)) {
- /* may be useful to remove table data, assuming we dont have
- * repeating memory where it would be useful to re-use chunks. */
- i += chunk_found->data_len;
- bchunk_list_append(info, bs_mem, chunk_list, chunk_found);
- /* chunk_found may be freed! */
- i_prev = i;
- BLI_assert(i_prev <= data_len);
- ASSERT_CHUNKLIST_SIZE(chunk_list, i_prev);
- ASSERT_CHUNKLIST_DATA(chunk_list, data);
- }
- else {
- break;
- }
- }
- }
- else {
- i = i + info->chunk_stride;
- }
- }
+ }
+ /* done making the table */
+
+ BLI_assert(i_prev <= data_len);
+ for (size_t i = i_prev; i < data_len;) {
+ /* Assumes exiting chunk isnt a match! */
+
+ const BChunkRef *cref_found = table_lookup(
+ info, table, table_len, i_table_start, data, data_len, i, table_hash_array);
+ if (cref_found != NULL) {
+ BLI_assert(i < data_len);
+ if (i != i_prev) {
+ bchunk_list_append_data_n(info, bs_mem, chunk_list, &data[i_prev], i - i_prev);
+ i_prev = i;
+ }
+
+ /* now add the reference chunk */
+ {
+ BChunk *chunk_found = cref_found->link;
+ i += chunk_found->data_len;
+ bchunk_list_append(info, bs_mem, chunk_list, chunk_found);
+ }
+ i_prev = i;
+ BLI_assert(i_prev <= data_len);
+ ASSERT_CHUNKLIST_SIZE(chunk_list, i_prev);
+ ASSERT_CHUNKLIST_DATA(chunk_list, data);
+
+ /* its likely that the next chunk in the list will be a match, so check it! */
+ while ((cref_found->next != NULL) && (cref_found->next != chunk_list_reference_last)) {
+ cref_found = cref_found->next;
+ BChunk *chunk_found = cref_found->link;
+
+ if (bchunk_data_compare(chunk_found, data, data_len, i_prev)) {
+ /* may be useful to remove table data, assuming we dont have
+ * repeating memory where it would be useful to re-use chunks. */
+ i += chunk_found->data_len;
+ bchunk_list_append(info, bs_mem, chunk_list, chunk_found);
+ /* chunk_found may be freed! */
+ i_prev = i;
+ BLI_assert(i_prev <= data_len);
+ ASSERT_CHUNKLIST_SIZE(chunk_list, i_prev);
+ ASSERT_CHUNKLIST_DATA(chunk_list, data);
+ }
+ else {
+ break;
+ }
+ }
+ }
+ else {
+ i = i + info->chunk_stride;
+ }
+ }
#ifdef USE_HASH_TABLE_ACCUMULATE
- MEM_freeN(table_hash_array);
+ MEM_freeN(table_hash_array);
#endif
- MEM_freeN(table);
- MEM_freeN(table_ref_stack);
+ MEM_freeN(table);
+ MEM_freeN(table_ref_stack);
- /* End Table Lookup
- * ---------------- */
- }
+ /* End Table Lookup
+ * ---------------- */
+ }
- ASSERT_CHUNKLIST_SIZE(chunk_list, i_prev);
- ASSERT_CHUNKLIST_DATA(chunk_list, data);
+ ASSERT_CHUNKLIST_SIZE(chunk_list, i_prev);
+ ASSERT_CHUNKLIST_DATA(chunk_list, data);
- /* -----------------------------------------------------------------------
- * No Duplicates to copy, write new chunks
- *
- * Trailing chunks, no matches found in table lookup above.
- * Write all new data. */
- if (i_prev != data_len) {
- bchunk_list_append_data_n(info, bs_mem, chunk_list, &data[i_prev], data_len - i_prev);
- i_prev = data_len;
- }
+ /* -----------------------------------------------------------------------
+ * No Duplicates to copy, write new chunks
+ *
+ * Trailing chunks, no matches found in table lookup above.
+ * Write all new data. */
+ if (i_prev != data_len) {
+ bchunk_list_append_data_n(info, bs_mem, chunk_list, &data[i_prev], data_len - i_prev);
+ i_prev = data_len;
+ }
- BLI_assert(i_prev == data_len);
+ BLI_assert(i_prev == data_len);
#ifdef USE_FASTPATH_CHUNKS_LAST
- if (chunk_list_reference_last != NULL) {
- /* write chunk_list_reference_last since it hasn't been written yet */
- const BChunkRef *cref = chunk_list_reference_last;
- while (cref != NULL) {
- BChunk *chunk = cref->link;
- // BLI_assert(bchunk_data_compare(chunk, data, data_len, i_prev));
- i_prev += chunk->data_len;
- /* use simple since we assume the references chunks
- * have already been sized correctly. */
- bchunk_list_append_only(bs_mem, chunk_list, chunk);
- ASSERT_CHUNKLIST_DATA(chunk_list, data);
- cref = cref->next;
- }
- }
+ if (chunk_list_reference_last != NULL) {
+ /* write chunk_list_reference_last since it hasn't been written yet */
+ const BChunkRef *cref = chunk_list_reference_last;
+ while (cref != NULL) {
+ BChunk *chunk = cref->link;
+ // BLI_assert(bchunk_data_compare(chunk, data, data_len, i_prev));
+ i_prev += chunk->data_len;
+ /* use simple since we assume the references chunks
+ * have already been sized correctly. */
+ bchunk_list_append_only(bs_mem, chunk_list, chunk);
+ ASSERT_CHUNKLIST_DATA(chunk_list, data);
+ cref = cref->next;
+ }
+ }
#endif
#undef data_len_original
- BLI_assert(i_prev == data_len_original);
+ BLI_assert(i_prev == data_len_original);
- /* check we're the correct size and that we didn't accidentally modify the reference */
- ASSERT_CHUNKLIST_SIZE(chunk_list, data_len_original);
- ASSERT_CHUNKLIST_SIZE(chunk_list_reference, chunk_list_reference->total_size);
+ /* check we're the correct size and that we didn't accidentally modify the reference */
+ ASSERT_CHUNKLIST_SIZE(chunk_list, data_len_original);
+ ASSERT_CHUNKLIST_SIZE(chunk_list_reference, chunk_list_reference->total_size);
- ASSERT_CHUNKLIST_DATA(chunk_list, data);
+ ASSERT_CHUNKLIST_DATA(chunk_list, data);
- return chunk_list;
+ return chunk_list;
}
/* end private API */
/** \} */
-
/** \name Main Array Storage API
* \{ */
-
/**
* Create a new array store, which can store any number of arrays
* as long as their stride matches.
@@ -1417,88 +1415,85 @@ static BChunkList *bchunk_list_from_data_merge(
*
* \return A new array store, to be freed with #BLI_array_store_destroy.
*/
-BArrayStore *BLI_array_store_create(
- uint stride,
- uint chunk_count)
+BArrayStore *BLI_array_store_create(uint stride, uint chunk_count)
{
- BArrayStore *bs = MEM_callocN(sizeof(BArrayStore), __func__);
+ BArrayStore *bs = MEM_callocN(sizeof(BArrayStore), __func__);
- bs->info.chunk_stride = stride;
- // bs->info.chunk_count = chunk_count;
+ bs->info.chunk_stride = stride;
+ // bs->info.chunk_count = chunk_count;
- bs->info.chunk_byte_size = chunk_count * stride;
+ bs->info.chunk_byte_size = chunk_count * stride;
#ifdef USE_MERGE_CHUNKS
- bs->info.chunk_byte_size_min = MAX2(1u, chunk_count / BCHUNK_SIZE_MIN_DIV) * stride;
- bs->info.chunk_byte_size_max = (chunk_count * BCHUNK_SIZE_MAX_MUL) * stride;
+ bs->info.chunk_byte_size_min = MAX2(1u, chunk_count / BCHUNK_SIZE_MIN_DIV) * stride;
+ bs->info.chunk_byte_size_max = (chunk_count * BCHUNK_SIZE_MAX_MUL) * stride;
#endif
#ifdef USE_HASH_TABLE_ACCUMULATE
- bs->info.accum_steps = BCHUNK_HASH_TABLE_ACCUMULATE_STEPS - 1;
- /* Triangle number, identifying now much read-ahead we need:
- * https://en.wikipedia.org/wiki/Triangular_number (+ 1) */
- bs->info.accum_read_ahead_len = (uint)((((bs->info.accum_steps * (bs->info.accum_steps + 1))) / 2) + 1);
- bs->info.accum_read_ahead_bytes = bs->info.accum_read_ahead_len * stride;
+ bs->info.accum_steps = BCHUNK_HASH_TABLE_ACCUMULATE_STEPS - 1;
+ /* Triangle number, identifying now much read-ahead we need:
+ * https://en.wikipedia.org/wiki/Triangular_number (+ 1) */
+ bs->info.accum_read_ahead_len = (uint)(
+ (((bs->info.accum_steps * (bs->info.accum_steps + 1))) / 2) + 1);
+ bs->info.accum_read_ahead_bytes = bs->info.accum_read_ahead_len * stride;
#else
- bs->info.accum_read_ahead_bytes = BCHUNK_HASH_LEN * stride;
+ bs->info.accum_read_ahead_bytes = BCHUNK_HASH_LEN * stride;
#endif
- bs->memory.chunk_list = BLI_mempool_create(sizeof(BChunkList), 0, 512, BLI_MEMPOOL_NOP);
- bs->memory.chunk_ref = BLI_mempool_create(sizeof(BChunkRef), 0, 512, BLI_MEMPOOL_NOP);
- /* allow iteration to simplify freeing, otherwise its not needed
- * (we could loop over all states as an alternative). */
- bs->memory.chunk = BLI_mempool_create(sizeof(BChunk), 0, 512, BLI_MEMPOOL_ALLOW_ITER);
+ bs->memory.chunk_list = BLI_mempool_create(sizeof(BChunkList), 0, 512, BLI_MEMPOOL_NOP);
+ bs->memory.chunk_ref = BLI_mempool_create(sizeof(BChunkRef), 0, 512, BLI_MEMPOOL_NOP);
+ /* allow iteration to simplify freeing, otherwise its not needed
+ * (we could loop over all states as an alternative). */
+ bs->memory.chunk = BLI_mempool_create(sizeof(BChunk), 0, 512, BLI_MEMPOOL_ALLOW_ITER);
- return bs;
+ return bs;
}
static void array_store_free_data(BArrayStore *bs)
{
- /* free chunk data */
- {
- BLI_mempool_iter iter;
- BChunk *chunk;
- BLI_mempool_iternew(bs->memory.chunk, &iter);
- while ((chunk = BLI_mempool_iterstep(&iter))) {
- BLI_assert(chunk->users > 0);
- MEM_freeN((void *)chunk->data);
- }
- }
-
- /* free states */
- for (BArrayState *state = bs->states.first, *state_next; state; state = state_next) {
- state_next = state->next;
- MEM_freeN(state);
- }
+ /* free chunk data */
+ {
+ BLI_mempool_iter iter;
+ BChunk *chunk;
+ BLI_mempool_iternew(bs->memory.chunk, &iter);
+ while ((chunk = BLI_mempool_iterstep(&iter))) {
+ BLI_assert(chunk->users > 0);
+ MEM_freeN((void *)chunk->data);
+ }
+ }
+
+ /* free states */
+ for (BArrayState *state = bs->states.first, *state_next; state; state = state_next) {
+ state_next = state->next;
+ MEM_freeN(state);
+ }
}
/**
* Free the #BArrayStore, including all states and chunks.
*/
-void BLI_array_store_destroy(
- BArrayStore *bs)
+void BLI_array_store_destroy(BArrayStore *bs)
{
- array_store_free_data(bs);
+ array_store_free_data(bs);
- BLI_mempool_destroy(bs->memory.chunk_list);
- BLI_mempool_destroy(bs->memory.chunk_ref);
- BLI_mempool_destroy(bs->memory.chunk);
+ BLI_mempool_destroy(bs->memory.chunk_list);
+ BLI_mempool_destroy(bs->memory.chunk_ref);
+ BLI_mempool_destroy(bs->memory.chunk);
- MEM_freeN(bs);
+ MEM_freeN(bs);
}
/**
* Clear all contents, allowing reuse of \a bs.
*/
-void BLI_array_store_clear(
- BArrayStore *bs)
+void BLI_array_store_clear(BArrayStore *bs)
{
- array_store_free_data(bs);
+ array_store_free_data(bs);
- BLI_listbase_clear(&bs->states);
+ BLI_listbase_clear(&bs->states);
- BLI_mempool_clear(bs->memory.chunk_list);
- BLI_mempool_clear(bs->memory.chunk_ref);
- BLI_mempool_clear(bs->memory.chunk);
+ BLI_mempool_clear(bs->memory.chunk_list);
+ BLI_mempool_clear(bs->memory.chunk_ref);
+ BLI_mempool_clear(bs->memory.chunk);
}
/** \} */
@@ -1509,37 +1504,34 @@ void BLI_array_store_clear(
/**
* \return the total amount of memory that would be used by getting the arrays for all states.
*/
-size_t BLI_array_store_calc_size_expanded_get(
- const BArrayStore *bs)
+size_t BLI_array_store_calc_size_expanded_get(const BArrayStore *bs)
{
- size_t size_accum = 0;
- for (const BArrayState *state = bs->states.first; state; state = state->next) {
- size_accum += state->chunk_list->total_size;
- }
- return size_accum;
+ size_t size_accum = 0;
+ for (const BArrayState *state = bs->states.first; state; state = state->next) {
+ size_accum += state->chunk_list->total_size;
+ }
+ return size_accum;
}
/**
* \return the amount of memory used by all #BChunk.data
* (duplicate chunks are only counted once).
*/
-size_t BLI_array_store_calc_size_compacted_get(
- const BArrayStore *bs)
+size_t BLI_array_store_calc_size_compacted_get(const BArrayStore *bs)
{
- size_t size_total = 0;
- BLI_mempool_iter iter;
- BChunk *chunk;
- BLI_mempool_iternew(bs->memory.chunk, &iter);
- while ((chunk = BLI_mempool_iterstep(&iter))) {
- BLI_assert(chunk->users > 0);
- size_total += (size_t)chunk->data_len;
- }
- return size_total;
+ size_t size_total = 0;
+ BLI_mempool_iter iter;
+ BChunk *chunk;
+ BLI_mempool_iternew(bs->memory.chunk, &iter);
+ while ((chunk = BLI_mempool_iterstep(&iter))) {
+ BLI_assert(chunk->users > 0);
+ size_total += (size_t)chunk->data_len;
+ }
+ return size_total;
}
/** \} */
-
/** \name BArrayState Access
* \{ */
@@ -1554,54 +1546,52 @@ size_t BLI_array_store_calc_size_compacted_get(
* This may be removed using #BLI_array_store_state_remove,
* otherwise it will be removed with #BLI_array_store_destroy.
*/
-BArrayState *BLI_array_store_state_add(
- BArrayStore *bs,
- const void *data, const size_t data_len,
- const BArrayState *state_reference)
+BArrayState *BLI_array_store_state_add(BArrayStore *bs,
+ const void *data,
+ const size_t data_len,
+ const BArrayState *state_reference)
{
- /* ensure we're aligned to the stride */
- BLI_assert((data_len % bs->info.chunk_stride) == 0);
+ /* ensure we're aligned to the stride */
+ BLI_assert((data_len % bs->info.chunk_stride) == 0);
#ifdef USE_PARANOID_CHECKS
- if (state_reference) {
- BLI_assert(BLI_findindex(&bs->states, state_reference) != -1);
- }
+ if (state_reference) {
+ BLI_assert(BLI_findindex(&bs->states, state_reference) != -1);
+ }
#endif
- BChunkList *chunk_list;
- if (state_reference) {
- chunk_list = bchunk_list_from_data_merge(
- &bs->info, &bs->memory,
- (const uchar *)data, data_len,
- /* re-use reference chunks */
- state_reference->chunk_list);
- }
- else {
- chunk_list = bchunk_list_new(&bs->memory, data_len);
- bchunk_list_fill_from_array(
- &bs->info, &bs->memory,
- chunk_list,
- (const uchar *)data, data_len);
- }
-
- chunk_list->users += 1;
-
- BArrayState *state = MEM_callocN(sizeof(BArrayState), __func__);
- state->chunk_list = chunk_list;
-
- BLI_addtail(&bs->states, state);
+ BChunkList *chunk_list;
+ if (state_reference) {
+ chunk_list = bchunk_list_from_data_merge(&bs->info,
+ &bs->memory,
+ (const uchar *)data,
+ data_len,
+ /* re-use reference chunks */
+ state_reference->chunk_list);
+ }
+ else {
+ chunk_list = bchunk_list_new(&bs->memory, data_len);
+ bchunk_list_fill_from_array(&bs->info, &bs->memory, chunk_list, (const uchar *)data, data_len);
+ }
+
+ chunk_list->users += 1;
+
+ BArrayState *state = MEM_callocN(sizeof(BArrayState), __func__);
+ state->chunk_list = chunk_list;
+
+ BLI_addtail(&bs->states, state);
#ifdef USE_PARANOID_CHECKS
- {
- size_t data_test_len;
- void *data_test = BLI_array_store_state_data_get_alloc(state, &data_test_len);
- BLI_assert(data_test_len == data_len);
- BLI_assert(memcmp(data_test, data, data_len) == 0);
- MEM_freeN(data_test);
- }
+ {
+ size_t data_test_len;
+ void *data_test = BLI_array_store_state_data_get_alloc(state, &data_test_len);
+ BLI_assert(data_test_len == data_len);
+ BLI_assert(memcmp(data_test, data, data_len) == 0);
+ MEM_freeN(data_test);
+ }
#endif
- return state;
+ return state;
}
/**
@@ -1609,196 +1599,187 @@ BArrayState *BLI_array_store_state_add(
*
* The states can be freed in any order.
*/
-void BLI_array_store_state_remove(
- BArrayStore *bs,
- BArrayState *state)
+void BLI_array_store_state_remove(BArrayStore *bs, BArrayState *state)
{
#ifdef USE_PARANOID_CHECKS
- BLI_assert(BLI_findindex(&bs->states, state) != -1);
+ BLI_assert(BLI_findindex(&bs->states, state) != -1);
#endif
- bchunk_list_decref(&bs->memory, state->chunk_list);
- BLI_remlink(&bs->states, state);
+ bchunk_list_decref(&bs->memory, state->chunk_list);
+ BLI_remlink(&bs->states, state);
- MEM_freeN(state);
+ MEM_freeN(state);
}
/**
* \return the expanded size of the array,
* use this to know how much memory to allocate #BLI_array_store_state_data_get's argument.
*/
-size_t BLI_array_store_state_size_get(
- BArrayState *state)
+size_t BLI_array_store_state_size_get(BArrayState *state)
{
- return state->chunk_list->total_size;
+ return state->chunk_list->total_size;
}
/**
* Fill in existing allocated memory with the contents of \a state.
*/
-void BLI_array_store_state_data_get(
- BArrayState *state,
- void *data)
+void BLI_array_store_state_data_get(BArrayState *state, void *data)
{
#ifdef USE_PARANOID_CHECKS
- size_t data_test_len = 0;
- for (BChunkRef *cref = state->chunk_list->chunk_refs.first; cref; cref = cref->next) {
- data_test_len += cref->link->data_len;
- }
- BLI_assert(data_test_len == state->chunk_list->total_size);
+ size_t data_test_len = 0;
+ for (BChunkRef *cref = state->chunk_list->chunk_refs.first; cref; cref = cref->next) {
+ data_test_len += cref->link->data_len;
+ }
+ BLI_assert(data_test_len == state->chunk_list->total_size);
#endif
- uchar *data_step = (uchar *)data;
- for (BChunkRef *cref = state->chunk_list->chunk_refs.first; cref; cref = cref->next) {
- BLI_assert(cref->link->users > 0);
- memcpy(data_step, cref->link->data, cref->link->data_len);
- data_step += cref->link->data_len;
- }
+ uchar *data_step = (uchar *)data;
+ for (BChunkRef *cref = state->chunk_list->chunk_refs.first; cref; cref = cref->next) {
+ BLI_assert(cref->link->users > 0);
+ memcpy(data_step, cref->link->data, cref->link->data_len);
+ data_step += cref->link->data_len;
+ }
}
/**
* Allocate an array for \a state and return it.
*/
-void *BLI_array_store_state_data_get_alloc(
- BArrayState *state,
- size_t *r_data_len)
+void *BLI_array_store_state_data_get_alloc(BArrayState *state, size_t *r_data_len)
{
- void *data = MEM_mallocN(state->chunk_list->total_size, __func__);
- BLI_array_store_state_data_get(state, data);
- *r_data_len = state->chunk_list->total_size;
- return data;
+ void *data = MEM_mallocN(state->chunk_list->total_size, __func__);
+ BLI_array_store_state_data_get(state, data);
+ *r_data_len = state->chunk_list->total_size;
+ return data;
}
/** \} */
-
/** \name Debugging API (for testing).
* \{ */
/* only for test validation */
static size_t bchunk_list_size(const BChunkList *chunk_list)
{
- size_t total_size = 0;
- for (BChunkRef *cref = chunk_list->chunk_refs.first; cref; cref = cref->next) {
- total_size += cref->link->data_len;
- }
- return total_size;
+ size_t total_size = 0;
+ for (BChunkRef *cref = chunk_list->chunk_refs.first; cref; cref = cref->next) {
+ total_size += cref->link->data_len;
+ }
+ return total_size;
}
-bool BLI_array_store_is_valid(
- BArrayStore *bs)
+bool BLI_array_store_is_valid(BArrayStore *bs)
{
- bool ok = true;
+ bool ok = true;
- /* Check Length
- * ------------ */
+ /* Check Length
+ * ------------ */
- for (BArrayState *state = bs->states.first; state; state = state->next) {
- BChunkList *chunk_list = state->chunk_list;
- if (!(bchunk_list_size(chunk_list) == chunk_list->total_size)) {
- return false;
- }
+ for (BArrayState *state = bs->states.first; state; state = state->next) {
+ BChunkList *chunk_list = state->chunk_list;
+ if (!(bchunk_list_size(chunk_list) == chunk_list->total_size)) {
+ return false;
+ }
- if (BLI_listbase_count(&chunk_list->chunk_refs) != (int)chunk_list->chunk_refs_len) {
- return false;
- }
+ if (BLI_listbase_count(&chunk_list->chunk_refs) != (int)chunk_list->chunk_refs_len) {
+ return false;
+ }
#ifdef USE_MERGE_CHUNKS
- /* ensure we merge all chunks that could be merged */
- if (chunk_list->total_size > bs->info.chunk_byte_size_min) {
- for (BChunkRef *cref = chunk_list->chunk_refs.first; cref; cref = cref->next) {
- if (cref->link->data_len < bs->info.chunk_byte_size_min) {
- return false;
- }
- }
- }
+ /* ensure we merge all chunks that could be merged */
+ if (chunk_list->total_size > bs->info.chunk_byte_size_min) {
+ for (BChunkRef *cref = chunk_list->chunk_refs.first; cref; cref = cref->next) {
+ if (cref->link->data_len < bs->info.chunk_byte_size_min) {
+ return false;
+ }
+ }
+ }
#endif
- }
-
- {
- BLI_mempool_iter iter;
- BChunk *chunk;
- BLI_mempool_iternew(bs->memory.chunk, &iter);
- while ((chunk = BLI_mempool_iterstep(&iter))) {
- if (!(MEM_allocN_len(chunk->data) >= chunk->data_len)) {
- return false;
- }
- }
- }
-
- /* Check User Count & Lost References
- * ---------------------------------- */
- {
- GHashIterator gh_iter;
+ }
+
+ {
+ BLI_mempool_iter iter;
+ BChunk *chunk;
+ BLI_mempool_iternew(bs->memory.chunk, &iter);
+ while ((chunk = BLI_mempool_iterstep(&iter))) {
+ if (!(MEM_allocN_len(chunk->data) >= chunk->data_len)) {
+ return false;
+ }
+ }
+ }
+
+ /* Check User Count & Lost References
+ * ---------------------------------- */
+ {
+ GHashIterator gh_iter;
#define GHASH_PTR_ADD_USER(gh, pt) \
- { \
- void **val; \
- if (BLI_ghash_ensure_p((gh), (pt), &val)) { \
- *((int *)val) += 1; \
- } \
- else { \
- *((int *)val) = 1; \
- } \
- } ((void)0)
-
- /* count chunk_list's */
- GHash *chunk_list_map = BLI_ghash_ptr_new(__func__);
- GHash *chunk_map = BLI_ghash_ptr_new(__func__);
-
- int totrefs = 0;
- for (BArrayState *state = bs->states.first; state; state = state->next) {
- GHASH_PTR_ADD_USER(chunk_list_map, state->chunk_list);
- }
- GHASH_ITER (gh_iter, chunk_list_map) {
- const struct BChunkList *chunk_list = BLI_ghashIterator_getKey(&gh_iter);
- const int users = POINTER_AS_INT(BLI_ghashIterator_getValue(&gh_iter));
- if (!(chunk_list->users == users)) {
- ok = false;
- goto user_finally;
- }
- }
- if (!(BLI_mempool_len(bs->memory.chunk_list) == (int)BLI_ghash_len(chunk_list_map))) {
- ok = false;
- goto user_finally;
- }
-
- /* count chunk's */
- GHASH_ITER (gh_iter, chunk_list_map) {
- const struct BChunkList *chunk_list = BLI_ghashIterator_getKey(&gh_iter);
- for (const BChunkRef *cref = chunk_list->chunk_refs.first; cref; cref = cref->next) {
- GHASH_PTR_ADD_USER(chunk_map, cref->link);
- totrefs += 1;
- }
- }
- if (!(BLI_mempool_len(bs->memory.chunk) == (int)BLI_ghash_len(chunk_map))) {
- ok = false;
- goto user_finally;
- }
- if (!(BLI_mempool_len(bs->memory.chunk_ref) == totrefs)) {
- ok = false;
- goto user_finally;
- }
-
- GHASH_ITER (gh_iter, chunk_map) {
- const struct BChunk *chunk = BLI_ghashIterator_getKey(&gh_iter);
- const int users = POINTER_AS_INT(BLI_ghashIterator_getValue(&gh_iter));
- if (!(chunk->users == users)) {
- ok = false;
- goto user_finally;
- }
- }
+ { \
+ void **val; \
+ if (BLI_ghash_ensure_p((gh), (pt), &val)) { \
+ *((int *)val) += 1; \
+ } \
+ else { \
+ *((int *)val) = 1; \
+ } \
+ } \
+ ((void)0)
+
+ /* count chunk_list's */
+ GHash *chunk_list_map = BLI_ghash_ptr_new(__func__);
+ GHash *chunk_map = BLI_ghash_ptr_new(__func__);
+
+ int totrefs = 0;
+ for (BArrayState *state = bs->states.first; state; state = state->next) {
+ GHASH_PTR_ADD_USER(chunk_list_map, state->chunk_list);
+ }
+ GHASH_ITER (gh_iter, chunk_list_map) {
+ const struct BChunkList *chunk_list = BLI_ghashIterator_getKey(&gh_iter);
+ const int users = POINTER_AS_INT(BLI_ghashIterator_getValue(&gh_iter));
+ if (!(chunk_list->users == users)) {
+ ok = false;
+ goto user_finally;
+ }
+ }
+ if (!(BLI_mempool_len(bs->memory.chunk_list) == (int)BLI_ghash_len(chunk_list_map))) {
+ ok = false;
+ goto user_finally;
+ }
+
+ /* count chunk's */
+ GHASH_ITER (gh_iter, chunk_list_map) {
+ const struct BChunkList *chunk_list = BLI_ghashIterator_getKey(&gh_iter);
+ for (const BChunkRef *cref = chunk_list->chunk_refs.first; cref; cref = cref->next) {
+ GHASH_PTR_ADD_USER(chunk_map, cref->link);
+ totrefs += 1;
+ }
+ }
+ if (!(BLI_mempool_len(bs->memory.chunk) == (int)BLI_ghash_len(chunk_map))) {
+ ok = false;
+ goto user_finally;
+ }
+ if (!(BLI_mempool_len(bs->memory.chunk_ref) == totrefs)) {
+ ok = false;
+ goto user_finally;
+ }
+
+ GHASH_ITER (gh_iter, chunk_map) {
+ const struct BChunk *chunk = BLI_ghashIterator_getKey(&gh_iter);
+ const int users = POINTER_AS_INT(BLI_ghashIterator_getValue(&gh_iter));
+ if (!(chunk->users == users)) {
+ ok = false;
+ goto user_finally;
+ }
+ }
#undef GHASH_PTR_ADD_USER
-user_finally:
- BLI_ghash_free(chunk_list_map, NULL, NULL);
- BLI_ghash_free(chunk_map, NULL, NULL);
- }
-
+ user_finally:
+ BLI_ghash_free(chunk_list_map, NULL, NULL);
+ BLI_ghash_free(chunk_map, NULL, NULL);
+ }
- return ok;
- /* TODO, dangling pointer checks */
+ return ok;
+ /* TODO, dangling pointer checks */
}
/** \} */
diff --git a/source/blender/blenlib/intern/array_store_utils.c b/source/blender/blenlib/intern/array_store_utils.c
index d1b936b76f7..64c985a4c63 100644
--- a/source/blender/blenlib/intern/array_store_utils.c
+++ b/source/blender/blenlib/intern/array_store_utils.c
@@ -24,72 +24,69 @@
#include "BLI_utildefines.h"
#include "BLI_array_store.h"
-#include "BLI_array_store_utils.h" /* own include */
+#include "BLI_array_store_utils.h" /* own include */
#include "BLI_math_base.h"
-BArrayStore *BLI_array_store_at_size_ensure(
- struct BArrayStore_AtSize *bs_stride,
- const int stride, const int chunk_size)
+BArrayStore *BLI_array_store_at_size_ensure(struct BArrayStore_AtSize *bs_stride,
+ const int stride,
+ const int chunk_size)
{
- if (bs_stride->stride_table_len < stride) {
- bs_stride->stride_table_len = stride;
- bs_stride->stride_table = MEM_recallocN(bs_stride->stride_table, sizeof(*bs_stride->stride_table) * stride);
- }
- BArrayStore **bs_p = &bs_stride->stride_table[stride - 1];
+ if (bs_stride->stride_table_len < stride) {
+ bs_stride->stride_table_len = stride;
+ bs_stride->stride_table = MEM_recallocN(bs_stride->stride_table,
+ sizeof(*bs_stride->stride_table) * stride);
+ }
+ BArrayStore **bs_p = &bs_stride->stride_table[stride - 1];
- if ((*bs_p) == NULL) {
- /* calculate best chunk-count to fit a power of two */
- unsigned int chunk_count = chunk_size;
- {
- unsigned int size = chunk_count * stride;
- size = power_of_2_max_u(size);
- size = MEM_SIZE_OPTIMAL(size);
- chunk_count = size / stride;
- }
+ if ((*bs_p) == NULL) {
+ /* calculate best chunk-count to fit a power of two */
+ unsigned int chunk_count = chunk_size;
+ {
+ unsigned int size = chunk_count * stride;
+ size = power_of_2_max_u(size);
+ size = MEM_SIZE_OPTIMAL(size);
+ chunk_count = size / stride;
+ }
- (*bs_p) = BLI_array_store_create(stride, chunk_count);
- }
- return *bs_p;
+ (*bs_p) = BLI_array_store_create(stride, chunk_count);
+ }
+ return *bs_p;
}
-BArrayStore *BLI_array_store_at_size_get(
- struct BArrayStore_AtSize *bs_stride,
- const int stride)
+BArrayStore *BLI_array_store_at_size_get(struct BArrayStore_AtSize *bs_stride, const int stride)
{
- BLI_assert(stride > 0 && stride <= bs_stride->stride_table_len);
- return bs_stride->stride_table[stride - 1];
+ BLI_assert(stride > 0 && stride <= bs_stride->stride_table_len);
+ return bs_stride->stride_table[stride - 1];
}
-void BLI_array_store_at_size_clear(
- struct BArrayStore_AtSize *bs_stride)
+void BLI_array_store_at_size_clear(struct BArrayStore_AtSize *bs_stride)
{
- for (int i = 0; i < bs_stride->stride_table_len; i += 1) {
- if (bs_stride->stride_table[i]) {
- BLI_array_store_destroy(bs_stride->stride_table[i]);
- }
- }
+ for (int i = 0; i < bs_stride->stride_table_len; i += 1) {
+ if (bs_stride->stride_table[i]) {
+ BLI_array_store_destroy(bs_stride->stride_table[i]);
+ }
+ }
- MEM_freeN(bs_stride->stride_table);
- bs_stride->stride_table = NULL;
- bs_stride->stride_table_len = 0;
+ MEM_freeN(bs_stride->stride_table);
+ bs_stride->stride_table = NULL;
+ bs_stride->stride_table_len = 0;
}
-
-void BLI_array_store_at_size_calc_memory_usage(
- struct BArrayStore_AtSize *bs_stride,
- size_t *r_size_expanded, size_t *r_size_compacted)
+void BLI_array_store_at_size_calc_memory_usage(struct BArrayStore_AtSize *bs_stride,
+ size_t *r_size_expanded,
+ size_t *r_size_compacted)
{
- size_t size_compacted = 0;
- size_t size_expanded = 0;
- for (int i = 0; i < bs_stride->stride_table_len; i++) {
- BArrayStore *bs = bs_stride->stride_table[i];
- if (bs) {
- size_compacted += BLI_array_store_calc_size_compacted_get(bs);
- size_expanded += BLI_array_store_calc_size_expanded_get(bs);
- }
- }
+ size_t size_compacted = 0;
+ size_t size_expanded = 0;
+ for (int i = 0; i < bs_stride->stride_table_len; i++) {
+ BArrayStore *bs = bs_stride->stride_table[i];
+ if (bs) {
+ size_compacted += BLI_array_store_calc_size_compacted_get(bs);
+ size_expanded += BLI_array_store_calc_size_expanded_get(bs);
+ }
+ }
- *r_size_expanded = size_expanded;
- *r_size_compacted = size_compacted;
+ *r_size_expanded = size_expanded;
+ *r_size_compacted = size_compacted;
}
diff --git a/source/blender/blenlib/intern/array_utils.c b/source/blender/blenlib/intern/array_utils.c
index 568f3f9b9ff..f941c05e570 100644
--- a/source/blender/blenlib/intern/array_utils.c
+++ b/source/blender/blenlib/intern/array_utils.c
@@ -42,20 +42,18 @@
*/
void _bli_array_reverse(void *arr_v, unsigned int arr_len, size_t arr_stride)
{
- const unsigned int arr_stride_uint = (unsigned int)arr_stride;
- const unsigned int arr_half_stride = (arr_len / 2) * arr_stride_uint;
- unsigned int i, i_end;
- char *arr = arr_v;
- char *buf = BLI_array_alloca(buf, arr_stride);
-
- for (i = 0, i_end = (arr_len - 1) * arr_stride_uint;
- i < arr_half_stride;
- i += arr_stride_uint, i_end -= arr_stride_uint)
- {
- memcpy(buf, &arr[i], arr_stride);
- memcpy(&arr[i], &arr[i_end], arr_stride);
- memcpy(&arr[i_end], buf, arr_stride);
- }
+ const unsigned int arr_stride_uint = (unsigned int)arr_stride;
+ const unsigned int arr_half_stride = (arr_len / 2) * arr_stride_uint;
+ unsigned int i, i_end;
+ char *arr = arr_v;
+ char *buf = BLI_array_alloca(buf, arr_stride);
+
+ for (i = 0, i_end = (arr_len - 1) * arr_stride_uint; i < arr_half_stride;
+ i += arr_stride_uint, i_end -= arr_stride_uint) {
+ memcpy(buf, &arr[i], arr_stride);
+ memcpy(&arr[i], &arr[i_end], arr_stride);
+ memcpy(&arr[i_end], buf, arr_stride);
+ }
}
/**
@@ -66,22 +64,22 @@ void _bli_array_reverse(void *arr_v, unsigned int arr_len, size_t arr_stride)
*/
void _bli_array_wrap(void *arr_v, unsigned int arr_len, size_t arr_stride, int dir)
{
- char *arr = arr_v;
- char *buf = BLI_array_alloca(buf, arr_stride);
-
- if (dir == -1) {
- memcpy(buf, arr, arr_stride);
- memmove(arr, arr + arr_stride, arr_stride * (arr_len - 1));
- memcpy(arr + (arr_stride * (arr_len - 1)), buf, arr_stride);
- }
- else if (dir == 1) {
- memcpy(buf, arr + (arr_stride * (arr_len - 1)), arr_stride);
- memmove(arr + arr_stride, arr, arr_stride * (arr_len - 1));
- memcpy(arr, buf, arr_stride);
- }
- else {
- BLI_assert(0);
- }
+ char *arr = arr_v;
+ char *buf = BLI_array_alloca(buf, arr_stride);
+
+ if (dir == -1) {
+ memcpy(buf, arr, arr_stride);
+ memmove(arr, arr + arr_stride, arr_stride * (arr_len - 1));
+ memcpy(arr + (arr_stride * (arr_len - 1)), buf, arr_stride);
+ }
+ else if (dir == 1) {
+ memcpy(buf, arr + (arr_stride * (arr_len - 1)), arr_stride);
+ memmove(arr + arr_stride, arr, arr_stride * (arr_len - 1));
+ memcpy(arr, buf, arr_stride);
+ }
+ else {
+ BLI_assert(0);
+ }
}
/**
@@ -90,34 +88,36 @@ void _bli_array_wrap(void *arr_v, unsigned int arr_len, size_t arr_stride, int d
*
* Access via #BLI_array_wrap
*/
-void _bli_array_permute(
- void *arr_v, const unsigned int arr_len, const size_t arr_stride,
- const unsigned int *order, void *arr_temp)
+void _bli_array_permute(void *arr_v,
+ const unsigned int arr_len,
+ const size_t arr_stride,
+ const unsigned int *order,
+ void *arr_temp)
{
- const size_t len = arr_len * arr_stride;
- const unsigned int arr_stride_uint = (unsigned int)arr_stride;
- void *arr_orig;
- unsigned int i;
-
- if (arr_temp == NULL) {
- arr_orig = MEM_mallocN(len, __func__);
- }
- else {
- arr_orig = arr_temp;
- }
-
- memcpy(arr_orig, arr_v, len);
-
- for (i = 0; i < arr_len; i++) {
- BLI_assert(order[i] < arr_len);
- memcpy(POINTER_OFFSET(arr_v, arr_stride_uint * i),
- POINTER_OFFSET(arr_orig, arr_stride_uint * order[i]),
- arr_stride);
- }
-
- if (arr_temp == NULL) {
- MEM_freeN(arr_orig);
- }
+ const size_t len = arr_len * arr_stride;
+ const unsigned int arr_stride_uint = (unsigned int)arr_stride;
+ void *arr_orig;
+ unsigned int i;
+
+ if (arr_temp == NULL) {
+ arr_orig = MEM_mallocN(len, __func__);
+ }
+ else {
+ arr_orig = arr_temp;
+ }
+
+ memcpy(arr_orig, arr_v, len);
+
+ for (i = 0; i < arr_len; i++) {
+ BLI_assert(order[i] < arr_len);
+ memcpy(POINTER_OFFSET(arr_v, arr_stride_uint * i),
+ POINTER_OFFSET(arr_orig, arr_stride_uint * order[i]),
+ arr_stride);
+ }
+
+ if (arr_temp == NULL) {
+ MEM_freeN(arr_orig);
+ }
}
/**
@@ -129,13 +129,13 @@ void _bli_array_permute(
*/
int _bli_array_findindex(const void *arr, unsigned int arr_len, size_t arr_stride, const void *p)
{
- const char *arr_step = (const char *)arr;
- for (unsigned int i = 0; i < arr_len; i++, arr_step += arr_stride) {
- if (memcmp(arr_step, p, arr_stride) == 0) {
- return (int)i;
- }
- }
- return -1;
+ const char *arr_step = (const char *)arr;
+ for (unsigned int i = 0; i < arr_len; i++, arr_step += arr_stride) {
+ if (memcmp(arr_step, p, arr_stride) == 0) {
+ return (int)i;
+ }
+ }
+ return -1;
}
/**
@@ -143,42 +143,40 @@ int _bli_array_findindex(const void *arr, unsigned int arr_len, size_t arr_strid
*/
int _bli_array_rfindindex(const void *arr, unsigned int arr_len, size_t arr_stride, const void *p)
{
- const char *arr_step = (const char *)arr + (arr_stride * arr_len);
- for (unsigned int i = arr_len; i-- != 0; ) {
- arr_step -= arr_stride;
- if (memcmp(arr_step, p, arr_stride) == 0) {
- return (int)i;
- }
- }
- return -1;
+ const char *arr_step = (const char *)arr + (arr_stride * arr_len);
+ for (unsigned int i = arr_len; i-- != 0;) {
+ arr_step -= arr_stride;
+ if (memcmp(arr_step, p, arr_stride) == 0) {
+ return (int)i;
+ }
+ }
+ return -1;
}
void _bli_array_binary_and(
- void *arr, const void *arr_a, const void *arr_b,
- unsigned int arr_len, size_t arr_stride)
+ void *arr, const void *arr_a, const void *arr_b, unsigned int arr_len, size_t arr_stride)
{
- char *dst = arr;
- const char *src_a = arr_a;
- const char *src_b = arr_b;
-
- size_t i = arr_stride * arr_len;
- while (i--) {
- *(dst++) = *(src_a++) & *(src_b++);
- }
+ char *dst = arr;
+ const char *src_a = arr_a;
+ const char *src_b = arr_b;
+
+ size_t i = arr_stride * arr_len;
+ while (i--) {
+ *(dst++) = *(src_a++) & *(src_b++);
+ }
}
void _bli_array_binary_or(
- void *arr, const void *arr_a, const void *arr_b,
- unsigned int arr_len, size_t arr_stride)
+ void *arr, const void *arr_a, const void *arr_b, unsigned int arr_len, size_t arr_stride)
{
- char *dst = arr;
- const char *src_a = arr_a;
- const char *src_b = arr_b;
-
- size_t i = arr_stride * arr_len;
- while (i--) {
- *(dst++) = *(src_a++) | *(src_b++);
- }
+ char *dst = arr;
+ const char *src_a = arr_a;
+ const char *src_b = arr_b;
+
+ size_t i = arr_stride * arr_len;
+ while (i--) {
+ *(dst++) = *(src_a++) | *(src_b++);
+ }
}
/**
@@ -196,128 +194,126 @@ void _bli_array_binary_or(
* \param r_span_len: The length of the span, useful when \a use_wrap is enabled,
* where calculating the length isnt a simple subtraction.
*/
-bool _bli_array_iter_span(
- const void *arr,
- unsigned int arr_len, size_t arr_stride,
- bool use_wrap, bool use_delimit_bounds,
- bool (*test_fn)(const void *arr_item, void *user_data), void *user_data,
- unsigned int span_step[2], unsigned int *r_span_len)
+bool _bli_array_iter_span(const void *arr,
+ unsigned int arr_len,
+ size_t arr_stride,
+ bool use_wrap,
+ bool use_delimit_bounds,
+ bool (*test_fn)(const void *arr_item, void *user_data),
+ void *user_data,
+ unsigned int span_step[2],
+ unsigned int *r_span_len)
{
- if (arr_len == 0) {
- return false;
- }
- else if (use_wrap && (span_step[0] != arr_len) && (span_step[0] > span_step[1])) {
- return false;
- }
-
- const unsigned int arr_stride_uint = (unsigned int)arr_stride;
- const void *item_prev;
- bool test_prev;
-
- unsigned int i_curr;
-
- if ((span_step[0] == arr_len) && (span_step[1] == arr_len)) {
- if (use_wrap) {
- item_prev = POINTER_OFFSET(arr, (arr_len - 1) * arr_stride_uint);
- i_curr = 0;
- test_prev = test_fn(item_prev, user_data);
- }
- else if (use_delimit_bounds == false) {
- item_prev = arr;
- i_curr = 1;
- test_prev = test_fn(item_prev, user_data);
- }
- else {
- item_prev = NULL;
- i_curr = 0;
- test_prev = false;
- }
- }
- else if ((i_curr = span_step[1] + 2) < arr_len) {
- item_prev = POINTER_OFFSET(arr, (span_step[1] + 1) * arr_stride_uint);
- test_prev = test_fn(item_prev, user_data);
- }
- else {
- return false;
- }
- BLI_assert(i_curr < arr_len);
-
- const void *item_curr = POINTER_OFFSET(arr, i_curr * arr_stride_uint);
-
- while (i_curr < arr_len) {
- bool test_curr = test_fn(item_curr, user_data);
- if ((test_prev == false) &&
- (test_curr == true))
- {
- unsigned int span_len;
- unsigned int i_step_prev = i_curr;
-
- if (use_wrap) {
- unsigned int i_step = i_curr + 1;
- if (UNLIKELY(i_step == arr_len)) {
- i_step = 0;
- }
- while (test_fn(POINTER_OFFSET(arr, i_step * arr_stride_uint), user_data)) {
- i_step_prev = i_step;
- i_step++;
- if (UNLIKELY(i_step == arr_len)) {
- i_step = 0;
- }
- }
-
- if (i_step_prev < i_curr) {
- span_len = (i_step_prev + (arr_len - i_curr)) + 1;
- }
- else {
- span_len = (i_step_prev - i_curr) + 1;
- }
- }
- else {
- unsigned int i_step = i_curr + 1;
- while ((i_step != arr_len) &&
- test_fn(POINTER_OFFSET(arr, i_step * arr_stride_uint), user_data))
- {
- i_step_prev = i_step;
- i_step++;
- }
-
- span_len = (i_step_prev - i_curr) + 1;
-
- if ((use_delimit_bounds == false) && (i_step_prev == arr_len - 1)) {
- return false;
- }
- }
-
- span_step[0] = i_curr;
- span_step[1] = i_step_prev;
- *r_span_len = span_len;
-
- return true;
- }
-
- test_prev = test_curr;
-
- item_prev = item_curr;
- item_curr = POINTER_OFFSET(item_curr, arr_stride_uint);
- i_curr++;
- }
-
- return false;
+ if (arr_len == 0) {
+ return false;
+ }
+ else if (use_wrap && (span_step[0] != arr_len) && (span_step[0] > span_step[1])) {
+ return false;
+ }
+
+ const unsigned int arr_stride_uint = (unsigned int)arr_stride;
+ const void *item_prev;
+ bool test_prev;
+
+ unsigned int i_curr;
+
+ if ((span_step[0] == arr_len) && (span_step[1] == arr_len)) {
+ if (use_wrap) {
+ item_prev = POINTER_OFFSET(arr, (arr_len - 1) * arr_stride_uint);
+ i_curr = 0;
+ test_prev = test_fn(item_prev, user_data);
+ }
+ else if (use_delimit_bounds == false) {
+ item_prev = arr;
+ i_curr = 1;
+ test_prev = test_fn(item_prev, user_data);
+ }
+ else {
+ item_prev = NULL;
+ i_curr = 0;
+ test_prev = false;
+ }
+ }
+ else if ((i_curr = span_step[1] + 2) < arr_len) {
+ item_prev = POINTER_OFFSET(arr, (span_step[1] + 1) * arr_stride_uint);
+ test_prev = test_fn(item_prev, user_data);
+ }
+ else {
+ return false;
+ }
+ BLI_assert(i_curr < arr_len);
+
+ const void *item_curr = POINTER_OFFSET(arr, i_curr * arr_stride_uint);
+
+ while (i_curr < arr_len) {
+ bool test_curr = test_fn(item_curr, user_data);
+ if ((test_prev == false) && (test_curr == true)) {
+ unsigned int span_len;
+ unsigned int i_step_prev = i_curr;
+
+ if (use_wrap) {
+ unsigned int i_step = i_curr + 1;
+ if (UNLIKELY(i_step == arr_len)) {
+ i_step = 0;
+ }
+ while (test_fn(POINTER_OFFSET(arr, i_step * arr_stride_uint), user_data)) {
+ i_step_prev = i_step;
+ i_step++;
+ if (UNLIKELY(i_step == arr_len)) {
+ i_step = 0;
+ }
+ }
+
+ if (i_step_prev < i_curr) {
+ span_len = (i_step_prev + (arr_len - i_curr)) + 1;
+ }
+ else {
+ span_len = (i_step_prev - i_curr) + 1;
+ }
+ }
+ else {
+ unsigned int i_step = i_curr + 1;
+ while ((i_step != arr_len) &&
+ test_fn(POINTER_OFFSET(arr, i_step * arr_stride_uint), user_data)) {
+ i_step_prev = i_step;
+ i_step++;
+ }
+
+ span_len = (i_step_prev - i_curr) + 1;
+
+ if ((use_delimit_bounds == false) && (i_step_prev == arr_len - 1)) {
+ return false;
+ }
+ }
+
+ span_step[0] = i_curr;
+ span_step[1] = i_step_prev;
+ *r_span_len = span_len;
+
+ return true;
+ }
+
+ test_prev = test_curr;
+
+ item_prev = item_curr;
+ item_curr = POINTER_OFFSET(item_curr, arr_stride_uint);
+ i_curr++;
+ }
+
+ return false;
}
/**
* Simple utility to check memory is zeroed.
*/
-bool _bli_array_is_zeroed(
- const void *arr_v,
- unsigned int arr_len, size_t arr_stride)
+bool _bli_array_is_zeroed(const void *arr_v, unsigned int arr_len, size_t arr_stride)
{
- const char *arr_step = (const char *)arr_v;
- size_t i = arr_stride * arr_len;
- while (i--) {
- if (*(arr_step++)) {
- return false;
- }
- }
- return true;
+ const char *arr_step = (const char *)arr_v;
+ size_t i = arr_stride * arr_len;
+ while (i--) {
+ if (*(arr_step++)) {
+ return false;
+ }
+ }
+ return true;
}
diff --git a/source/blender/blenlib/intern/astar.c b/source/blender/blenlib/intern/astar.c
index 13998bad81d..c275f679dc6 100644
--- a/source/blender/blenlib/intern/astar.c
+++ b/source/blender/blenlib/intern/astar.c
@@ -57,7 +57,7 @@
*/
void BLI_astar_node_init(BLI_AStarGraph *as_graph, const int node_index, void *custom_data)
{
- as_graph->nodes[node_index].custom_data = custom_data;
+ as_graph->nodes[node_index].custom_data = custom_data;
}
/**
@@ -66,22 +66,25 @@ void BLI_astar_node_init(BLI_AStarGraph *as_graph, const int node_index, void *c
* \param cost: the 'length' of the link (actual distance between two vertices or face centers e.g.).
* \param custom_data: an opaque pointer attached to this link, available e.g. to cost callback function.
*/
-void BLI_astar_node_link_add(
- BLI_AStarGraph *as_graph, const int node1_index, const int node2_index, const float cost, void *custom_data)
+void BLI_astar_node_link_add(BLI_AStarGraph *as_graph,
+ const int node1_index,
+ const int node2_index,
+ const float cost,
+ void *custom_data)
{
- MemArena *mem = as_graph->mem;
- BLI_AStarGNLink *link = BLI_memarena_alloc(mem, sizeof(*link));
- LinkData *ld = BLI_memarena_alloc(mem, sizeof(*ld) * 2);
+ MemArena *mem = as_graph->mem;
+ BLI_AStarGNLink *link = BLI_memarena_alloc(mem, sizeof(*link));
+ LinkData *ld = BLI_memarena_alloc(mem, sizeof(*ld) * 2);
- link->nodes[0] = node1_index;
- link->nodes[1] = node2_index;
- link->cost = cost;
- link->custom_data = custom_data;
+ link->nodes[0] = node1_index;
+ link->nodes[1] = node2_index;
+ link->cost = cost;
+ link->custom_data = custom_data;
- ld[0].data = ld[1].data = link;
+ ld[0].data = ld[1].data = link;
- BLI_addtail(&(as_graph->nodes[node1_index].neighbor_links), &ld[0]);
- BLI_addtail(&(as_graph->nodes[node2_index].neighbor_links), &ld[1]);
+ BLI_addtail(&(as_graph->nodes[node1_index].neighbor_links), &ld[0]);
+ BLI_addtail(&(as_graph->nodes[node2_index].neighbor_links), &ld[1]);
}
/**
@@ -89,7 +92,7 @@ void BLI_astar_node_link_add(
*/
int BLI_astar_node_link_other_node(BLI_AStarGNLink *lnk, const int idx)
{
- return (lnk->nodes[0] == idx) ? lnk->nodes[1] : lnk->nodes[0];
+ return (lnk->nodes[0] == idx) ? lnk->nodes[1] : lnk->nodes[0];
}
/**
@@ -99,26 +102,28 @@ int BLI_astar_node_link_other_node(BLI_AStarGNLink *lnk, const int idx)
*
* \note BLI_AStarSolution stores nearly all data needed during solution compute.
*/
-void BLI_astar_solution_init(BLI_AStarGraph *as_graph, BLI_AStarSolution *as_solution, void *custom_data)
+void BLI_astar_solution_init(BLI_AStarGraph *as_graph,
+ BLI_AStarSolution *as_solution,
+ void *custom_data)
{
- MemArena *mem = as_solution->mem;
- size_t node_num = (size_t)as_graph->node_num;
+ MemArena *mem = as_solution->mem;
+ size_t node_num = (size_t)as_graph->node_num;
- if (mem == NULL) {
- mem = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
- as_solution->mem = mem;
- }
- /* else memarena should be cleared */
+ if (mem == NULL) {
+ mem = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
+ as_solution->mem = mem;
+ }
+ /* else memarena should be cleared */
- as_solution->steps = 0;
- as_solution->prev_nodes = BLI_memarena_alloc(mem, sizeof(*as_solution->prev_nodes) * node_num);
- as_solution->prev_links = BLI_memarena_alloc(mem, sizeof(*as_solution->prev_links) * node_num);
+ as_solution->steps = 0;
+ as_solution->prev_nodes = BLI_memarena_alloc(mem, sizeof(*as_solution->prev_nodes) * node_num);
+ as_solution->prev_links = BLI_memarena_alloc(mem, sizeof(*as_solution->prev_links) * node_num);
- as_solution->custom_data = custom_data;
+ as_solution->custom_data = custom_data;
- as_solution->done_nodes = BLI_BITMAP_NEW_MEMARENA(mem, node_num);
- as_solution->g_costs = BLI_memarena_alloc(mem, sizeof(*as_solution->g_costs) * node_num);
- as_solution->g_steps = BLI_memarena_alloc(mem, sizeof(*as_solution->g_steps) * node_num);
+ as_solution->done_nodes = BLI_BITMAP_NEW_MEMARENA(mem, node_num);
+ as_solution->g_costs = BLI_memarena_alloc(mem, sizeof(*as_solution->g_costs) * node_num);
+ as_solution->g_steps = BLI_memarena_alloc(mem, sizeof(*as_solution->g_steps) * node_num);
}
/**
@@ -129,19 +134,19 @@ void BLI_astar_solution_init(BLI_AStarGraph *as_graph, BLI_AStarSolution *as_sol
*/
void BLI_astar_solution_clear(BLI_AStarSolution *as_solution)
{
- if (as_solution->mem) {
- BLI_memarena_clear(as_solution->mem);
- }
+ if (as_solution->mem) {
+ BLI_memarena_clear(as_solution->mem);
+ }
- as_solution->steps = 0;
- as_solution->prev_nodes = NULL;
- as_solution->prev_links = NULL;
+ as_solution->steps = 0;
+ as_solution->prev_nodes = NULL;
+ as_solution->prev_links = NULL;
- as_solution->custom_data = NULL;
+ as_solution->custom_data = NULL;
- as_solution->done_nodes = NULL;
- as_solution->g_costs = NULL;
- as_solution->g_steps = NULL;
+ as_solution->done_nodes = NULL;
+ as_solution->g_costs = NULL;
+ as_solution->g_steps = NULL;
}
/**
@@ -149,10 +154,10 @@ void BLI_astar_solution_clear(BLI_AStarSolution *as_solution)
*/
void BLI_astar_solution_free(BLI_AStarSolution *as_solution)
{
- if (as_solution->mem) {
- BLI_memarena_free(as_solution->mem);
- as_solution->mem = NULL;
- }
+ if (as_solution->mem) {
+ BLI_memarena_free(as_solution->mem);
+ as_solution->mem = NULL;
+ }
}
/**
@@ -164,26 +169,26 @@ void BLI_astar_solution_free(BLI_AStarSolution *as_solution)
*/
void BLI_astar_graph_init(BLI_AStarGraph *as_graph, const int node_num, void *custom_data)
{
- MemArena *mem = as_graph->mem;
+ MemArena *mem = as_graph->mem;
- if (mem == NULL) {
- mem = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
- as_graph->mem = mem;
- }
- /* else memarena should be cleared */
+ if (mem == NULL) {
+ mem = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
+ as_graph->mem = mem;
+ }
+ /* else memarena should be cleared */
- as_graph->node_num = node_num;
- as_graph->nodes = BLI_memarena_calloc(mem, sizeof(*as_graph->nodes) * (size_t)node_num);
+ as_graph->node_num = node_num;
+ as_graph->nodes = BLI_memarena_calloc(mem, sizeof(*as_graph->nodes) * (size_t)node_num);
- as_graph->custom_data = custom_data;
+ as_graph->custom_data = custom_data;
}
void BLI_astar_graph_free(BLI_AStarGraph *as_graph)
{
- if (as_graph->mem) {
- BLI_memarena_free(as_graph->mem);
- as_graph->mem = NULL;
- }
+ if (as_graph->mem) {
+ BLI_memarena_free(as_graph->mem);
+ as_graph->mem = NULL;
+ }
}
/**
@@ -193,84 +198,86 @@ void BLI_astar_graph_free(BLI_AStarGraph *as_graph)
* If no path is found within given steps, returns false too.
* \return true if a path was found, false otherwise.
*/
-bool BLI_astar_graph_solve(
- BLI_AStarGraph *as_graph, const int node_index_src, const int node_index_dst, astar_f_cost f_cost_cb,
- BLI_AStarSolution *r_solution, const int max_steps)
+bool BLI_astar_graph_solve(BLI_AStarGraph *as_graph,
+ const int node_index_src,
+ const int node_index_dst,
+ astar_f_cost f_cost_cb,
+ BLI_AStarSolution *r_solution,
+ const int max_steps)
{
- HeapSimple *todo_nodes;
-
- BLI_bitmap *done_nodes = r_solution->done_nodes;
- int *prev_nodes = r_solution->prev_nodes;
- BLI_AStarGNLink **prev_links = r_solution->prev_links;
- float *g_costs = r_solution->g_costs;
- int *g_steps = r_solution->g_steps;
-
- r_solution->steps = 0;
- prev_nodes[node_index_src] = -1;
- BLI_bitmap_set_all(done_nodes, false, as_graph->node_num);
- copy_vn_fl(g_costs, as_graph->node_num, FLT_MAX);
- g_costs[node_index_src] = 0.0f;
- g_steps[node_index_src] = 0;
-
- if (node_index_src == node_index_dst) {
- return true;
- }
-
- todo_nodes = BLI_heapsimple_new();
- BLI_heapsimple_insert(
- todo_nodes,
- f_cost_cb(as_graph, r_solution, NULL, -1, node_index_src, node_index_dst),
- POINTER_FROM_INT(node_index_src));
-
- while (!BLI_heapsimple_is_empty(todo_nodes)) {
- const int node_curr_idx = POINTER_AS_INT(BLI_heapsimple_pop_min(todo_nodes));
- BLI_AStarGNode *node_curr = &as_graph->nodes[node_curr_idx];
- LinkData *ld;
-
- if (BLI_BITMAP_TEST(done_nodes, node_curr_idx)) {
- /* Might happen, because we always add nodes to heap when evaluating them,
- * without ever removing them. */
- continue;
- }
-
- /* If we are limited in amount of steps to find a path, skip if we reached limit. */
- if (max_steps && g_steps[node_curr_idx] > max_steps) {
- continue;
- }
-
- if (node_curr_idx == node_index_dst) {
- /* Success! Path found... */
- r_solution->steps = g_steps[node_curr_idx] + 1;
-
- BLI_heapsimple_free(todo_nodes, NULL);
- return true;
- }
-
- BLI_BITMAP_ENABLE(done_nodes, node_curr_idx);
-
- for (ld = node_curr->neighbor_links.first; ld; ld = ld->next) {
- BLI_AStarGNLink *link = ld->data;
- const int node_next_idx = BLI_astar_node_link_other_node(link, node_curr_idx);
-
- if (!BLI_BITMAP_TEST(done_nodes, node_next_idx)) {
- float g_cst = g_costs[node_curr_idx] + link->cost;
-
- if (g_cst < g_costs[node_next_idx]) {
- prev_nodes[node_next_idx] = node_curr_idx;
- prev_links[node_next_idx] = link;
- g_costs[node_next_idx] = g_cst;
- g_steps[node_next_idx] = g_steps[node_curr_idx] + 1;
- /* We might have this node already in heap, but since this 'instance'
- * will be evaluated first, no problem. */
- BLI_heapsimple_insert(
- todo_nodes,
- f_cost_cb(as_graph, r_solution, link, node_curr_idx, node_next_idx, node_index_dst),
- POINTER_FROM_INT(node_next_idx));
- }
- }
- }
- }
-
- BLI_heapsimple_free(todo_nodes, NULL);
- return false;
+ HeapSimple *todo_nodes;
+
+ BLI_bitmap *done_nodes = r_solution->done_nodes;
+ int *prev_nodes = r_solution->prev_nodes;
+ BLI_AStarGNLink **prev_links = r_solution->prev_links;
+ float *g_costs = r_solution->g_costs;
+ int *g_steps = r_solution->g_steps;
+
+ r_solution->steps = 0;
+ prev_nodes[node_index_src] = -1;
+ BLI_bitmap_set_all(done_nodes, false, as_graph->node_num);
+ copy_vn_fl(g_costs, as_graph->node_num, FLT_MAX);
+ g_costs[node_index_src] = 0.0f;
+ g_steps[node_index_src] = 0;
+
+ if (node_index_src == node_index_dst) {
+ return true;
+ }
+
+ todo_nodes = BLI_heapsimple_new();
+ BLI_heapsimple_insert(todo_nodes,
+ f_cost_cb(as_graph, r_solution, NULL, -1, node_index_src, node_index_dst),
+ POINTER_FROM_INT(node_index_src));
+
+ while (!BLI_heapsimple_is_empty(todo_nodes)) {
+ const int node_curr_idx = POINTER_AS_INT(BLI_heapsimple_pop_min(todo_nodes));
+ BLI_AStarGNode *node_curr = &as_graph->nodes[node_curr_idx];
+ LinkData *ld;
+
+ if (BLI_BITMAP_TEST(done_nodes, node_curr_idx)) {
+ /* Might happen, because we always add nodes to heap when evaluating them,
+ * without ever removing them. */
+ continue;
+ }
+
+ /* If we are limited in amount of steps to find a path, skip if we reached limit. */
+ if (max_steps && g_steps[node_curr_idx] > max_steps) {
+ continue;
+ }
+
+ if (node_curr_idx == node_index_dst) {
+ /* Success! Path found... */
+ r_solution->steps = g_steps[node_curr_idx] + 1;
+
+ BLI_heapsimple_free(todo_nodes, NULL);
+ return true;
+ }
+
+ BLI_BITMAP_ENABLE(done_nodes, node_curr_idx);
+
+ for (ld = node_curr->neighbor_links.first; ld; ld = ld->next) {
+ BLI_AStarGNLink *link = ld->data;
+ const int node_next_idx = BLI_astar_node_link_other_node(link, node_curr_idx);
+
+ if (!BLI_BITMAP_TEST(done_nodes, node_next_idx)) {
+ float g_cst = g_costs[node_curr_idx] + link->cost;
+
+ if (g_cst < g_costs[node_next_idx]) {
+ prev_nodes[node_next_idx] = node_curr_idx;
+ prev_links[node_next_idx] = link;
+ g_costs[node_next_idx] = g_cst;
+ g_steps[node_next_idx] = g_steps[node_curr_idx] + 1;
+ /* We might have this node already in heap, but since this 'instance'
+ * will be evaluated first, no problem. */
+ BLI_heapsimple_insert(
+ todo_nodes,
+ f_cost_cb(as_graph, r_solution, link, node_curr_idx, node_next_idx, node_index_dst),
+ POINTER_FROM_INT(node_next_idx));
+ }
+ }
+ }
+ }
+
+ BLI_heapsimple_free(todo_nodes, NULL);
+ return false;
}
diff --git a/source/blender/blenlib/intern/bitmap.c b/source/blender/blenlib/intern/bitmap.c
index 8cc359ac7f2..4e26ae23774 100644
--- a/source/blender/blenlib/intern/bitmap.c
+++ b/source/blender/blenlib/intern/bitmap.c
@@ -32,38 +32,38 @@
/** Set or clear all bits in the bitmap. */
void BLI_bitmap_set_all(BLI_bitmap *bitmap, bool set, size_t bits)
{
- memset(bitmap, set ? UCHAR_MAX : 0, BLI_BITMAP_SIZE(bits));
+ memset(bitmap, set ? UCHAR_MAX : 0, BLI_BITMAP_SIZE(bits));
}
/** Invert all bits in the bitmap. */
void BLI_bitmap_flip_all(BLI_bitmap *bitmap, size_t bits)
{
- size_t num_blocks = _BITMAP_NUM_BLOCKS(bits);
- for (size_t i = 0; i < num_blocks; i++) {
- bitmap[i] ^= ~(BLI_bitmap)0;
- }
+ size_t num_blocks = _BITMAP_NUM_BLOCKS(bits);
+ for (size_t i = 0; i < num_blocks; i++) {
+ bitmap[i] ^= ~(BLI_bitmap)0;
+ }
}
/** Copy all bits from one bitmap to another. */
void BLI_bitmap_copy_all(BLI_bitmap *dst, const BLI_bitmap *src, size_t bits)
{
- memcpy(dst, src, BLI_BITMAP_SIZE(bits));
+ memcpy(dst, src, BLI_BITMAP_SIZE(bits));
}
/** Combine two bitmaps with boolean AND. */
void BLI_bitmap_and_all(BLI_bitmap *dst, const BLI_bitmap *src, size_t bits)
{
- size_t num_blocks = _BITMAP_NUM_BLOCKS(bits);
- for (size_t i = 0; i < num_blocks; i++) {
- dst[i] &= src[i];
- }
+ size_t num_blocks = _BITMAP_NUM_BLOCKS(bits);
+ for (size_t i = 0; i < num_blocks; i++) {
+ dst[i] &= src[i];
+ }
}
/** Combine two bitmaps with boolean OR. */
void BLI_bitmap_or_all(BLI_bitmap *dst, const BLI_bitmap *src, size_t bits)
{
- size_t num_blocks = _BITMAP_NUM_BLOCKS(bits);
- for (size_t i = 0; i < num_blocks; i++) {
- dst[i] |= src[i];
- }
+ size_t num_blocks = _BITMAP_NUM_BLOCKS(bits);
+ for (size_t i = 0; i < num_blocks; i++) {
+ dst[i] |= src[i];
+ }
}
diff --git a/source/blender/blenlib/intern/bitmap_draw_2d.c b/source/blender/blenlib/intern/bitmap_draw_2d.c
index aa2e93d06a1..17debb38326 100644
--- a/source/blender/blenlib/intern/bitmap_draw_2d.c
+++ b/source/blender/blenlib/intern/bitmap_draw_2d.c
@@ -47,74 +47,75 @@
*
* \note For clipped line drawing, see: http://stackoverflow.com/a/40902741/432509
*/
-void BLI_bitmap_draw_2d_line_v2v2i(
- const int p1[2], const int p2[2],
- bool (*callback)(int, int, void *), void *user_data)
+void BLI_bitmap_draw_2d_line_v2v2i(const int p1[2],
+ const int p2[2],
+ bool (*callback)(int, int, void *),
+ void *user_data)
{
- /* Bresenham's line algorithm. */
- int x1 = p1[0];
- int y1 = p1[1];
- int x2 = p2[0];
- int y2 = p2[1];
-
- if (callback(x1, y1, user_data) == 0) {
- return;
- }
-
- /* if x1 == x2 or y1 == y2, then it does not matter what we set here */
- const int sign_x = (x2 > x1) ? 1 : -1;
- const int sign_y = (y2 > y1) ? 1 : -1;
-
- const int delta_x = (sign_x == 1) ? (x2 - x1) : (x1 - x2);
- const int delta_y = (sign_y == 1) ? (y2 - y1) : (y1 - y2);
-
- const int delta_x_step = delta_x * 2;
- const int delta_y_step = delta_y * 2;
-
- if (delta_x >= delta_y) {
- /* error may go below zero */
- int error = delta_y_step - delta_x;
-
- while (x1 != x2) {
- if (error >= 0) {
- if (error || (sign_x == 1)) {
- y1 += sign_y;
- error -= delta_x_step;
- }
- /* else do nothing */
- }
- /* else do nothing */
-
- x1 += sign_x;
- error += delta_y_step;
-
- if (callback(x1, y1, user_data) == 0) {
- return;
- }
- }
- }
- else {
- /* error may go below zero */
- int error = delta_x_step - delta_y;
-
- while (y1 != y2) {
- if (error >= 0) {
- if (error || (sign_y == 1)) {
- x1 += sign_x;
- error -= delta_y_step;
- }
- /* else do nothing */
- }
- /* else do nothing */
-
- y1 += sign_y;
- error += delta_x_step;
-
- if (callback(x1, y1, user_data) == 0) {
- return;
- }
- }
- }
+ /* Bresenham's line algorithm. */
+ int x1 = p1[0];
+ int y1 = p1[1];
+ int x2 = p2[0];
+ int y2 = p2[1];
+
+ if (callback(x1, y1, user_data) == 0) {
+ return;
+ }
+
+ /* if x1 == x2 or y1 == y2, then it does not matter what we set here */
+ const int sign_x = (x2 > x1) ? 1 : -1;
+ const int sign_y = (y2 > y1) ? 1 : -1;
+
+ const int delta_x = (sign_x == 1) ? (x2 - x1) : (x1 - x2);
+ const int delta_y = (sign_y == 1) ? (y2 - y1) : (y1 - y2);
+
+ const int delta_x_step = delta_x * 2;
+ const int delta_y_step = delta_y * 2;
+
+ if (delta_x >= delta_y) {
+ /* error may go below zero */
+ int error = delta_y_step - delta_x;
+
+ while (x1 != x2) {
+ if (error >= 0) {
+ if (error || (sign_x == 1)) {
+ y1 += sign_y;
+ error -= delta_x_step;
+ }
+ /* else do nothing */
+ }
+ /* else do nothing */
+
+ x1 += sign_x;
+ error += delta_y_step;
+
+ if (callback(x1, y1, user_data) == 0) {
+ return;
+ }
+ }
+ }
+ else {
+ /* error may go below zero */
+ int error = delta_x_step - delta_y;
+
+ while (y1 != y2) {
+ if (error >= 0) {
+ if (error || (sign_y == 1)) {
+ x1 += sign_x;
+ error -= delta_y_step;
+ }
+ /* else do nothing */
+ }
+ /* else do nothing */
+
+ y1 += sign_y;
+ error += delta_x_step;
+
+ if (callback(x1, y1, user_data) == 0) {
+ return;
+ }
+ }
+ }
}
/** \} */
@@ -141,25 +142,34 @@ void BLI_bitmap_draw_2d_line_v2v2i(
/* Macros could be moved to a shared location. */
#define ORDERED_SWAP(ty, a, b) \
- if (a > b) { SWAP(ty, a, b); } ((void)0)
+ if (a > b) { \
+ SWAP(ty, a, b); \
+ } \
+ ((void)0)
#define ORDERED_SWAP_BY(ty, a, b, by) \
- if ((a by) > (b by)) { SWAP(ty, a, b); } ((void)0)
+ if ((a by) > (b by)) { \
+ SWAP(ty, a, b); \
+ } \
+ ((void)0)
#define ORDER_VARS2(ty, a, b) \
- { ORDERED_SWAP(ty, a, b); } ((void)0)
+ { \
+ ORDERED_SWAP(ty, a, b); \
+ } \
+ ((void)0)
#define ORDER_VARS3_BY(ty, a, b, c, by) \
- { \
- ORDERED_SWAP_BY(ty, b, c, by); \
- ORDERED_SWAP_BY(ty, a, c, by); \
- ORDERED_SWAP_BY(ty, a, b, by); \
- } ((void)0)
+ { \
+ ORDERED_SWAP_BY(ty, b, c, by); \
+ ORDERED_SWAP_BY(ty, a, c, by); \
+ ORDERED_SWAP_BY(ty, a, b, by); \
+ } \
+ ((void)0)
static float inv_slope(const int a[2], const int b[2])
{
- return ((float)(a[0] - b[0]) /
- (float)(a[1] - b[1]));
+ return ((float)(a[0] - b[0]) / (float)(a[1] - b[1]));
}
/**
@@ -169,24 +179,23 @@ static float inv_slope(const int a[2], const int b[2])
* *
* </pre>
*/
-static void draw_tri_flat_max(
- const int p[2],
- const int max_y,
- const float inv_slope1,
- const float inv_slope2,
- void (*callback)(int x, int x_end, int y, void *),
- void *user_data)
+static void draw_tri_flat_max(const int p[2],
+ const int max_y,
+ const float inv_slope1,
+ const float inv_slope2,
+ void (*callback)(int x, int x_end, int y, void *),
+ void *user_data)
{
- float cur_x1 = (float)p[0];
- float cur_x2 = cur_x1;
- /* start-end inclusive */
- const int min_y = p[1];
- const int max_y_end = max_y + 1;
- for (int scanline_y = min_y; scanline_y != max_y_end; scanline_y += 1) {
- callback((int)cur_x1, 1 + (int)cur_x2, scanline_y, user_data);
- cur_x1 += inv_slope1;
- cur_x2 += inv_slope2;
- }
+ float cur_x1 = (float)p[0];
+ float cur_x2 = cur_x1;
+ /* start-end inclusive */
+ const int min_y = p[1];
+ const int max_y_end = max_y + 1;
+ for (int scanline_y = min_y; scanline_y != max_y_end; scanline_y += 1) {
+ callback((int)cur_x1, 1 + (int)cur_x2, scanline_y, user_data);
+ cur_x1 += inv_slope1;
+ cur_x2 += inv_slope2;
+ }
}
/**
@@ -196,95 +205,92 @@ static void draw_tri_flat_max(
* *---*
* </pre>
*/
-static void draw_tri_flat_min(
- const int p[2],
- const int min_y,
- const float inv_slope1,
- const float inv_slope2,
- void (*callback)(int x, int x_end, int y, void *),
- void *user_data)
+static void draw_tri_flat_min(const int p[2],
+ const int min_y,
+ const float inv_slope1,
+ const float inv_slope2,
+ void (*callback)(int x, int x_end, int y, void *),
+ void *user_data)
{
- float cur_x1 = (float)p[0];
- float cur_x2 = cur_x1;
- /* start-end inclusive */
- const int max_y = p[1];
- const int min_y_end = min_y - 1;
- for (int scanline_y = max_y; scanline_y != min_y_end; scanline_y -= 1) {
- callback((int)cur_x1, 1 + (int)cur_x2, scanline_y, user_data);
- cur_x1 -= inv_slope1;
- cur_x2 -= inv_slope2;
- }
+ float cur_x1 = (float)p[0];
+ float cur_x2 = cur_x1;
+ /* start-end inclusive */
+ const int max_y = p[1];
+ const int min_y_end = min_y - 1;
+ for (int scanline_y = max_y; scanline_y != min_y_end; scanline_y -= 1) {
+ callback((int)cur_x1, 1 + (int)cur_x2, scanline_y, user_data);
+ cur_x1 -= inv_slope1;
+ cur_x2 -= inv_slope2;
+ }
}
/**
* \note Unclipped (clipped version can be added if needed).
*/
void BLI_bitmap_draw_2d_tri_v2i(
- /* all 2d */
- const int p1[2],
- const int p2[2],
- const int p3[2],
- void (*callback)(int x, int x_end, int y, void *),
- void *user_data)
+ /* all 2d */
+ const int p1[2],
+ const int p2[2],
+ const int p3[2],
+ void (*callback)(int x, int x_end, int y, void *),
+ void *user_data)
{
- /* At first sort the three vertices by y-coordinate ascending so p1 is the top-most vertice */
- ORDER_VARS3_BY(const int *, p1, p2, p3, [1]);
-
- BLI_assert(p1[1] <= p2[1] && p2[1] <= p3[1]);
-
- /* Check for trivial case of bottom-flat triangle. */
- if (p2[1] == p3[1]) {
- float inv_slope1 = inv_slope(p2, p1);
- float inv_slope2 = inv_slope(p3, p1);
- ORDER_VARS2(float, inv_slope1, inv_slope2);
- BLI_assert(!(inv_slope1 > inv_slope2));
- draw_tri_flat_max(
- p1, p2[1],
- inv_slope1, inv_slope2,
- callback, user_data);
- }
- else if (p1[1] == p2[1]) {
- /* Check for trivial case of top-flat triangle. */
- float inv_slope1 = inv_slope(p3, p1);
- float inv_slope2 = inv_slope(p3, p2);
- ORDER_VARS2(float, inv_slope2, inv_slope1);
- BLI_assert(!(inv_slope1 < inv_slope2));
- draw_tri_flat_min(
- p3, p2[1] + 1, /* avoid overlap */
- inv_slope1, inv_slope2,
- callback, user_data);
- }
- else {
- /* General case - split the triangle in a top-flat and bottom-flat one. */
- const float inv_slope_p21 = inv_slope(p2, p1);
- const float inv_slope_p31 = inv_slope(p3, p1);
- const float inv_slope_p32 = inv_slope(p3, p2);
-
- float inv_slope1_max, inv_slope2_max;
- float inv_slope2_min, inv_slope1_min;
-
- if (inv_slope_p21 < inv_slope_p31) {
- inv_slope1_max = inv_slope_p21;
- inv_slope2_max = inv_slope_p31;
- inv_slope2_min = inv_slope_p31;
- inv_slope1_min = inv_slope_p32;
- }
- else {
- inv_slope1_max = inv_slope_p31;
- inv_slope2_max = inv_slope_p21;
- inv_slope2_min = inv_slope_p32;
- inv_slope1_min = inv_slope_p31;
- }
-
- draw_tri_flat_max(
- p1, p2[1],
- inv_slope1_max, inv_slope2_max,
- callback, user_data);
- draw_tri_flat_min(
- p3, p2[1] + 1, /* avoid overlap */
- inv_slope1_min, inv_slope2_min,
- callback, user_data);
- }
+ /* At first sort the three vertices by y-coordinate ascending so p1 is the top-most vertice */
+ ORDER_VARS3_BY(const int *, p1, p2, p3, [1]);
+
+ BLI_assert(p1[1] <= p2[1] && p2[1] <= p3[1]);
+
+ /* Check for trivial case of bottom-flat triangle. */
+ if (p2[1] == p3[1]) {
+ float inv_slope1 = inv_slope(p2, p1);
+ float inv_slope2 = inv_slope(p3, p1);
+ ORDER_VARS2(float, inv_slope1, inv_slope2);
+ BLI_assert(!(inv_slope1 > inv_slope2));
+ draw_tri_flat_max(p1, p2[1], inv_slope1, inv_slope2, callback, user_data);
+ }
+ else if (p1[1] == p2[1]) {
+ /* Check for trivial case of top-flat triangle. */
+ float inv_slope1 = inv_slope(p3, p1);
+ float inv_slope2 = inv_slope(p3, p2);
+ ORDER_VARS2(float, inv_slope2, inv_slope1);
+ BLI_assert(!(inv_slope1 < inv_slope2));
+ draw_tri_flat_min(p3,
+ p2[1] + 1, /* avoid overlap */
+ inv_slope1,
+ inv_slope2,
+ callback,
+ user_data);
+ }
+ else {
+ /* General case - split the triangle in a top-flat and bottom-flat one. */
+ const float inv_slope_p21 = inv_slope(p2, p1);
+ const float inv_slope_p31 = inv_slope(p3, p1);
+ const float inv_slope_p32 = inv_slope(p3, p2);
+
+ float inv_slope1_max, inv_slope2_max;
+ float inv_slope2_min, inv_slope1_min;
+
+ if (inv_slope_p21 < inv_slope_p31) {
+ inv_slope1_max = inv_slope_p21;
+ inv_slope2_max = inv_slope_p31;
+ inv_slope2_min = inv_slope_p31;
+ inv_slope1_min = inv_slope_p32;
+ }
+ else {
+ inv_slope1_max = inv_slope_p31;
+ inv_slope2_max = inv_slope_p21;
+ inv_slope2_min = inv_slope_p32;
+ inv_slope1_min = inv_slope_p31;
+ }
+
+ draw_tri_flat_max(p1, p2[1], inv_slope1_max, inv_slope2_max, callback, user_data);
+ draw_tri_flat_min(p3,
+ p2[1] + 1, /* avoid overlap */
+ inv_slope1_min,
+ inv_slope2_min,
+ callback,
+ user_data);
+ }
}
#undef ORDERED_SWAP
@@ -301,39 +307,38 @@ void BLI_bitmap_draw_2d_tri_v2i(
/* sort edge-segments on y, then x axis */
static int draw_poly_v2i_n__span_y_sort(const void *a_p, const void *b_p, void *verts_p)
{
- const int (*verts)[2] = verts_p;
- const int *a = a_p;
- const int *b = b_p;
- const int *co_a = verts[a[0]];
- const int *co_b = verts[b[0]];
-
- if (co_a[1] < co_b[1]) {
- return -1;
- }
- else if (co_a[1] > co_b[1]) {
- return 1;
- }
- else if (co_a[0] < co_b[0]) {
- return -1;
- }
- else if (co_a[0] > co_b[0]) {
- return 1;
- }
- else {
- /* co_a & co_b are identical, use the line closest to the x-min */
- const int *co = co_a;
- co_a = verts[a[1]];
- co_b = verts[b[1]];
- int ord = (((co_b[0] - co[0]) * (co_a[1] - co[1])) -
- ((co_a[0] - co[0]) * (co_b[1] - co[1])));
- if (ord > 0) {
- return -1;
- }
- if (ord < 0) {
- return 1;
- }
- }
- return 0;
+ const int(*verts)[2] = verts_p;
+ const int *a = a_p;
+ const int *b = b_p;
+ const int *co_a = verts[a[0]];
+ const int *co_b = verts[b[0]];
+
+ if (co_a[1] < co_b[1]) {
+ return -1;
+ }
+ else if (co_a[1] > co_b[1]) {
+ return 1;
+ }
+ else if (co_a[0] < co_b[0]) {
+ return -1;
+ }
+ else if (co_a[0] > co_b[0]) {
+ return 1;
+ }
+ else {
+ /* co_a & co_b are identical, use the line closest to the x-min */
+ const int *co = co_a;
+ co_a = verts[a[1]];
+ co_b = verts[b[1]];
+ int ord = (((co_b[0] - co[0]) * (co_a[1] - co[1])) - ((co_a[0] - co[0]) * (co_b[1] - co[1])));
+ if (ord > 0) {
+ return -1;
+ }
+ if (ord < 0) {
+ return 1;
+ }
+ }
+ return 0;
}
/**
@@ -348,166 +353,164 @@ static int draw_poly_v2i_n__span_y_sort(const void *a_p, const void *b_p, void *
* } while (++x != x_end);
* \endcode
*/
-void BLI_bitmap_draw_2d_poly_v2i_n(
- const int xmin, const int ymin, const int xmax, const int ymax,
- const int verts[][2], const int verts_len,
- void (*callback)(int x, int x_end, int y, void *), void *user_data)
+void BLI_bitmap_draw_2d_poly_v2i_n(const int xmin,
+ const int ymin,
+ const int xmax,
+ const int ymax,
+ const int verts[][2],
+ const int verts_len,
+ void (*callback)(int x, int x_end, int y, void *),
+ void *user_data)
{
- /* Originally by Darel Rex Finley, 2007.
- * Optimized by Campbell Barton, 2016 to track sorted intersections. */
-
- int (*span_y)[2] = MEM_mallocN(sizeof(*span_y) * (size_t)verts_len, __func__);
- int span_y_len = 0;
-
- for (int i_curr = 0, i_prev = verts_len - 1; i_curr < verts_len; i_prev = i_curr++) {
- const int *co_prev = verts[i_prev];
- const int *co_curr = verts[i_curr];
-
- if (co_prev[1] != co_curr[1]) {
- /* Any segments entirely above or below the area of interest can be skipped. */
- if ((min_ii(co_prev[1], co_curr[1]) >= ymax) ||
- (max_ii(co_prev[1], co_curr[1]) < ymin))
- {
- continue;
- }
-
- int *s = span_y[span_y_len++];
- if (co_prev[1] < co_curr[1]) {
- s[0] = i_prev;
- s[1] = i_curr;
- }
- else {
- s[0] = i_curr;
- s[1] = i_prev;
- }
- }
- }
-
- BLI_qsort_r(span_y, (size_t)span_y_len, sizeof(*span_y), draw_poly_v2i_n__span_y_sort, (void *)verts);
-
- struct NodeX {
- int span_y_index;
- int x;
- } *node_x = MEM_mallocN(sizeof(*node_x) * (size_t)(verts_len + 1), __func__);
- int node_x_len = 0;
-
- int span_y_index = 0;
- if (span_y_len != 0 && verts[span_y[0][0]][1] < ymin) {
- while ((span_y_index < span_y_len) &&
- (verts[span_y[span_y_index][0]][1] < ymin))
- {
- BLI_assert(verts[span_y[span_y_index][0]][1] <
- verts[span_y[span_y_index][1]][1]);
- if (verts[span_y[span_y_index][1]][1] >= ymin) {
- struct NodeX *n = &node_x[node_x_len++];
- n->span_y_index = span_y_index;
- }
- span_y_index += 1;
- }
- }
-
- /* Loop through the rows of the image. */
- for (int pixel_y = ymin; pixel_y < ymax; pixel_y++) {
- bool is_sorted = true;
- bool do_remove = false;
-
- for (int i = 0, x_ix_prev = INT_MIN; i < node_x_len; i++) {
- struct NodeX *n = &node_x[i];
- const int *s = span_y[n->span_y_index];
- const int *co_prev = verts[s[0]];
- const int *co_curr = verts[s[1]];
-
- BLI_assert(co_prev[1] < pixel_y && co_curr[1] >= pixel_y);
-
- const double x = (co_prev[0] - co_curr[0]);
- const double y = (co_prev[1] - co_curr[1]);
- const double y_px = (pixel_y - co_curr[1]);
- const int x_ix = (int)((double)co_curr[0] + ((y_px / y) * x));
- n->x = x_ix;
-
- if (is_sorted && (x_ix_prev > x_ix)) {
- is_sorted = false;
- }
- if (do_remove == false && co_curr[1] == pixel_y) {
- do_remove = true;
- }
- x_ix_prev = x_ix;
- }
-
- /* Sort the nodes, via a simple "Bubble" sort. */
- if (is_sorted == false) {
- int i = 0;
- const int node_x_end = node_x_len - 1;
- while (i < node_x_end) {
- if (node_x[i].x > node_x[i + 1].x) {
- SWAP(struct NodeX, node_x[i], node_x[i + 1]);
- if (i != 0) {
- i -= 1;
- }
- }
- else {
- i += 1;
- }
- }
- }
-
- /* Fill the pixels between node pairs. */
- for (int i = 0; i < node_x_len; i += 2) {
- int x_src = node_x[i].x;
- int x_dst = node_x[i + 1].x;
-
- if (x_src >= xmax) {
- break;
- }
-
- if (x_dst > xmin) {
- if (x_src < xmin) {
- x_src = xmin;
- }
- if (x_dst > xmax) {
- x_dst = xmax;
- }
- /* for single call per x-span */
- if (x_src < x_dst) {
- callback(x_src - xmin, x_dst - xmin, pixel_y - ymin, user_data);
- }
- }
- }
-
- /* Clear finalized nodes in one pass, only when needed
- * (avoids excessive array-resizing). */
- if (do_remove == true) {
- int i_dst = 0;
- for (int i_src = 0; i_src < node_x_len; i_src += 1) {
- const int *s = span_y[node_x[i_src].span_y_index];
- const int *co = verts[s[1]];
- if (co[1] != pixel_y) {
- if (i_dst != i_src) {
- /* x is initialized for the next pixel_y (no need to adjust here) */
- node_x[i_dst].span_y_index = node_x[i_src].span_y_index;
- }
- i_dst += 1;
- }
- }
- node_x_len = i_dst;
- }
-
- /* Scan for new x-nodes */
- while ((span_y_index < span_y_len) &&
- (verts[span_y[span_y_index][0]][1] == pixel_y))
- {
- /* note, node_x these are just added at the end,
- * not ideal but sorting once will resolve. */
-
- /* x is initialized for the next pixel_y */
- struct NodeX *n = &node_x[node_x_len++];
- n->span_y_index = span_y_index;
- span_y_index += 1;
- }
- }
-
- MEM_freeN(span_y);
- MEM_freeN(node_x);
+ /* Originally by Darel Rex Finley, 2007.
+ * Optimized by Campbell Barton, 2016 to track sorted intersections. */
+
+ int(*span_y)[2] = MEM_mallocN(sizeof(*span_y) * (size_t)verts_len, __func__);
+ int span_y_len = 0;
+
+ for (int i_curr = 0, i_prev = verts_len - 1; i_curr < verts_len; i_prev = i_curr++) {
+ const int *co_prev = verts[i_prev];
+ const int *co_curr = verts[i_curr];
+
+ if (co_prev[1] != co_curr[1]) {
+ /* Any segments entirely above or below the area of interest can be skipped. */
+ if ((min_ii(co_prev[1], co_curr[1]) >= ymax) || (max_ii(co_prev[1], co_curr[1]) < ymin)) {
+ continue;
+ }
+
+ int *s = span_y[span_y_len++];
+ if (co_prev[1] < co_curr[1]) {
+ s[0] = i_prev;
+ s[1] = i_curr;
+ }
+ else {
+ s[0] = i_curr;
+ s[1] = i_prev;
+ }
+ }
+ }
+
+ BLI_qsort_r(
+ span_y, (size_t)span_y_len, sizeof(*span_y), draw_poly_v2i_n__span_y_sort, (void *)verts);
+
+ struct NodeX {
+ int span_y_index;
+ int x;
+ } *node_x = MEM_mallocN(sizeof(*node_x) * (size_t)(verts_len + 1), __func__);
+ int node_x_len = 0;
+
+ int span_y_index = 0;
+ if (span_y_len != 0 && verts[span_y[0][0]][1] < ymin) {
+ while ((span_y_index < span_y_len) && (verts[span_y[span_y_index][0]][1] < ymin)) {
+ BLI_assert(verts[span_y[span_y_index][0]][1] < verts[span_y[span_y_index][1]][1]);
+ if (verts[span_y[span_y_index][1]][1] >= ymin) {
+ struct NodeX *n = &node_x[node_x_len++];
+ n->span_y_index = span_y_index;
+ }
+ span_y_index += 1;
+ }
+ }
+
+ /* Loop through the rows of the image. */
+ for (int pixel_y = ymin; pixel_y < ymax; pixel_y++) {
+ bool is_sorted = true;
+ bool do_remove = false;
+
+ for (int i = 0, x_ix_prev = INT_MIN; i < node_x_len; i++) {
+ struct NodeX *n = &node_x[i];
+ const int *s = span_y[n->span_y_index];
+ const int *co_prev = verts[s[0]];
+ const int *co_curr = verts[s[1]];
+
+ BLI_assert(co_prev[1] < pixel_y && co_curr[1] >= pixel_y);
+
+ const double x = (co_prev[0] - co_curr[0]);
+ const double y = (co_prev[1] - co_curr[1]);
+ const double y_px = (pixel_y - co_curr[1]);
+ const int x_ix = (int)((double)co_curr[0] + ((y_px / y) * x));
+ n->x = x_ix;
+
+ if (is_sorted && (x_ix_prev > x_ix)) {
+ is_sorted = false;
+ }
+ if (do_remove == false && co_curr[1] == pixel_y) {
+ do_remove = true;
+ }
+ x_ix_prev = x_ix;
+ }
+
+ /* Sort the nodes, via a simple "Bubble" sort. */
+ if (is_sorted == false) {
+ int i = 0;
+ const int node_x_end = node_x_len - 1;
+ while (i < node_x_end) {
+ if (node_x[i].x > node_x[i + 1].x) {
+ SWAP(struct NodeX, node_x[i], node_x[i + 1]);
+ if (i != 0) {
+ i -= 1;
+ }
+ }
+ else {
+ i += 1;
+ }
+ }
+ }
+
+ /* Fill the pixels between node pairs. */
+ for (int i = 0; i < node_x_len; i += 2) {
+ int x_src = node_x[i].x;
+ int x_dst = node_x[i + 1].x;
+
+ if (x_src >= xmax) {
+ break;
+ }
+
+ if (x_dst > xmin) {
+ if (x_src < xmin) {
+ x_src = xmin;
+ }
+ if (x_dst > xmax) {
+ x_dst = xmax;
+ }
+ /* for single call per x-span */
+ if (x_src < x_dst) {
+ callback(x_src - xmin, x_dst - xmin, pixel_y - ymin, user_data);
+ }
+ }
+ }
+
+ /* Clear finalized nodes in one pass, only when needed
+ * (avoids excessive array-resizing). */
+ if (do_remove == true) {
+ int i_dst = 0;
+ for (int i_src = 0; i_src < node_x_len; i_src += 1) {
+ const int *s = span_y[node_x[i_src].span_y_index];
+ const int *co = verts[s[1]];
+ if (co[1] != pixel_y) {
+ if (i_dst != i_src) {
+ /* x is initialized for the next pixel_y (no need to adjust here) */
+ node_x[i_dst].span_y_index = node_x[i_src].span_y_index;
+ }
+ i_dst += 1;
+ }
+ }
+ node_x_len = i_dst;
+ }
+
+ /* Scan for new x-nodes */
+ while ((span_y_index < span_y_len) && (verts[span_y[span_y_index][0]][1] == pixel_y)) {
+ /* note, node_x these are just added at the end,
+ * not ideal but sorting once will resolve. */
+
+ /* x is initialized for the next pixel_y */
+ struct NodeX *n = &node_x[node_x_len++];
+ n->span_y_index = span_y_index;
+ span_y_index += 1;
+ }
+ }
+
+ MEM_freeN(span_y);
+ MEM_freeN(node_x);
}
/** \} */
diff --git a/source/blender/blenlib/intern/boxpack_2d.c b/source/blender/blenlib/intern/boxpack_2d.c
index c90038b78a1..f05523b8897 100644
--- a/source/blender/blenlib/intern/boxpack_2d.c
+++ b/source/blender/blenlib/intern/boxpack_2d.c
@@ -19,15 +19,15 @@
*/
#include <stdlib.h> /* for qsort */
-#include <math.h> /* for fabsf */
+#include <math.h> /* for fabsf */
#include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
-#include "BLI_boxpack_2d.h" /* own include */
+#include "BLI_boxpack_2d.h" /* own include */
-#include "BLI_sort.h" /* qsort_r */
-#define qsort_r BLI_qsort_r
+#include "BLI_sort.h" /* qsort_r */
+#define qsort_r BLI_qsort_r
#include "BLI_strict_flags.h"
@@ -42,31 +42,30 @@
/* slight bias, needed when packing many boxes the _exact_ same size */
#define USE_PACK_BIAS
-
/* BoxPacker for backing 2D rectangles into a square
*
* The defined Below are for internal use only */
typedef struct BoxVert {
- float x;
- float y;
+ float x;
+ float y;
- int free : 8; /* vert status */
- uint used : 1;
- uint _pad : 23;
- uint index;
+ int free : 8; /* vert status */
+ uint used : 1;
+ uint _pad : 23;
+ uint index;
- struct BoxPack *trb; /* top right box */
- struct BoxPack *blb; /* bottom left box */
- struct BoxPack *brb; /* bottom right box */
- struct BoxPack *tlb; /* top left box */
+ struct BoxPack *trb; /* top right box */
+ struct BoxPack *blb; /* bottom left box */
+ struct BoxPack *brb; /* bottom right box */
+ struct BoxPack *tlb; /* top left box */
- /* Store last intersecting boxes here
- * speedup intersection testing */
- struct BoxPack *isect_cache[4];
+ /* Store last intersecting boxes here
+ * speedup intersection testing */
+ struct BoxPack *isect_cache[4];
#ifdef USE_PACK_BIAS
- float bias;
- int _pad2;
+ float bias;
+ int _pad2;
#endif
} BoxVert;
@@ -88,8 +87,8 @@ typedef struct BoxVert {
BLI_INLINE int quad_flag(uint q)
{
- BLI_assert(q < 4);
- return (1 << q);
+ BLI_assert(q < 4);
+ return (1 << q);
}
#define BL 0
@@ -102,106 +101,105 @@ BLI_INLINE int quad_flag(uint q)
static float box_xmin_get(const BoxPack *box)
{
- return box->v[BL]->x;
+ return box->v[BL]->x;
}
static float box_xmax_get(const BoxPack *box)
{
- return box->v[TR]->x;
+ return box->v[TR]->x;
}
static float box_ymin_get(const BoxPack *box)
{
- return box->v[BL]->y;
+ return box->v[BL]->y;
}
static float box_ymax_get(const BoxPack *box)
{
- return box->v[TR]->y;
+ return box->v[TR]->y;
}
/** \} */
-
/** \name Box Placement
* \{ */
BLI_INLINE void box_v34x_update(BoxPack *box)
{
- box->v[TL]->x = box->v[BL]->x;
- box->v[BR]->x = box->v[TR]->x;
+ box->v[TL]->x = box->v[BL]->x;
+ box->v[BR]->x = box->v[TR]->x;
}
BLI_INLINE void box_v34y_update(BoxPack *box)
{
- box->v[TL]->y = box->v[TR]->y;
- box->v[BR]->y = box->v[BL]->y;
+ box->v[TL]->y = box->v[TR]->y;
+ box->v[BR]->y = box->v[BL]->y;
}
static void box_xmin_set(BoxPack *box, const float f)
{
- box->v[TR]->x = f + box->w;
- box->v[BL]->x = f;
- box_v34x_update(box);
+ box->v[TR]->x = f + box->w;
+ box->v[BL]->x = f;
+ box_v34x_update(box);
}
static void box_xmax_set(BoxPack *box, const float f)
{
- box->v[BL]->x = f - box->w;
- box->v[TR]->x = f;
- box_v34x_update(box);
+ box->v[BL]->x = f - box->w;
+ box->v[TR]->x = f;
+ box_v34x_update(box);
}
static void box_ymin_set(BoxPack *box, const float f)
{
- box->v[TR]->y = f + box->h;
- box->v[BL]->y = f;
- box_v34y_update(box);
+ box->v[TR]->y = f + box->h;
+ box->v[BL]->y = f;
+ box_v34y_update(box);
}
static void box_ymax_set(BoxPack *box, const float f)
{
- box->v[BL]->y = f - box->h;
- box->v[TR]->y = f;
- box_v34y_update(box);
+ box->v[BL]->y = f - box->h;
+ box->v[TR]->y = f;
+ box_v34y_update(box);
}
/** \} */
-
/** \name Box Utils
* \{ */
static float box_area(const BoxPack *box)
{
- return box->w * box->h;
+ return box->w * box->h;
}
static bool box_isect(const BoxPack *box_a, const BoxPack *box_b)
{
- return !(box_xmin_get(box_a) + EPSILON >= box_xmax_get(box_b) ||
- box_ymin_get(box_a) + EPSILON >= box_ymax_get(box_b) ||
- box_xmax_get(box_a) - EPSILON <= box_xmin_get(box_b) ||
- box_ymax_get(box_a) - EPSILON <= box_ymin_get(box_b));
+ return !(box_xmin_get(box_a) + EPSILON >= box_xmax_get(box_b) ||
+ box_ymin_get(box_a) + EPSILON >= box_ymax_get(box_b) ||
+ box_xmax_get(box_a) - EPSILON <= box_xmin_get(box_b) ||
+ box_ymax_get(box_a) - EPSILON <= box_ymin_get(box_b));
}
/** \} */
-
/* compiler should inline */
-static float max_ff(const float a, const float b) { return b > a ? b : a; }
+static float max_ff(const float a, const float b)
+{
+ return b > a ? b : a;
+}
#ifdef USE_PACK_BIAS
/* set when used is enabled */
static void vert_bias_update(BoxVert *v)
{
- BLI_assert(v->used);
- v->bias = (v->x * v->y) * EPSILON_BIAS;
+ BLI_assert(v->used);
+ v->bias = (v->x * v->y) * EPSILON_BIAS;
}
#endif
#if 0
-#define BOXDEBUG(b) \
- printf("\tBox Debug i %i, w:%.3f h:%.3f x:%.3f y:%.3f\n", \
- b->index, b->w, b->h, b->x, b->y)
+# define BOXDEBUG(b) \
+ printf("\tBox Debug i %i, w:%.3f h:%.3f x:%.3f y:%.3f\n", b->index, b->w, b->h, b->x, b->y)
#endif
/** \name Box/Vert Sorting
@@ -210,13 +208,17 @@ static void vert_bias_update(BoxVert *v)
/* qsort function - sort largest to smallest */
static int box_areasort(const void *p1, const void *p2)
{
- const BoxPack *b1 = p1, *b2 = p2;
- const float a1 = box_area(b1);
- const float a2 = box_area(b2);
-
- if (a1 < a2) { return 1; }
- else if (a1 > a2) { return -1; }
- return 0;
+ const BoxPack *b1 = p1, *b2 = p2;
+ const float a1 = box_area(b1);
+ const float a2 = box_area(b2);
+
+ if (a1 < a2) {
+ return 1;
+ }
+ else if (a1 > a2) {
+ return -1;
+ }
+ return 0;
}
/* qsort vertex sorting function
@@ -225,38 +227,48 @@ static int box_areasort(const void *p1, const void *p2)
* the bounds of the existing backed area where possible
*/
struct VertSortContext {
- BoxVert *vertarray;
- float box_width, box_height;
+ BoxVert *vertarray;
+ float box_width, box_height;
};
static int vertex_sort(const void *p1, const void *p2, void *vs_ctx_p)
{
- const struct VertSortContext *vs_ctx = vs_ctx_p;
- const BoxVert *v1, *v2;
- float a1, a2;
+ const struct VertSortContext *vs_ctx = vs_ctx_p;
+ const BoxVert *v1, *v2;
+ float a1, a2;
- v1 = &vs_ctx->vertarray[*((const uint *)p1)];
- v2 = &vs_ctx->vertarray[*((const uint *)p2)];
+ v1 = &vs_ctx->vertarray[*((const uint *)p1)];
+ v2 = &vs_ctx->vertarray[*((const uint *)p2)];
#ifdef USE_FREE_STRIP
- /* push free verts to the end so we can strip */
- if (UNLIKELY(v1->free == 0 && v2->free == 0)) { return 0; }
- else if (UNLIKELY(v1->free == 0)) { return 1; }
- else if (UNLIKELY(v2->free == 0)) { return -1; }
+ /* push free verts to the end so we can strip */
+ if (UNLIKELY(v1->free == 0 && v2->free == 0)) {
+ return 0;
+ }
+ else if (UNLIKELY(v1->free == 0)) {
+ return 1;
+ }
+ else if (UNLIKELY(v2->free == 0)) {
+ return -1;
+ }
#endif
- a1 = max_ff(v1->x + vs_ctx->box_width, v1->y + vs_ctx->box_height);
- a2 = max_ff(v2->x + vs_ctx->box_width, v2->y + vs_ctx->box_height);
+ a1 = max_ff(v1->x + vs_ctx->box_width, v1->y + vs_ctx->box_height);
+ a2 = max_ff(v2->x + vs_ctx->box_width, v2->y + vs_ctx->box_height);
#ifdef USE_PACK_BIAS
- a1 += v1->bias;
- a2 += v2->bias;
+ a1 += v1->bias;
+ a2 += v2->bias;
#endif
- /* sort largest to smallest */
- if (a1 > a2) { return 1; }
- else if (a1 < a2) { return -1; }
- return 0;
+ /* sort largest to smallest */
+ if (a1 > a2) {
+ return 1;
+ }
+ else if (a1 < a2) {
+ return -1;
+ }
+ return 0;
}
/** \} */
@@ -276,394 +288,388 @@ static int vertex_sort(const void *p1, const void *p2, void *vs_ctx_p)
* */
void BLI_box_pack_2d(BoxPack *boxarray, const uint len, float *r_tot_x, float *r_tot_y)
{
- uint box_index, verts_pack_len, i, j, k;
- uint *vertex_pack_indices; /* an array of indices used for sorting verts */
- bool isect;
- float tot_x = 0.0f, tot_y = 0.0f;
-
- BoxPack *box, *box_test; /*current box and another for intersection tests*/
- BoxVert *vert; /* the current vert */
-
- struct VertSortContext vs_ctx;
-
- if (!len) {
- *r_tot_x = tot_x;
- *r_tot_y = tot_y;
- return;
- }
-
- /* Sort boxes, biggest first */
- qsort(boxarray, (size_t)len, sizeof(BoxPack), box_areasort);
-
- /* add verts to the boxes, these are only used internally */
- vert = MEM_mallocN((size_t)len * 4 * sizeof(BoxVert), "BoxPack Verts");
- vertex_pack_indices = MEM_mallocN((size_t)len * 3 * sizeof(int), "BoxPack Indices");
-
- vs_ctx.vertarray = vert;
-
- for (box = boxarray, box_index = 0, i = 0; box_index < len; box_index++, box++) {
-
- vert->blb = vert->brb = vert->tlb =
- vert->isect_cache[0] = vert->isect_cache[1] =
- vert->isect_cache[2] = vert->isect_cache[3] = NULL;
- vert->free = CORNERFLAGS & ~TRF;
- vert->trb = box;
- vert->used = false;
- vert->index = i++;
- box->v[BL] = vert++;
-
- vert->trb = vert->brb = vert->tlb =
- vert->isect_cache[0] = vert->isect_cache[1] =
- vert->isect_cache[2] = vert->isect_cache[3] = NULL;
- vert->free = CORNERFLAGS & ~BLF;
- vert->blb = box;
- vert->used = false;
- vert->index = i++;
- box->v[TR] = vert++;
-
- vert->trb = vert->blb = vert->tlb =
- vert->isect_cache[0] = vert->isect_cache[1] =
- vert->isect_cache[2] = vert->isect_cache[3] = NULL;
- vert->free = CORNERFLAGS & ~BRF;
- vert->brb = box;
- vert->used = false;
- vert->index = i++;
- box->v[TL] = vert++;
-
- vert->trb = vert->blb = vert->brb =
- vert->isect_cache[0] = vert->isect_cache[1] =
- vert->isect_cache[2] = vert->isect_cache[3] = NULL;
- vert->free = CORNERFLAGS & ~TLF;
- vert->tlb = box;
- vert->used = false;
- vert->index = i++;
- box->v[BR] = vert++;
- }
- vert = NULL;
-
- /* Pack the First box!
- * then enter the main box-packing loop */
-
- box = boxarray; /* get the first box */
- /* First time, no boxes packed */
- box->v[BL]->free = 0; /* Can't use any if these */
- box->v[BR]->free &= ~(BLF | BRF);
- box->v[TL]->free &= ~(BLF | TLF);
-
- tot_x = box->w;
- tot_y = box->h;
-
- /* This sets all the vertex locations */
- box_xmin_set(box, 0.0f);
- box_ymin_set(box, 0.0f);
- box->x = box->y = 0.0f;
-
- for (i = 0; i < 4; i++) {
- box->v[i]->used = true;
+ uint box_index, verts_pack_len, i, j, k;
+ uint *vertex_pack_indices; /* an array of indices used for sorting verts */
+ bool isect;
+ float tot_x = 0.0f, tot_y = 0.0f;
+
+ BoxPack *box, *box_test; /*current box and another for intersection tests*/
+ BoxVert *vert; /* the current vert */
+
+ struct VertSortContext vs_ctx;
+
+ if (!len) {
+ *r_tot_x = tot_x;
+ *r_tot_y = tot_y;
+ return;
+ }
+
+ /* Sort boxes, biggest first */
+ qsort(boxarray, (size_t)len, sizeof(BoxPack), box_areasort);
+
+ /* add verts to the boxes, these are only used internally */
+ vert = MEM_mallocN((size_t)len * 4 * sizeof(BoxVert), "BoxPack Verts");
+ vertex_pack_indices = MEM_mallocN((size_t)len * 3 * sizeof(int), "BoxPack Indices");
+
+ vs_ctx.vertarray = vert;
+
+ for (box = boxarray, box_index = 0, i = 0; box_index < len; box_index++, box++) {
+
+ vert->blb = vert->brb = vert->tlb = vert->isect_cache[0] = vert->isect_cache[1] =
+ vert->isect_cache[2] = vert->isect_cache[3] = NULL;
+ vert->free = CORNERFLAGS & ~TRF;
+ vert->trb = box;
+ vert->used = false;
+ vert->index = i++;
+ box->v[BL] = vert++;
+
+ vert->trb = vert->brb = vert->tlb = vert->isect_cache[0] = vert->isect_cache[1] =
+ vert->isect_cache[2] = vert->isect_cache[3] = NULL;
+ vert->free = CORNERFLAGS & ~BLF;
+ vert->blb = box;
+ vert->used = false;
+ vert->index = i++;
+ box->v[TR] = vert++;
+
+ vert->trb = vert->blb = vert->tlb = vert->isect_cache[0] = vert->isect_cache[1] =
+ vert->isect_cache[2] = vert->isect_cache[3] = NULL;
+ vert->free = CORNERFLAGS & ~BRF;
+ vert->brb = box;
+ vert->used = false;
+ vert->index = i++;
+ box->v[TL] = vert++;
+
+ vert->trb = vert->blb = vert->brb = vert->isect_cache[0] = vert->isect_cache[1] =
+ vert->isect_cache[2] = vert->isect_cache[3] = NULL;
+ vert->free = CORNERFLAGS & ~TLF;
+ vert->tlb = box;
+ vert->used = false;
+ vert->index = i++;
+ box->v[BR] = vert++;
+ }
+ vert = NULL;
+
+ /* Pack the First box!
+ * then enter the main box-packing loop */
+
+ box = boxarray; /* get the first box */
+ /* First time, no boxes packed */
+ box->v[BL]->free = 0; /* Can't use any if these */
+ box->v[BR]->free &= ~(BLF | BRF);
+ box->v[TL]->free &= ~(BLF | TLF);
+
+ tot_x = box->w;
+ tot_y = box->h;
+
+ /* This sets all the vertex locations */
+ box_xmin_set(box, 0.0f);
+ box_ymin_set(box, 0.0f);
+ box->x = box->y = 0.0f;
+
+ for (i = 0; i < 4; i++) {
+ box->v[i]->used = true;
#ifdef USE_PACK_BIAS
- vert_bias_update(box->v[i]);
+ vert_bias_update(box->v[i]);
#endif
- }
+ }
- for (i = 0; i < 3; i++) {
- vertex_pack_indices[i] = box->v[i + 1]->index;
- }
- verts_pack_len = 3;
- box++; /* next box, needed for the loop below */
- /* ...done packing the first box */
+ for (i = 0; i < 3; i++) {
+ vertex_pack_indices[i] = box->v[i + 1]->index;
+ }
+ verts_pack_len = 3;
+ box++; /* next box, needed for the loop below */
+ /* ...done packing the first box */
- /* Main boxpacking loop */
- for (box_index = 1; box_index < len; box_index++, box++) {
+ /* Main boxpacking loop */
+ for (box_index = 1; box_index < len; box_index++, box++) {
- /* These floats are used for sorting re-sorting */
- vs_ctx.box_width = box->w;
- vs_ctx.box_height = box->h;
+ /* These floats are used for sorting re-sorting */
+ vs_ctx.box_width = box->w;
+ vs_ctx.box_height = box->h;
- qsort_r(vertex_pack_indices, (size_t)verts_pack_len, sizeof(int), vertex_sort, &vs_ctx);
+ qsort_r(vertex_pack_indices, (size_t)verts_pack_len, sizeof(int), vertex_sort, &vs_ctx);
#ifdef USE_FREE_STRIP
- /* strip free vertices */
- i = verts_pack_len - 1;
- while ((i != 0) && vs_ctx.vertarray[vertex_pack_indices[i]].free == 0) {
- i--;
- }
- verts_pack_len = i + 1;
+ /* strip free vertices */
+ i = verts_pack_len - 1;
+ while ((i != 0) && vs_ctx.vertarray[vertex_pack_indices[i]].free == 0) {
+ i--;
+ }
+ verts_pack_len = i + 1;
#endif
- /* Pack the box in with the others */
- /* sort the verts */
- isect = true;
-
- for (i = 0; i < verts_pack_len && isect; i++) {
- vert = &vs_ctx.vertarray[vertex_pack_indices[i]];
- /* printf("\ttesting vert %i %i %i %f %f\n", i,
- * vert->free, verts_pack_len, vert->x, vert->y); */
-
- /* This vert has a free quadrant
- * Test if we can place the box here
- * vert->free & quad_flags[j] - Checks
- * */
-
- for (j = 0; (j < 4) && isect; j++) {
- if (vert->free & quad_flag(j)) {
- switch (j) {
- case BL:
- box_xmax_set(box, vert->x);
- box_ymax_set(box, vert->y);
- break;
- case TR:
- box_xmin_set(box, vert->x);
- box_ymin_set(box, vert->y);
- break;
- case TL:
- box_xmax_set(box, vert->x);
- box_ymin_set(box, vert->y);
- break;
- case BR:
- box_xmin_set(box, vert->x);
- box_ymax_set(box, vert->y);
- break;
- }
-
- /* Now we need to check that the box intersects
- * with any other boxes
- * Assume no intersection... */
- isect = false;
-
- if ( /* Constrain boxes to positive X/Y values */
- box_xmin_get(box) < 0.0f || box_ymin_get(box) < 0.0f ||
- /* check for last intersected */
- (vert->isect_cache[j] &&
- box_isect(box, vert->isect_cache[j])))
- {
- /* Here we check that the last intersected
- * box will intersect with this one using
- * isect_cache that can store a pointer to a
- * box for each quadrant
- * big speedup */
- isect = true;
- }
- else {
- /* do a full search for colliding box
- * this is really slow, some spatially divided
- * data-structure would be better */
- for (box_test = boxarray; box_test != box; box_test++) {
- if (box_isect(box, box_test)) {
- /* Store the last intersecting here as cache
- * for faster checking next time around */
- vert->isect_cache[j] = box_test;
- isect = true;
- break;
- }
- }
- }
-
- if (!isect) {
-
- /* maintain the total width and height */
- tot_x = max_ff(box_xmax_get(box), tot_x);
- tot_y = max_ff(box_ymax_get(box), tot_y);
-
- /* Place the box */
- vert->free &= (signed char)(~quad_flag(j));
-
- switch (j) {
- case TR:
- box->v[BL] = vert;
- vert->trb = box;
- break;
- case TL:
- box->v[BR] = vert;
- vert->tlb = box;
- break;
- case BR:
- box->v[TL] = vert;
- vert->brb = box;
- break;
- case BL:
- box->v[TR] = vert;
- vert->blb = box;
- break;
- }
-
- /* Mask free flags for verts that are
- * on the bottom or side so we don't get
- * boxes outside the given rectangle ares
- *
- * We can do an else/if here because only the first
- * box can be at the very bottom left corner */
- if (box_xmin_get(box) <= 0) {
- box->v[TL]->free &= ~(TLF | BLF);
- box->v[BL]->free &= ~(TLF | BLF);
- }
- else if (box_ymin_get(box) <= 0) {
- box->v[BL]->free &= ~(BRF | BLF);
- box->v[BR]->free &= ~(BRF | BLF);
- }
-
- /* The following block of code does a logical
- * check with 2 adjacent boxes, its possible to
- * flag verts on one or both of the boxes
- * as being used by checking the width or
- * height of both boxes */
- if (vert->tlb && vert->trb && (box == vert->tlb || box == vert->trb)) {
- if (UNLIKELY(fabsf(vert->tlb->h - vert->trb->h) < EPSILON_MERGE)) {
+ /* Pack the box in with the others */
+ /* sort the verts */
+ isect = true;
+
+ for (i = 0; i < verts_pack_len && isect; i++) {
+ vert = &vs_ctx.vertarray[vertex_pack_indices[i]];
+ /* printf("\ttesting vert %i %i %i %f %f\n", i,
+ * vert->free, verts_pack_len, vert->x, vert->y); */
+
+ /* This vert has a free quadrant
+ * Test if we can place the box here
+ * vert->free & quad_flags[j] - Checks
+ * */
+
+ for (j = 0; (j < 4) && isect; j++) {
+ if (vert->free & quad_flag(j)) {
+ switch (j) {
+ case BL:
+ box_xmax_set(box, vert->x);
+ box_ymax_set(box, vert->y);
+ break;
+ case TR:
+ box_xmin_set(box, vert->x);
+ box_ymin_set(box, vert->y);
+ break;
+ case TL:
+ box_xmax_set(box, vert->x);
+ box_ymin_set(box, vert->y);
+ break;
+ case BR:
+ box_xmin_set(box, vert->x);
+ box_ymax_set(box, vert->y);
+ break;
+ }
+
+ /* Now we need to check that the box intersects
+ * with any other boxes
+ * Assume no intersection... */
+ isect = false;
+
+ if (/* Constrain boxes to positive X/Y values */
+ box_xmin_get(box) < 0.0f || box_ymin_get(box) < 0.0f ||
+ /* check for last intersected */
+ (vert->isect_cache[j] && box_isect(box, vert->isect_cache[j]))) {
+ /* Here we check that the last intersected
+ * box will intersect with this one using
+ * isect_cache that can store a pointer to a
+ * box for each quadrant
+ * big speedup */
+ isect = true;
+ }
+ else {
+ /* do a full search for colliding box
+ * this is really slow, some spatially divided
+ * data-structure would be better */
+ for (box_test = boxarray; box_test != box; box_test++) {
+ if (box_isect(box, box_test)) {
+ /* Store the last intersecting here as cache
+ * for faster checking next time around */
+ vert->isect_cache[j] = box_test;
+ isect = true;
+ break;
+ }
+ }
+ }
+
+ if (!isect) {
+
+ /* maintain the total width and height */
+ tot_x = max_ff(box_xmax_get(box), tot_x);
+ tot_y = max_ff(box_ymax_get(box), tot_y);
+
+ /* Place the box */
+ vert->free &= (signed char)(~quad_flag(j));
+
+ switch (j) {
+ case TR:
+ box->v[BL] = vert;
+ vert->trb = box;
+ break;
+ case TL:
+ box->v[BR] = vert;
+ vert->tlb = box;
+ break;
+ case BR:
+ box->v[TL] = vert;
+ vert->brb = box;
+ break;
+ case BL:
+ box->v[TR] = vert;
+ vert->blb = box;
+ break;
+ }
+
+ /* Mask free flags for verts that are
+ * on the bottom or side so we don't get
+ * boxes outside the given rectangle ares
+ *
+ * We can do an else/if here because only the first
+ * box can be at the very bottom left corner */
+ if (box_xmin_get(box) <= 0) {
+ box->v[TL]->free &= ~(TLF | BLF);
+ box->v[BL]->free &= ~(TLF | BLF);
+ }
+ else if (box_ymin_get(box) <= 0) {
+ box->v[BL]->free &= ~(BRF | BLF);
+ box->v[BR]->free &= ~(BRF | BLF);
+ }
+
+ /* The following block of code does a logical
+ * check with 2 adjacent boxes, its possible to
+ * flag verts on one or both of the boxes
+ * as being used by checking the width or
+ * height of both boxes */
+ if (vert->tlb && vert->trb && (box == vert->tlb || box == vert->trb)) {
+ if (UNLIKELY(fabsf(vert->tlb->h - vert->trb->h) < EPSILON_MERGE)) {
#ifdef USE_MERGE
# define A (vert->trb->v[TL])
# define B (vert->tlb->v[TR])
# define MASK (BLF | BRF)
- BLI_assert(A->used != B->used);
- if (A->used) {
- A->free &= B->free & ~MASK;
- B = A;
- }
- else {
- B->free &= A->free & ~MASK;
- A = B;
- }
- BLI_assert((A->free & MASK) == 0);
+ BLI_assert(A->used != B->used);
+ if (A->used) {
+ A->free &= B->free & ~MASK;
+ B = A;
+ }
+ else {
+ B->free &= A->free & ~MASK;
+ A = B;
+ }
+ BLI_assert((A->free & MASK) == 0);
# undef A
# undef B
# undef MASK
#else
- vert->tlb->v[TR]->free &= ~BLF;
- vert->trb->v[TL]->free &= ~BRF;
+ vert->tlb->v[TR]->free &= ~BLF;
+ vert->trb->v[TL]->free &= ~BRF;
#endif
- }
- else if (vert->tlb->h > vert->trb->h) {
- vert->trb->v[TL]->free &= ~(TLF | BLF);
- }
- else /* if (vert->tlb->h < vert->trb->h) */ {
- vert->tlb->v[TR]->free &= ~(TRF | BRF);
- }
- }
- else if (vert->blb && vert->brb && (box == vert->blb || box == vert->brb)) {
- if (UNLIKELY(fabsf(vert->blb->h - vert->brb->h) < EPSILON_MERGE)) {
+ }
+ else if (vert->tlb->h > vert->trb->h) {
+ vert->trb->v[TL]->free &= ~(TLF | BLF);
+ }
+ else /* if (vert->tlb->h < vert->trb->h) */ {
+ vert->tlb->v[TR]->free &= ~(TRF | BRF);
+ }
+ }
+ else if (vert->blb && vert->brb && (box == vert->blb || box == vert->brb)) {
+ if (UNLIKELY(fabsf(vert->blb->h - vert->brb->h) < EPSILON_MERGE)) {
#ifdef USE_MERGE
# define A (vert->blb->v[BR])
# define B (vert->brb->v[BL])
# define MASK (TRF | TLF)
- BLI_assert(A->used != B->used);
- if (A->used) {
- A->free &= B->free & ~MASK;
- B = A;
- }
- else {
- B->free &= A->free & ~MASK;
- A = B;
- }
- BLI_assert((A->free & MASK) == 0);
+ BLI_assert(A->used != B->used);
+ if (A->used) {
+ A->free &= B->free & ~MASK;
+ B = A;
+ }
+ else {
+ B->free &= A->free & ~MASK;
+ A = B;
+ }
+ BLI_assert((A->free & MASK) == 0);
# undef A
# undef B
# undef MASK
#else
- vert->blb->v[BR]->free &= ~TRF;
- vert->brb->v[BL]->free &= ~TLF;
+ vert->blb->v[BR]->free &= ~TRF;
+ vert->brb->v[BL]->free &= ~TLF;
#endif
- }
- else if (vert->blb->h > vert->brb->h) {
- vert->brb->v[BL]->free &= ~(TLF | BLF);
- }
- else /* if (vert->blb->h < vert->brb->h) */ {
- vert->blb->v[BR]->free &= ~(TRF | BRF);
- }
- }
- /* Horizontal */
- if (vert->tlb && vert->blb && (box == vert->tlb || box == vert->blb)) {
- if (UNLIKELY(fabsf(vert->tlb->w - vert->blb->w) < EPSILON_MERGE)) {
+ }
+ else if (vert->blb->h > vert->brb->h) {
+ vert->brb->v[BL]->free &= ~(TLF | BLF);
+ }
+ else /* if (vert->blb->h < vert->brb->h) */ {
+ vert->blb->v[BR]->free &= ~(TRF | BRF);
+ }
+ }
+ /* Horizontal */
+ if (vert->tlb && vert->blb && (box == vert->tlb || box == vert->blb)) {
+ if (UNLIKELY(fabsf(vert->tlb->w - vert->blb->w) < EPSILON_MERGE)) {
#ifdef USE_MERGE
# define A (vert->blb->v[TL])
# define B (vert->tlb->v[BL])
# define MASK (TRF | BRF)
- BLI_assert(A->used != B->used);
- if (A->used) {
- A->free &= B->free & ~MASK;
- B = A;
- }
- else {
- B->free &= A->free & ~MASK;
- A = B;
- }
- BLI_assert((A->free & MASK) == 0);
+ BLI_assert(A->used != B->used);
+ if (A->used) {
+ A->free &= B->free & ~MASK;
+ B = A;
+ }
+ else {
+ B->free &= A->free & ~MASK;
+ A = B;
+ }
+ BLI_assert((A->free & MASK) == 0);
# undef A
# undef B
# undef MASK
#else
- vert->blb->v[TL]->free &= ~TRF;
- vert->tlb->v[BL]->free &= ~BRF;
+ vert->blb->v[TL]->free &= ~TRF;
+ vert->tlb->v[BL]->free &= ~BRF;
#endif
- }
- else if (vert->tlb->w > vert->blb->w) {
- vert->blb->v[TL]->free &= ~(TLF | TRF);
- }
- else /* if (vert->tlb->w < vert->blb->w) */ {
- vert->tlb->v[BL]->free &= ~(BLF | BRF);
- }
- }
- else if (vert->trb && vert->brb && (box == vert->trb || box == vert->brb)) {
- if (UNLIKELY(fabsf(vert->trb->w - vert->brb->w) < EPSILON_MERGE)) {
+ }
+ else if (vert->tlb->w > vert->blb->w) {
+ vert->blb->v[TL]->free &= ~(TLF | TRF);
+ }
+ else /* if (vert->tlb->w < vert->blb->w) */ {
+ vert->tlb->v[BL]->free &= ~(BLF | BRF);
+ }
+ }
+ else if (vert->trb && vert->brb && (box == vert->trb || box == vert->brb)) {
+ if (UNLIKELY(fabsf(vert->trb->w - vert->brb->w) < EPSILON_MERGE)) {
#ifdef USE_MERGE
# define A (vert->brb->v[TR])
# define B (vert->trb->v[BR])
# define MASK (TLF | BLF)
- BLI_assert(A->used != B->used);
- if (A->used) {
- A->free &= B->free & ~MASK;
- B = A;
- }
- else {
- B->free &= A->free & ~MASK;
- A = B;
- }
- BLI_assert((A->free & MASK) == 0);
+ BLI_assert(A->used != B->used);
+ if (A->used) {
+ A->free &= B->free & ~MASK;
+ B = A;
+ }
+ else {
+ B->free &= A->free & ~MASK;
+ A = B;
+ }
+ BLI_assert((A->free & MASK) == 0);
# undef A
# undef B
# undef MASK
#else
- vert->brb->v[TR]->free &= ~TLF;
- vert->trb->v[BR]->free &= ~BLF;
+ vert->brb->v[TR]->free &= ~TLF;
+ vert->trb->v[BR]->free &= ~BLF;
#endif
- }
- else if (vert->trb->w > vert->brb->w) {
- vert->brb->v[TR]->free &= ~(TLF | TRF);
- }
- else /* if (vert->trb->w < vert->brb->w) */ {
- vert->trb->v[BR]->free &= ~(BLF | BRF);
- }
- }
- /* End logical check */
-
- for (k = 0; k < 4; k++) {
- if (box->v[k]->used == false) {
- box->v[k]->used = true;
+ }
+ else if (vert->trb->w > vert->brb->w) {
+ vert->brb->v[TR]->free &= ~(TLF | TRF);
+ }
+ else /* if (vert->trb->w < vert->brb->w) */ {
+ vert->trb->v[BR]->free &= ~(BLF | BRF);
+ }
+ }
+ /* End logical check */
+
+ for (k = 0; k < 4; k++) {
+ if (box->v[k]->used == false) {
+ box->v[k]->used = true;
#ifdef USE_PACK_BIAS
- vert_bias_update(box->v[k]);
+ vert_bias_update(box->v[k]);
#endif
- vertex_pack_indices[verts_pack_len] = box->v[k]->index;
- verts_pack_len++;
- }
- }
- /* The Box verts are only used internally
- * Update the box x and y since thats what external
- * functions will see */
- box->x = box_xmin_get(box);
- box->y = box_ymin_get(box);
- }
- }
- }
- }
- }
-
- *r_tot_x = tot_x;
- *r_tot_y = tot_y;
-
- /* free all the verts, not really needed because they shouldn't be
- * touched anymore but accessing the pointers would crash blender */
- for (box_index = 0; box_index < len; box_index++) {
- box = boxarray + box_index;
- box->v[0] = box->v[1] = box->v[2] = box->v[3] = NULL;
- }
- MEM_freeN(vertex_pack_indices);
- MEM_freeN(vs_ctx.vertarray);
+ vertex_pack_indices[verts_pack_len] = box->v[k]->index;
+ verts_pack_len++;
+ }
+ }
+ /* The Box verts are only used internally
+ * Update the box x and y since thats what external
+ * functions will see */
+ box->x = box_xmin_get(box);
+ box->y = box_ymin_get(box);
+ }
+ }
+ }
+ }
+ }
+
+ *r_tot_x = tot_x;
+ *r_tot_y = tot_y;
+
+ /* free all the verts, not really needed because they shouldn't be
+ * touched anymore but accessing the pointers would crash blender */
+ for (box_index = 0; box_index < len; box_index++) {
+ box = boxarray + box_index;
+ box->v[0] = box->v[1] = box->v[2] = box->v[3] = NULL;
+ }
+ MEM_freeN(vertex_pack_indices);
+ MEM_freeN(vs_ctx.vertarray);
}
diff --git a/source/blender/blenlib/intern/buffer.c b/source/blender/blenlib/intern/buffer.c
index 50401fe6091..fb4350501cd 100644
--- a/source/blender/blenlib/intern/buffer.c
+++ b/source/blender/blenlib/intern/buffer.c
@@ -52,38 +52,38 @@
static void *buffer_alloc(BLI_Buffer *buffer, const size_t len)
{
- return MEM_mallocN(buffer->elem_size * len, "BLI_Buffer.data");
+ return MEM_mallocN(buffer->elem_size * len, "BLI_Buffer.data");
}
static void *buffer_realloc(BLI_Buffer *buffer, const size_t len)
{
- return MEM_reallocN_id(buffer->data, buffer->elem_size * len, "BLI_Buffer.data");
+ return MEM_reallocN_id(buffer->data, buffer->elem_size * len, "BLI_Buffer.data");
}
void BLI_buffer_resize(BLI_Buffer *buffer, const size_t new_count)
{
- if (UNLIKELY(new_count > buffer->alloc_count)) {
- if (buffer->flag & BLI_BUFFER_USE_STATIC) {
- void *orig = buffer->data;
-
- buffer->data = buffer_alloc(buffer, new_count);
- memcpy(buffer->data, orig, buffer->elem_size * buffer->count);
- buffer->alloc_count = new_count;
- buffer->flag &= ~BLI_BUFFER_USE_STATIC;
- }
- else {
- if (buffer->alloc_count && (new_count < buffer->alloc_count * 2)) {
- buffer->alloc_count *= 2;
- }
- else {
- buffer->alloc_count = new_count;
- }
-
- buffer->data = buffer_realloc(buffer, buffer->alloc_count);
- }
- }
-
- buffer->count = new_count;
+ if (UNLIKELY(new_count > buffer->alloc_count)) {
+ if (buffer->flag & BLI_BUFFER_USE_STATIC) {
+ void *orig = buffer->data;
+
+ buffer->data = buffer_alloc(buffer, new_count);
+ memcpy(buffer->data, orig, buffer->elem_size * buffer->count);
+ buffer->alloc_count = new_count;
+ buffer->flag &= ~BLI_BUFFER_USE_STATIC;
+ }
+ else {
+ if (buffer->alloc_count && (new_count < buffer->alloc_count * 2)) {
+ buffer->alloc_count *= 2;
+ }
+ else {
+ buffer->alloc_count = new_count;
+ }
+
+ buffer->data = buffer_realloc(buffer, buffer->alloc_count);
+ }
+ }
+
+ buffer->count = new_count;
}
/**
@@ -93,34 +93,34 @@ void BLI_buffer_resize(BLI_Buffer *buffer, const size_t new_count)
*/
void BLI_buffer_reinit(BLI_Buffer *buffer, const size_t new_count)
{
- if (UNLIKELY(new_count > buffer->alloc_count)) {
- if ((buffer->flag & BLI_BUFFER_USE_STATIC) == 0) {
- if (buffer->data) {
- MEM_freeN(buffer->data);
- }
- }
-
- if (buffer->alloc_count && (new_count < buffer->alloc_count * 2)) {
- buffer->alloc_count *= 2;
- }
- else {
- buffer->alloc_count = new_count;
- }
-
- buffer->flag &= ~BLI_BUFFER_USE_STATIC;
- buffer->data = buffer_alloc(buffer, buffer->alloc_count);
- }
-
- buffer->count = new_count;
+ if (UNLIKELY(new_count > buffer->alloc_count)) {
+ if ((buffer->flag & BLI_BUFFER_USE_STATIC) == 0) {
+ if (buffer->data) {
+ MEM_freeN(buffer->data);
+ }
+ }
+
+ if (buffer->alloc_count && (new_count < buffer->alloc_count * 2)) {
+ buffer->alloc_count *= 2;
+ }
+ else {
+ buffer->alloc_count = new_count;
+ }
+
+ buffer->flag &= ~BLI_BUFFER_USE_STATIC;
+ buffer->data = buffer_alloc(buffer, buffer->alloc_count);
+ }
+
+ buffer->count = new_count;
}
/* callers use BLI_buffer_free */
void _bli_buffer_free(BLI_Buffer *buffer)
{
- if ((buffer->flag & BLI_BUFFER_USE_STATIC) == 0) {
- if (buffer->data) {
- MEM_freeN(buffer->data);
- }
- }
- memset(buffer, 0, sizeof(*buffer));
+ if ((buffer->flag & BLI_BUFFER_USE_STATIC) == 0) {
+ if (buffer->data) {
+ MEM_freeN(buffer->data);
+ }
+ }
+ memset(buffer, 0, sizeof(*buffer));
}
diff --git a/source/blender/blenlib/intern/callbacks.c b/source/blender/blenlib/intern/callbacks.c
index 0f84cd588a9..c4f93a9831d 100644
--- a/source/blender/blenlib/intern/callbacks.c
+++ b/source/blender/blenlib/intern/callbacks.c
@@ -28,39 +28,39 @@ static ListBase callback_slots[BLI_CB_EVT_TOT] = {{NULL}};
void BLI_callback_exec(struct Main *bmain, struct ID *self, eCbEvent evt)
{
- ListBase *lb = &callback_slots[evt];
- bCallbackFuncStore *funcstore;
+ ListBase *lb = &callback_slots[evt];
+ bCallbackFuncStore *funcstore;
- for (funcstore = lb->first; funcstore; funcstore = funcstore->next) {
- funcstore->func(bmain, self, funcstore->arg);
- }
+ for (funcstore = lb->first; funcstore; funcstore = funcstore->next) {
+ funcstore->func(bmain, self, funcstore->arg);
+ }
}
void BLI_callback_add(bCallbackFuncStore *funcstore, eCbEvent evt)
{
- ListBase *lb = &callback_slots[evt];
- BLI_addtail(lb, funcstore);
+ ListBase *lb = &callback_slots[evt];
+ BLI_addtail(lb, funcstore);
}
void BLI_callback_global_init(void)
{
- /* do nothing */
+ /* do nothing */
}
/* call on application exit */
void BLI_callback_global_finalize(void)
{
- eCbEvent evt;
- for (evt = 0; evt < BLI_CB_EVT_TOT; evt++) {
- ListBase *lb = &callback_slots[evt];
- bCallbackFuncStore *funcstore;
- bCallbackFuncStore *funcstore_next;
- for (funcstore = lb->first; funcstore; funcstore = funcstore_next) {
- funcstore_next = funcstore->next;
- BLI_remlink(lb, funcstore);
- if (funcstore->alloc) {
- MEM_freeN(funcstore);
- }
- }
- }
+ eCbEvent evt;
+ for (evt = 0; evt < BLI_CB_EVT_TOT; evt++) {
+ ListBase *lb = &callback_slots[evt];
+ bCallbackFuncStore *funcstore;
+ bCallbackFuncStore *funcstore_next;
+ for (funcstore = lb->first; funcstore; funcstore = funcstore_next) {
+ funcstore_next = funcstore->next;
+ BLI_remlink(lb, funcstore);
+ if (funcstore->alloc) {
+ MEM_freeN(funcstore);
+ }
+ }
+ }
}
diff --git a/source/blender/blenlib/intern/convexhull_2d.c b/source/blender/blenlib/intern/convexhull_2d.c
index 87471ea65a5..b37dc73db29 100644
--- a/source/blender/blenlib/intern/convexhull_2d.c
+++ b/source/blender/blenlib/intern/convexhull_2d.c
@@ -18,7 +18,6 @@
* \ingroup bli
*/
-
#include <stdlib.h>
#include <string.h>
@@ -50,7 +49,7 @@
*/
static float is_left(const float p0[2], const float p1[2], const float p2[2])
{
- return (p1[0] - p0[0]) * (p2[1] - p0[1]) - (p2[0] - p0[0]) * (p1[1] - p0[1]);
+ return (p1[0] - p0[0]) * (p2[1] - p0[1]) - (p2[0] - p0[0]) * (p1[1] - p0[1]);
}
/**
@@ -63,120 +62,130 @@ static float is_left(const float p0[2], const float p1[2], const float p2[2])
*/
int BLI_convexhull_2d_sorted(const float (*points)[2], const int n, int r_points[])
{
- /* the output array r_points[] will be used as the stack */
- int bot = 0;
- int top = -1; /* indices for bottom and top of the stack */
- int i; /* array scan index */
- int minmin, minmax;
- int maxmin, maxmax;
- float xmax;
-
- /* Get the indices of points with min x-coord and min|max y-coord */
- float xmin = points[0][0];
- for (i = 1; i < n; i++) {
- if (points[i][0] != xmin) {
- break;
- }
- }
-
- minmin = 0;
- minmax = i - 1;
- if (minmax == n - 1) { /* degenerate case: all x-coords == xmin */
- r_points[++top] = minmin;
- if (points[minmax][1] != points[minmin][1]) {
- /* a nontrivial segment */
- r_points[++top] = minmax;
- }
- r_points[++top] = minmin; /* add polygon endpoint */
- return top + 1;
- }
-
- /* Get the indices of points with max x-coord and min|max y-coord */
-
- maxmax = n - 1;
- xmax = points[n - 1][0];
- for (i = n - 2; i >= 0; i--) {
- if (points[i][0] != xmax) {
- break;
- }
- }
- maxmin = i + 1;
-
- /* Compute the lower hull on the stack r_points */
- r_points[++top] = minmin; /* push minmin point onto stack */
- i = minmax;
- while (++i <= maxmin) {
- /* the lower line joins points[minmin] with points[maxmin] */
- if (is_left(points[minmin], points[maxmin], points[i]) >= 0 && i < maxmin) {
- continue; /* ignore points[i] above or on the lower line */
- }
-
- while (top > 0) { /* there are at least 2 points on the stack */
- /* test if points[i] is left of the line at the stack top */
- if (is_left(points[r_points[top - 1]], points[r_points[top]], points[i]) > 0.0f) {
- break; /* points[i] is a new hull vertex */
- }
- else {
- top--; /* pop top point off stack */
- }
- }
-
- r_points[++top] = i; /* push points[i] onto stack */
- }
-
- /* Next, compute the upper hull on the stack r_points above the bottom hull */
- if (maxmax != maxmin) { /* if distinct xmax points */
- r_points[++top] = maxmax; /* push maxmax point onto stack */
- }
-
- bot = top; /* the bottom point of the upper hull stack */
- i = maxmin;
- while (--i >= minmax) {
- /* the upper line joins points[maxmax] with points[minmax] */
- if (is_left(points[maxmax], points[minmax], points[i]) >= 0 && i > minmax) {
- continue; /* ignore points[i] below or on the upper line */
- }
-
- while (top > bot) { /* at least 2 points on the upper stack */
- /* test if points[i] is left of the line at the stack top */
- if (is_left(points[r_points[top - 1]], points[r_points[top]], points[i]) > 0.0f) {
- break; /* points[i] is a new hull vertex */
- }
- else {
- top--; /* pop top point off stack */
- }
- }
-
- if (points[i][0] == points[r_points[0]][0] && points[i][1] == points[r_points[0]][1]) {
- return top + 1; /* special case (mgomes) */
- }
-
- r_points[++top] = i; /* push points[i] onto stack */
- }
-
- if (minmax != minmin) {
- r_points[++top] = minmin; /* push joining endpoint onto stack */
- }
-
- return top + 1;
+ /* the output array r_points[] will be used as the stack */
+ int bot = 0;
+ int top = -1; /* indices for bottom and top of the stack */
+ int i; /* array scan index */
+ int minmin, minmax;
+ int maxmin, maxmax;
+ float xmax;
+
+ /* Get the indices of points with min x-coord and min|max y-coord */
+ float xmin = points[0][0];
+ for (i = 1; i < n; i++) {
+ if (points[i][0] != xmin) {
+ break;
+ }
+ }
+
+ minmin = 0;
+ minmax = i - 1;
+ if (minmax == n - 1) { /* degenerate case: all x-coords == xmin */
+ r_points[++top] = minmin;
+ if (points[minmax][1] != points[minmin][1]) {
+ /* a nontrivial segment */
+ r_points[++top] = minmax;
+ }
+ r_points[++top] = minmin; /* add polygon endpoint */
+ return top + 1;
+ }
+
+ /* Get the indices of points with max x-coord and min|max y-coord */
+
+ maxmax = n - 1;
+ xmax = points[n - 1][0];
+ for (i = n - 2; i >= 0; i--) {
+ if (points[i][0] != xmax) {
+ break;
+ }
+ }
+ maxmin = i + 1;
+
+ /* Compute the lower hull on the stack r_points */
+ r_points[++top] = minmin; /* push minmin point onto stack */
+ i = minmax;
+ while (++i <= maxmin) {
+ /* the lower line joins points[minmin] with points[maxmin] */
+ if (is_left(points[minmin], points[maxmin], points[i]) >= 0 && i < maxmin) {
+ continue; /* ignore points[i] above or on the lower line */
+ }
+
+ while (top > 0) { /* there are at least 2 points on the stack */
+ /* test if points[i] is left of the line at the stack top */
+ if (is_left(points[r_points[top - 1]], points[r_points[top]], points[i]) > 0.0f) {
+ break; /* points[i] is a new hull vertex */
+ }
+ else {
+ top--; /* pop top point off stack */
+ }
+ }
+
+ r_points[++top] = i; /* push points[i] onto stack */
+ }
+
+ /* Next, compute the upper hull on the stack r_points above the bottom hull */
+ if (maxmax != maxmin) { /* if distinct xmax points */
+ r_points[++top] = maxmax; /* push maxmax point onto stack */
+ }
+
+ bot = top; /* the bottom point of the upper hull stack */
+ i = maxmin;
+ while (--i >= minmax) {
+ /* the upper line joins points[maxmax] with points[minmax] */
+ if (is_left(points[maxmax], points[minmax], points[i]) >= 0 && i > minmax) {
+ continue; /* ignore points[i] below or on the upper line */
+ }
+
+ while (top > bot) { /* at least 2 points on the upper stack */
+ /* test if points[i] is left of the line at the stack top */
+ if (is_left(points[r_points[top - 1]], points[r_points[top]], points[i]) > 0.0f) {
+ break; /* points[i] is a new hull vertex */
+ }
+ else {
+ top--; /* pop top point off stack */
+ }
+ }
+
+ if (points[i][0] == points[r_points[0]][0] && points[i][1] == points[r_points[0]][1]) {
+ return top + 1; /* special case (mgomes) */
+ }
+
+ r_points[++top] = i; /* push points[i] onto stack */
+ }
+
+ if (minmax != minmin) {
+ r_points[++top] = minmin; /* push joining endpoint onto stack */
+ }
+
+ return top + 1;
}
struct PointRef {
- const float *pt; /* 2d vector */
+ const float *pt; /* 2d vector */
};
static int pointref_cmp_yx(const void *a_, const void *b_)
{
- const struct PointRef *a = a_;
- const struct PointRef *b = b_;
-
- if (a->pt[1] > b->pt[1]) { return 1; }
- else if (a->pt[1] < b->pt[1]) { return -1; }
-
- if (a->pt[0] > b->pt[0]) { return 1; }
- else if (a->pt[0] < b->pt[0]) { return -1; }
-
- else { return 0; }
+ const struct PointRef *a = a_;
+ const struct PointRef *b = b_;
+
+ if (a->pt[1] > b->pt[1]) {
+ return 1;
+ }
+ else if (a->pt[1] < b->pt[1]) {
+ return -1;
+ }
+
+ if (a->pt[0] > b->pt[0]) {
+ return 1;
+ }
+ else if (a->pt[0] < b->pt[0]) {
+ return -1;
+ }
+
+ else {
+ return 0;
+ }
}
/**
@@ -191,41 +200,40 @@ static int pointref_cmp_yx(const void *a_, const void *b_)
*/
int BLI_convexhull_2d(const float (*points)[2], const int n, int r_points[])
{
- struct PointRef *points_ref = MEM_mallocN(sizeof(*points_ref) * (size_t)n, __func__);
- float (*points_sort)[2] = MEM_mallocN(sizeof(*points_sort) * (size_t)n, __func__);
- int *points_map;
- int tot, i;
+ struct PointRef *points_ref = MEM_mallocN(sizeof(*points_ref) * (size_t)n, __func__);
+ float(*points_sort)[2] = MEM_mallocN(sizeof(*points_sort) * (size_t)n, __func__);
+ int *points_map;
+ int tot, i;
- for (i = 0; i < n; i++) {
- points_ref[i].pt = points[i];
- }
+ for (i = 0; i < n; i++) {
+ points_ref[i].pt = points[i];
+ }
- /* Sort the points by X, then by Y (required by the algorithm) */
- qsort(points_ref, (size_t)n, sizeof(struct PointRef), pointref_cmp_yx);
+ /* Sort the points by X, then by Y (required by the algorithm) */
+ qsort(points_ref, (size_t)n, sizeof(struct PointRef), pointref_cmp_yx);
- for (i = 0; i < n; i++) {
- memcpy(points_sort[i], points_ref[i].pt, sizeof(float[2]));
- }
+ for (i = 0; i < n; i++) {
+ memcpy(points_sort[i], points_ref[i].pt, sizeof(float[2]));
+ }
- tot = BLI_convexhull_2d_sorted(points_sort, n, r_points);
+ tot = BLI_convexhull_2d_sorted(points_sort, n, r_points);
- /* map back to the original index values */
- points_map = (int *)points_sort; /* abuse float array for temp storage */
- for (i = 0; i < tot; i++) {
- points_map[i] = (int)((const float(*)[2])points_ref[r_points[i]].pt - points);
- }
+ /* map back to the original index values */
+ points_map = (int *)points_sort; /* abuse float array for temp storage */
+ for (i = 0; i < tot; i++) {
+ points_map[i] = (int)((const float(*)[2])points_ref[r_points[i]].pt - points);
+ }
- memcpy(r_points, points_map, (size_t)tot * sizeof(*points_map));
+ memcpy(r_points, points_map, (size_t)tot * sizeof(*points_map));
- MEM_freeN(points_ref);
- MEM_freeN(points_sort);
+ MEM_freeN(points_ref);
+ MEM_freeN(points_sort);
- return tot;
+ return tot;
}
/** \} */
-
/* -------------------------------------------------------------------- */
/* Helper functions */
@@ -244,49 +252,49 @@ int BLI_convexhull_2d(const float (*points)[2], const int n, int r_points[])
*/
float BLI_convexhull_aabb_fit_hull_2d(const float (*points_hull)[2], unsigned int n)
{
- unsigned int i, i_prev;
- float area_best = FLT_MAX;
- float dvec_best[2]; /* best angle, delay atan2 */
-
- i_prev = n - 1;
- for (i = 0; i < n; i++) {
- const float *ev_a = points_hull[i];
- const float *ev_b = points_hull[i_prev];
- float dvec[2]; /* 2d rotation matrix */
-
- sub_v2_v2v2(dvec, ev_a, ev_b);
- if (normalize_v2(dvec) != 0.0f) {
- /* rotation matrix */
- float min[2] = {FLT_MAX, FLT_MAX}, max[2] = {-FLT_MAX, -FLT_MAX};
- unsigned int j;
- float area;
-
- for (j = 0; j < n; j++) {
- float tvec[2];
- mul_v2_v2_cw(tvec, dvec, points_hull[j]);
-
- min[0] = min_ff(min[0], tvec[0]);
- min[1] = min_ff(min[1], tvec[1]);
-
- max[0] = max_ff(max[0], tvec[0]);
- max[1] = max_ff(max[1], tvec[1]);
-
- area = (max[0] - min[0]) * (max[1] - min[1]);
- if (area > area_best) {
- break;
- }
- }
-
- if (area < area_best) {
- area_best = area;
- copy_v2_v2(dvec_best, dvec);
- }
- }
-
- i_prev = i;
- }
-
- return (area_best != FLT_MAX) ? atan2f(dvec_best[0], dvec_best[1]) : 0.0f;
+ unsigned int i, i_prev;
+ float area_best = FLT_MAX;
+ float dvec_best[2]; /* best angle, delay atan2 */
+
+ i_prev = n - 1;
+ for (i = 0; i < n; i++) {
+ const float *ev_a = points_hull[i];
+ const float *ev_b = points_hull[i_prev];
+ float dvec[2]; /* 2d rotation matrix */
+
+ sub_v2_v2v2(dvec, ev_a, ev_b);
+ if (normalize_v2(dvec) != 0.0f) {
+ /* rotation matrix */
+ float min[2] = {FLT_MAX, FLT_MAX}, max[2] = {-FLT_MAX, -FLT_MAX};
+ unsigned int j;
+ float area;
+
+ for (j = 0; j < n; j++) {
+ float tvec[2];
+ mul_v2_v2_cw(tvec, dvec, points_hull[j]);
+
+ min[0] = min_ff(min[0], tvec[0]);
+ min[1] = min_ff(min[1], tvec[1]);
+
+ max[0] = max_ff(max[0], tvec[0]);
+ max[1] = max_ff(max[1], tvec[1]);
+
+ area = (max[0] - min[0]) * (max[1] - min[1]);
+ if (area > area_best) {
+ break;
+ }
+ }
+
+ if (area < area_best) {
+ area_best = area;
+ copy_v2_v2(dvec_best, dvec);
+ }
+ }
+
+ i_prev = i;
+ }
+
+ return (area_best != FLT_MAX) ? atan2f(dvec_best[0], dvec_best[1]) : 0.0f;
}
/**
@@ -296,34 +304,34 @@ float BLI_convexhull_aabb_fit_hull_2d(const float (*points_hull)[2], unsigned in
*/
float BLI_convexhull_aabb_fit_points_2d(const float (*points)[2], unsigned int n)
{
- int *index_map;
- int tot;
+ int *index_map;
+ int tot;
- float angle;
+ float angle;
- index_map = MEM_mallocN(sizeof(*index_map) * n * 2, __func__);
+ index_map = MEM_mallocN(sizeof(*index_map) * n * 2, __func__);
- tot = BLI_convexhull_2d(points, (int)n, index_map);
+ tot = BLI_convexhull_2d(points, (int)n, index_map);
- if (tot) {
- float (*points_hull)[2];
- int j;
+ if (tot) {
+ float(*points_hull)[2];
+ int j;
- points_hull = MEM_mallocN(sizeof(*points_hull) * (size_t)tot, __func__);
- for (j = 0; j < tot; j++) {
- copy_v2_v2(points_hull[j], points[index_map[j]]);
- }
+ points_hull = MEM_mallocN(sizeof(*points_hull) * (size_t)tot, __func__);
+ for (j = 0; j < tot; j++) {
+ copy_v2_v2(points_hull[j], points[index_map[j]]);
+ }
- angle = BLI_convexhull_aabb_fit_hull_2d(points_hull, (unsigned int)tot);
- MEM_freeN(points_hull);
- }
- else {
- angle = 0.0f;
- }
+ angle = BLI_convexhull_aabb_fit_hull_2d(points_hull, (unsigned int)tot);
+ MEM_freeN(points_hull);
+ }
+ else {
+ angle = 0.0f;
+ }
- MEM_freeN(index_map);
+ MEM_freeN(index_map);
- return angle;
+ return angle;
}
/** \} */
diff --git a/source/blender/blenlib/intern/dynlib.c b/source/blender/blenlib/intern/dynlib.c
index 31f8d9d3d57..c648a212fef 100644
--- a/source/blender/blenlib/intern/dynlib.c
+++ b/source/blender/blenlib/intern/dynlib.c
@@ -30,106 +30,109 @@
#include "BLI_dynlib.h"
struct DynamicLibrary {
- void *handle;
+ void *handle;
};
#ifdef WIN32
-#ifndef _WIN32_WINNT
-#define _WIN32_WINNT 0x501 /* Windows XP or newer */
-#endif
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include "utf_winfunc.h"
-#include "utfconv.h"
+# ifndef _WIN32_WINNT
+# define _WIN32_WINNT 0x501 /* Windows XP or newer */
+# endif
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+# include "utf_winfunc.h"
+# include "utfconv.h"
DynamicLibrary *BLI_dynlib_open(const char *name)
{
- DynamicLibrary *lib;
- void *handle;
+ DynamicLibrary *lib;
+ void *handle;
- UTF16_ENCODE(name);
- handle = LoadLibraryW(name_16);
- UTF16_UN_ENCODE(name);
+ UTF16_ENCODE(name);
+ handle = LoadLibraryW(name_16);
+ UTF16_UN_ENCODE(name);
- if (!handle) {
- return NULL;
- }
+ if (!handle) {
+ return NULL;
+ }
- lib = MEM_callocN(sizeof(*lib), "Dynamic Library");
- lib->handle = handle;
+ lib = MEM_callocN(sizeof(*lib), "Dynamic Library");
+ lib->handle = handle;
- return lib;
+ return lib;
}
void *BLI_dynlib_find_symbol(DynamicLibrary *lib, const char *symname)
{
- return GetProcAddress(lib->handle, symname);
+ return GetProcAddress(lib->handle, symname);
}
char *BLI_dynlib_get_error_as_string(DynamicLibrary *lib)
{
- int err;
-
- /* if lib is NULL reset the last error code */
- err = GetLastError();
- if (!lib) {
- SetLastError(ERROR_SUCCESS);
- }
-
- if (err) {
- static char buf[1024];
-
- if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
- NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- buf, sizeof(buf), NULL))
- {
- return buf;
- }
- }
-
- return NULL;
+ int err;
+
+ /* if lib is NULL reset the last error code */
+ err = GetLastError();
+ if (!lib) {
+ SetLastError(ERROR_SUCCESS);
+ }
+
+ if (err) {
+ static char buf[1024];
+
+ if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ err,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ buf,
+ sizeof(buf),
+ NULL)) {
+ return buf;
+ }
+ }
+
+ return NULL;
}
void BLI_dynlib_close(DynamicLibrary *lib)
{
- FreeLibrary(lib->handle);
- MEM_freeN(lib);
+ FreeLibrary(lib->handle);
+ MEM_freeN(lib);
}
#else /* Unix */
-#include <dlfcn.h>
+# include <dlfcn.h>
DynamicLibrary *BLI_dynlib_open(const char *name)
{
- DynamicLibrary *lib;
- void *handle = dlopen(name, RTLD_LAZY);
+ DynamicLibrary *lib;
+ void *handle = dlopen(name, RTLD_LAZY);
- if (!handle) {
- return NULL;
- }
+ if (!handle) {
+ return NULL;
+ }
- lib = MEM_callocN(sizeof(*lib), "Dynamic Library");
- lib->handle = handle;
+ lib = MEM_callocN(sizeof(*lib), "Dynamic Library");
+ lib->handle = handle;
- return lib;
+ return lib;
}
void *BLI_dynlib_find_symbol(DynamicLibrary *lib, const char *symname)
{
- return dlsym(lib->handle, symname);
+ return dlsym(lib->handle, symname);
}
char *BLI_dynlib_get_error_as_string(DynamicLibrary *lib)
{
- (void)lib; /* unused */
- return dlerror();
+ (void)lib; /* unused */
+ return dlerror();
}
void BLI_dynlib_close(DynamicLibrary *lib)
{
- dlclose(lib->handle);
- MEM_freeN(lib);
+ dlclose(lib->handle);
+ MEM_freeN(lib);
}
#endif
diff --git a/source/blender/blenlib/intern/easing.c b/source/blender/blenlib/intern/easing.c
index 99077eddc4e..9532f78bd44 100644
--- a/source/blender/blenlib/intern/easing.c
+++ b/source/blender/blenlib/intern/easing.c
@@ -34,111 +34,114 @@
#include "BLI_math_base.h"
-#include "BLI_easing.h" /* own include */
+#include "BLI_easing.h" /* own include */
#include "BLI_strict_flags.h"
/* blend if (amplitude < fabsf(change) */
#define USE_ELASTIC_BLEND
-float BLI_easing_back_ease_in(float time, float begin, float change, float duration, float overshoot)
+float BLI_easing_back_ease_in(
+ float time, float begin, float change, float duration, float overshoot)
{
- time /= duration;
- return change * time * time * ((overshoot + 1) * time - overshoot) + begin;
+ time /= duration;
+ return change * time * time * ((overshoot + 1) * time - overshoot) + begin;
}
-float BLI_easing_back_ease_out(float time, float begin, float change, float duration, float overshoot)
+float BLI_easing_back_ease_out(
+ float time, float begin, float change, float duration, float overshoot)
{
- time = time / duration - 1;
- return change * (time * time * ((overshoot + 1) * time + overshoot) + 1) + begin;
+ time = time / duration - 1;
+ return change * (time * time * ((overshoot + 1) * time + overshoot) + 1) + begin;
}
-float BLI_easing_back_ease_in_out(float time, float begin, float change, float duration, float overshoot)
+float BLI_easing_back_ease_in_out(
+ float time, float begin, float change, float duration, float overshoot)
{
- overshoot *= 1.525f;
- if ((time /= duration / 2) < 1.0f) {
- return change / 2 * (time * time * ((overshoot + 1) * time - overshoot)) + begin;
- }
- time -= 2.0f;
- return change / 2 * (time * time * ((overshoot + 1) * time + overshoot) + 2) + begin;
-
+ overshoot *= 1.525f;
+ if ((time /= duration / 2) < 1.0f) {
+ return change / 2 * (time * time * ((overshoot + 1) * time - overshoot)) + begin;
+ }
+ time -= 2.0f;
+ return change / 2 * (time * time * ((overshoot + 1) * time + overshoot) + 2) + begin;
}
float BLI_easing_bounce_ease_out(float time, float begin, float change, float duration)
{
- time /= duration;
- if (time < (1 / 2.75f)) {
- return change * (7.5625f * time * time) + begin;
- }
- else if (time < (2 / 2.75f)) {
- time -= (1.5f / 2.75f);
- return change * ((7.5625f * time) * time + 0.75f) + begin;
- }
- else if (time < (2.5f / 2.75f)) {
- time -= (2.25f / 2.75f);
- return change * ((7.5625f * time) * time + 0.9375f) + begin;
- }
- else {
- time -= (2.625f / 2.75f);
- return change * ((7.5625f * time) * time + 0.984375f) + begin;
- }
+ time /= duration;
+ if (time < (1 / 2.75f)) {
+ return change * (7.5625f * time * time) + begin;
+ }
+ else if (time < (2 / 2.75f)) {
+ time -= (1.5f / 2.75f);
+ return change * ((7.5625f * time) * time + 0.75f) + begin;
+ }
+ else if (time < (2.5f / 2.75f)) {
+ time -= (2.25f / 2.75f);
+ return change * ((7.5625f * time) * time + 0.9375f) + begin;
+ }
+ else {
+ time -= (2.625f / 2.75f);
+ return change * ((7.5625f * time) * time + 0.984375f) + begin;
+ }
}
float BLI_easing_bounce_ease_in(float time, float begin, float change, float duration)
{
- return change - BLI_easing_bounce_ease_out(duration - time, 0, change, duration) + begin;
+ return change - BLI_easing_bounce_ease_out(duration - time, 0, change, duration) + begin;
}
float BLI_easing_bounce_ease_in_out(float time, float begin, float change, float duration)
{
- if (time < duration / 2) {
- return BLI_easing_bounce_ease_in(time * 2, 0, change, duration) * 0.5f + begin;
- }
- else {
- return BLI_easing_bounce_ease_out(time * 2 - duration, 0, change, duration) * 0.5f + change * 0.5f + begin;
- }
+ if (time < duration / 2) {
+ return BLI_easing_bounce_ease_in(time * 2, 0, change, duration) * 0.5f + begin;
+ }
+ else {
+ return BLI_easing_bounce_ease_out(time * 2 - duration, 0, change, duration) * 0.5f +
+ change * 0.5f + begin;
+ }
}
float BLI_easing_circ_ease_in(float time, float begin, float change, float duration)
{
- time /= duration;
- return -change * (sqrtf(1 - time * time) - 1) + begin;
+ time /= duration;
+ return -change * (sqrtf(1 - time * time) - 1) + begin;
}
float BLI_easing_circ_ease_out(float time, float begin, float change, float duration)
{
- time = time / duration - 1;
- return change * sqrtf(1 - time * time) + begin;
+ time = time / duration - 1;
+ return change * sqrtf(1 - time * time) + begin;
}
float BLI_easing_circ_ease_in_out(float time, float begin, float change, float duration)
{
- if ((time /= duration / 2) < 1.0f) {
- return -change / 2 * (sqrtf(1 - time * time) - 1) + begin;
- }
- time -= 2.0f;
- return change / 2 * (sqrtf(1 - time * time) + 1) + begin;
+ if ((time /= duration / 2) < 1.0f) {
+ return -change / 2 * (sqrtf(1 - time * time) - 1) + begin;
+ }
+ time -= 2.0f;
+ return change / 2 * (sqrtf(1 - time * time) + 1) + begin;
}
float BLI_easing_cubic_ease_in(float time, float begin, float change, float duration)
{
- time /= duration;
- return change * time * time * time + begin;
+ time /= duration;
+ return change * time * time * time + begin;
}
float BLI_easing_cubic_ease_out(float time, float begin, float change, float duration)
{
- time = time / duration - 1;
- return change * (time * time * time + 1) + begin;
+ time = time / duration - 1;
+ return change * (time * time * time + 1) + begin;
}
float BLI_easing_cubic_ease_in_out(float time, float begin, float change, float duration)
{
- if ((time /= duration / 2) < 1.0f) {
- return change / 2 * time * time * time + begin;
- }
- time -= 2.0f;
- return change / 2 * (time * time * time + 2) + begin;
+ if ((time /= duration / 2) < 1.0f) {
+ return change / 2 * time * time * time + begin;
+ }
+ time -= 2.0f;
+ return change / 2 * (time * time * time + 2) + begin;
}
#ifdef USE_ELASTIC_BLEND
@@ -146,123 +149,135 @@ float BLI_easing_cubic_ease_in_out(float time, float begin, float change, float
* 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)
-{
- if (change) {
- /* Looks like a magic number,
- * but this is a part of the sine curve we need to blend from */
- const float t = fabsf(s);
- if (amplitude) {
- f *= amplitude / fabsf(change);
- }
- else {
- f = 0.0f;
- }
-
- if (fabsf(time * duration) < t) {
- float l = fabsf(time * duration) / t;
- f = (f * l) + (1.0f - l);
- }
- }
-
- return f;
+static float elastic_blend(
+ float time, float change, float duration, float amplitude, float s, float f)
+{
+ if (change) {
+ /* Looks like a magic number,
+ * but this is a part of the sine curve we need to blend from */
+ const float t = fabsf(s);
+ if (amplitude) {
+ f *= amplitude / fabsf(change);
+ }
+ else {
+ f = 0.0f;
+ }
+
+ if (fabsf(time * duration) < t) {
+ float l = fabsf(time * duration) / t;
+ f = (f * l) + (1.0f - l);
+ }
+ }
+
+ return f;
}
#endif
-float BLI_easing_elastic_ease_in(float time, float begin, float change, float duration, float amplitude, float period)
-{
- float s;
- float f = 1.0f;
-
- if (time == 0.0f) {
- return begin;
- }
-
- if ((time /= duration) == 1.0f) {
- return begin + change;
- }
- time -= 1.0f;
- if (!period) {
- period = duration * 0.3f;
- }
- if (!amplitude || amplitude < fabsf(change)) {
- s = period / 4;
+float BLI_easing_elastic_ease_in(
+ float time, float begin, float change, float duration, float amplitude, float period)
+{
+ float s;
+ float f = 1.0f;
+
+ if (time == 0.0f) {
+ return begin;
+ }
+
+ if ((time /= duration) == 1.0f) {
+ return begin + change;
+ }
+ time -= 1.0f;
+ if (!period) {
+ period = duration * 0.3f;
+ }
+ if (!amplitude || amplitude < fabsf(change)) {
+ s = period / 4;
#ifdef USE_ELASTIC_BLEND
- f = elastic_blend(time, change, duration, amplitude, s, f);
+ f = elastic_blend(time, change, duration, amplitude, s, f);
#endif
- amplitude = change;
- }
- else {
- s = period / (2 * (float)M_PI) * asinf(change / amplitude);
- }
-
- return (-f * (amplitude * powf(2, 10 * time) * sinf((time * duration - s) * (2 * (float)M_PI) / period))) + begin;
-}
-
-float BLI_easing_elastic_ease_out(float time, float begin, float change, float duration, float amplitude, float period)
-{
- float s;
- float f = 1.0f;
-
- if (time == 0.0f) {
- return begin;
- }
- if ((time /= duration) == 1.0f) {
- return begin + change;
- }
- time = -time;
- if (!period) {
- period = duration * 0.3f;
- }
- if (!amplitude || amplitude < fabsf(change)) {
- s = period / 4;
+ amplitude = change;
+ }
+ else {
+ s = period / (2 * (float)M_PI) * asinf(change / amplitude);
+ }
+
+ return (-f * (amplitude * powf(2, 10 * time) *
+ sinf((time * duration - s) * (2 * (float)M_PI) / period))) +
+ begin;
+}
+
+float BLI_easing_elastic_ease_out(
+ float time, float begin, float change, float duration, float amplitude, float period)
+{
+ float s;
+ float f = 1.0f;
+
+ if (time == 0.0f) {
+ return begin;
+ }
+ if ((time /= duration) == 1.0f) {
+ return begin + change;
+ }
+ time = -time;
+ if (!period) {
+ period = duration * 0.3f;
+ }
+ if (!amplitude || amplitude < fabsf(change)) {
+ s = period / 4;
#ifdef USE_ELASTIC_BLEND
- f = elastic_blend(time, change, duration, amplitude, s, f);
+ f = elastic_blend(time, change, duration, amplitude, s, f);
#endif
- amplitude = change;
- }
- else {
- s = period / (2 * (float)M_PI) * asinf(change / amplitude);
- }
-
- return (f * (amplitude * powf(2, 10 * time) * sinf((time * duration - s) * (2 * (float)M_PI) / period))) + change + begin;
-}
-
-float BLI_easing_elastic_ease_in_out(float time, float begin, float change, float duration, float amplitude, float period)
-{
- float s;
- float f = 1.0f;
-
- if (time == 0.0f) {
- return begin;
- }
- if ((time /= duration / 2) == 2.0f) {
- return begin + change;
- }
- time -= 1.0f;
- if (!period) {
- period = duration * (0.3f * 1.5f);
- }
- if (!amplitude || amplitude < fabsf(change)) {
- s = period / 4;
+ amplitude = change;
+ }
+ else {
+ s = period / (2 * (float)M_PI) * asinf(change / amplitude);
+ }
+
+ return (f * (amplitude * powf(2, 10 * time) *
+ sinf((time * duration - s) * (2 * (float)M_PI) / period))) +
+ change + begin;
+}
+
+float BLI_easing_elastic_ease_in_out(
+ float time, float begin, float change, float duration, float amplitude, float period)
+{
+ float s;
+ float f = 1.0f;
+
+ if (time == 0.0f) {
+ return begin;
+ }
+ if ((time /= duration / 2) == 2.0f) {
+ return begin + change;
+ }
+ time -= 1.0f;
+ if (!period) {
+ period = duration * (0.3f * 1.5f);
+ }
+ if (!amplitude || amplitude < fabsf(change)) {
+ s = period / 4;
#ifdef USE_ELASTIC_BLEND
- f = elastic_blend(time, change, duration, amplitude, s, f);
+ f = elastic_blend(time, change, duration, amplitude, s, f);
#endif
- amplitude = change;
- }
- else {
- s = period / (2 * (float)M_PI) * asinf(change / amplitude);
- }
-
- if (time < 0.0f) {
- f *= -0.5f;
- return (f * (amplitude * powf(2, 10 * time) * sinf((time * duration - s) * (2 * (float)M_PI) / period))) + begin;
- }
- else {
- time = -time;
- f *= 0.5f;
- return (f * (amplitude * powf(2, 10 * time) * sinf((time * duration - s) * (2 * (float)M_PI) / period))) + change + begin;
- }
+ amplitude = change;
+ }
+ else {
+ s = period / (2 * (float)M_PI) * asinf(change / amplitude);
+ }
+
+ if (time < 0.0f) {
+ f *= -0.5f;
+ return (f * (amplitude * powf(2, 10 * time) *
+ sinf((time * duration - s) * (2 * (float)M_PI) / period))) +
+ begin;
+ }
+ else {
+ time = -time;
+ f *= 0.5f;
+ return (f * (amplitude * powf(2, 10 * time) *
+ sinf((time * duration - s) * (2 * (float)M_PI) / period))) +
+ change + begin;
+ }
}
static const float pow_min = 0.0009765625f; /* = 2^(-10) */
@@ -270,112 +285,110 @@ static const float pow_scale = 1.0f / (1.0f - 0.0009765625f);
float BLI_easing_expo_ease_in(float time, float begin, float change, float duration)
{
- if (time == 0.0) {
- return begin;
- }
- return change * (powf(2, 10 * (time / duration - 1)) - pow_min) * pow_scale + begin;
+ if (time == 0.0) {
+ return begin;
+ }
+ return change * (powf(2, 10 * (time / duration - 1)) - pow_min) * pow_scale + begin;
}
float BLI_easing_expo_ease_out(float time, float begin, float change, float duration)
{
- if (time == 0.0) {
- return begin;
- }
- return change * (1 - (powf(2, -10 * time / duration) - pow_min) * pow_scale) + begin;
+ if (time == 0.0) {
+ return begin;
+ }
+ return change * (1 - (powf(2, -10 * time / duration) - pow_min) * pow_scale) + begin;
}
float BLI_easing_expo_ease_in_out(float time, float begin, float change, float duration)
{
- float duration_half = duration / 2.0f;
- float change_half = change / 2.0f;
- if (time <= duration_half) {
- return BLI_easing_expo_ease_in(
- time, begin, change_half, duration_half);
- }
- else {
- return BLI_easing_expo_ease_out(
- time - duration_half, begin + change_half, change_half, duration_half);
- }
+ float duration_half = duration / 2.0f;
+ float change_half = change / 2.0f;
+ if (time <= duration_half) {
+ return BLI_easing_expo_ease_in(time, begin, change_half, duration_half);
+ }
+ else {
+ return BLI_easing_expo_ease_out(
+ time - duration_half, begin + change_half, change_half, duration_half);
+ }
}
float BLI_easing_linear_ease(float time, float begin, float change, float duration)
{
- return change * time / duration + begin;
+ return change * time / duration + begin;
}
float BLI_easing_quad_ease_in(float time, float begin, float change, float duration)
{
- time /= duration;
- return change * time * time + begin;
+ time /= duration;
+ return change * time * time + begin;
}
float BLI_easing_quad_ease_out(float time, float begin, float change, float duration)
{
- time /= duration;
- return -change * time * (time - 2) + begin;
+ time /= duration;
+ return -change * time * (time - 2) + begin;
}
float BLI_easing_quad_ease_in_out(float time, float begin, float change, float duration)
{
- if ((time /= duration / 2) < 1.0f) {
- return change / 2 * time * time + begin;
- }
- time -= 1.0f;
- return -change / 2 * (time * (time - 2) - 1) + begin;
+ if ((time /= duration / 2) < 1.0f) {
+ return change / 2 * time * time + begin;
+ }
+ time -= 1.0f;
+ return -change / 2 * (time * (time - 2) - 1) + begin;
}
-
float BLI_easing_quart_ease_in(float time, float begin, float change, float duration)
{
- time /= duration;
- return change * time * time * time * time + begin;
+ time /= duration;
+ return change * time * time * time * time + begin;
}
float BLI_easing_quart_ease_out(float time, float begin, float change, float duration)
{
- time = time / duration - 1;
- return -change * (time * time * time * time - 1) + begin;
+ time = time / duration - 1;
+ return -change * (time * time * time * time - 1) + begin;
}
float BLI_easing_quart_ease_in_out(float time, float begin, float change, float duration)
{
- if ((time /= duration / 2) < 1.0f) {
- return change / 2 * time * time * time * time + begin;
- }
- time -= 2.0f;
- return -change / 2 * ( time * time * time * time - 2) + begin;
+ if ((time /= duration / 2) < 1.0f) {
+ return change / 2 * time * time * time * time + begin;
+ }
+ time -= 2.0f;
+ return -change / 2 * (time * time * time * time - 2) + begin;
}
float BLI_easing_quint_ease_in(float time, float begin, float change, float duration)
{
- time /= duration;
- return change * time * time * time * time * time + begin;
+ time /= duration;
+ return change * time * time * time * time * time + begin;
}
float BLI_easing_quint_ease_out(float time, float begin, float change, float duration)
{
- time = time / duration - 1;
- return change * (time * time * time * time * time + 1) + begin;
+ time = time / duration - 1;
+ return change * (time * time * time * time * time + 1) + begin;
}
float BLI_easing_quint_ease_in_out(float time, float begin, float change, float duration)
{
- if ((time /= duration / 2) < 1.0f) {
- return change / 2 * time * time * time * time * time + begin;
- }
- time -= 2.0f;
- return change / 2 * (time * time * time * time * time + 2) + begin;
+ if ((time /= duration / 2) < 1.0f) {
+ return change / 2 * time * time * time * time * time + begin;
+ }
+ time -= 2.0f;
+ return change / 2 * (time * time * time * time * time + 2) + begin;
}
float BLI_easing_sine_ease_in(float time, float begin, float change, float duration)
{
- return -change * cosf(time / duration * (float)M_PI_2) + change + begin;
+ return -change * cosf(time / duration * (float)M_PI_2) + change + begin;
}
float BLI_easing_sine_ease_out(float time, float begin, float change, float duration)
{
- return change * sinf(time / duration * (float)M_PI_2) + begin;
+ return change * sinf(time / duration * (float)M_PI_2) + begin;
}
float BLI_easing_sine_ease_in_out(float time, float begin, float change, float duration)
{
- return -change / 2 * (cosf((float)M_PI * time / duration) - 1) + begin;
+ return -change / 2 * (cosf((float)M_PI * time / duration) - 1) + begin;
}
diff --git a/source/blender/blenlib/intern/edgehash.c b/source/blender/blenlib/intern/edgehash.c
index 564090f734e..528f206c02e 100644
--- a/source/blender/blenlib/intern/edgehash.c
+++ b/source/blender/blenlib/intern/edgehash.c
@@ -37,20 +37,20 @@ typedef struct _EdgeHash_Edge Edge;
typedef struct _EdgeHash_Entry EdgeHashEntry;
typedef struct EdgeHash {
- EdgeHashEntry *entries;
- int32_t *map;
- uint32_t slot_mask;
- uint capacity_exp;
- uint length;
- uint dummy_count;
+ EdgeHashEntry *entries;
+ int32_t *map;
+ uint32_t slot_mask;
+ uint capacity_exp;
+ uint length;
+ uint dummy_count;
} EdgeHash;
typedef struct EdgeSet {
- Edge *entries;
- int32_t *map;
- uint32_t slot_mask;
- uint capacity_exp;
- uint length;
+ Edge *entries;
+ int32_t *map;
+ uint32_t slot_mask;
+ uint capacity_exp;
+ uint length;
} EdgeSet;
/* -------------------------------------------------------------------- */
@@ -59,18 +59,23 @@ typedef struct EdgeSet {
#define ENTRIES_CAPACITY(container) (uint)(1 << (container)->capacity_exp)
#define MAP_CAPACITY(container) (uint)(1 << ((container)->capacity_exp + 1))
-#define CLEAR_MAP(container) memset((container)->map, 0xFF, sizeof(int32_t) * MAP_CAPACITY(container))
-#define UPDATE_SLOT_MASK(container) { (container)->slot_mask = MAP_CAPACITY(container) - 1; } ((void)0)
+#define CLEAR_MAP(container) \
+ memset((container)->map, 0xFF, sizeof(int32_t) * MAP_CAPACITY(container))
+#define UPDATE_SLOT_MASK(container) \
+ { \
+ (container)->slot_mask = MAP_CAPACITY(container) - 1; \
+ } \
+ ((void)0)
#define PERTURB_SHIFT 5
#define ITER_SLOTS(CONTAINER, EDGE, SLOT, INDEX) \
- uint32_t hash = calc_edge_hash(EDGE); \
- uint32_t mask = (CONTAINER)->slot_mask; \
- uint32_t perturb = hash; \
- int32_t *map = (CONTAINER)->map; \
- uint32_t SLOT = mask & hash; \
- int INDEX = map[SLOT]; \
- for (;;SLOT = mask & ((5 * SLOT) + 1 + perturb), perturb >>= PERTURB_SHIFT, INDEX = map[SLOT])
+ uint32_t hash = calc_edge_hash(EDGE); \
+ uint32_t mask = (CONTAINER)->slot_mask; \
+ uint32_t perturb = hash; \
+ int32_t *map = (CONTAINER)->map; \
+ uint32_t SLOT = mask & hash; \
+ int INDEX = map[SLOT]; \
+ for (;; SLOT = mask & ((5 * SLOT) + 1 + perturb), perturb >>= PERTURB_SHIFT, INDEX = map[SLOT])
#define SLOT_EMPTY -1
#define SLOT_DUMMY -2
@@ -85,38 +90,38 @@ typedef struct EdgeSet {
BLI_INLINE uint32_t calc_edge_hash(Edge edge)
{
- return (edge.v_low << 8) ^ edge.v_high;
+ return (edge.v_low << 8) ^ edge.v_high;
}
BLI_INLINE Edge init_edge(uint v0, uint v1)
{
- /* If there are use cases where we need this it could be removed (or flag to allow),
- * for now this helps avoid incorrect usage (creating degenerate geometry). */
- BLI_assert(v0 != v1);
- Edge edge;
- if (v0 < v1) {
- edge.v_low = v0;
- edge.v_high = v1;
- }
- else {
- edge.v_low = v1;
- edge.v_high = v0;
- }
- return edge;
+ /* If there are use cases where we need this it could be removed (or flag to allow),
+ * for now this helps avoid incorrect usage (creating degenerate geometry). */
+ BLI_assert(v0 != v1);
+ Edge edge;
+ if (v0 < v1) {
+ edge.v_low = v0;
+ edge.v_high = v1;
+ }
+ else {
+ edge.v_low = v1;
+ edge.v_high = v0;
+ }
+ return edge;
}
BLI_INLINE bool edges_equal(Edge e1, Edge e2)
{
- return memcmp(&e1, &e2, sizeof(Edge)) == 0;
+ return memcmp(&e1, &e2, sizeof(Edge)) == 0;
}
static uint calc_capacity_exp_for_reserve(uint reserve)
{
- uint result = 1;
- while (reserve >>= 1) {
- result++;
- }
- return result;
+ uint result = 1;
+ while (reserve >>= 1) {
+ result++;
+ }
+ return result;
}
/** \} */
@@ -125,89 +130,94 @@ static uint calc_capacity_exp_for_reserve(uint reserve)
/** \name Internal Utility API
* \{ */
-#define EH_INDEX_HAS_EDGE(eh, index, edge) ((index) >= 0 && edges_equal((edge), (eh)->entries[index].edge))
+#define EH_INDEX_HAS_EDGE(eh, index, edge) \
+ ((index) >= 0 && edges_equal((edge), (eh)->entries[index].edge))
static void edgehash_free_values(EdgeHash *eh, EdgeHashFreeFP free_value)
{
- if (free_value) {
- for (uint i = 0; i < eh->length; i++) {
- free_value(eh->entries[i].value);
- }
- }
+ if (free_value) {
+ for (uint i = 0; i < eh->length; i++) {
+ free_value(eh->entries[i].value);
+ }
+ }
}
BLI_INLINE void edgehash_insert_index(EdgeHash *eh, Edge edge, uint entry_index)
{
- ITER_SLOTS(eh, edge, slot, index) {
- if (index == SLOT_EMPTY) {
- eh->map[slot] = (int32_t)entry_index;
- break;
- }
- }
+ ITER_SLOTS(eh, edge, slot, index)
+ {
+ if (index == SLOT_EMPTY) {
+ eh->map[slot] = (int32_t)entry_index;
+ break;
+ }
+ }
}
BLI_INLINE EdgeHashEntry *edgehash_insert_at_slot(EdgeHash *eh, uint slot, Edge edge, void *value)
{
- EdgeHashEntry *entry = &eh->entries[eh->length];
- entry->edge = edge;
- entry->value = value;
- eh->map[slot] = (int32_t)eh->length;
- eh->length++;
- return entry;
+ EdgeHashEntry *entry = &eh->entries[eh->length];
+ entry->edge = edge;
+ entry->value = value;
+ eh->map[slot] = (int32_t)eh->length;
+ eh->length++;
+ return entry;
}
BLI_INLINE bool edgehash_ensure_can_insert(EdgeHash *eh)
{
- if (UNLIKELY(ENTRIES_CAPACITY(eh) <= eh->length + eh->dummy_count)) {
- eh->capacity_exp++;
- UPDATE_SLOT_MASK(eh);
- eh->dummy_count = 0;
- eh->entries = MEM_reallocN(eh->entries, sizeof(EdgeHashEntry) * ENTRIES_CAPACITY(eh));
- eh->map = MEM_reallocN(eh->map, sizeof(int32_t) * MAP_CAPACITY(eh));
- CLEAR_MAP(eh);
- for (uint i = 0; i < eh->length; i++) {
- edgehash_insert_index(eh, eh->entries[i].edge, i);
- }
- return true;
- }
- return false;
+ if (UNLIKELY(ENTRIES_CAPACITY(eh) <= eh->length + eh->dummy_count)) {
+ eh->capacity_exp++;
+ UPDATE_SLOT_MASK(eh);
+ eh->dummy_count = 0;
+ eh->entries = MEM_reallocN(eh->entries, sizeof(EdgeHashEntry) * ENTRIES_CAPACITY(eh));
+ eh->map = MEM_reallocN(eh->map, sizeof(int32_t) * MAP_CAPACITY(eh));
+ CLEAR_MAP(eh);
+ for (uint i = 0; i < eh->length; i++) {
+ edgehash_insert_index(eh, eh->entries[i].edge, i);
+ }
+ return true;
+ }
+ return false;
}
BLI_INLINE EdgeHashEntry *edgehash_insert(EdgeHash *eh, Edge edge, void *value)
{
- ITER_SLOTS(eh, edge, slot, index) {
- if (index == SLOT_EMPTY) {
- return edgehash_insert_at_slot(eh, slot, edge, value);
- }
- else if (index == SLOT_DUMMY) {
- eh->dummy_count--;
- return edgehash_insert_at_slot(eh, slot, edge, value);
- }
- }
+ ITER_SLOTS(eh, edge, slot, index)
+ {
+ if (index == SLOT_EMPTY) {
+ return edgehash_insert_at_slot(eh, slot, edge, value);
+ }
+ else if (index == SLOT_DUMMY) {
+ eh->dummy_count--;
+ return edgehash_insert_at_slot(eh, slot, edge, value);
+ }
+ }
}
BLI_INLINE EdgeHashEntry *edgehash_lookup_entry(EdgeHash *eh, uint v0, uint v1)
{
- Edge edge = init_edge(v0, v1);
+ Edge edge = init_edge(v0, v1);
- ITER_SLOTS(eh, edge, slot, index) {
- if (EH_INDEX_HAS_EDGE(eh, index, edge)) {
- return &eh->entries[index];
- }
- else if (index == SLOT_EMPTY) {
- return NULL;
- }
- }
+ ITER_SLOTS(eh, edge, slot, index)
+ {
+ if (EH_INDEX_HAS_EDGE(eh, index, edge)) {
+ return &eh->entries[index];
+ }
+ else if (index == SLOT_EMPTY) {
+ return NULL;
+ }
+ }
}
BLI_INLINE void edgehash_change_index(EdgeHash *eh, Edge edge, int new_index)
{
- ITER_SLOTS(eh, edge, slot, index) {
- if (EH_INDEX_HAS_EDGE(eh, index, edge)) {
- eh->map[slot] = new_index;
- break;
- }
- }
+ ITER_SLOTS(eh, edge, slot, index)
+ {
+ if (EH_INDEX_HAS_EDGE(eh, index, edge)) {
+ eh->map[slot] = new_index;
+ break;
+ }
+ }
}
/** \} */
@@ -218,52 +228,51 @@ BLI_INLINE void edgehash_change_index(EdgeHash *eh, Edge edge, int new_index)
EdgeHash *BLI_edgehash_new_ex(const char *info, const uint reserve)
{
- EdgeHash *eh = MEM_mallocN(sizeof(EdgeHash), info);
- eh->capacity_exp = calc_capacity_exp_for_reserve(reserve);
- UPDATE_SLOT_MASK(eh);
- eh->length = 0;
- eh->dummy_count = 0;
- eh->entries = MEM_calloc_arrayN(sizeof(EdgeHashEntry), ENTRIES_CAPACITY(eh), "eh entries");
- eh->map = MEM_malloc_arrayN(sizeof(int32_t), MAP_CAPACITY(eh), "eh map");
- CLEAR_MAP(eh);
- return eh;
+ EdgeHash *eh = MEM_mallocN(sizeof(EdgeHash), info);
+ eh->capacity_exp = calc_capacity_exp_for_reserve(reserve);
+ UPDATE_SLOT_MASK(eh);
+ eh->length = 0;
+ eh->dummy_count = 0;
+ eh->entries = MEM_calloc_arrayN(sizeof(EdgeHashEntry), ENTRIES_CAPACITY(eh), "eh entries");
+ eh->map = MEM_malloc_arrayN(sizeof(int32_t), MAP_CAPACITY(eh), "eh map");
+ CLEAR_MAP(eh);
+ return eh;
}
EdgeHash *BLI_edgehash_new(const char *info)
{
- return BLI_edgehash_new_ex(info, 1 << CAPACITY_EXP_DEFAULT);
+ return BLI_edgehash_new_ex(info, 1 << CAPACITY_EXP_DEFAULT);
}
void BLI_edgehash_free(EdgeHash *eh, EdgeHashFreeFP free_value)
{
- edgehash_free_values(eh, free_value);
- MEM_freeN(eh->map);
- MEM_freeN(eh->entries);
- MEM_freeN(eh);
+ edgehash_free_values(eh, free_value);
+ MEM_freeN(eh->map);
+ MEM_freeN(eh->entries);
+ MEM_freeN(eh);
}
void BLI_edgehash_print(EdgeHash *eh)
{
- printf("Edgehash at %p:\n", eh);
- printf(" Map:\n");
- for (uint i = 0; i < MAP_CAPACITY(eh); i++) {
- int index = eh->map[i];
- printf(" %u: %d", i, index);
- if (index >= 0) {
- EdgeHashEntry entry = eh->entries[index];
- printf(" -> (%u, %u) -> %p", entry.edge.v_low, entry.edge.v_high, entry.value);
- }
- printf("\n");
- }
- printf(" Entries:\n");
- for (uint i = 0; i < ENTRIES_CAPACITY(eh); i++) {
- if (i == eh->length) {
- printf(" **** below is rest capacity ****\n");
- }
- EdgeHashEntry entry = eh->entries[i];
- printf(" %u: (%u, %u) -> %p\n", i, entry.edge.v_low, entry.edge.v_high, entry.value);
-
- }
+ printf("Edgehash at %p:\n", eh);
+ printf(" Map:\n");
+ for (uint i = 0; i < MAP_CAPACITY(eh); i++) {
+ int index = eh->map[i];
+ printf(" %u: %d", i, index);
+ if (index >= 0) {
+ EdgeHashEntry entry = eh->entries[index];
+ printf(" -> (%u, %u) -> %p", entry.edge.v_low, entry.edge.v_high, entry.value);
+ }
+ printf("\n");
+ }
+ printf(" Entries:\n");
+ for (uint i = 0; i < ENTRIES_CAPACITY(eh); i++) {
+ if (i == eh->length) {
+ printf(" **** below is rest capacity ****\n");
+ }
+ EdgeHashEntry entry = eh->entries[i];
+ printf(" %u: (%u, %u) -> %p\n", i, entry.edge.v_low, entry.edge.v_high, entry.value);
+ }
}
/**
@@ -272,9 +281,9 @@ void BLI_edgehash_print(EdgeHash *eh)
*/
void BLI_edgehash_insert(EdgeHash *eh, uint v0, uint v1, void *value)
{
- edgehash_ensure_can_insert(eh);
- Edge edge = init_edge(v0, v1);
- edgehash_insert(eh, edge, value);
+ edgehash_ensure_can_insert(eh);
+ Edge edge = init_edge(v0, v1);
+ edgehash_insert(eh, edge, value);
}
/**
@@ -282,23 +291,24 @@ void BLI_edgehash_insert(EdgeHash *eh, uint v0, uint v1, void *value)
*/
bool BLI_edgehash_reinsert(EdgeHash *eh, uint v0, uint v1, void *value)
{
- Edge edge = init_edge(v0, v1);
-
- ITER_SLOTS(eh, edge, slot, index) {
- if (EH_INDEX_HAS_EDGE(eh, index, edge)) {
- eh->entries[index].value = value;
- return false;
- }
- else if (index == SLOT_EMPTY) {
- if (edgehash_ensure_can_insert(eh)) {
- edgehash_insert(eh, edge, value);
- }
- else {
- edgehash_insert_at_slot(eh, slot, edge, value);
- }
- return true;
- }
- }
+ Edge edge = init_edge(v0, v1);
+
+ ITER_SLOTS(eh, edge, slot, index)
+ {
+ if (EH_INDEX_HAS_EDGE(eh, index, edge)) {
+ eh->entries[index].value = value;
+ return false;
+ }
+ else if (index == SLOT_EMPTY) {
+ if (edgehash_ensure_can_insert(eh)) {
+ edgehash_insert(eh, edge, value);
+ }
+ else {
+ edgehash_insert_at_slot(eh, slot, edge, value);
+ }
+ return true;
+ }
+ }
}
/**
@@ -306,8 +316,8 @@ bool BLI_edgehash_reinsert(EdgeHash *eh, uint v0, uint v1, void *value)
*/
void *BLI_edgehash_lookup_default(EdgeHash *eh, uint v0, uint v1, void *default_value)
{
- EdgeHashEntry *entry = edgehash_lookup_entry(eh, v0, v1);
- return entry ? entry->value : default_value;
+ EdgeHashEntry *entry = edgehash_lookup_entry(eh, v0, v1);
+ return entry ? entry->value : default_value;
}
/**
@@ -318,8 +328,8 @@ void *BLI_edgehash_lookup_default(EdgeHash *eh, uint v0, uint v1, void *default_
*/
void *BLI_edgehash_lookup(EdgeHash *eh, uint v0, uint v1)
{
- EdgeHashEntry *entry = edgehash_lookup_entry(eh, v0, v1);
- return entry ? entry->value : NULL;
+ EdgeHashEntry *entry = edgehash_lookup_entry(eh, v0, v1);
+ return entry ? entry->value : NULL;
}
/**
@@ -328,8 +338,8 @@ void *BLI_edgehash_lookup(EdgeHash *eh, uint v0, uint v1)
*/
void **BLI_edgehash_lookup_p(EdgeHash *eh, uint v0, uint v1)
{
- EdgeHashEntry *entry = edgehash_lookup_entry(eh, v0, v1);
- return entry ? &entry->value : NULL;
+ EdgeHashEntry *entry = edgehash_lookup_entry(eh, v0, v1);
+ return entry ? &entry->value : NULL;
}
/**
@@ -348,23 +358,24 @@ void **BLI_edgehash_lookup_p(EdgeHash *eh, uint v0, uint v1)
*/
bool BLI_edgehash_ensure_p(EdgeHash *eh, uint v0, uint v1, void ***r_value)
{
- Edge edge = init_edge(v0, v1);
-
- ITER_SLOTS(eh, edge, slot, index) {
- if (EH_INDEX_HAS_EDGE(eh, index, edge)) {
- *r_value = &eh->entries[index].value;
- return true;
- }
- else if (index == SLOT_EMPTY) {
- if (edgehash_ensure_can_insert(eh)) {
- *r_value = &edgehash_insert(eh, edge, NULL)->value;
- }
- else {
- *r_value = &edgehash_insert_at_slot(eh, slot, edge, NULL)->value;
- }
- return false;
- }
- }
+ Edge edge = init_edge(v0, v1);
+
+ ITER_SLOTS(eh, edge, slot, index)
+ {
+ if (EH_INDEX_HAS_EDGE(eh, index, edge)) {
+ *r_value = &eh->entries[index].value;
+ return true;
+ }
+ else if (index == SLOT_EMPTY) {
+ if (edgehash_ensure_can_insert(eh)) {
+ *r_value = &edgehash_insert(eh, edge, NULL)->value;
+ }
+ else {
+ *r_value = &edgehash_insert_at_slot(eh, slot, edge, NULL)->value;
+ }
+ return false;
+ }
+ }
}
/**
@@ -376,12 +387,12 @@ bool BLI_edgehash_ensure_p(EdgeHash *eh, uint v0, uint v1, void ***r_value)
*/
bool BLI_edgehash_remove(EdgeHash *eh, uint v0, uint v1, EdgeHashFreeFP free_value)
{
- uint old_length = eh->length;
- void *value = BLI_edgehash_popkey(eh, v0, v1);
- if (free_value && value) {
- free_value(value);
- }
- return old_length > eh->length;
+ uint old_length = eh->length;
+ void *value = BLI_edgehash_popkey(eh, v0, v1);
+ if (free_value && value) {
+ free_value(value);
+ }
+ return old_length > eh->length;
}
/* same as above but return the value,
@@ -394,24 +405,25 @@ bool BLI_edgehash_remove(EdgeHash *eh, uint v0, uint v1, EdgeHashFreeFP free_val
*/
void *BLI_edgehash_popkey(EdgeHash *eh, uint v0, uint v1)
{
- Edge edge = init_edge(v0, v1);
-
- ITER_SLOTS(eh, edge, slot, index) {
- if (EH_INDEX_HAS_EDGE(eh, index, edge)) {
- void *value = eh->entries[index].value;
- eh->length--;
- eh->dummy_count++;
- eh->map[slot] = SLOT_DUMMY;
- eh->entries[index] = eh->entries[eh->length];
- if ((uint)index < eh->length) {
- edgehash_change_index(eh, eh->entries[index].edge, index);
- }
- return value;
- }
- else if (index == SLOT_EMPTY) {
- return NULL;
- }
- }
+ Edge edge = init_edge(v0, v1);
+
+ ITER_SLOTS(eh, edge, slot, index)
+ {
+ if (EH_INDEX_HAS_EDGE(eh, index, edge)) {
+ void *value = eh->entries[index].value;
+ eh->length--;
+ eh->dummy_count++;
+ eh->map[slot] = SLOT_DUMMY;
+ eh->entries[index] = eh->entries[eh->length];
+ if ((uint)index < eh->length) {
+ edgehash_change_index(eh, eh->entries[index].edge, index);
+ }
+ return value;
+ }
+ else if (index == SLOT_EMPTY) {
+ return NULL;
+ }
+ }
}
/**
@@ -419,7 +431,7 @@ void *BLI_edgehash_popkey(EdgeHash *eh, uint v0, uint v1)
*/
bool BLI_edgehash_haskey(EdgeHash *eh, uint v0, uint v1)
{
- return edgehash_lookup_entry(eh, v0, v1) != NULL;
+ return edgehash_lookup_entry(eh, v0, v1) != NULL;
}
/**
@@ -427,7 +439,7 @@ bool BLI_edgehash_haskey(EdgeHash *eh, uint v0, uint v1)
*/
int BLI_edgehash_len(EdgeHash *eh)
{
- return (int)eh->length;
+ return (int)eh->length;
}
/**
@@ -435,12 +447,12 @@ int BLI_edgehash_len(EdgeHash *eh)
*/
void BLI_edgehash_clear_ex(EdgeHash *eh, EdgeHashFreeFP free_value, const uint UNUSED(reserve))
{
- /* TODO: handle reserve */
- edgehash_free_values(eh, free_value);
- eh->length = 0;
- eh->dummy_count = 0;
- eh->capacity_exp = CAPACITY_EXP_DEFAULT;
- CLEAR_MAP(eh);
+ /* TODO: handle reserve */
+ edgehash_free_values(eh, free_value);
+ eh->length = 0;
+ eh->dummy_count = 0;
+ eh->capacity_exp = CAPACITY_EXP_DEFAULT;
+ CLEAR_MAP(eh);
}
/**
@@ -448,7 +460,7 @@ void BLI_edgehash_clear_ex(EdgeHash *eh, EdgeHashFreeFP free_value, const uint U
*/
void BLI_edgehash_clear(EdgeHash *eh, EdgeHashFreeFP free_value)
{
- BLI_edgehash_clear_ex(eh, free_value, 0);
+ BLI_edgehash_clear_ex(eh, free_value, 0);
}
/** \} */
@@ -464,9 +476,9 @@ void BLI_edgehash_clear(EdgeHash *eh, EdgeHashFreeFP free_value)
*/
EdgeHashIterator *BLI_edgehashIterator_new(EdgeHash *eh)
{
- EdgeHashIterator *ehi = MEM_mallocN(sizeof(EdgeHashIterator), __func__);
- BLI_edgehashIterator_init(ehi, eh);
- return ehi;
+ EdgeHashIterator *ehi = MEM_mallocN(sizeof(EdgeHashIterator), __func__);
+ BLI_edgehashIterator_init(ehi, eh);
+ return ehi;
}
/**
@@ -479,9 +491,9 @@ EdgeHashIterator *BLI_edgehashIterator_new(EdgeHash *eh)
*/
void BLI_edgehashIterator_init(EdgeHashIterator *ehi, EdgeHash *eh)
{
- ehi->entries = eh->entries;
- ehi->length = eh->length;
- ehi->index = 0;
+ ehi->entries = eh->entries;
+ ehi->length = eh->length;
+ ehi->index = 0;
}
/**
@@ -489,10 +501,9 @@ void BLI_edgehashIterator_init(EdgeHashIterator *ehi, EdgeHash *eh)
*/
void BLI_edgehashIterator_free(EdgeHashIterator *ehi)
{
- MEM_freeN(ehi);
+ MEM_freeN(ehi);
}
-
/** \} */
/* -------------------------------------------------------------------- */
@@ -501,66 +512,68 @@ void BLI_edgehashIterator_free(EdgeHashIterator *ehi)
* Use edgehash API to give 'set' functionality
* \{ */
-#define ES_INDEX_HAS_EDGE(es, index, edge) (index) >= 0 && edges_equal((edge), (es)->entries[index])
+#define ES_INDEX_HAS_EDGE(es, index, edge) \
+ (index) >= 0 && edges_equal((edge), (es)->entries[index])
EdgeSet *BLI_edgeset_new_ex(const char *info, const uint reserve)
{
- EdgeSet *es = MEM_mallocN(sizeof(EdgeSet), info);
- es->capacity_exp = calc_capacity_exp_for_reserve(reserve);
- UPDATE_SLOT_MASK(es);
- es->length = 0;
- es->entries = MEM_malloc_arrayN(sizeof(Edge), ENTRIES_CAPACITY(es), "es entries");
- es->map = MEM_malloc_arrayN(sizeof(int32_t), MAP_CAPACITY(es), "es map");
- CLEAR_MAP(es);
- return es;
+ EdgeSet *es = MEM_mallocN(sizeof(EdgeSet), info);
+ es->capacity_exp = calc_capacity_exp_for_reserve(reserve);
+ UPDATE_SLOT_MASK(es);
+ es->length = 0;
+ es->entries = MEM_malloc_arrayN(sizeof(Edge), ENTRIES_CAPACITY(es), "es entries");
+ es->map = MEM_malloc_arrayN(sizeof(int32_t), MAP_CAPACITY(es), "es map");
+ CLEAR_MAP(es);
+ return es;
}
EdgeSet *BLI_edgeset_new(const char *info)
{
- return BLI_edgeset_new_ex(info, 1 << CAPACITY_EXP_DEFAULT);
+ return BLI_edgeset_new_ex(info, 1 << CAPACITY_EXP_DEFAULT);
}
void BLI_edgeset_free(EdgeSet *es)
{
- MEM_freeN(es->entries);
- MEM_freeN(es->map);
- MEM_freeN(es);
+ MEM_freeN(es->entries);
+ MEM_freeN(es->map);
+ MEM_freeN(es);
}
int BLI_edgeset_len(EdgeSet *es)
{
- return (int)es->length;
+ return (int)es->length;
}
static void edgeset_insert_index(EdgeSet *es, Edge edge, uint entry_index)
{
- ITER_SLOTS(es, edge, slot, index) {
- if (index == SLOT_EMPTY) {
- es->map[slot] = (int)entry_index;
- break;
- }
- }
+ ITER_SLOTS(es, edge, slot, index)
+ {
+ if (index == SLOT_EMPTY) {
+ es->map[slot] = (int)entry_index;
+ break;
+ }
+ }
}
BLI_INLINE void edgeset_ensure_can_insert(EdgeSet *es)
{
- if (UNLIKELY(ENTRIES_CAPACITY(es) <= es->length)) {
- es->capacity_exp++;
- UPDATE_SLOT_MASK(es);
- es->entries = MEM_reallocN(es->entries, sizeof(Edge) * ENTRIES_CAPACITY(es));
- es->map = MEM_reallocN(es->map, sizeof(int32_t) * MAP_CAPACITY(es));
- CLEAR_MAP(es);
- for (uint i = 0; i < es->length; i++) {
- edgeset_insert_index(es, es->entries[i], i);
- }
- }
+ if (UNLIKELY(ENTRIES_CAPACITY(es) <= es->length)) {
+ es->capacity_exp++;
+ UPDATE_SLOT_MASK(es);
+ es->entries = MEM_reallocN(es->entries, sizeof(Edge) * ENTRIES_CAPACITY(es));
+ es->map = MEM_reallocN(es->map, sizeof(int32_t) * MAP_CAPACITY(es));
+ CLEAR_MAP(es);
+ for (uint i = 0; i < es->length; i++) {
+ edgeset_insert_index(es, es->entries[i], i);
+ }
+ }
}
BLI_INLINE void edgeset_insert_at_slot(EdgeSet *es, uint slot, Edge edge)
{
- es->entries[es->length] = edge;
- es->map[slot] = (int)es->length;
- es->length++;
+ es->entries[es->length] = edge;
+ es->map[slot] = (int)es->length;
+ es->length++;
}
/**
@@ -571,18 +584,19 @@ BLI_INLINE void edgeset_insert_at_slot(EdgeSet *es, uint slot, Edge edge)
*/
bool BLI_edgeset_add(EdgeSet *es, uint v0, uint v1)
{
- edgeset_ensure_can_insert(es);
- Edge edge = init_edge(v0, v1);
+ edgeset_ensure_can_insert(es);
+ Edge edge = init_edge(v0, v1);
- ITER_SLOTS(es, edge, slot, index) {
- if (ES_INDEX_HAS_EDGE(es, index, edge)) {
- return false;
- }
- else if (index == SLOT_EMPTY) {
- edgeset_insert_at_slot(es, slot, edge);
- return true;
- }
- }
+ ITER_SLOTS(es, edge, slot, index)
+ {
+ if (ES_INDEX_HAS_EDGE(es, index, edge)) {
+ return false;
+ }
+ else if (index == SLOT_EMPTY) {
+ edgeset_insert_at_slot(es, slot, edge);
+ return true;
+ }
+ }
}
/**
@@ -591,43 +605,45 @@ bool BLI_edgeset_add(EdgeSet *es, uint v0, uint v1)
*/
void BLI_edgeset_insert(EdgeSet *es, uint v0, uint v1)
{
- edgeset_ensure_can_insert(es);
- Edge edge = init_edge(v0, v1);
+ edgeset_ensure_can_insert(es);
+ Edge edge = init_edge(v0, v1);
- ITER_SLOTS(es, edge, slot, index) {
- if (index == SLOT_EMPTY) {
- edgeset_insert_at_slot(es, slot, edge);
- return;
- }
- }
+ ITER_SLOTS(es, edge, slot, index)
+ {
+ if (index == SLOT_EMPTY) {
+ edgeset_insert_at_slot(es, slot, edge);
+ return;
+ }
+ }
}
bool BLI_edgeset_haskey(EdgeSet *es, uint v0, uint v1)
{
- Edge edge = init_edge(v0, v1);
+ Edge edge = init_edge(v0, v1);
- ITER_SLOTS(es, edge, slot, index) {
- if (ES_INDEX_HAS_EDGE(es, index, edge)) {
- return true;
- }
- else if (index == SLOT_EMPTY) {
- return false;
- }
- }
+ ITER_SLOTS(es, edge, slot, index)
+ {
+ if (ES_INDEX_HAS_EDGE(es, index, edge)) {
+ return true;
+ }
+ else if (index == SLOT_EMPTY) {
+ return false;
+ }
+ }
}
EdgeSetIterator *BLI_edgesetIterator_new(EdgeSet *es)
{
- EdgeSetIterator *esi = MEM_mallocN(sizeof(EdgeSetIterator), __func__);
- esi->edges = es->entries;
- esi->length = es->length;
- esi->index = 0;
- return esi;
+ EdgeSetIterator *esi = MEM_mallocN(sizeof(EdgeSetIterator), __func__);
+ esi->edges = es->entries;
+ esi->length = es->length;
+ esi->index = 0;
+ return esi;
}
void BLI_edgesetIterator_free(EdgeSetIterator *esi)
{
- MEM_freeN(esi);
+ MEM_freeN(esi);
}
/** \} */
diff --git a/source/blender/blenlib/intern/endian_switch.c b/source/blender/blenlib/intern/endian_switch.c
index cc2ffa864f5..09d1d3d0774 100644
--- a/source/blender/blenlib/intern/endian_switch.c
+++ b/source/blender/blenlib/intern/endian_switch.c
@@ -24,81 +24,80 @@
void BLI_endian_switch_int16_array(short *val, const int size)
{
- if (size > 0) {
- int i = size;
- while (i--) {
- BLI_endian_switch_int16(val++);
- }
- }
+ if (size > 0) {
+ int i = size;
+ while (i--) {
+ BLI_endian_switch_int16(val++);
+ }
+ }
}
void BLI_endian_switch_uint16_array(unsigned short *val, const int size)
{
- if (size > 0) {
- int i = size;
- while (i--) {
- BLI_endian_switch_uint16(val++);
- }
- }
+ if (size > 0) {
+ int i = size;
+ while (i--) {
+ BLI_endian_switch_uint16(val++);
+ }
+ }
}
void BLI_endian_switch_int32_array(int *val, const int size)
{
- if (size > 0) {
- int i = size;
- while (i--) {
- BLI_endian_switch_int32(val++);
- }
- }
+ if (size > 0) {
+ int i = size;
+ while (i--) {
+ BLI_endian_switch_int32(val++);
+ }
+ }
}
void BLI_endian_switch_uint32_array(unsigned int *val, const int size)
{
- if (size > 0) {
- int i = size;
- while (i--) {
- BLI_endian_switch_uint32(val++);
- }
- }
+ if (size > 0) {
+ int i = size;
+ while (i--) {
+ BLI_endian_switch_uint32(val++);
+ }
+ }
}
void BLI_endian_switch_float_array(float *val, const int size)
{
- if (size > 0) {
- int i = size;
- while (i--) {
- BLI_endian_switch_float(val++);
- }
- }
+ if (size > 0) {
+ int i = size;
+ while (i--) {
+ BLI_endian_switch_float(val++);
+ }
+ }
}
void BLI_endian_switch_int64_array(int64_t *val, const int size)
{
- if (size > 0) {
- int i = size;
- while (i--) {
- BLI_endian_switch_int64(val++);
- }
- }
+ if (size > 0) {
+ int i = size;
+ while (i--) {
+ BLI_endian_switch_int64(val++);
+ }
+ }
}
void BLI_endian_switch_uint64_array(uint64_t *val, const int size)
{
- if (size > 0) {
- int i = size;
- while (i--) {
- BLI_endian_switch_uint64(val++);
- }
- }
+ if (size > 0) {
+ int i = size;
+ while (i--) {
+ BLI_endian_switch_uint64(val++);
+ }
+ }
}
-
void BLI_endian_switch_double_array(double *val, const int size)
{
- if (size > 0) {
- int i = size;
- while (i--) {
- BLI_endian_switch_double(val++);
- }
- }
+ if (size > 0) {
+ int i = size;
+ while (i--) {
+ BLI_endian_switch_double(val++);
+ }
+ }
}
diff --git a/source/blender/blenlib/intern/expr_pylike_eval.c b/source/blender/blenlib/intern/expr_pylike_eval.c
index 51a004f846f..40df9711ef1 100644
--- a/source/blender/blenlib/intern/expr_pylike_eval.c
+++ b/source/blender/blenlib/intern/expr_pylike_eval.c
@@ -58,7 +58,7 @@
#include "BLI_alloca.h"
#ifdef _MSC_VER
-#pragma fenv_access (on)
+# pragma fenv_access(on)
#endif
/* -------------------------------------------------------------------- */
@@ -66,52 +66,52 @@
* \{ */
typedef enum eOpCode {
- /* Double constant: (-> dval) */
- OPCODE_CONST,
- /* 1 argument function call: (a -> func1(a)) */
- OPCODE_FUNC1,
- /* 2 argument function call: (a b -> func2(a,b)) */
- OPCODE_FUNC2,
- /* Parameter access: (-> params[ival]) */
- OPCODE_PARAMETER,
- /* Minimum of multiple inputs: (a b c... -> min); ival = arg count */
- OPCODE_MIN,
- /* Maximum of multiple inputs: (a b c... -> max); ival = arg count */
- OPCODE_MAX,
- /* Jump (pc += jmp_offset) */
- OPCODE_JMP,
- /* Pop and jump if zero: (a -> ); JUMP IF NOT a */
- OPCODE_JMP_ELSE,
- /* Jump if nonzero, or pop: (a -> a JUMP) IF a ELSE (a -> ) */
- OPCODE_JMP_OR,
- /* Jump if zero, or pop: (a -> a JUMP) IF NOT a ELSE (a -> ) */
- OPCODE_JMP_AND,
- /* For comparison chaining: (a b -> 0 JUMP) IF NOT func2(a,b) ELSE (a b -> b) */
- OPCODE_CMP_CHAIN,
+ /* Double constant: (-> dval) */
+ OPCODE_CONST,
+ /* 1 argument function call: (a -> func1(a)) */
+ OPCODE_FUNC1,
+ /* 2 argument function call: (a b -> func2(a,b)) */
+ OPCODE_FUNC2,
+ /* Parameter access: (-> params[ival]) */
+ OPCODE_PARAMETER,
+ /* Minimum of multiple inputs: (a b c... -> min); ival = arg count */
+ OPCODE_MIN,
+ /* Maximum of multiple inputs: (a b c... -> max); ival = arg count */
+ OPCODE_MAX,
+ /* Jump (pc += jmp_offset) */
+ OPCODE_JMP,
+ /* Pop and jump if zero: (a -> ); JUMP IF NOT a */
+ OPCODE_JMP_ELSE,
+ /* Jump if nonzero, or pop: (a -> a JUMP) IF a ELSE (a -> ) */
+ OPCODE_JMP_OR,
+ /* Jump if zero, or pop: (a -> a JUMP) IF NOT a ELSE (a -> ) */
+ OPCODE_JMP_AND,
+ /* For comparison chaining: (a b -> 0 JUMP) IF NOT func2(a,b) ELSE (a b -> b) */
+ OPCODE_CMP_CHAIN,
} eOpCode;
typedef double (*UnaryOpFunc)(double);
typedef double (*BinaryOpFunc)(double, double);
typedef struct ExprOp {
- eOpCode opcode;
+ eOpCode opcode;
- int jmp_offset;
+ int jmp_offset;
- union {
- int ival;
- double dval;
- void *ptr;
- UnaryOpFunc func1;
- BinaryOpFunc func2;
- } arg;
+ union {
+ int ival;
+ double dval;
+ void *ptr;
+ UnaryOpFunc func1;
+ BinaryOpFunc func2;
+ } arg;
} ExprOp;
struct ExprPyLike_Parsed {
- int ops_count;
- int max_stack;
+ int ops_count;
+ int max_stack;
- ExprOp ops[];
+ ExprOp ops[];
};
/** \} */
@@ -123,21 +123,21 @@ struct ExprPyLike_Parsed {
/** Free the parsed data; NULL argument is ok. */
void BLI_expr_pylike_free(ExprPyLike_Parsed *expr)
{
- if (expr != NULL) {
- MEM_freeN(expr);
- }
+ if (expr != NULL) {
+ MEM_freeN(expr);
+ }
}
/** Check if the parsing result is valid for evaluation. */
bool BLI_expr_pylike_is_valid(ExprPyLike_Parsed *expr)
{
- return expr != NULL && expr->ops_count > 0;
+ return expr != NULL && expr->ops_count > 0;
}
/** Check if the parsed expression always evaluates to the same value. */
bool BLI_expr_pylike_is_constant(ExprPyLike_Parsed *expr)
{
- return expr != NULL && expr->ops_count == 1 && expr->ops[0].opcode == OPCODE_CONST;
+ return expr != NULL && expr->ops_count == 1 && expr->ops[0].opcode == OPCODE_CONST;
}
/** \} */
@@ -150,117 +150,120 @@ bool BLI_expr_pylike_is_constant(ExprPyLike_Parsed *expr)
* Evaluate the expression with the given parameters.
* The order and number of parameters must match the names given to parse.
*/
-eExprPyLike_EvalStatus BLI_expr_pylike_eval(
- ExprPyLike_Parsed *expr,
- const double *param_values, int param_values_len,
- double *r_result)
-{
- *r_result = 0.0;
-
- if (!BLI_expr_pylike_is_valid(expr)) {
- return EXPR_PYLIKE_INVALID;
- }
-
-#define FAIL_IF(condition) if (condition) { return EXPR_PYLIKE_FATAL_ERROR; }
-
- /* Check the stack requirement is at least remotely sane and allocate on the actual stack. */
- FAIL_IF(expr->max_stack <= 0 || expr->max_stack > 1000);
-
- double *stack = BLI_array_alloca(stack, expr->max_stack);
-
- /* Evaluate expression. */
- ExprOp *ops = expr->ops;
- int sp = 0, pc;
-
- feclearexcept(FE_ALL_EXCEPT);
-
- for (pc = 0; pc >= 0 && pc < expr->ops_count; pc++) {
- switch (ops[pc].opcode) {
- /* Arithmetic */
- case OPCODE_CONST:
- FAIL_IF(sp >= expr->max_stack);
- stack[sp++] = ops[pc].arg.dval;
- break;
- case OPCODE_PARAMETER:
- FAIL_IF(sp >= expr->max_stack || ops[pc].arg.ival >= param_values_len);
- stack[sp++] = param_values[ops[pc].arg.ival];
- break;
- case OPCODE_FUNC1:
- FAIL_IF(sp < 1);
- stack[sp - 1] = ops[pc].arg.func1(stack[sp - 1]);
- break;
- case OPCODE_FUNC2:
- FAIL_IF(sp < 2);
- stack[sp - 2] = ops[pc].arg.func2(stack[sp - 2], stack[sp - 1]);
- sp--;
- break;
- case OPCODE_MIN:
- FAIL_IF(sp < ops[pc].arg.ival);
- for (int j = 1; j < ops[pc].arg.ival; j++, sp--) {
- CLAMP_MAX(stack[sp - 2], stack[sp - 1]);
- }
- break;
- case OPCODE_MAX:
- FAIL_IF(sp < ops[pc].arg.ival);
- for (int j = 1; j < ops[pc].arg.ival; j++, sp--) {
- CLAMP_MIN(stack[sp - 2], stack[sp - 1]);
- }
- break;
-
- /* Jumps */
- case OPCODE_JMP:
- pc += ops[pc].jmp_offset;
- break;
- case OPCODE_JMP_ELSE:
- FAIL_IF(sp < 1);
- if (!stack[--sp]) {
- pc += ops[pc].jmp_offset;
- }
- break;
- case OPCODE_JMP_OR:
- case OPCODE_JMP_AND:
- FAIL_IF(sp < 1);
- if (!stack[sp - 1] == !(ops[pc].opcode == OPCODE_JMP_OR)) {
- pc += ops[pc].jmp_offset;
- }
- else {
- sp--;
- }
- break;
-
- /* For chaining comparisons, i.e. "a < b < c" as "a < b and b < c" */
- case OPCODE_CMP_CHAIN:
- FAIL_IF(sp < 2);
- /* If comparison fails, return 0 and jump to end. */
- if (!ops[pc].arg.func2(stack[sp - 2], stack[sp - 1])) {
- stack[sp - 2] = 0.0;
- pc += ops[pc].jmp_offset;
- }
- /* Otherwise keep b on the stack and proceed. */
- else {
- stack[sp - 2] = stack[sp - 1];
- }
- sp--;
- break;
-
- default:
- return EXPR_PYLIKE_FATAL_ERROR;
- }
- }
-
- FAIL_IF(sp != 1 || pc != expr->ops_count);
+eExprPyLike_EvalStatus BLI_expr_pylike_eval(ExprPyLike_Parsed *expr,
+ const double *param_values,
+ int param_values_len,
+ double *r_result)
+{
+ *r_result = 0.0;
+
+ if (!BLI_expr_pylike_is_valid(expr)) {
+ return EXPR_PYLIKE_INVALID;
+ }
+
+#define FAIL_IF(condition) \
+ if (condition) { \
+ return EXPR_PYLIKE_FATAL_ERROR; \
+ }
+
+ /* Check the stack requirement is at least remotely sane and allocate on the actual stack. */
+ FAIL_IF(expr->max_stack <= 0 || expr->max_stack > 1000);
+
+ double *stack = BLI_array_alloca(stack, expr->max_stack);
+
+ /* Evaluate expression. */
+ ExprOp *ops = expr->ops;
+ int sp = 0, pc;
+
+ feclearexcept(FE_ALL_EXCEPT);
+
+ for (pc = 0; pc >= 0 && pc < expr->ops_count; pc++) {
+ switch (ops[pc].opcode) {
+ /* Arithmetic */
+ case OPCODE_CONST:
+ FAIL_IF(sp >= expr->max_stack);
+ stack[sp++] = ops[pc].arg.dval;
+ break;
+ case OPCODE_PARAMETER:
+ FAIL_IF(sp >= expr->max_stack || ops[pc].arg.ival >= param_values_len);
+ stack[sp++] = param_values[ops[pc].arg.ival];
+ break;
+ case OPCODE_FUNC1:
+ FAIL_IF(sp < 1);
+ stack[sp - 1] = ops[pc].arg.func1(stack[sp - 1]);
+ break;
+ case OPCODE_FUNC2:
+ FAIL_IF(sp < 2);
+ stack[sp - 2] = ops[pc].arg.func2(stack[sp - 2], stack[sp - 1]);
+ sp--;
+ break;
+ case OPCODE_MIN:
+ FAIL_IF(sp < ops[pc].arg.ival);
+ for (int j = 1; j < ops[pc].arg.ival; j++, sp--) {
+ CLAMP_MAX(stack[sp - 2], stack[sp - 1]);
+ }
+ break;
+ case OPCODE_MAX:
+ FAIL_IF(sp < ops[pc].arg.ival);
+ for (int j = 1; j < ops[pc].arg.ival; j++, sp--) {
+ CLAMP_MIN(stack[sp - 2], stack[sp - 1]);
+ }
+ break;
+
+ /* Jumps */
+ case OPCODE_JMP:
+ pc += ops[pc].jmp_offset;
+ break;
+ case OPCODE_JMP_ELSE:
+ FAIL_IF(sp < 1);
+ if (!stack[--sp]) {
+ pc += ops[pc].jmp_offset;
+ }
+ break;
+ case OPCODE_JMP_OR:
+ case OPCODE_JMP_AND:
+ FAIL_IF(sp < 1);
+ if (!stack[sp - 1] == !(ops[pc].opcode == OPCODE_JMP_OR)) {
+ pc += ops[pc].jmp_offset;
+ }
+ else {
+ sp--;
+ }
+ break;
+
+ /* For chaining comparisons, i.e. "a < b < c" as "a < b and b < c" */
+ case OPCODE_CMP_CHAIN:
+ FAIL_IF(sp < 2);
+ /* If comparison fails, return 0 and jump to end. */
+ if (!ops[pc].arg.func2(stack[sp - 2], stack[sp - 1])) {
+ stack[sp - 2] = 0.0;
+ pc += ops[pc].jmp_offset;
+ }
+ /* Otherwise keep b on the stack and proceed. */
+ else {
+ stack[sp - 2] = stack[sp - 1];
+ }
+ sp--;
+ break;
+
+ default:
+ return EXPR_PYLIKE_FATAL_ERROR;
+ }
+ }
+
+ FAIL_IF(sp != 1 || pc != expr->ops_count);
#undef FAIL_IF
- *r_result = stack[0];
+ *r_result = stack[0];
- /* Detect floating point evaluation errors. */
- int flags = fetestexcept(FE_DIVBYZERO | FE_INVALID);
- if (flags) {
- return (flags & FE_INVALID) ? EXPR_PYLIKE_MATH_ERROR : EXPR_PYLIKE_DIV_BY_ZERO;
- }
+ /* Detect floating point evaluation errors. */
+ int flags = fetestexcept(FE_DIVBYZERO | FE_INVALID);
+ if (flags) {
+ return (flags & FE_INVALID) ? EXPR_PYLIKE_MATH_ERROR : EXPR_PYLIKE_DIV_BY_ZERO;
+ }
- return EXPR_PYLIKE_SUCCESS;
+ return EXPR_PYLIKE_SUCCESS;
}
/** \} */
@@ -271,115 +274,109 @@ eExprPyLike_EvalStatus BLI_expr_pylike_eval(
static double op_negate(double arg)
{
- return -arg;
+ return -arg;
}
static double op_mul(double a, double b)
{
- return a * b;
+ return a * b;
}
static double op_div(double a, double b)
{
- return a / b;
+ return a / b;
}
static double op_add(double a, double b)
{
- return a + b;
+ return a + b;
}
static double op_sub(double a, double b)
{
- return a - b;
+ return a - b;
}
static double op_radians(double arg)
{
- return arg * M_PI / 180.0;
+ return arg * M_PI / 180.0;
}
static double op_degrees(double arg)
{
- return arg * 180.0 / M_PI;
+ return arg * 180.0 / M_PI;
}
static double op_not(double a)
{
- return a ? 0.0 : 1.0;
+ return a ? 0.0 : 1.0;
}
static double op_eq(double a, double b)
{
- return a == b ? 1.0 : 0.0;
+ return a == b ? 1.0 : 0.0;
}
static double op_ne(double a, double b)
{
- return a != b ? 1.0 : 0.0;
+ return a != b ? 1.0 : 0.0;
}
static double op_lt(double a, double b)
{
- return a < b ? 1.0 : 0.0;
+ return a < b ? 1.0 : 0.0;
}
static double op_le(double a, double b)
{
- return a <= b ? 1.0 : 0.0;
+ return a <= b ? 1.0 : 0.0;
}
static double op_gt(double a, double b)
{
- return a > b ? 1.0 : 0.0;
+ return a > b ? 1.0 : 0.0;
}
static double op_ge(double a, double b)
{
- return a >= b ? 1.0 : 0.0;
+ return a >= b ? 1.0 : 0.0;
}
typedef struct BuiltinConstDef {
- const char *name;
- double value;
+ const char *name;
+ double value;
} BuiltinConstDef;
static BuiltinConstDef builtin_consts[] = {
- { "pi", M_PI },
- { "True", 1.0 },
- { "False", 0.0 },
- { NULL, 0.0 }
-};
+ {"pi", M_PI}, {"True", 1.0}, {"False", 0.0}, {NULL, 0.0}};
typedef struct BuiltinOpDef {
- const char *name;
- eOpCode op;
- void *funcptr;
+ const char *name;
+ eOpCode op;
+ void *funcptr;
} BuiltinOpDef;
-static BuiltinOpDef builtin_ops[] = {
- { "radians", OPCODE_FUNC1, op_radians },
- { "degrees", OPCODE_FUNC1, op_degrees },
- { "abs", OPCODE_FUNC1, fabs },
- { "fabs", OPCODE_FUNC1, fabs },
- { "floor", OPCODE_FUNC1, floor },
- { "ceil", OPCODE_FUNC1, ceil },
- { "trunc", OPCODE_FUNC1, trunc },
- { "int", OPCODE_FUNC1, trunc },
- { "sin", OPCODE_FUNC1, sin },
- { "cos", OPCODE_FUNC1, cos },
- { "tan", OPCODE_FUNC1, tan },
- { "asin", OPCODE_FUNC1, asin },
- { "acos", OPCODE_FUNC1, acos },
- { "atan", OPCODE_FUNC1, atan },
- { "atan2", OPCODE_FUNC2, atan2 },
- { "exp", OPCODE_FUNC1, exp },
- { "log", OPCODE_FUNC1, log },
- { "sqrt", OPCODE_FUNC1, sqrt },
- { "pow", OPCODE_FUNC2, pow },
- { "fmod", OPCODE_FUNC2, fmod },
- { NULL, OPCODE_CONST, NULL }
-};
+static BuiltinOpDef builtin_ops[] = {{"radians", OPCODE_FUNC1, op_radians},
+ {"degrees", OPCODE_FUNC1, op_degrees},
+ {"abs", OPCODE_FUNC1, fabs},
+ {"fabs", OPCODE_FUNC1, fabs},
+ {"floor", OPCODE_FUNC1, floor},
+ {"ceil", OPCODE_FUNC1, ceil},
+ {"trunc", OPCODE_FUNC1, trunc},
+ {"int", OPCODE_FUNC1, trunc},
+ {"sin", OPCODE_FUNC1, sin},
+ {"cos", OPCODE_FUNC1, cos},
+ {"tan", OPCODE_FUNC1, tan},
+ {"asin", OPCODE_FUNC1, asin},
+ {"acos", OPCODE_FUNC1, acos},
+ {"atan", OPCODE_FUNC1, atan},
+ {"atan2", OPCODE_FUNC2, atan2},
+ {"exp", OPCODE_FUNC1, exp},
+ {"log", OPCODE_FUNC1, log},
+ {"sqrt", OPCODE_FUNC1, sqrt},
+ {"pow", OPCODE_FUNC2, pow},
+ {"fmod", OPCODE_FUNC2, fmod},
+ {NULL, OPCODE_CONST, NULL}};
/** \} */
@@ -389,250 +386,252 @@ static BuiltinOpDef builtin_ops[] = {
#define MAKE_CHAR2(a, b) (((a) << 8) | (b))
-#define CHECK_ERROR(condition) if (!(condition)) { return false; }
+#define CHECK_ERROR(condition) \
+ if (!(condition)) { \
+ return false; \
+ }
/* For simplicity simple token types are represented by their own character;
* these are special identifiers for multi-character tokens. */
-#define TOKEN_ID MAKE_CHAR2('I', 'D')
-#define TOKEN_NUMBER MAKE_CHAR2('0', '0')
-#define TOKEN_GE MAKE_CHAR2('>', '=')
-#define TOKEN_LE MAKE_CHAR2('<', '=')
-#define TOKEN_NE MAKE_CHAR2('!', '=')
-#define TOKEN_EQ MAKE_CHAR2('=', '=')
-#define TOKEN_AND MAKE_CHAR2('A', 'N')
-#define TOKEN_OR MAKE_CHAR2('O', 'R')
-#define TOKEN_NOT MAKE_CHAR2('N', 'O')
-#define TOKEN_IF MAKE_CHAR2('I', 'F')
-#define TOKEN_ELSE MAKE_CHAR2('E', 'L')
+#define TOKEN_ID MAKE_CHAR2('I', 'D')
+#define TOKEN_NUMBER MAKE_CHAR2('0', '0')
+#define TOKEN_GE MAKE_CHAR2('>', '=')
+#define TOKEN_LE MAKE_CHAR2('<', '=')
+#define TOKEN_NE MAKE_CHAR2('!', '=')
+#define TOKEN_EQ MAKE_CHAR2('=', '=')
+#define TOKEN_AND MAKE_CHAR2('A', 'N')
+#define TOKEN_OR MAKE_CHAR2('O', 'R')
+#define TOKEN_NOT MAKE_CHAR2('N', 'O')
+#define TOKEN_IF MAKE_CHAR2('I', 'F')
+#define TOKEN_ELSE MAKE_CHAR2('E', 'L')
static const char *token_eq_characters = "!=><";
static const char *token_characters = "~`!@#$%^&*+-=/\\?:;<>(){}[]|.,\"'";
typedef struct KeywordTokenDef {
- const char *name;
- short token;
+ const char *name;
+ short token;
} KeywordTokenDef;
-static KeywordTokenDef keyword_list[] = {
- { "and", TOKEN_AND },
- { "or", TOKEN_OR },
- { "not", TOKEN_NOT },
- { "if", TOKEN_IF },
- { "else", TOKEN_ELSE },
- { NULL, TOKEN_ID }
-};
+static KeywordTokenDef keyword_list[] = {{"and", TOKEN_AND},
+ {"or", TOKEN_OR},
+ {"not", TOKEN_NOT},
+ {"if", TOKEN_IF},
+ {"else", TOKEN_ELSE},
+ {NULL, TOKEN_ID}};
typedef struct ExprParseState {
- int param_names_len;
- const char **param_names;
+ int param_names_len;
+ const char **param_names;
- /* Original expression */
- const char *expr;
- const char *cur;
+ /* Original expression */
+ const char *expr;
+ const char *cur;
- /* Current token */
- short token;
- char *tokenbuf;
- double tokenval;
+ /* Current token */
+ short token;
+ char *tokenbuf;
+ double tokenval;
- /* Opcode buffer */
- int ops_count, max_ops, last_jmp;
- ExprOp *ops;
+ /* Opcode buffer */
+ int ops_count, max_ops, last_jmp;
+ ExprOp *ops;
- /* Stack space requirement tracking */
- int stack_ptr, max_stack;
+ /* Stack space requirement tracking */
+ int stack_ptr, max_stack;
} ExprParseState;
/* Reserve space for the specified number of operations in the buffer. */
static ExprOp *parse_alloc_ops(ExprParseState *state, int count)
{
- if (state->ops_count + count > state->max_ops) {
- state->max_ops = power_of_2_max_i(state->ops_count + count);
- state->ops = MEM_reallocN(state->ops, state->max_ops * sizeof(ExprOp));
- }
+ if (state->ops_count + count > state->max_ops) {
+ state->max_ops = power_of_2_max_i(state->ops_count + count);
+ state->ops = MEM_reallocN(state->ops, state->max_ops * sizeof(ExprOp));
+ }
- ExprOp *op = &state->ops[state->ops_count];
- state->ops_count += count;
- return op;
+ ExprOp *op = &state->ops[state->ops_count];
+ state->ops_count += count;
+ return op;
}
/* Add one operation and track stack usage. */
static ExprOp *parse_add_op(ExprParseState *state, eOpCode code, int stack_delta)
{
- /* track evaluation stack depth */
- state->stack_ptr += stack_delta;
- CLAMP_MIN(state->stack_ptr, 0);
- CLAMP_MIN(state->max_stack, state->stack_ptr);
+ /* track evaluation stack depth */
+ state->stack_ptr += stack_delta;
+ CLAMP_MIN(state->stack_ptr, 0);
+ CLAMP_MIN(state->max_stack, state->stack_ptr);
- /* allocate the new instruction */
- ExprOp *op = parse_alloc_ops(state, 1);
- memset(op, 0, sizeof(ExprOp));
- op->opcode = code;
- return op;
+ /* allocate the new instruction */
+ ExprOp *op = parse_alloc_ops(state, 1);
+ memset(op, 0, sizeof(ExprOp));
+ op->opcode = code;
+ return op;
}
/* Add one jump operation and return an index for parse_set_jump. */
static int parse_add_jump(ExprParseState *state, eOpCode code)
{
- parse_add_op(state, code, -1);
- return state->last_jmp = state->ops_count;
+ parse_add_op(state, code, -1);
+ return state->last_jmp = state->ops_count;
}
/* Set the jump offset in a previously added jump operation. */
static void parse_set_jump(ExprParseState *state, int jump)
{
- state->last_jmp = state->ops_count;
- state->ops[jump - 1].jmp_offset = state->ops_count - jump;
+ state->last_jmp = state->ops_count;
+ state->ops[jump - 1].jmp_offset = state->ops_count - jump;
}
/* Add a function call operation, applying constant folding when possible. */
static bool parse_add_func(ExprParseState *state, eOpCode code, int args, void *funcptr)
{
- ExprOp *prev_ops = &state->ops[state->ops_count];
- int jmp_gap = state->ops_count - state->last_jmp;
+ ExprOp *prev_ops = &state->ops[state->ops_count];
+ int jmp_gap = state->ops_count - state->last_jmp;
- feclearexcept(FE_ALL_EXCEPT);
+ feclearexcept(FE_ALL_EXCEPT);
- switch (code) {
- case OPCODE_FUNC1:
- CHECK_ERROR(args == 1);
+ switch (code) {
+ case OPCODE_FUNC1:
+ CHECK_ERROR(args == 1);
- if (jmp_gap >= 1 && prev_ops[-1].opcode == OPCODE_CONST) {
- UnaryOpFunc func = funcptr;
+ if (jmp_gap >= 1 && prev_ops[-1].opcode == OPCODE_CONST) {
+ UnaryOpFunc func = funcptr;
- double result = func(prev_ops[-1].arg.dval);
+ double result = func(prev_ops[-1].arg.dval);
- if (fetestexcept(FE_DIVBYZERO | FE_INVALID) == 0) {
- prev_ops[-1].arg.dval = result;
- return true;
- }
- }
- break;
+ if (fetestexcept(FE_DIVBYZERO | FE_INVALID) == 0) {
+ prev_ops[-1].arg.dval = result;
+ return true;
+ }
+ }
+ break;
- case OPCODE_FUNC2:
- CHECK_ERROR(args == 2);
+ case OPCODE_FUNC2:
+ CHECK_ERROR(args == 2);
- if (jmp_gap >= 2 && prev_ops[-2].opcode == OPCODE_CONST && prev_ops[-1].opcode == OPCODE_CONST) {
- BinaryOpFunc func = funcptr;
+ if (jmp_gap >= 2 && prev_ops[-2].opcode == OPCODE_CONST &&
+ prev_ops[-1].opcode == OPCODE_CONST) {
+ BinaryOpFunc func = funcptr;
- double result = func(prev_ops[-2].arg.dval, prev_ops[-1].arg.dval);
+ double result = func(prev_ops[-2].arg.dval, prev_ops[-1].arg.dval);
- if (fetestexcept(FE_DIVBYZERO | FE_INVALID) == 0) {
- prev_ops[-2].arg.dval = result;
- state->ops_count--;
- state->stack_ptr--;
- return true;
- }
- }
- break;
+ if (fetestexcept(FE_DIVBYZERO | FE_INVALID) == 0) {
+ prev_ops[-2].arg.dval = result;
+ state->ops_count--;
+ state->stack_ptr--;
+ return true;
+ }
+ }
+ break;
- default:
- BLI_assert(false);
- return false;
- }
+ default:
+ BLI_assert(false);
+ return false;
+ }
- parse_add_op(state, code, 1 - args)->arg.ptr = funcptr;
- return true;
+ parse_add_op(state, code, 1 - args)->arg.ptr = funcptr;
+ return true;
}
/* Extract the next token from raw characters. */
static bool parse_next_token(ExprParseState *state)
{
- /* Skip whitespace. */
- while (isspace(*state->cur)) {
- state->cur++;
- }
-
- /* End of string. */
- if (*state->cur == 0) {
- state->token = 0;
- return true;
- }
-
- /* Floating point numbers. */
- if (isdigit(*state->cur) || (state->cur[0] == '.' && isdigit(state->cur[1]))) {
- char *end, *out = state->tokenbuf;
- bool is_float = false;
-
- while (isdigit(*state->cur)) {
- *out++ = *state->cur++;
- }
-
- if (*state->cur == '.') {
- is_float = true;
- *out++ = *state->cur++;
-
- while (isdigit(*state->cur)) {
- *out++ = *state->cur++;
- }
- }
-
- if (ELEM(*state->cur, 'e', 'E')) {
- is_float = true;
- *out++ = *state->cur++;
-
- if (ELEM(*state->cur, '+', '-')) {
- *out++ = *state->cur++;
- }
-
- CHECK_ERROR(isdigit(*state->cur));
-
- while (isdigit(*state->cur)) {
- *out++ = *state->cur++;
- }
- }
-
- *out = 0;
-
- /* Forbid C-style octal constants. */
- if (!is_float && state->tokenbuf[0] == '0') {
- for (char *p = state->tokenbuf + 1; *p; p++) {
- if (*p != '0') {
- return false;
- }
- }
- }
-
- state->token = TOKEN_NUMBER;
- state->tokenval = strtod(state->tokenbuf, &end);
- return (end == out);
- }
-
- /* ?= tokens */
- if (state->cur[1] == '=' && strchr(token_eq_characters, state->cur[0])) {
- state->token = MAKE_CHAR2(state->cur[0], state->cur[1]);
- state->cur += 2;
- return true;
- }
-
- /* Special characters (single character tokens) */
- if (strchr(token_characters, *state->cur)) {
- state->token = *state->cur++;
- return true;
- }
-
- /* Identifiers */
- if (isalpha(*state->cur) || ELEM(*state->cur, '_')) {
- char *out = state->tokenbuf;
-
- while (isalnum(*state->cur) || ELEM(*state->cur, '_')) {
- *out++ = *state->cur++;
- }
-
- *out = 0;
-
- for (int i = 0; keyword_list[i].name; i++) {
- if (STREQ(state->tokenbuf, keyword_list[i].name)) {
- state->token = keyword_list[i].token;
- return true;
- }
- }
-
- state->token = TOKEN_ID;
- return true;
- }
-
- return false;
+ /* Skip whitespace. */
+ while (isspace(*state->cur)) {
+ state->cur++;
+ }
+
+ /* End of string. */
+ if (*state->cur == 0) {
+ state->token = 0;
+ return true;
+ }
+
+ /* Floating point numbers. */
+ if (isdigit(*state->cur) || (state->cur[0] == '.' && isdigit(state->cur[1]))) {
+ char *end, *out = state->tokenbuf;
+ bool is_float = false;
+
+ while (isdigit(*state->cur)) {
+ *out++ = *state->cur++;
+ }
+
+ if (*state->cur == '.') {
+ is_float = true;
+ *out++ = *state->cur++;
+
+ while (isdigit(*state->cur)) {
+ *out++ = *state->cur++;
+ }
+ }
+
+ if (ELEM(*state->cur, 'e', 'E')) {
+ is_float = true;
+ *out++ = *state->cur++;
+
+ if (ELEM(*state->cur, '+', '-')) {
+ *out++ = *state->cur++;
+ }
+
+ CHECK_ERROR(isdigit(*state->cur));
+
+ while (isdigit(*state->cur)) {
+ *out++ = *state->cur++;
+ }
+ }
+
+ *out = 0;
+
+ /* Forbid C-style octal constants. */
+ if (!is_float && state->tokenbuf[0] == '0') {
+ for (char *p = state->tokenbuf + 1; *p; p++) {
+ if (*p != '0') {
+ return false;
+ }
+ }
+ }
+
+ state->token = TOKEN_NUMBER;
+ state->tokenval = strtod(state->tokenbuf, &end);
+ return (end == out);
+ }
+
+ /* ?= tokens */
+ if (state->cur[1] == '=' && strchr(token_eq_characters, state->cur[0])) {
+ state->token = MAKE_CHAR2(state->cur[0], state->cur[1]);
+ state->cur += 2;
+ return true;
+ }
+
+ /* Special characters (single character tokens) */
+ if (strchr(token_characters, *state->cur)) {
+ state->token = *state->cur++;
+ return true;
+ }
+
+ /* Identifiers */
+ if (isalpha(*state->cur) || ELEM(*state->cur, '_')) {
+ char *out = state->tokenbuf;
+
+ while (isalnum(*state->cur) || ELEM(*state->cur, '_')) {
+ *out++ = *state->cur++;
+ }
+
+ *out = 0;
+
+ for (int i = 0; keyword_list[i].name; i++) {
+ if (STREQ(state->tokenbuf, keyword_list[i].name)) {
+ state->token = keyword_list[i].token;
+ return true;
+ }
+ }
+
+ state->token = TOKEN_ID;
+ return true;
+ }
+
+ return false;
}
/** \} */
@@ -645,303 +644,300 @@ static bool parse_expr(ExprParseState *state);
static int parse_function_args(ExprParseState *state)
{
- if (!parse_next_token(state) || state->token != '(' || !parse_next_token(state)) {
- return -1;
- }
+ if (!parse_next_token(state) || state->token != '(' || !parse_next_token(state)) {
+ return -1;
+ }
- int arg_count = 0;
+ int arg_count = 0;
- for (;;) {
- if (!parse_expr(state)) {
- return -1;
- }
+ for (;;) {
+ if (!parse_expr(state)) {
+ return -1;
+ }
- arg_count++;
+ arg_count++;
- switch (state->token) {
- case ',':
- if (!parse_next_token(state)) {
- return -1;
- }
- break;
+ switch (state->token) {
+ case ',':
+ if (!parse_next_token(state)) {
+ return -1;
+ }
+ break;
- case ')':
- if (!parse_next_token(state)) {
- return -1;
- }
- return arg_count;
+ case ')':
+ if (!parse_next_token(state)) {
+ return -1;
+ }
+ return arg_count;
- default:
- return -1;
- }
- }
+ default:
+ return -1;
+ }
+ }
}
static bool parse_unary(ExprParseState *state)
{
- int i;
-
- switch (state->token) {
- case '+':
- return parse_next_token(state) && parse_unary(state);
-
- case '-':
- CHECK_ERROR(parse_next_token(state) && parse_unary(state));
- parse_add_func(state, OPCODE_FUNC1, 1, op_negate);
- return true;
-
- case '(':
- return parse_next_token(state) &&
- parse_expr(state) &&
- state->token == ')' &&
- parse_next_token(state);
-
- case TOKEN_NUMBER:
- parse_add_op(state, OPCODE_CONST, 1)->arg.dval = state->tokenval;
- return parse_next_token(state);
-
- case TOKEN_ID:
- /* Parameters: search in reverse order in case of duplicate names -
- * the last one should win. */
- for (i = state->param_names_len - 1; i >= 0; i--) {
- if (STREQ(state->tokenbuf, state->param_names[i])) {
- parse_add_op(state, OPCODE_PARAMETER, 1)->arg.ival = i;
- return parse_next_token(state);
- }
- }
-
- /* Ordinary builtin constants. */
- for (i = 0; builtin_consts[i].name; i++) {
- if (STREQ(state->tokenbuf, builtin_consts[i].name)) {
- parse_add_op(state, OPCODE_CONST, 1)->arg.dval = builtin_consts[i].value;
- return parse_next_token(state);
- }
- }
-
- /* Ordinary builtin functions. */
- for (i = 0; builtin_ops[i].name; i++) {
- if (STREQ(state->tokenbuf, builtin_ops[i].name)) {
- int args = parse_function_args(state);
-
- return parse_add_func(state, builtin_ops[i].op, args, builtin_ops[i].funcptr);
- }
- }
-
- /* Specially supported functions. */
- if (STREQ(state->tokenbuf, "min")) {
- int cnt = parse_function_args(state);
- CHECK_ERROR(cnt > 0);
-
- parse_add_op(state, OPCODE_MIN, 1 - cnt)->arg.ival = cnt;
- return true;
- }
-
- if (STREQ(state->tokenbuf, "max")) {
- int cnt = parse_function_args(state);
- CHECK_ERROR(cnt > 0);
-
- parse_add_op(state, OPCODE_MAX, 1 - cnt)->arg.ival = cnt;
- return true;
- }
-
- return false;
-
- default:
- return false;
- }
+ int i;
+
+ switch (state->token) {
+ case '+':
+ return parse_next_token(state) && parse_unary(state);
+
+ case '-':
+ CHECK_ERROR(parse_next_token(state) && parse_unary(state));
+ parse_add_func(state, OPCODE_FUNC1, 1, op_negate);
+ return true;
+
+ case '(':
+ return parse_next_token(state) && parse_expr(state) && state->token == ')' &&
+ parse_next_token(state);
+
+ case TOKEN_NUMBER:
+ parse_add_op(state, OPCODE_CONST, 1)->arg.dval = state->tokenval;
+ return parse_next_token(state);
+
+ case TOKEN_ID:
+ /* Parameters: search in reverse order in case of duplicate names -
+ * the last one should win. */
+ for (i = state->param_names_len - 1; i >= 0; i--) {
+ if (STREQ(state->tokenbuf, state->param_names[i])) {
+ parse_add_op(state, OPCODE_PARAMETER, 1)->arg.ival = i;
+ return parse_next_token(state);
+ }
+ }
+
+ /* Ordinary builtin constants. */
+ for (i = 0; builtin_consts[i].name; i++) {
+ if (STREQ(state->tokenbuf, builtin_consts[i].name)) {
+ parse_add_op(state, OPCODE_CONST, 1)->arg.dval = builtin_consts[i].value;
+ return parse_next_token(state);
+ }
+ }
+
+ /* Ordinary builtin functions. */
+ for (i = 0; builtin_ops[i].name; i++) {
+ if (STREQ(state->tokenbuf, builtin_ops[i].name)) {
+ int args = parse_function_args(state);
+
+ return parse_add_func(state, builtin_ops[i].op, args, builtin_ops[i].funcptr);
+ }
+ }
+
+ /* Specially supported functions. */
+ if (STREQ(state->tokenbuf, "min")) {
+ int cnt = parse_function_args(state);
+ CHECK_ERROR(cnt > 0);
+
+ parse_add_op(state, OPCODE_MIN, 1 - cnt)->arg.ival = cnt;
+ return true;
+ }
+
+ if (STREQ(state->tokenbuf, "max")) {
+ int cnt = parse_function_args(state);
+ CHECK_ERROR(cnt > 0);
+
+ parse_add_op(state, OPCODE_MAX, 1 - cnt)->arg.ival = cnt;
+ return true;
+ }
+
+ return false;
+
+ default:
+ return false;
+ }
}
static bool parse_mul(ExprParseState *state)
{
- CHECK_ERROR(parse_unary(state));
+ CHECK_ERROR(parse_unary(state));
- for (;;) {
- switch (state->token) {
- case '*':
- CHECK_ERROR(parse_next_token(state) && parse_unary(state));
- parse_add_func(state, OPCODE_FUNC2, 2, op_mul);
- break;
+ for (;;) {
+ switch (state->token) {
+ case '*':
+ CHECK_ERROR(parse_next_token(state) && parse_unary(state));
+ parse_add_func(state, OPCODE_FUNC2, 2, op_mul);
+ break;
- case '/':
- CHECK_ERROR(parse_next_token(state) && parse_unary(state));
- parse_add_func(state, OPCODE_FUNC2, 2, op_div);
- break;
+ case '/':
+ CHECK_ERROR(parse_next_token(state) && parse_unary(state));
+ parse_add_func(state, OPCODE_FUNC2, 2, op_div);
+ break;
- default:
- return true;
- }
- }
+ default:
+ return true;
+ }
+ }
}
static bool parse_add(ExprParseState *state)
{
- CHECK_ERROR(parse_mul(state));
+ CHECK_ERROR(parse_mul(state));
- for (;;) {
- switch (state->token) {
- case '+':
- CHECK_ERROR(parse_next_token(state) && parse_mul(state));
- parse_add_func(state, OPCODE_FUNC2, 2, op_add);
- break;
+ for (;;) {
+ switch (state->token) {
+ case '+':
+ CHECK_ERROR(parse_next_token(state) && parse_mul(state));
+ parse_add_func(state, OPCODE_FUNC2, 2, op_add);
+ break;
- case '-':
- CHECK_ERROR(parse_next_token(state) && parse_mul(state));
- parse_add_func(state, OPCODE_FUNC2, 2, op_sub);
- break;
+ case '-':
+ CHECK_ERROR(parse_next_token(state) && parse_mul(state));
+ parse_add_func(state, OPCODE_FUNC2, 2, op_sub);
+ break;
- default:
- return true;
- }
- }
+ default:
+ return true;
+ }
+ }
}
static BinaryOpFunc parse_get_cmp_func(short token)
{
- switch (token) {
- case TOKEN_EQ:
- return op_eq;
- case TOKEN_NE:
- return op_ne;
- case '>':
- return op_gt;
- case TOKEN_GE:
- return op_ge;
- case '<':
- return op_lt;
- case TOKEN_LE:
- return op_le;
- default:
- return NULL;
- }
+ switch (token) {
+ case TOKEN_EQ:
+ return op_eq;
+ case TOKEN_NE:
+ return op_ne;
+ case '>':
+ return op_gt;
+ case TOKEN_GE:
+ return op_ge;
+ case '<':
+ return op_lt;
+ case TOKEN_LE:
+ return op_le;
+ default:
+ return NULL;
+ }
}
static bool parse_cmp_chain(ExprParseState *state, BinaryOpFunc cur_func)
{
- BinaryOpFunc next_func = parse_get_cmp_func(state->token);
+ BinaryOpFunc next_func = parse_get_cmp_func(state->token);
- if (next_func) {
- parse_add_op(state, OPCODE_CMP_CHAIN, -1)->arg.func2 = cur_func;
- int jump = state->last_jmp = state->ops_count;
+ if (next_func) {
+ parse_add_op(state, OPCODE_CMP_CHAIN, -1)->arg.func2 = cur_func;
+ int jump = state->last_jmp = state->ops_count;
- CHECK_ERROR(parse_next_token(state) && parse_add(state));
- CHECK_ERROR(parse_cmp_chain(state, next_func));
+ CHECK_ERROR(parse_next_token(state) && parse_add(state));
+ CHECK_ERROR(parse_cmp_chain(state, next_func));
- parse_set_jump(state, jump);
- }
- else {
- parse_add_func(state, OPCODE_FUNC2, 2, cur_func);
- }
+ parse_set_jump(state, jump);
+ }
+ else {
+ parse_add_func(state, OPCODE_FUNC2, 2, cur_func);
+ }
- return true;
+ return true;
}
static bool parse_cmp(ExprParseState *state)
{
- CHECK_ERROR(parse_add(state));
+ CHECK_ERROR(parse_add(state));
- BinaryOpFunc func = parse_get_cmp_func(state->token);
+ BinaryOpFunc func = parse_get_cmp_func(state->token);
- if (func) {
- CHECK_ERROR(parse_next_token(state) && parse_add(state));
+ if (func) {
+ CHECK_ERROR(parse_next_token(state) && parse_add(state));
- return parse_cmp_chain(state, func);
- }
+ return parse_cmp_chain(state, func);
+ }
- return true;
+ return true;
}
static bool parse_not(ExprParseState *state)
{
- if (state->token == TOKEN_NOT) {
- CHECK_ERROR(parse_next_token(state) && parse_not(state));
- parse_add_func(state, OPCODE_FUNC1, 1, op_not);
- return true;
- }
+ if (state->token == TOKEN_NOT) {
+ CHECK_ERROR(parse_next_token(state) && parse_not(state));
+ parse_add_func(state, OPCODE_FUNC1, 1, op_not);
+ return true;
+ }
- return parse_cmp(state);
+ return parse_cmp(state);
}
static bool parse_and(ExprParseState *state)
{
- CHECK_ERROR(parse_not(state));
+ CHECK_ERROR(parse_not(state));
- if (state->token == TOKEN_AND) {
- int jump = parse_add_jump(state, OPCODE_JMP_AND);
+ if (state->token == TOKEN_AND) {
+ int jump = parse_add_jump(state, OPCODE_JMP_AND);
- CHECK_ERROR(parse_next_token(state) && parse_and(state));
+ CHECK_ERROR(parse_next_token(state) && parse_and(state));
- parse_set_jump(state, jump);
- }
+ parse_set_jump(state, jump);
+ }
- return true;
+ return true;
}
static bool parse_or(ExprParseState *state)
{
- CHECK_ERROR(parse_and(state));
+ CHECK_ERROR(parse_and(state));
- if (state->token == TOKEN_OR) {
- int jump = parse_add_jump(state, OPCODE_JMP_OR);
+ if (state->token == TOKEN_OR) {
+ int jump = parse_add_jump(state, OPCODE_JMP_OR);
- CHECK_ERROR(parse_next_token(state) && parse_or(state));
+ CHECK_ERROR(parse_next_token(state) && parse_or(state));
- parse_set_jump(state, jump);
- }
+ parse_set_jump(state, jump);
+ }
- return true;
+ return true;
}
static bool parse_expr(ExprParseState *state)
{
- /* Temporarily set the constant expression evaluation barrier */
- int prev_last_jmp = state->last_jmp;
- int start = state->last_jmp = state->ops_count;
+ /* Temporarily set the constant expression evaluation barrier */
+ int prev_last_jmp = state->last_jmp;
+ int start = state->last_jmp = state->ops_count;
- CHECK_ERROR(parse_or(state));
+ CHECK_ERROR(parse_or(state));
- if (state->token == TOKEN_IF) {
- /* Ternary IF expression in python requires swapping the
- * main body with condition, so stash the body opcodes. */
- int size = state->ops_count - start;
- int bytes = size * sizeof(ExprOp);
+ if (state->token == TOKEN_IF) {
+ /* Ternary IF expression in python requires swapping the
+ * main body with condition, so stash the body opcodes. */
+ int size = state->ops_count - start;
+ int bytes = size * sizeof(ExprOp);
- ExprOp *body = MEM_mallocN(bytes, "driver if body");
- memcpy(body, state->ops + start, bytes);
+ ExprOp *body = MEM_mallocN(bytes, "driver if body");
+ memcpy(body, state->ops + start, bytes);
- state->last_jmp = state->ops_count = start;
- state->stack_ptr--;
+ state->last_jmp = state->ops_count = start;
+ state->stack_ptr--;
- /* Parse condition. */
- if (!parse_next_token(state) || !parse_or(state) ||
- state->token != TOKEN_ELSE || !parse_next_token(state))
- {
- MEM_freeN(body);
- return false;
- }
+ /* Parse condition. */
+ if (!parse_next_token(state) || !parse_or(state) || state->token != TOKEN_ELSE ||
+ !parse_next_token(state)) {
+ MEM_freeN(body);
+ return false;
+ }
- int jmp_else = parse_add_jump(state, OPCODE_JMP_ELSE);
+ int jmp_else = parse_add_jump(state, OPCODE_JMP_ELSE);
- /* Add body back. */
- memcpy(parse_alloc_ops(state, size), body, bytes);
- MEM_freeN(body);
+ /* Add body back. */
+ memcpy(parse_alloc_ops(state, size), body, bytes);
+ MEM_freeN(body);
- state->stack_ptr++;
+ state->stack_ptr++;
- int jmp_end = parse_add_jump(state, OPCODE_JMP);
+ int jmp_end = parse_add_jump(state, OPCODE_JMP);
- /* Parse the else block. */
- parse_set_jump(state, jmp_else);
+ /* Parse the else block. */
+ parse_set_jump(state, jmp_else);
- CHECK_ERROR(parse_expr(state));
+ CHECK_ERROR(parse_expr(state));
- parse_set_jump(state, jmp_end);
- }
- /* If no actual jumps happened, restore previous barrier */
- else if (state->last_jmp == start) {
- state->last_jmp = prev_last_jmp;
- }
+ parse_set_jump(state, jmp_end);
+ }
+ /* If no actual jumps happened, restore previous barrier */
+ else if (state->last_jmp == start) {
+ state->last_jmp = prev_last_jmp;
+ }
- return true;
+ return true;
}
/** \} */
@@ -956,44 +952,46 @@ static bool parse_expr(ExprParseState *state)
* Parse the expression for evaluation later.
* Returns non-NULL even on failure; use is_valid to check.
*/
-ExprPyLike_Parsed *BLI_expr_pylike_parse(const char *expression, const char **param_names, int param_names_len)
+ExprPyLike_Parsed *BLI_expr_pylike_parse(const char *expression,
+ const char **param_names,
+ int param_names_len)
{
- /* Prepare the parser state. */
- ExprParseState state;
- memset(&state, 0, sizeof(state));
+ /* Prepare the parser state. */
+ ExprParseState state;
+ memset(&state, 0, sizeof(state));
- state.cur = state.expr = expression;
+ state.cur = state.expr = expression;
- state.param_names_len = param_names_len;
- state.param_names = param_names;
+ state.param_names_len = param_names_len;
+ state.param_names = param_names;
- state.tokenbuf = MEM_mallocN(strlen(expression) + 1, __func__);
+ state.tokenbuf = MEM_mallocN(strlen(expression) + 1, __func__);
- state.max_ops = 16;
- state.ops = MEM_mallocN(state.max_ops * sizeof(ExprOp), __func__);
+ state.max_ops = 16;
+ state.ops = MEM_mallocN(state.max_ops * sizeof(ExprOp), __func__);
- /* Parse the expression. */
- ExprPyLike_Parsed *expr;
+ /* Parse the expression. */
+ ExprPyLike_Parsed *expr;
- if (parse_next_token(&state) && parse_expr(&state) && state.token == 0) {
- BLI_assert(state.stack_ptr == 1);
+ if (parse_next_token(&state) && parse_expr(&state) && state.token == 0) {
+ BLI_assert(state.stack_ptr == 1);
- int bytesize = sizeof(ExprPyLike_Parsed) + state.ops_count * sizeof(ExprOp);
+ int bytesize = sizeof(ExprPyLike_Parsed) + state.ops_count * sizeof(ExprOp);
- expr = MEM_mallocN(bytesize, "ExprPyLike_Parsed");
- expr->ops_count = state.ops_count;
- expr->max_stack = state.max_stack;
+ expr = MEM_mallocN(bytesize, "ExprPyLike_Parsed");
+ expr->ops_count = state.ops_count;
+ expr->max_stack = state.max_stack;
- memcpy(expr->ops, state.ops, state.ops_count * sizeof(ExprOp));
- }
- else {
- /* Always return a non-NULL object so that parse failure can be cached. */
- expr = MEM_callocN(sizeof(ExprPyLike_Parsed), "ExprPyLike_Parsed(empty)");
- }
+ memcpy(expr->ops, state.ops, state.ops_count * sizeof(ExprOp));
+ }
+ else {
+ /* Always return a non-NULL object so that parse failure can be cached. */
+ expr = MEM_callocN(sizeof(ExprPyLike_Parsed), "ExprPyLike_Parsed(empty)");
+ }
- MEM_freeN(state.tokenbuf);
- MEM_freeN(state.ops);
- return expr;
+ MEM_freeN(state.tokenbuf);
+ MEM_freeN(state.ops);
+ return expr;
}
/** \} */
diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c
index afedd19b6d5..9e07b4d2836 100644
--- a/source/blender/blenlib/intern/fileops.c
+++ b/source/blender/blenlib/intern/fileops.c
@@ -21,8 +21,7 @@
* \ingroup bli
*/
-
-#include <stdlib.h> /* malloc */
+#include <stdlib.h> /* malloc */
#include <string.h>
#include <sys/types.h>
@@ -53,52 +52,52 @@
#include "BLI_string.h"
#include "BLI_path_util.h"
#include "BLI_fileops.h"
-#include "BLI_sys_types.h" // for intptr_t support
+#include "BLI_sys_types.h" // for intptr_t support
-#if 0 /* UNUSED */
+#if 0 /* UNUSED */
/* gzip the file in from and write it to "to".
* return -1 if zlib fails, -2 if the originating file does not exist
* note: will remove the "from" file
*/
int BLI_file_gzip(const char *from, const char *to)
{
- char buffer[10240];
- int file;
- int readsize = 0;
- int rval = 0, err;
- gzFile gzfile;
-
- /* level 1 is very close to 3 (the default) in terms of file size,
- * but about twice as fast, best use for speedy saving - campbell */
- gzfile = BLI_gzopen(to, "wb1");
- if (gzfile == NULL)
- return -1;
- file = BLI_open(from, O_BINARY | O_RDONLY, 0);
- if (file == -1)
- return -2;
-
- while (1) {
- readsize = read(file, buffer, sizeof(buffer));
-
- if (readsize < 0) {
- rval = -2; /* error happened in reading */
- fprintf(stderr, "Error reading file %s: %s.\n", from, strerror(errno));
- break;
- }
- else if (readsize == 0)
- break; /* done reading */
-
- if (gzwrite(gzfile, buffer, readsize) <= 0) {
- rval = -1; /* error happened in writing */
- fprintf(stderr, "Error writing gz file %s: %s.\n", to, gzerror(gzfile, &err));
- break;
- }
- }
-
- gzclose(gzfile);
- close(file);
-
- return rval;
+ char buffer[10240];
+ int file;
+ int readsize = 0;
+ int rval = 0, err;
+ gzFile gzfile;
+
+ /* level 1 is very close to 3 (the default) in terms of file size,
+ * but about twice as fast, best use for speedy saving - campbell */
+ gzfile = BLI_gzopen(to, "wb1");
+ if (gzfile == NULL)
+ return -1;
+ file = BLI_open(from, O_BINARY | O_RDONLY, 0);
+ if (file == -1)
+ return -2;
+
+ while (1) {
+ readsize = read(file, buffer, sizeof(buffer));
+
+ if (readsize < 0) {
+ rval = -2; /* error happened in reading */
+ fprintf(stderr, "Error reading file %s: %s.\n", from, strerror(errno));
+ break;
+ }
+ else if (readsize == 0)
+ break; /* done reading */
+
+ if (gzwrite(gzfile, buffer, readsize) <= 0) {
+ rval = -1; /* error happened in writing */
+ fprintf(stderr, "Error writing gz file %s: %s.\n", to, gzerror(gzfile, &err));
+ break;
+ }
+ }
+
+ gzclose(gzfile);
+ close(file);
+
+ return rval;
}
#endif
@@ -107,46 +106,46 @@ int BLI_file_gzip(const char *from, const char *to)
*/
char *BLI_file_ungzip_to_mem(const char *from_file, int *r_size)
{
- gzFile gzfile;
- int readsize, size, alloc_size = 0;
- char *mem = NULL;
- const int chunk_size = 512 * 1024;
-
- size = 0;
-
- gzfile = BLI_gzopen(from_file, "rb");
- for (;; ) {
- if (mem == NULL) {
- mem = MEM_callocN(chunk_size, "BLI_ungzip_to_mem");
- alloc_size = chunk_size;
- }
- else {
- mem = MEM_reallocN(mem, size + chunk_size);
- alloc_size += chunk_size;
- }
-
- readsize = gzread(gzfile, mem + size, chunk_size);
- if (readsize > 0) {
- size += readsize;
- }
- else {
- break;
- }
- }
-
- gzclose(gzfile);
-
- if (size == 0) {
- MEM_freeN(mem);
- mem = NULL;
- }
- else if (alloc_size != size) {
- mem = MEM_reallocN(mem, size);
- }
-
- *r_size = size;
-
- return mem;
+ gzFile gzfile;
+ int readsize, size, alloc_size = 0;
+ char *mem = NULL;
+ const int chunk_size = 512 * 1024;
+
+ size = 0;
+
+ gzfile = BLI_gzopen(from_file, "rb");
+ for (;;) {
+ if (mem == NULL) {
+ mem = MEM_callocN(chunk_size, "BLI_ungzip_to_mem");
+ alloc_size = chunk_size;
+ }
+ else {
+ mem = MEM_reallocN(mem, size + chunk_size);
+ alloc_size += chunk_size;
+ }
+
+ readsize = gzread(gzfile, mem + size, chunk_size);
+ if (readsize > 0) {
+ size += readsize;
+ }
+ else {
+ break;
+ }
+ }
+
+ gzclose(gzfile);
+
+ if (size == 0) {
+ MEM_freeN(mem);
+ mem = NULL;
+ }
+ else if (alloc_size != size) {
+ mem = MEM_reallocN(mem, size);
+ }
+
+ *r_size = size;
+
+ return mem;
}
/**
@@ -158,27 +157,27 @@ char *BLI_file_ungzip_to_mem(const char *from_file, int *r_size)
*/
bool BLI_file_is_writable(const char *filename)
{
- bool writable;
- if (BLI_access(filename, W_OK) == 0) {
- /* file exists and I can write to it */
- writable = true;
- }
- else if (errno != ENOENT) {
- /* most likely file or containing directory cannot be accessed */
- writable = false;
- }
- else {
- /* file doesn't exist -- check I can create it in parent directory */
- char parent[FILE_MAX];
- BLI_split_dirfile(filename, parent, NULL, sizeof(parent), 0);
+ bool writable;
+ if (BLI_access(filename, W_OK) == 0) {
+ /* file exists and I can write to it */
+ writable = true;
+ }
+ else if (errno != ENOENT) {
+ /* most likely file or containing directory cannot be accessed */
+ writable = false;
+ }
+ else {
+ /* file doesn't exist -- check I can create it in parent directory */
+ char parent[FILE_MAX];
+ BLI_split_dirfile(filename, parent, NULL, sizeof(parent), 0);
#ifdef WIN32
- /* windows does not have X_OK */
- writable = BLI_access(parent, W_OK) == 0;
+ /* windows does not have X_OK */
+ writable = BLI_access(parent, W_OK) == 0;
#else
- writable = BLI_access(parent, X_OK | W_OK) == 0;
+ writable = BLI_access(parent, X_OK | W_OK) == 0;
#endif
- }
- return writable;
+ }
+ return writable;
}
/**
@@ -187,338 +186,338 @@ bool BLI_file_is_writable(const char *filename)
*/
bool BLI_file_touch(const char *file)
{
- FILE *f = BLI_fopen(file, "r+b");
-
- if (f != NULL) {
- int c = getc(f);
-
- if (c == EOF) {
- /* Empty file, reopen in truncate write mode... */
- fclose(f);
- f = BLI_fopen(file, "w+b");
- }
- else {
- /* Otherwise, rewrite first byte. */
- rewind(f);
- putc(c, f);
- }
- }
- else {
- f = BLI_fopen(file, "wb");
- }
- if (f) {
- fclose(f);
- return true;
- }
- return false;
+ FILE *f = BLI_fopen(file, "r+b");
+
+ if (f != NULL) {
+ int c = getc(f);
+
+ if (c == EOF) {
+ /* Empty file, reopen in truncate write mode... */
+ fclose(f);
+ f = BLI_fopen(file, "w+b");
+ }
+ else {
+ /* Otherwise, rewrite first byte. */
+ rewind(f);
+ putc(c, f);
+ }
+ }
+ else {
+ f = BLI_fopen(file, "wb");
+ }
+ if (f) {
+ fclose(f);
+ return true;
+ }
+ return false;
}
#ifdef WIN32
static void callLocalErrorCallBack(const char *err)
{
- printf("%s\n", err);
+ printf("%s\n", err);
}
FILE *BLI_fopen(const char *filename, const char *mode)
{
- BLI_assert(!BLI_path_is_rel(filename));
+ BLI_assert(!BLI_path_is_rel(filename));
- return ufopen(filename, mode);
+ return ufopen(filename, mode);
}
void BLI_get_short_name(char short_name[256], const char *filename)
{
- wchar_t short_name_16[256];
- int i = 0;
+ wchar_t short_name_16[256];
+ int i = 0;
- UTF16_ENCODE(filename);
+ UTF16_ENCODE(filename);
- GetShortPathNameW(filename_16, short_name_16, 256);
+ GetShortPathNameW(filename_16, short_name_16, 256);
- for (i = 0; i < 256; i++) {
- short_name[i] = (char)short_name_16[i];
- }
+ for (i = 0; i < 256; i++) {
+ short_name[i] = (char)short_name_16[i];
+ }
- UTF16_UN_ENCODE(filename);
+ UTF16_UN_ENCODE(filename);
}
void *BLI_gzopen(const char *filename, const char *mode)
{
- gzFile gzfile;
+ gzFile gzfile;
- BLI_assert(!BLI_path_is_rel(filename));
+ BLI_assert(!BLI_path_is_rel(filename));
- /* xxx Creates file before transcribing the path */
- if (mode[0] == 'w') {
- fclose(ufopen(filename, "a"));
- }
+ /* xxx Creates file before transcribing the path */
+ if (mode[0] == 'w') {
+ fclose(ufopen(filename, "a"));
+ }
- /* temporary #if until we update all libraries to 1.2.7
- * for correct wide char path handling */
-#if ZLIB_VERNUM >= 0x1270
- UTF16_ENCODE(filename);
+ /* temporary #if until we update all libraries to 1.2.7
+ * for correct wide char path handling */
+# if ZLIB_VERNUM >= 0x1270
+ UTF16_ENCODE(filename);
- gzfile = gzopen_w(filename_16, mode);
+ gzfile = gzopen_w(filename_16, mode);
- UTF16_UN_ENCODE(filename);
-#else
- {
- char short_name[256];
- BLI_get_short_name(short_name, filename);
- gzfile = gzopen(short_name, mode);
- }
-#endif
+ UTF16_UN_ENCODE(filename);
+# else
+ {
+ char short_name[256];
+ BLI_get_short_name(short_name, filename);
+ gzfile = gzopen(short_name, mode);
+ }
+# endif
- return gzfile;
+ return gzfile;
}
-int BLI_open(const char *filename, int oflag, int pmode)
+int BLI_open(const char *filename, int oflag, int pmode)
{
- BLI_assert(!BLI_path_is_rel(filename));
+ BLI_assert(!BLI_path_is_rel(filename));
- return uopen(filename, oflag, pmode);
+ return uopen(filename, oflag, pmode);
}
-int BLI_access(const char *filename, int mode)
+int BLI_access(const char *filename, int mode)
{
- BLI_assert(!BLI_path_is_rel(filename));
+ BLI_assert(!BLI_path_is_rel(filename));
- return uaccess(filename, mode);
+ return uaccess(filename, mode);
}
static bool delete_unique(const char *path, const bool dir)
{
- bool err;
-
- UTF16_ENCODE(path);
-
- if (dir) {
- err = !RemoveDirectoryW(path_16);
- if (err) {
- printf("Unable to remove directory\n");
- }
- }
- else {
- err = !DeleteFileW(path_16);
- if (err) {
- callLocalErrorCallBack("Unable to delete file");
- }
- }
-
- UTF16_UN_ENCODE(path);
-
- return err;
+ bool err;
+
+ UTF16_ENCODE(path);
+
+ if (dir) {
+ err = !RemoveDirectoryW(path_16);
+ if (err) {
+ printf("Unable to remove directory\n");
+ }
+ }
+ else {
+ err = !DeleteFileW(path_16);
+ if (err) {
+ callLocalErrorCallBack("Unable to delete file");
+ }
+ }
+
+ UTF16_UN_ENCODE(path);
+
+ return err;
}
static bool delete_recursive(const char *dir)
{
- struct direntry *filelist, *fl;
- bool err = false;
- uint nbr, i;
-
- i = nbr = BLI_filelist_dir_contents(dir, &filelist);
- fl = filelist;
- while (i--) {
- const char *file = BLI_path_basename(fl->path);
-
- if (FILENAME_IS_CURRPAR(file)) {
- /* Skip! */
- }
- else if (S_ISDIR(fl->type)) {
- char path[FILE_MAXDIR];
-
- /* dir listing produces dir path without trailing slash... */
- BLI_strncpy(path, fl->path, sizeof(path));
- BLI_add_slash(path);
-
- if (delete_recursive(path)) {
- err = true;
- }
- }
- else {
- if (delete_unique(fl->path, false)) {
- err = true;
- }
- }
- ++fl;
- }
-
- if (!err && delete_unique(dir, true)) {
- err = true;
- }
-
- BLI_filelist_free(filelist, nbr);
-
- return err;
+ struct direntry *filelist, *fl;
+ bool err = false;
+ uint nbr, i;
+
+ i = nbr = BLI_filelist_dir_contents(dir, &filelist);
+ fl = filelist;
+ while (i--) {
+ const char *file = BLI_path_basename(fl->path);
+
+ if (FILENAME_IS_CURRPAR(file)) {
+ /* Skip! */
+ }
+ else if (S_ISDIR(fl->type)) {
+ char path[FILE_MAXDIR];
+
+ /* dir listing produces dir path without trailing slash... */
+ BLI_strncpy(path, fl->path, sizeof(path));
+ BLI_add_slash(path);
+
+ if (delete_recursive(path)) {
+ err = true;
+ }
+ }
+ else {
+ if (delete_unique(fl->path, false)) {
+ err = true;
+ }
+ }
+ ++fl;
+ }
+
+ if (!err && delete_unique(dir, true)) {
+ err = true;
+ }
+
+ BLI_filelist_free(filelist, nbr);
+
+ return err;
}
int BLI_delete(const char *file, bool dir, bool recursive)
{
- int err;
+ int err;
- BLI_assert(!BLI_path_is_rel(file));
+ BLI_assert(!BLI_path_is_rel(file));
- if (recursive) {
- err = delete_recursive(file);
- }
- else {
- err = delete_unique(file, dir);
- }
+ if (recursive) {
+ err = delete_recursive(file);
+ }
+ else {
+ err = delete_unique(file, dir);
+ }
- return err;
+ return err;
}
/* Not used anywhere! */
-#if 0
+# if 0
int BLI_move(const char *file, const char *to)
{
- char str[MAXPATHLEN + 12];
- int err;
-
- /* windows doesn't support moving to a directory
- * it has to be 'mv filename filename' and not
- * 'mv filename destdir' */
-
- BLI_strncpy(str, to, sizeof(str));
- /* points 'to' to a directory ? */
- if (BLI_last_slash(str) == (str + strlen(str) - 1)) {
- if (BLI_last_slash(file) != NULL) {
- strcat(str, BLI_last_slash(file) + 1);
- }
- }
-
- UTF16_ENCODE(file);
- UTF16_ENCODE(str);
- err = !MoveFileW(file_16, str_16);
- UTF16_UN_ENCODE(str);
- UTF16_UN_ENCODE(file);
-
- if (err) {
- callLocalErrorCallBack("Unable to move file");
- printf(" Move from '%s' to '%s' failed\n", file, str);
- }
-
- return err;
+ char str[MAXPATHLEN + 12];
+ int err;
+
+ /* windows doesn't support moving to a directory
+ * it has to be 'mv filename filename' and not
+ * 'mv filename destdir' */
+
+ BLI_strncpy(str, to, sizeof(str));
+ /* points 'to' to a directory ? */
+ if (BLI_last_slash(str) == (str + strlen(str) - 1)) {
+ if (BLI_last_slash(file) != NULL) {
+ strcat(str, BLI_last_slash(file) + 1);
+ }
+ }
+
+ UTF16_ENCODE(file);
+ UTF16_ENCODE(str);
+ err = !MoveFileW(file_16, str_16);
+ UTF16_UN_ENCODE(str);
+ UTF16_UN_ENCODE(file);
+
+ if (err) {
+ callLocalErrorCallBack("Unable to move file");
+ printf(" Move from '%s' to '%s' failed\n", file, str);
+ }
+
+ return err;
}
-#endif
+# endif
int BLI_copy(const char *file, const char *to)
{
- char str[MAXPATHLEN + 12];
- int err;
-
- /* windows doesn't support copying to a directory
- * it has to be 'cp filename filename' and not
- * 'cp filename destdir' */
-
- BLI_strncpy(str, to, sizeof(str));
- /* points 'to' to a directory ? */
- if (BLI_last_slash(str) == (str + strlen(str) - 1)) {
- if (BLI_last_slash(file) != NULL) {
- strcat(str, BLI_last_slash(file) + 1);
- }
- }
-
- UTF16_ENCODE(file);
- UTF16_ENCODE(str);
- err = !CopyFileW(file_16, str_16, false);
- UTF16_UN_ENCODE(str);
- UTF16_UN_ENCODE(file);
-
- if (err) {
- callLocalErrorCallBack("Unable to copy file!");
- printf(" Copy from '%s' to '%s' failed\n", file, str);
- }
-
- return err;
+ char str[MAXPATHLEN + 12];
+ int err;
+
+ /* windows doesn't support copying to a directory
+ * it has to be 'cp filename filename' and not
+ * 'cp filename destdir' */
+
+ BLI_strncpy(str, to, sizeof(str));
+ /* points 'to' to a directory ? */
+ if (BLI_last_slash(str) == (str + strlen(str) - 1)) {
+ if (BLI_last_slash(file) != NULL) {
+ strcat(str, BLI_last_slash(file) + 1);
+ }
+ }
+
+ UTF16_ENCODE(file);
+ UTF16_ENCODE(str);
+ err = !CopyFileW(file_16, str_16, false);
+ UTF16_UN_ENCODE(str);
+ UTF16_UN_ENCODE(file);
+
+ if (err) {
+ callLocalErrorCallBack("Unable to copy file!");
+ printf(" Copy from '%s' to '%s' failed\n", file, str);
+ }
+
+ return err;
}
-#if 0
+# if 0
int BLI_create_symlink(const char *file, const char *to)
{
- /* See patch from T30870, should this ever become needed. */
- callLocalErrorCallBack("Linking files is unsupported on Windows");
- (void)file;
- (void)to;
- return 1;
+ /* See patch from T30870, should this ever become needed. */
+ callLocalErrorCallBack("Linking files is unsupported on Windows");
+ (void)file;
+ (void)to;
+ return 1;
}
-#endif
+# endif
/** \return true on success (i.e. given path now exists on FS), false otherwise. */
bool BLI_dir_create_recursive(const char *dirname)
{
- char *lslash;
- char tmp[MAXPATHLEN];
- bool ret = true;
-
- /* First remove possible slash at the end of the dirname.
- * This routine otherwise tries to create
- * blah1/blah2/ (with slash) after creating
- * blah1/blah2 (without slash) */
-
- BLI_strncpy(tmp, dirname, sizeof(tmp));
- BLI_del_slash(tmp);
-
- /* check special case "c:\foo", don't try create "c:", harmless but prints an error below */
- if (isalpha(tmp[0]) && (tmp[1] == ':') && tmp[2] == '\0') {
- return true;
- }
-
- if (BLI_is_dir(tmp)) {
- return true;
- }
- else if (BLI_exists(tmp)) {
- return false;
- }
-
- lslash = (char *)BLI_last_slash(tmp);
-
- if (lslash) {
- /* Split about the last slash and recurse */
- *lslash = 0;
- if (!BLI_dir_create_recursive(tmp)) {
- ret = false;
- }
- }
-
- if (ret && dirname[0]) { /* patch, this recursive loop tries to create a nameless directory */
- if (umkdir(dirname) == -1) {
- printf("Unable to create directory %s\n", dirname);
- ret = false;
- }
- }
- return ret;
+ char *lslash;
+ char tmp[MAXPATHLEN];
+ bool ret = true;
+
+ /* First remove possible slash at the end of the dirname.
+ * This routine otherwise tries to create
+ * blah1/blah2/ (with slash) after creating
+ * blah1/blah2 (without slash) */
+
+ BLI_strncpy(tmp, dirname, sizeof(tmp));
+ BLI_del_slash(tmp);
+
+ /* check special case "c:\foo", don't try create "c:", harmless but prints an error below */
+ if (isalpha(tmp[0]) && (tmp[1] == ':') && tmp[2] == '\0') {
+ return true;
+ }
+
+ if (BLI_is_dir(tmp)) {
+ return true;
+ }
+ else if (BLI_exists(tmp)) {
+ return false;
+ }
+
+ lslash = (char *)BLI_last_slash(tmp);
+
+ if (lslash) {
+ /* Split about the last slash and recurse */
+ *lslash = 0;
+ if (!BLI_dir_create_recursive(tmp)) {
+ ret = false;
+ }
+ }
+
+ if (ret && dirname[0]) { /* patch, this recursive loop tries to create a nameless directory */
+ if (umkdir(dirname) == -1) {
+ printf("Unable to create directory %s\n", dirname);
+ ret = false;
+ }
+ }
+ return ret;
}
int BLI_rename(const char *from, const char *to)
{
- if (!BLI_exists(from)) {
- return 0;
- }
-
- /* make sure the filenames are different (case insensitive) before removing */
- if (BLI_exists(to) && BLI_strcasecmp(from, to)) {
- if (BLI_delete(to, false, false)) {
- return 1;
- }
- }
-
- return urename(from, to);
+ if (!BLI_exists(from)) {
+ return 0;
+ }
+
+ /* make sure the filenames are different (case insensitive) before removing */
+ if (BLI_exists(to) && BLI_strcasecmp(from, to)) {
+ if (BLI_delete(to, false, false)) {
+ return 1;
+ }
+ }
+
+ return urename(from, to);
}
#else /* The UNIX world */
/* results from recursive_operation and its callbacks */
enum {
- /* operation succeeded */
- RecursiveOp_Callback_OK = 0,
+ /* operation succeeded */
+ RecursiveOp_Callback_OK = 0,
- /* operation requested not to perform recursive digging for current path */
- RecursiveOp_Callback_StopRecurs = 1,
+ /* operation requested not to perform recursive digging for current path */
+ RecursiveOp_Callback_StopRecurs = 1,
- /* error occured in callback and recursive walking should stop immediately */
- RecursiveOp_Callback_Error = 2,
+ /* error occured in callback and recursive walking should stop immediately */
+ RecursiveOp_Callback_Error = 2,
};
typedef int (*RecursiveOp_Callback)(const char *from, const char *to);
@@ -526,30 +525,28 @@ typedef int (*RecursiveOp_Callback)(const char *from, const char *to);
/* appending of filename to dir (ensures for buffer size before appending) */
static void join_dirfile_alloc(char **dst, size_t *alloc_len, const char *dir, const char *file)
{
- size_t len = strlen(dir) + strlen(file) + 1;
+ size_t len = strlen(dir) + strlen(file) + 1;
- if (*dst == NULL) {
- *dst = MEM_mallocN(len + 1, "join_dirfile_alloc path");
- }
- else if (*alloc_len < len) {
- *dst = MEM_reallocN(*dst, len + 1);
- }
+ if (*dst == NULL) {
+ *dst = MEM_mallocN(len + 1, "join_dirfile_alloc path");
+ }
+ else if (*alloc_len < len) {
+ *dst = MEM_reallocN(*dst, len + 1);
+ }
- *alloc_len = len;
+ *alloc_len = len;
- BLI_join_dirfile(*dst, len + 1, dir, file);
+ BLI_join_dirfile(*dst, len + 1, dir, file);
}
static char *strip_last_slash(const char *dir)
{
- char *result = BLI_strdup(dir);
- BLI_del_slash(result);
+ char *result = BLI_strdup(dir);
+ BLI_del_slash(result);
- return result;
+ return result;
}
-
-
/**
* Scans \a startfrom, generating a corresponding destination name for each item found by
* prefixing it with startto, recursively scanning subdirectories, and invoking the specified
@@ -563,190 +560,192 @@ static char *strip_last_slash(const char *dir)
* \param callback_dir_post: optional, to be invoked after leaving a subdirectory.
* \return
*/
-static int recursive_operation(const char *startfrom, const char *startto,
+static int recursive_operation(const char *startfrom,
+ const char *startto,
RecursiveOp_Callback callback_dir_pre,
- RecursiveOp_Callback callback_file, RecursiveOp_Callback callback_dir_post)
+ RecursiveOp_Callback callback_file,
+ RecursiveOp_Callback callback_dir_post)
{
- struct stat st;
- char *from = NULL, *to = NULL;
- char *from_path = NULL, *to_path = NULL;
- struct dirent **dirlist = NULL;
- size_t from_alloc_len = -1, to_alloc_len = -1;
- int i, n = 0, ret = 0;
-
- do { /* once */
- /* ensure there's no trailing slash in file path */
- from = strip_last_slash(startfrom);
- if (startto) {
- to = strip_last_slash(startto);
- }
-
- ret = lstat(from, &st);
- if (ret < 0) {
- /* source wasn't found, nothing to operate with */
- break;
- }
-
- if (!S_ISDIR(st.st_mode)) {
- /* source isn't a directory, can't do recursive walking for it,
- * so just call file callback and leave */
- if (callback_file != NULL) {
- ret = callback_file(from, to);
- if (ret != RecursiveOp_Callback_OK) {
- ret = -1;
- }
- }
- break;
- }
-
- n = scandir(startfrom, &dirlist, NULL, alphasort);
- if (n < 0) {
- /* error opening directory for listing */
- perror("scandir");
- ret = -1;
- break;
- }
-
- if (callback_dir_pre != NULL) {
- ret = callback_dir_pre(from, to);
- if (ret != RecursiveOp_Callback_OK) {
- if (ret == RecursiveOp_Callback_StopRecurs) {
- /* callback requested not to perform recursive walking, not an error */
- ret = 0;
- }
- else {
- ret = -1;
- }
- break;
- }
- }
-
- for (i = 0; i < n; i++) {
- const struct dirent * const dirent = dirlist[i];
-
- if (FILENAME_IS_CURRPAR(dirent->d_name)) {
- continue;
- }
-
- join_dirfile_alloc(&from_path, &from_alloc_len, from, dirent->d_name);
- if (to) {
- join_dirfile_alloc(&to_path, &to_alloc_len, to, dirent->d_name);
- }
-
- bool is_dir;
-
-#ifdef __HAIKU__
- {
- struct stat st_dir;
- char filename[FILE_MAX];
- BLI_path_join(filename, sizeof(filename), startfrom, dirent->d_name, NULL);
- lstat(filename, &st_dir);
- is_dir = S_ISDIR(st_dir.st_mode);
- }
-#else
- is_dir = (dirent->d_type == DT_DIR);
-#endif
-
- if (is_dir) {
- /* recursively dig into a subfolder */
- ret = recursive_operation(from_path, to_path, callback_dir_pre, callback_file, callback_dir_post);
- }
- else if (callback_file != NULL) {
- ret = callback_file(from_path, to_path);
- if (ret != RecursiveOp_Callback_OK) {
- ret = -1;
- }
- }
-
- if (ret != 0) {
- break;
- }
- }
- if (ret != 0) {
- break;
- }
-
- if (callback_dir_post != NULL) {
- ret = callback_dir_post(from, to);
- if (ret != RecursiveOp_Callback_OK) {
- ret = -1;
- }
- }
- } while (false);
-
- if (dirlist != NULL) {
- for (i = 0; i < n; i++) {
- free(dirlist[i]);
- }
- free(dirlist);
- }
- if (from_path != NULL) {
- MEM_freeN(from_path);
- }
- if (to_path != NULL) {
- MEM_freeN(to_path);
- }
- if (from != NULL) {
- MEM_freeN(from);
- }
- if (to != NULL) {
- MEM_freeN(to);
- }
-
- return ret;
+ struct stat st;
+ char *from = NULL, *to = NULL;
+ char *from_path = NULL, *to_path = NULL;
+ struct dirent **dirlist = NULL;
+ size_t from_alloc_len = -1, to_alloc_len = -1;
+ int i, n = 0, ret = 0;
+
+ do { /* once */
+ /* ensure there's no trailing slash in file path */
+ from = strip_last_slash(startfrom);
+ if (startto) {
+ to = strip_last_slash(startto);
+ }
+
+ ret = lstat(from, &st);
+ if (ret < 0) {
+ /* source wasn't found, nothing to operate with */
+ break;
+ }
+
+ if (!S_ISDIR(st.st_mode)) {
+ /* source isn't a directory, can't do recursive walking for it,
+ * so just call file callback and leave */
+ if (callback_file != NULL) {
+ ret = callback_file(from, to);
+ if (ret != RecursiveOp_Callback_OK) {
+ ret = -1;
+ }
+ }
+ break;
+ }
+
+ n = scandir(startfrom, &dirlist, NULL, alphasort);
+ if (n < 0) {
+ /* error opening directory for listing */
+ perror("scandir");
+ ret = -1;
+ break;
+ }
+
+ if (callback_dir_pre != NULL) {
+ ret = callback_dir_pre(from, to);
+ if (ret != RecursiveOp_Callback_OK) {
+ if (ret == RecursiveOp_Callback_StopRecurs) {
+ /* callback requested not to perform recursive walking, not an error */
+ ret = 0;
+ }
+ else {
+ ret = -1;
+ }
+ break;
+ }
+ }
+
+ for (i = 0; i < n; i++) {
+ const struct dirent *const dirent = dirlist[i];
+
+ if (FILENAME_IS_CURRPAR(dirent->d_name)) {
+ continue;
+ }
+
+ join_dirfile_alloc(&from_path, &from_alloc_len, from, dirent->d_name);
+ if (to) {
+ join_dirfile_alloc(&to_path, &to_alloc_len, to, dirent->d_name);
+ }
+
+ bool is_dir;
+
+# ifdef __HAIKU__
+ {
+ struct stat st_dir;
+ char filename[FILE_MAX];
+ BLI_path_join(filename, sizeof(filename), startfrom, dirent->d_name, NULL);
+ lstat(filename, &st_dir);
+ is_dir = S_ISDIR(st_dir.st_mode);
+ }
+# else
+ is_dir = (dirent->d_type == DT_DIR);
+# endif
+
+ if (is_dir) {
+ /* recursively dig into a subfolder */
+ ret = recursive_operation(
+ from_path, to_path, callback_dir_pre, callback_file, callback_dir_post);
+ }
+ else if (callback_file != NULL) {
+ ret = callback_file(from_path, to_path);
+ if (ret != RecursiveOp_Callback_OK) {
+ ret = -1;
+ }
+ }
+
+ if (ret != 0) {
+ break;
+ }
+ }
+ if (ret != 0) {
+ break;
+ }
+
+ if (callback_dir_post != NULL) {
+ ret = callback_dir_post(from, to);
+ if (ret != RecursiveOp_Callback_OK) {
+ ret = -1;
+ }
+ }
+ } while (false);
+
+ if (dirlist != NULL) {
+ for (i = 0; i < n; i++) {
+ free(dirlist[i]);
+ }
+ free(dirlist);
+ }
+ if (from_path != NULL) {
+ MEM_freeN(from_path);
+ }
+ if (to_path != NULL) {
+ MEM_freeN(to_path);
+ }
+ if (from != NULL) {
+ MEM_freeN(from);
+ }
+ if (to != NULL) {
+ MEM_freeN(to);
+ }
+
+ return ret;
}
static int delete_callback_post(const char *from, const char *UNUSED(to))
{
- if (rmdir(from)) {
- perror("rmdir");
+ if (rmdir(from)) {
+ perror("rmdir");
- return RecursiveOp_Callback_Error;
- }
+ return RecursiveOp_Callback_Error;
+ }
- return RecursiveOp_Callback_OK;
+ return RecursiveOp_Callback_OK;
}
static int delete_single_file(const char *from, const char *UNUSED(to))
{
- if (unlink(from)) {
- perror("unlink");
+ if (unlink(from)) {
+ perror("unlink");
- return RecursiveOp_Callback_Error;
- }
+ return RecursiveOp_Callback_Error;
+ }
- return RecursiveOp_Callback_OK;
+ return RecursiveOp_Callback_OK;
}
FILE *BLI_fopen(const char *filename, const char *mode)
{
- BLI_assert(!BLI_path_is_rel(filename));
+ BLI_assert(!BLI_path_is_rel(filename));
- return fopen(filename, mode);
+ return fopen(filename, mode);
}
void *BLI_gzopen(const char *filename, const char *mode)
{
- BLI_assert(!BLI_path_is_rel(filename));
+ BLI_assert(!BLI_path_is_rel(filename));
- return gzopen(filename, mode);
+ return gzopen(filename, mode);
}
int BLI_open(const char *filename, int oflag, int pmode)
{
- BLI_assert(!BLI_path_is_rel(filename));
+ BLI_assert(!BLI_path_is_rel(filename));
- return open(filename, oflag, pmode);
+ return open(filename, oflag, pmode);
}
-int BLI_access(const char *filename, int mode)
+int BLI_access(const char *filename, int mode)
{
- BLI_assert(!BLI_path_is_rel(filename));
+ BLI_assert(!BLI_path_is_rel(filename));
- return access(filename, mode);
+ return access(filename, mode);
}
-
/**
* Deletes the specified file or directory (depending on dir), optionally
* doing recursive delete of directory contents.
@@ -755,17 +754,17 @@ int BLI_access(const char *filename, int mode)
*/
int BLI_delete(const char *file, bool dir, bool recursive)
{
- BLI_assert(!BLI_path_is_rel(file));
-
- if (recursive) {
- return recursive_operation(file, NULL, NULL, delete_single_file, delete_callback_post);
- }
- else if (dir) {
- return rmdir(file);
- }
- else {
- return remove(file);
- }
+ BLI_assert(!BLI_path_is_rel(file));
+
+ if (recursive) {
+ return recursive_operation(file, NULL, NULL, delete_single_file, delete_callback_post);
+ }
+ else if (dir) {
+ return rmdir(file);
+ }
+ else {
+ return remove(file);
+ }
}
/**
@@ -773,17 +772,17 @@ int BLI_delete(const char *file, bool dir, bool recursive)
*/
static bool check_the_same(const char *path_a, const char *path_b)
{
- struct stat st_a, st_b;
+ struct stat st_a, st_b;
- if (lstat(path_a, &st_a)) {
- return false;
- }
+ if (lstat(path_a, &st_a)) {
+ return false;
+ }
- if (lstat(path_b, &st_b)) {
- return false;
- }
+ if (lstat(path_b, &st_b)) {
+ return false;
+ }
- return st_a.st_dev == st_b.st_dev && st_a.st_ino == st_b.st_ino;
+ return st_a.st_dev == st_b.st_dev && st_a.st_ino == st_b.st_ino;
}
/**
@@ -791,298 +790,295 @@ static bool check_the_same(const char *path_a, const char *path_b)
*/
static int set_permissions(const char *file, const struct stat *st)
{
- if (chown(file, st->st_uid, st->st_gid)) {
- perror("chown");
- return -1;
- }
+ if (chown(file, st->st_uid, st->st_gid)) {
+ perror("chown");
+ return -1;
+ }
- if (chmod(file, st->st_mode)) {
- perror("chmod");
- return -1;
- }
+ if (chmod(file, st->st_mode)) {
+ perror("chmod");
+ return -1;
+ }
- return 0;
+ return 0;
}
/* pre-recursive callback for copying operation
* creates a destination directory where all source content fill be copied to */
static int copy_callback_pre(const char *from, const char *to)
{
- struct stat st;
-
- if (check_the_same(from, to)) {
- fprintf(stderr, "%s: '%s' is the same as '%s'\n", __func__, from, to);
- return RecursiveOp_Callback_Error;
- }
-
- if (lstat(from, &st)) {
- perror("stat");
- return RecursiveOp_Callback_Error;
- }
-
- /* create a directory */
- if (mkdir(to, st.st_mode)) {
- perror("mkdir");
- return RecursiveOp_Callback_Error;
- }
-
- /* set proper owner and group on new directory */
- if (chown(to, st.st_uid, st.st_gid)) {
- perror("chown");
- return RecursiveOp_Callback_Error;
- }
-
- return RecursiveOp_Callback_OK;
+ struct stat st;
+
+ if (check_the_same(from, to)) {
+ fprintf(stderr, "%s: '%s' is the same as '%s'\n", __func__, from, to);
+ return RecursiveOp_Callback_Error;
+ }
+
+ if (lstat(from, &st)) {
+ perror("stat");
+ return RecursiveOp_Callback_Error;
+ }
+
+ /* create a directory */
+ if (mkdir(to, st.st_mode)) {
+ perror("mkdir");
+ return RecursiveOp_Callback_Error;
+ }
+
+ /* set proper owner and group on new directory */
+ if (chown(to, st.st_uid, st.st_gid)) {
+ perror("chown");
+ return RecursiveOp_Callback_Error;
+ }
+
+ return RecursiveOp_Callback_OK;
}
static int copy_single_file(const char *from, const char *to)
{
- FILE *from_stream, *to_stream;
- struct stat st;
- char buf[4096];
- size_t len;
-
- if (check_the_same(from, to)) {
- fprintf(stderr, "%s: '%s' is the same as '%s'\n", __func__, from, to);
- return RecursiveOp_Callback_Error;
- }
-
- if (lstat(from, &st)) {
- perror("lstat");
- return RecursiveOp_Callback_Error;
- }
-
- if (S_ISLNK(st.st_mode)) {
- /* symbolic links should be copied in special way */
- char *link_buffer;
- int need_free;
- ssize_t link_len;
-
- /* get large enough buffer to read link content */
- if ((st.st_size + 1) < sizeof(buf)) {
- link_buffer = buf;
- need_free = 0;
- }
- else {
- link_buffer = MEM_callocN(st.st_size + 2, "copy_single_file link_buffer");
- need_free = 1;
- }
-
- link_len = readlink(from, link_buffer, st.st_size + 1);
- if (link_len < 0) {
- perror("readlink");
-
- if (need_free) {
- MEM_freeN(link_buffer);
- }
-
- return RecursiveOp_Callback_Error;
- }
-
- link_buffer[link_len] = '\0';
-
- if (symlink(link_buffer, to)) {
- perror("symlink");
- if (need_free) {
- MEM_freeN(link_buffer);
- }
- return RecursiveOp_Callback_Error;
- }
-
- if (need_free) {
- MEM_freeN(link_buffer);
- }
-
- return RecursiveOp_Callback_OK;
- }
- else if (S_ISCHR(st.st_mode) ||
- S_ISBLK(st.st_mode) ||
- S_ISFIFO(st.st_mode) ||
- S_ISSOCK(st.st_mode))
- {
- /* copy special type of file */
- if (mknod(to, st.st_mode, st.st_rdev)) {
- perror("mknod");
- return RecursiveOp_Callback_Error;
- }
-
- if (set_permissions(to, &st)) {
- return RecursiveOp_Callback_Error;
- }
-
- return RecursiveOp_Callback_OK;
- }
- else if (!S_ISREG(st.st_mode)) {
- fprintf(stderr, "Copying of this kind of files isn't supported yet\n");
- return RecursiveOp_Callback_Error;
- }
-
- from_stream = fopen(from, "rb");
- if (!from_stream) {
- perror("fopen");
- return RecursiveOp_Callback_Error;
- }
-
- to_stream = fopen(to, "wb");
- if (!to_stream) {
- perror("fopen");
- fclose(from_stream);
- return RecursiveOp_Callback_Error;
- }
-
- while ((len = fread(buf, 1, sizeof(buf), from_stream)) > 0) {
- fwrite(buf, 1, len, to_stream);
- }
-
- fclose(to_stream);
- fclose(from_stream);
-
- if (set_permissions(to, &st)) {
- return RecursiveOp_Callback_Error;
- }
-
- return RecursiveOp_Callback_OK;
+ FILE *from_stream, *to_stream;
+ struct stat st;
+ char buf[4096];
+ size_t len;
+
+ if (check_the_same(from, to)) {
+ fprintf(stderr, "%s: '%s' is the same as '%s'\n", __func__, from, to);
+ return RecursiveOp_Callback_Error;
+ }
+
+ if (lstat(from, &st)) {
+ perror("lstat");
+ return RecursiveOp_Callback_Error;
+ }
+
+ if (S_ISLNK(st.st_mode)) {
+ /* symbolic links should be copied in special way */
+ char *link_buffer;
+ int need_free;
+ ssize_t link_len;
+
+ /* get large enough buffer to read link content */
+ if ((st.st_size + 1) < sizeof(buf)) {
+ link_buffer = buf;
+ need_free = 0;
+ }
+ else {
+ link_buffer = MEM_callocN(st.st_size + 2, "copy_single_file link_buffer");
+ need_free = 1;
+ }
+
+ link_len = readlink(from, link_buffer, st.st_size + 1);
+ if (link_len < 0) {
+ perror("readlink");
+
+ if (need_free) {
+ MEM_freeN(link_buffer);
+ }
+
+ return RecursiveOp_Callback_Error;
+ }
+
+ link_buffer[link_len] = '\0';
+
+ if (symlink(link_buffer, to)) {
+ perror("symlink");
+ if (need_free) {
+ MEM_freeN(link_buffer);
+ }
+ return RecursiveOp_Callback_Error;
+ }
+
+ if (need_free) {
+ MEM_freeN(link_buffer);
+ }
+
+ return RecursiveOp_Callback_OK;
+ }
+ else if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode) || S_ISFIFO(st.st_mode) ||
+ S_ISSOCK(st.st_mode)) {
+ /* copy special type of file */
+ if (mknod(to, st.st_mode, st.st_rdev)) {
+ perror("mknod");
+ return RecursiveOp_Callback_Error;
+ }
+
+ if (set_permissions(to, &st)) {
+ return RecursiveOp_Callback_Error;
+ }
+
+ return RecursiveOp_Callback_OK;
+ }
+ else if (!S_ISREG(st.st_mode)) {
+ fprintf(stderr, "Copying of this kind of files isn't supported yet\n");
+ return RecursiveOp_Callback_Error;
+ }
+
+ from_stream = fopen(from, "rb");
+ if (!from_stream) {
+ perror("fopen");
+ return RecursiveOp_Callback_Error;
+ }
+
+ to_stream = fopen(to, "wb");
+ if (!to_stream) {
+ perror("fopen");
+ fclose(from_stream);
+ return RecursiveOp_Callback_Error;
+ }
+
+ while ((len = fread(buf, 1, sizeof(buf), from_stream)) > 0) {
+ fwrite(buf, 1, len, to_stream);
+ }
+
+ fclose(to_stream);
+ fclose(from_stream);
+
+ if (set_permissions(to, &st)) {
+ return RecursiveOp_Callback_Error;
+ }
+
+ return RecursiveOp_Callback_OK;
}
/* Not used anywhere! */
-#if 0
+# if 0
static int move_callback_pre(const char *from, const char *to)
{
- int ret = rename(from, to);
+ int ret = rename(from, to);
- if (ret)
- return copy_callback_pre(from, to);
+ if (ret)
+ return copy_callback_pre(from, to);
- return RecursiveOp_Callback_StopRecurs;
+ return RecursiveOp_Callback_StopRecurs;
}
static int move_single_file(const char *from, const char *to)
{
- int ret = rename(from, to);
+ int ret = rename(from, to);
- if (ret)
- return copy_single_file(from, to);
+ if (ret)
+ return copy_single_file(from, to);
- return RecursiveOp_Callback_OK;
+ return RecursiveOp_Callback_OK;
}
/* if *file represents a directory, moves all its contents into *to, else renames
* file itself to *to. */
int BLI_move(const char *file, const char *to)
{
- int ret = recursive_operation(file, to, move_callback_pre, move_single_file, NULL);
+ int ret = recursive_operation(file, to, move_callback_pre, move_single_file, NULL);
- if (ret && ret != -1) {
- return recursive_operation(file, NULL, NULL, delete_single_file, delete_callback_post);
- }
+ if (ret && ret != -1) {
+ return recursive_operation(file, NULL, NULL, delete_single_file, delete_callback_post);
+ }
- return ret;
+ return ret;
}
-#endif
+# endif
static const char *check_destination(const char *file, const char *to)
{
- struct stat st;
+ struct stat st;
- if (!stat(to, &st)) {
- if (S_ISDIR(st.st_mode)) {
- char *str, *path;
- const char *filename;
- size_t len = 0;
+ if (!stat(to, &st)) {
+ if (S_ISDIR(st.st_mode)) {
+ char *str, *path;
+ const char *filename;
+ size_t len = 0;
- str = strip_last_slash(file);
- filename = BLI_last_slash(str);
+ str = strip_last_slash(file);
+ filename = BLI_last_slash(str);
- if (!filename) {
- MEM_freeN(str);
- return (char *)to;
- }
+ if (!filename) {
+ MEM_freeN(str);
+ return (char *)to;
+ }
- /* skip slash */
- filename += 1;
+ /* skip slash */
+ filename += 1;
- len = strlen(to) + strlen(filename) + 1;
- path = MEM_callocN(len + 1, "check_destination path");
- BLI_join_dirfile(path, len + 1, to, filename);
+ len = strlen(to) + strlen(filename) + 1;
+ path = MEM_callocN(len + 1, "check_destination path");
+ BLI_join_dirfile(path, len + 1, to, filename);
- MEM_freeN(str);
+ MEM_freeN(str);
- return path;
- }
- }
+ return path;
+ }
+ }
- return to;
+ return to;
}
int BLI_copy(const char *file, const char *to)
{
- const char *actual_to = check_destination(file, to);
- int ret;
+ const char *actual_to = check_destination(file, to);
+ int ret;
- ret = recursive_operation(file, actual_to, copy_callback_pre, copy_single_file, NULL);
+ ret = recursive_operation(file, actual_to, copy_callback_pre, copy_single_file, NULL);
- if (actual_to != to) {
- MEM_freeN((void *)actual_to);
- }
+ if (actual_to != to) {
+ MEM_freeN((void *)actual_to);
+ }
- return ret;
+ return ret;
}
-#if 0
+# if 0
int BLI_create_symlink(const char *file, const char *to)
{
- return symlink(to, file);
+ return symlink(to, file);
}
-#endif
+# endif
/** \return true on success (i.e. given path now exists on FS), false otherwise. */
bool BLI_dir_create_recursive(const char *dirname)
{
- char *lslash;
- size_t size;
-#ifdef MAXPATHLEN
- char static_buf[MAXPATHLEN];
-#endif
- char *tmp;
- bool ret = true;
-
- if (BLI_is_dir(dirname)) {
- return true;
- }
- else if (BLI_exists(dirname)) {
- return false;
- }
-
-#ifdef MAXPATHLEN
- size = MAXPATHLEN;
- tmp = static_buf;
-#else
- size = strlen(dirname) + 1;
- tmp = MEM_callocN(size, __func__);
-#endif
-
- BLI_strncpy(tmp, dirname, size);
-
- /* Avoids one useless recursion in case of '/foo/bar/' path... */
- BLI_del_slash(tmp);
-
- lslash = (char *)BLI_last_slash(tmp);
- if (lslash) {
- /* Split about the last slash and recurse */
- *lslash = 0;
- if (!BLI_dir_create_recursive(tmp)) {
- ret = false;
- }
- }
-
-#ifndef MAXPATHLEN
- MEM_freeN(tmp);
-#endif
-
- if (ret) {
- ret = (mkdir(dirname, 0777) == 0);
- }
- return ret;
+ char *lslash;
+ size_t size;
+# ifdef MAXPATHLEN
+ char static_buf[MAXPATHLEN];
+# endif
+ char *tmp;
+ bool ret = true;
+
+ if (BLI_is_dir(dirname)) {
+ return true;
+ }
+ else if (BLI_exists(dirname)) {
+ return false;
+ }
+
+# ifdef MAXPATHLEN
+ size = MAXPATHLEN;
+ tmp = static_buf;
+# else
+ size = strlen(dirname) + 1;
+ tmp = MEM_callocN(size, __func__);
+# endif
+
+ BLI_strncpy(tmp, dirname, size);
+
+ /* Avoids one useless recursion in case of '/foo/bar/' path... */
+ BLI_del_slash(tmp);
+
+ lslash = (char *)BLI_last_slash(tmp);
+ if (lslash) {
+ /* Split about the last slash and recurse */
+ *lslash = 0;
+ if (!BLI_dir_create_recursive(tmp)) {
+ ret = false;
+ }
+ }
+
+# ifndef MAXPATHLEN
+ MEM_freeN(tmp);
+# endif
+
+ if (ret) {
+ ret = (mkdir(dirname, 0777) == 0);
+ }
+ return ret;
}
/**
@@ -1090,17 +1086,17 @@ bool BLI_dir_create_recursive(const char *dirname)
*/
int BLI_rename(const char *from, const char *to)
{
- if (!BLI_exists(from)) {
- return 1;
- }
+ if (!BLI_exists(from)) {
+ return 1;
+ }
- if (BLI_exists(to)) {
- if (BLI_delete(to, false, false)) {
- return 1;
- }
- }
+ if (BLI_exists(to)) {
+ if (BLI_delete(to, false, false)) {
+ return 1;
+ }
+ }
- return rename(from, to);
+ return rename(from, to);
}
#endif
diff --git a/source/blender/blenlib/intern/fnmatch.c b/source/blender/blenlib/intern/fnmatch.c
index c0675e8c4d6..3df09976972 100644
--- a/source/blender/blenlib/intern/fnmatch.c
+++ b/source/blender/blenlib/intern/fnmatch.c
@@ -19,13 +19,12 @@
#ifdef WIN32
-
/* Maintained by GLIBC. */
/* clang-format off */
/* Enable GNU extensions in fnmatch.h. */
#ifndef _GNU_SOURCE
-# define _GNU_SOURCE 1
+# define _GNU_SOURCE 1
#endif
#include <errno.h>
@@ -69,170 +68,170 @@ fnmatch (const char *pattern, const char *string, int flags)
# define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c))
while ((c = *p++) != '\0')
- {
- c = FOLD (c);
-
- switch (c)
- {
- case '?':
- if (*n == '\0')
- return FNM_NOMATCH;
- else if ((flags & FNM_FILE_NAME) && *n == '/')
- return FNM_NOMATCH;
- else if ((flags & FNM_PERIOD) && *n == '.' &&
- (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
- return FNM_NOMATCH;
- break;
-
- case '\\':
- if (!(flags & FNM_NOESCAPE))
- {
- c = *p++;
- if (c == '\0')
- /* Trailing \ loses. */
- return FNM_NOMATCH;
- c = FOLD (c);
- }
- if (FOLD (*n) != c)
- return FNM_NOMATCH;
- break;
-
- case '*':
- if ((flags & FNM_PERIOD) && *n == '.' &&
- (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
- return FNM_NOMATCH;
-
- for (c = *p++; c == '?' || c == '*'; c = *p++)
- {
- if ((flags & FNM_FILE_NAME) && *n == '/')
- /* A slash does not match a wildcard under FNM_FILE_NAME. */
- return FNM_NOMATCH;
- else if (c == '?')
- {
- /* A ? needs to match one character. */
- if (*n == '\0')
- /* There isn't another character; no match. */
- return FNM_NOMATCH;
- else
- /* One character of the string is consumed in matching
- this ? wildcard, so *??? won't match if there are
- less than three characters. */
- ++n;
- }
- }
-
- if (c == '\0')
- return 0;
-
- {
- char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
- c1 = FOLD (c1);
- for (--p; *n != '\0'; ++n)
- if ((c == '[' || FOLD (*n) == c1) &&
- fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
- return 0;
- return FNM_NOMATCH;
- }
-
- case '[':
- {
- /* Nonzero if the sense of the character class is inverted. */
- register int not;
-
- if (*n == '\0')
- return FNM_NOMATCH;
-
- if ((flags & FNM_PERIOD) && *n == '.' &&
- (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
- return FNM_NOMATCH;
-
- not = (*p == '!' || *p == '^');
- if (not)
- ++p;
-
- c = *p++;
- for (;;)
- {
- register char cstart = c, cend = c;
-
- if (!(flags & FNM_NOESCAPE) && c == '\\')
- {
- if (*p == '\0')
- return FNM_NOMATCH;
- cstart = cend = *p++;
- }
-
- cstart = cend = FOLD (cstart);
-
- if (c == '\0')
- /* [ (unterminated) loses. */
- return FNM_NOMATCH;
-
- c = *p++;
- c = FOLD (c);
-
- if ((flags & FNM_FILE_NAME) && c == '/')
- /* [/] can never match. */
- return FNM_NOMATCH;
-
- if (c == '-' && *p != ']')
- {
- cend = *p++;
- if (!(flags & FNM_NOESCAPE) && cend == '\\')
- cend = *p++;
- if (cend == '\0')
- return FNM_NOMATCH;
- cend = FOLD (cend);
-
- c = *p++;
- }
-
- if (FOLD (*n) >= cstart && FOLD (*n) <= cend)
- goto matched;
-
- if (c == ']')
- break;
- }
- if (!not)
- return FNM_NOMATCH;
- break;
-
- matched:;
- /* Skip the rest of the [...] that already matched. */
- while (c != ']')
- {
- if (c == '\0')
- /* [... (unterminated) loses. */
- return FNM_NOMATCH;
-
- c = *p++;
- if (!(flags & FNM_NOESCAPE) && c == '\\')
- {
- if (*p == '\0')
- return FNM_NOMATCH;
- /* XXX 1003.2d11 is unclear if this is right. */
- ++p;
- }
- }
- if (not)
- return FNM_NOMATCH;
- }
- break;
-
- default:
- if (c != FOLD (*n))
- return FNM_NOMATCH;
- }
-
- ++n;
- }
+ {
+ c = FOLD (c);
+
+ switch (c)
+ {
+ case '?':
+ if (*n == '\0')
+ return FNM_NOMATCH;
+ else if ((flags & FNM_FILE_NAME) && *n == '/')
+ return FNM_NOMATCH;
+ else if ((flags & FNM_PERIOD) && *n == '.' &&
+ (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+ return FNM_NOMATCH;
+ break;
+
+ case '\\':
+ if (!(flags & FNM_NOESCAPE))
+ {
+ c = *p++;
+ if (c == '\0')
+ /* Trailing \ loses. */
+ return FNM_NOMATCH;
+ c = FOLD (c);
+ }
+ if (FOLD (*n) != c)
+ return FNM_NOMATCH;
+ break;
+
+ case '*':
+ if ((flags & FNM_PERIOD) && *n == '.' &&
+ (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+ return FNM_NOMATCH;
+
+ for (c = *p++; c == '?' || c == '*'; c = *p++)
+ {
+ if ((flags & FNM_FILE_NAME) && *n == '/')
+ /* A slash does not match a wildcard under FNM_FILE_NAME. */
+ return FNM_NOMATCH;
+ else if (c == '?')
+ {
+ /* A ? needs to match one character. */
+ if (*n == '\0')
+ /* There isn't another character; no match. */
+ return FNM_NOMATCH;
+ else
+ /* One character of the string is consumed in matching
+ this ? wildcard, so *??? won't match if there are
+ less than three characters. */
+ ++n;
+ }
+ }
+
+ if (c == '\0')
+ return 0;
+
+ {
+ char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
+ c1 = FOLD (c1);
+ for (--p; *n != '\0'; ++n)
+ if ((c == '[' || FOLD (*n) == c1) &&
+ fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
+ return 0;
+ return FNM_NOMATCH;
+ }
+
+ case '[':
+ {
+ /* Nonzero if the sense of the character class is inverted. */
+ register int not;
+
+ if (*n == '\0')
+ return FNM_NOMATCH;
+
+ if ((flags & FNM_PERIOD) && *n == '.' &&
+ (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+ return FNM_NOMATCH;
+
+ not = (*p == '!' || *p == '^');
+ if (not)
+ ++p;
+
+ c = *p++;
+ for (;;)
+ {
+ register char cstart = c, cend = c;
+
+ if (!(flags & FNM_NOESCAPE) && c == '\\')
+ {
+ if (*p == '\0')
+ return FNM_NOMATCH;
+ cstart = cend = *p++;
+ }
+
+ cstart = cend = FOLD (cstart);
+
+ if (c == '\0')
+ /* [ (unterminated) loses. */
+ return FNM_NOMATCH;
+
+ c = *p++;
+ c = FOLD (c);
+
+ if ((flags & FNM_FILE_NAME) && c == '/')
+ /* [/] can never match. */
+ return FNM_NOMATCH;
+
+ if (c == '-' && *p != ']')
+ {
+ cend = *p++;
+ if (!(flags & FNM_NOESCAPE) && cend == '\\')
+ cend = *p++;
+ if (cend == '\0')
+ return FNM_NOMATCH;
+ cend = FOLD (cend);
+
+ c = *p++;
+ }
+
+ if (FOLD (*n) >= cstart && FOLD (*n) <= cend)
+ goto matched;
+
+ if (c == ']')
+ break;
+ }
+ if (!not)
+ return FNM_NOMATCH;
+ break;
+
+ matched:;
+ /* Skip the rest of the [...] that already matched. */
+ while (c != ']')
+ {
+ if (c == '\0')
+ /* [... (unterminated) loses. */
+ return FNM_NOMATCH;
+
+ c = *p++;
+ if (!(flags & FNM_NOESCAPE) && c == '\\')
+ {
+ if (*p == '\0')
+ return FNM_NOMATCH;
+ /* XXX 1003.2d11 is unclear if this is right. */
+ ++p;
+ }
+ }
+ if (not)
+ return FNM_NOMATCH;
+ }
+ break;
+
+ default:
+ if (c != FOLD (*n))
+ return FNM_NOMATCH;
+ }
+
+ ++n;
+ }
if (*n == '\0')
- return 0;
+ return 0;
if ((flags & FNM_LEADING_DIR) && *n == '/')
- /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
- return 0;
+ /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
+ return 0;
return FNM_NOMATCH;
diff --git a/source/blender/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c
index 36051e3e7f0..a8b8f01fa22 100644
--- a/source/blender/blenlib/intern/freetypefont.c
+++ b/source/blender/blenlib/intern/freetypefont.c
@@ -50,371 +50,363 @@
static FT_Library library;
static FT_Error err;
-
static VChar *freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData *vfd)
{
- const float scale = vfd->scale;
- const float eps = 0.0001f;
- const float eps_sq = eps * eps;
- /* Blender */
- struct Nurb *nu;
- struct VChar *che;
- struct BezTriple *bezt;
-
- /* Freetype2 */
- FT_GlyphSlot glyph;
- FT_UInt glyph_index;
- FT_Outline ftoutline;
- float dx, dy;
- int j, k, l, l_first = 0;
-
- /*
- * Generate the character 3D data
- *
- * Get the FT Glyph index and load the Glyph */
- glyph_index = FT_Get_Char_Index(face, charcode);
- err = FT_Load_Glyph(face, glyph_index, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP);
-
- /* If loading succeeded, convert the FT glyph to the internal format */
- if (!err) {
- /* initialize as -1 to add 1 on first loop each time */
- int contour_prev;
- int *onpoints;
-
- /* First we create entry for the new character to the character list */
- che = (VChar *) MEM_callocN(sizeof(struct VChar), "objfnt_char");
-
- /* Take some data for modifying purposes */
- glyph = face->glyph;
- ftoutline = glyph->outline;
-
- /* Set the width and character code */
- che->index = charcode;
- che->width = glyph->advance.x * scale;
-
- BLI_ghash_insert(vfd->characters, POINTER_FROM_UINT(che->index), che);
-
- /* Start converting the FT data */
- onpoints = (int *)MEM_callocN((ftoutline.n_contours) * sizeof(int), "onpoints");
-
- /* get number of on-curve points for beziertriples (including conic virtual on-points) */
- for (j = 0, contour_prev = -1; j < ftoutline.n_contours; j++) {
- const int n = ftoutline.contours[j] - contour_prev;
- contour_prev = ftoutline.contours[j];
-
- for (k = 0; k < n; k++) {
- l = (j > 0) ? (k + ftoutline.contours[j - 1] + 1) : k;
- if (k == 0) {
- l_first = l;
- }
-
- if (ftoutline.tags[l] == FT_Curve_Tag_On) {
- onpoints[j]++;
- }
-
- {
- const int l_next = (k < n - 1) ? (l + 1) : l_first;
- if (ftoutline.tags[l] == FT_Curve_Tag_Conic &&
- ftoutline.tags[l_next] == FT_Curve_Tag_Conic)
- {
- onpoints[j]++;
- }
- }
- }
- }
-
- /* contour loop, bezier & conic styles merged */
- for (j = 0, contour_prev = -1; j < ftoutline.n_contours; j++) {
- const int n = ftoutline.contours[j] - contour_prev;
- contour_prev = ftoutline.contours[j];
-
- /* add new curve */
- nu = (Nurb *)MEM_callocN(sizeof(struct Nurb), "objfnt_nurb");
- bezt = (BezTriple *)MEM_callocN((onpoints[j]) * sizeof(BezTriple), "objfnt_bezt");
- BLI_addtail(&che->nurbsbase, nu);
-
- nu->type = CU_BEZIER;
- nu->pntsu = onpoints[j];
- nu->resolu = 8;
- nu->flag = CU_2D;
- nu->flagu = CU_NURB_CYCLIC;
- nu->bezt = bezt;
-
- /* individual curve loop, start-end */
- for (k = 0; k < n; k++) {
- l = (j > 0) ? (k + ftoutline.contours[j - 1] + 1) : k;
- if (k == 0) {
- l_first = l;
- }
-
- /* virtual conic on-curve points */
- {
- const int l_next = (k < n - 1) ? (l + 1) : l_first;
- if (ftoutline.tags[l] == FT_Curve_Tag_Conic &&
- ftoutline.tags[l_next] == FT_Curve_Tag_Conic)
- {
- dx = (ftoutline.points[l].x + ftoutline.points[l_next].x) * scale / 2.0f;
- dy = (ftoutline.points[l].y + ftoutline.points[l_next].y) * scale / 2.0f;
-
- /* left handle */
- bezt->vec[0][0] = (dx + (2 * ftoutline.points[l].x) * scale) / 3.0f;
- bezt->vec[0][1] = (dy + (2 * ftoutline.points[l].y) * scale) / 3.0f;
-
- /* midpoint (virtual on-curve point) */
- bezt->vec[1][0] = dx;
- bezt->vec[1][1] = dy;
-
- /* right handle */
- bezt->vec[2][0] = (dx + (2 * ftoutline.points[l_next].x) * scale) / 3.0f;
- bezt->vec[2][1] = (dy + (2 * ftoutline.points[l_next].y) * scale) / 3.0f;
-
- bezt->h1 = bezt->h2 = HD_ALIGN;
- bezt->radius = 1.0f;
- bezt++;
- }
- }
-
- /* on-curve points */
- if (ftoutline.tags[l] == FT_Curve_Tag_On) {
- const int l_prev = (k > 0) ? (l - 1) : ftoutline.contours[j];
- const int l_next = (k < n - 1) ? (l + 1) : l_first;
-
- /* left handle */
- if (ftoutline.tags[l_prev] == FT_Curve_Tag_Cubic) {
- bezt->vec[0][0] = ftoutline.points[l_prev].x * scale;
- bezt->vec[0][1] = ftoutline.points[l_prev].y * scale;
- bezt->h1 = HD_FREE;
- }
- else if (ftoutline.tags[l_prev] == FT_Curve_Tag_Conic) {
- bezt->vec[0][0] = (ftoutline.points[l].x + (2 * ftoutline.points[l_prev].x)) * scale / 3.0f;
- bezt->vec[0][1] = (ftoutline.points[l].y + (2 * ftoutline.points[l_prev].y)) * scale / 3.0f;
- bezt->h1 = HD_FREE;
- }
- else {
- bezt->vec[0][0] = ftoutline.points[l].x * scale - (ftoutline.points[l].x - ftoutline.points[l_prev].x) * scale / 3.0f;
- bezt->vec[0][1] = ftoutline.points[l].y * scale - (ftoutline.points[l].y - ftoutline.points[l_prev].y) * scale / 3.0f;
- bezt->h1 = HD_VECT;
- }
-
- /* midpoint (on-curve point) */
- bezt->vec[1][0] = ftoutline.points[l].x * scale;
- bezt->vec[1][1] = ftoutline.points[l].y * scale;
-
- /* right handle */
- if (ftoutline.tags[l_next] == FT_Curve_Tag_Cubic) {
- bezt->vec[2][0] = ftoutline.points[l_next].x * scale;
- bezt->vec[2][1] = ftoutline.points[l_next].y * scale;
- bezt->h2 = HD_FREE;
- }
- else if (ftoutline.tags[l_next] == FT_Curve_Tag_Conic) {
- bezt->vec[2][0] = (ftoutline.points[l].x + (2 * ftoutline.points[l_next].x)) * scale / 3.0f;
- bezt->vec[2][1] = (ftoutline.points[l].y + (2 * ftoutline.points[l_next].y)) * scale / 3.0f;
- bezt->h2 = HD_FREE;
- }
- else {
- bezt->vec[2][0] = ftoutline.points[l].x * scale - (ftoutline.points[l].x - ftoutline.points[l_next].x) * scale / 3.0f;
- bezt->vec[2][1] = ftoutline.points[l].y * scale - (ftoutline.points[l].y - ftoutline.points[l_next].y) * scale / 3.0f;
- bezt->h2 = HD_VECT;
- }
-
- /* get the handles that are aligned, tricky...
- * - check if one of them is a vector handle.
- * - dist_squared_to_line_v2, check if the three beztriple points are on one line
- * - len_squared_v2v2, see if there's a distance between the three points
- * - len_squared_v2v2 again, to check the angle between the handles
- */
- if ((bezt->h1 != HD_VECT && bezt->h2 != HD_VECT) &&
- (dist_squared_to_line_v2(bezt->vec[0], bezt->vec[1], bezt->vec[2]) < (0.001f * 0.001f)) &&
- (len_squared_v2v2(bezt->vec[0], bezt->vec[1]) > eps_sq) &&
- (len_squared_v2v2(bezt->vec[1], bezt->vec[2]) > eps_sq) &&
- (len_squared_v2v2(bezt->vec[0], bezt->vec[2]) > eps_sq) &&
- (len_squared_v2v2(bezt->vec[0], bezt->vec[2]) >
- max_ff(len_squared_v2v2(bezt->vec[0], bezt->vec[1]),
- len_squared_v2v2(bezt->vec[1], bezt->vec[2]))))
- {
- bezt->h1 = bezt->h2 = HD_ALIGN;
- }
- bezt->radius = 1.0f;
- bezt++;
- }
- }
- }
-
- MEM_freeN(onpoints);
-
- return che;
- }
-
- return NULL;
+ const float scale = vfd->scale;
+ const float eps = 0.0001f;
+ const float eps_sq = eps * eps;
+ /* Blender */
+ struct Nurb *nu;
+ struct VChar *che;
+ struct BezTriple *bezt;
+
+ /* Freetype2 */
+ FT_GlyphSlot glyph;
+ FT_UInt glyph_index;
+ FT_Outline ftoutline;
+ float dx, dy;
+ int j, k, l, l_first = 0;
+
+ /*
+ * Generate the character 3D data
+ *
+ * Get the FT Glyph index and load the Glyph */
+ glyph_index = FT_Get_Char_Index(face, charcode);
+ err = FT_Load_Glyph(face, glyph_index, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP);
+
+ /* If loading succeeded, convert the FT glyph to the internal format */
+ if (!err) {
+ /* initialize as -1 to add 1 on first loop each time */
+ int contour_prev;
+ int *onpoints;
+
+ /* First we create entry for the new character to the character list */
+ che = (VChar *)MEM_callocN(sizeof(struct VChar), "objfnt_char");
+
+ /* Take some data for modifying purposes */
+ glyph = face->glyph;
+ ftoutline = glyph->outline;
+
+ /* Set the width and character code */
+ che->index = charcode;
+ che->width = glyph->advance.x * scale;
+
+ BLI_ghash_insert(vfd->characters, POINTER_FROM_UINT(che->index), che);
+
+ /* Start converting the FT data */
+ onpoints = (int *)MEM_callocN((ftoutline.n_contours) * sizeof(int), "onpoints");
+
+ /* get number of on-curve points for beziertriples (including conic virtual on-points) */
+ for (j = 0, contour_prev = -1; j < ftoutline.n_contours; j++) {
+ const int n = ftoutline.contours[j] - contour_prev;
+ contour_prev = ftoutline.contours[j];
+
+ for (k = 0; k < n; k++) {
+ l = (j > 0) ? (k + ftoutline.contours[j - 1] + 1) : k;
+ if (k == 0) {
+ l_first = l;
+ }
+
+ if (ftoutline.tags[l] == FT_Curve_Tag_On) {
+ onpoints[j]++;
+ }
+
+ {
+ const int l_next = (k < n - 1) ? (l + 1) : l_first;
+ if (ftoutline.tags[l] == FT_Curve_Tag_Conic &&
+ ftoutline.tags[l_next] == FT_Curve_Tag_Conic) {
+ onpoints[j]++;
+ }
+ }
+ }
+ }
+
+ /* contour loop, bezier & conic styles merged */
+ for (j = 0, contour_prev = -1; j < ftoutline.n_contours; j++) {
+ const int n = ftoutline.contours[j] - contour_prev;
+ contour_prev = ftoutline.contours[j];
+
+ /* add new curve */
+ nu = (Nurb *)MEM_callocN(sizeof(struct Nurb), "objfnt_nurb");
+ bezt = (BezTriple *)MEM_callocN((onpoints[j]) * sizeof(BezTriple), "objfnt_bezt");
+ BLI_addtail(&che->nurbsbase, nu);
+
+ nu->type = CU_BEZIER;
+ nu->pntsu = onpoints[j];
+ nu->resolu = 8;
+ nu->flag = CU_2D;
+ nu->flagu = CU_NURB_CYCLIC;
+ nu->bezt = bezt;
+
+ /* individual curve loop, start-end */
+ for (k = 0; k < n; k++) {
+ l = (j > 0) ? (k + ftoutline.contours[j - 1] + 1) : k;
+ if (k == 0) {
+ l_first = l;
+ }
+
+ /* virtual conic on-curve points */
+ {
+ const int l_next = (k < n - 1) ? (l + 1) : l_first;
+ if (ftoutline.tags[l] == FT_Curve_Tag_Conic &&
+ ftoutline.tags[l_next] == FT_Curve_Tag_Conic) {
+ dx = (ftoutline.points[l].x + ftoutline.points[l_next].x) * scale / 2.0f;
+ dy = (ftoutline.points[l].y + ftoutline.points[l_next].y) * scale / 2.0f;
+
+ /* left handle */
+ bezt->vec[0][0] = (dx + (2 * ftoutline.points[l].x) * scale) / 3.0f;
+ bezt->vec[0][1] = (dy + (2 * ftoutline.points[l].y) * scale) / 3.0f;
+
+ /* midpoint (virtual on-curve point) */
+ bezt->vec[1][0] = dx;
+ bezt->vec[1][1] = dy;
+
+ /* right handle */
+ bezt->vec[2][0] = (dx + (2 * ftoutline.points[l_next].x) * scale) / 3.0f;
+ bezt->vec[2][1] = (dy + (2 * ftoutline.points[l_next].y) * scale) / 3.0f;
+
+ bezt->h1 = bezt->h2 = HD_ALIGN;
+ bezt->radius = 1.0f;
+ bezt++;
+ }
+ }
+
+ /* on-curve points */
+ if (ftoutline.tags[l] == FT_Curve_Tag_On) {
+ const int l_prev = (k > 0) ? (l - 1) : ftoutline.contours[j];
+ const int l_next = (k < n - 1) ? (l + 1) : l_first;
+
+ /* left handle */
+ if (ftoutline.tags[l_prev] == FT_Curve_Tag_Cubic) {
+ bezt->vec[0][0] = ftoutline.points[l_prev].x * scale;
+ bezt->vec[0][1] = ftoutline.points[l_prev].y * scale;
+ bezt->h1 = HD_FREE;
+ }
+ else if (ftoutline.tags[l_prev] == FT_Curve_Tag_Conic) {
+ bezt->vec[0][0] = (ftoutline.points[l].x + (2 * ftoutline.points[l_prev].x)) * scale /
+ 3.0f;
+ bezt->vec[0][1] = (ftoutline.points[l].y + (2 * ftoutline.points[l_prev].y)) * scale /
+ 3.0f;
+ bezt->h1 = HD_FREE;
+ }
+ else {
+ bezt->vec[0][0] = ftoutline.points[l].x * scale -
+ (ftoutline.points[l].x - ftoutline.points[l_prev].x) * scale / 3.0f;
+ bezt->vec[0][1] = ftoutline.points[l].y * scale -
+ (ftoutline.points[l].y - ftoutline.points[l_prev].y) * scale / 3.0f;
+ bezt->h1 = HD_VECT;
+ }
+
+ /* midpoint (on-curve point) */
+ bezt->vec[1][0] = ftoutline.points[l].x * scale;
+ bezt->vec[1][1] = ftoutline.points[l].y * scale;
+
+ /* right handle */
+ if (ftoutline.tags[l_next] == FT_Curve_Tag_Cubic) {
+ bezt->vec[2][0] = ftoutline.points[l_next].x * scale;
+ bezt->vec[2][1] = ftoutline.points[l_next].y * scale;
+ bezt->h2 = HD_FREE;
+ }
+ else if (ftoutline.tags[l_next] == FT_Curve_Tag_Conic) {
+ bezt->vec[2][0] = (ftoutline.points[l].x + (2 * ftoutline.points[l_next].x)) * scale /
+ 3.0f;
+ bezt->vec[2][1] = (ftoutline.points[l].y + (2 * ftoutline.points[l_next].y)) * scale /
+ 3.0f;
+ bezt->h2 = HD_FREE;
+ }
+ else {
+ bezt->vec[2][0] = ftoutline.points[l].x * scale -
+ (ftoutline.points[l].x - ftoutline.points[l_next].x) * scale / 3.0f;
+ bezt->vec[2][1] = ftoutline.points[l].y * scale -
+ (ftoutline.points[l].y - ftoutline.points[l_next].y) * scale / 3.0f;
+ bezt->h2 = HD_VECT;
+ }
+
+ /* get the handles that are aligned, tricky...
+ * - check if one of them is a vector handle.
+ * - dist_squared_to_line_v2, check if the three beztriple points are on one line
+ * - len_squared_v2v2, see if there's a distance between the three points
+ * - len_squared_v2v2 again, to check the angle between the handles
+ */
+ if ((bezt->h1 != HD_VECT && bezt->h2 != HD_VECT) &&
+ (dist_squared_to_line_v2(bezt->vec[0], bezt->vec[1], bezt->vec[2]) <
+ (0.001f * 0.001f)) &&
+ (len_squared_v2v2(bezt->vec[0], bezt->vec[1]) > eps_sq) &&
+ (len_squared_v2v2(bezt->vec[1], bezt->vec[2]) > eps_sq) &&
+ (len_squared_v2v2(bezt->vec[0], bezt->vec[2]) > eps_sq) &&
+ (len_squared_v2v2(bezt->vec[0], bezt->vec[2]) >
+ max_ff(len_squared_v2v2(bezt->vec[0], bezt->vec[1]),
+ len_squared_v2v2(bezt->vec[1], bezt->vec[2])))) {
+ bezt->h1 = bezt->h2 = HD_ALIGN;
+ }
+ bezt->radius = 1.0f;
+ bezt++;
+ }
+ }
+ }
+
+ MEM_freeN(onpoints);
+
+ return che;
+ }
+
+ return NULL;
}
static VChar *objchr_to_ftvfontdata(VFont *vfont, FT_ULong charcode)
{
- VChar *che;
-
- /* Freetype2 */
- FT_Face face;
-
- /* Load the font to memory */
- if (vfont->temp_pf) {
- err = FT_New_Memory_Face(library,
- vfont->temp_pf->data,
- vfont->temp_pf->size,
- 0,
- &face);
- if (err) {
- return NULL;
- }
- }
- else {
- err = true;
- return NULL;
- }
-
- /* Read the char */
- che = freetypechar_to_vchar(face, charcode, vfont->data);
-
- /* And everything went ok */
- return che;
+ VChar *che;
+
+ /* Freetype2 */
+ FT_Face face;
+
+ /* Load the font to memory */
+ if (vfont->temp_pf) {
+ err = FT_New_Memory_Face(library, vfont->temp_pf->data, vfont->temp_pf->size, 0, &face);
+ if (err) {
+ return NULL;
+ }
+ }
+ else {
+ err = true;
+ return NULL;
+ }
+
+ /* Read the char */
+ che = freetypechar_to_vchar(face, charcode, vfont->data);
+
+ /* And everything went ok */
+ return che;
}
-
static VFontData *objfnt_to_ftvfontdata(PackedFile *pf)
{
- /* Variables */
- FT_Face face;
- const FT_ULong charcode_reserve = 256;
- FT_ULong charcode = 0, lcode;
- FT_UInt glyph_index;
- const char *fontname;
- VFontData *vfd;
-
- /* load the freetype font */
- err = FT_New_Memory_Face(library,
- pf->data,
- pf->size,
- 0,
- &face);
-
- if (err) {
- return NULL;
- }
-
- /* allocate blender font */
- vfd = MEM_callocN(sizeof(*vfd), "FTVFontData");
-
- /* get the name */
- fontname = FT_Get_Postscript_Name(face);
- BLI_strncpy(vfd->name, (fontname == NULL) ? "" : fontname, sizeof(vfd->name));
-
- /* Extract the first 256 character from TTF */
- lcode = charcode = FT_Get_First_Char(face, &glyph_index);
-
- /* No charmap found from the ttf so we need to figure it out */
- if (glyph_index == 0) {
- FT_CharMap found = NULL;
- FT_CharMap charmap;
- int n;
-
- for (n = 0; n < face->num_charmaps; n++) {
- charmap = face->charmaps[n];
- if (charmap->encoding == FT_ENCODING_APPLE_ROMAN) {
- found = charmap;
- break;
- }
- }
-
- err = FT_Set_Charmap(face, found);
-
- if (err) {
- return NULL;
- }
-
- lcode = charcode = FT_Get_First_Char(face, &glyph_index);
- }
-
- /* Blender default BFont is not "complete". */
- const bool complete_font = (face->ascender != 0) && (face->descender != 0) &&
- (face->ascender != face->descender);
-
- if (complete_font) {
- /* We can get descender as well, but we simple store descender in relation to the ascender.
- * Also note that descender is stored as a negative number. */
- vfd->ascender = (float)face->ascender / (face->ascender - face->descender);
- }
- else {
- vfd->ascender = 0.8f;
- vfd->em_height = 1.0f;
- }
-
- /* Adjust font size */
- if (face->bbox.yMax != face->bbox.yMin) {
- vfd->scale = (float)(1.0 / (double)(face->bbox.yMax - face->bbox.yMin));
-
- if (complete_font) {
- vfd->em_height = (float)(face->ascender - face->descender) / (face->bbox.yMax - face->bbox.yMin);
- }
- }
- else {
- vfd->scale = 1.0f / 1000.0f;
- }
-
- /* Load characters */
- vfd->characters = BLI_ghash_int_new_ex(__func__, charcode_reserve);
-
- while (charcode < charcode_reserve) {
- /* Generate the font data */
- freetypechar_to_vchar(face, charcode, vfd);
-
- /* Next glyph */
- charcode = FT_Get_Next_Char(face, charcode, &glyph_index);
-
- /* Check that we won't start infinite loop */
- if (charcode <= lcode) {
- break;
- }
- lcode = charcode;
- }
-
- return vfd;
+ /* Variables */
+ FT_Face face;
+ const FT_ULong charcode_reserve = 256;
+ FT_ULong charcode = 0, lcode;
+ FT_UInt glyph_index;
+ const char *fontname;
+ VFontData *vfd;
+
+ /* load the freetype font */
+ err = FT_New_Memory_Face(library, pf->data, pf->size, 0, &face);
+
+ if (err) {
+ return NULL;
+ }
+
+ /* allocate blender font */
+ vfd = MEM_callocN(sizeof(*vfd), "FTVFontData");
+
+ /* get the name */
+ fontname = FT_Get_Postscript_Name(face);
+ BLI_strncpy(vfd->name, (fontname == NULL) ? "" : fontname, sizeof(vfd->name));
+
+ /* Extract the first 256 character from TTF */
+ lcode = charcode = FT_Get_First_Char(face, &glyph_index);
+
+ /* No charmap found from the ttf so we need to figure it out */
+ if (glyph_index == 0) {
+ FT_CharMap found = NULL;
+ FT_CharMap charmap;
+ int n;
+
+ for (n = 0; n < face->num_charmaps; n++) {
+ charmap = face->charmaps[n];
+ if (charmap->encoding == FT_ENCODING_APPLE_ROMAN) {
+ found = charmap;
+ break;
+ }
+ }
+
+ err = FT_Set_Charmap(face, found);
+
+ if (err) {
+ return NULL;
+ }
+
+ lcode = charcode = FT_Get_First_Char(face, &glyph_index);
+ }
+
+ /* Blender default BFont is not "complete". */
+ const bool complete_font = (face->ascender != 0) && (face->descender != 0) &&
+ (face->ascender != face->descender);
+
+ if (complete_font) {
+ /* We can get descender as well, but we simple store descender in relation to the ascender.
+ * Also note that descender is stored as a negative number. */
+ vfd->ascender = (float)face->ascender / (face->ascender - face->descender);
+ }
+ else {
+ vfd->ascender = 0.8f;
+ vfd->em_height = 1.0f;
+ }
+
+ /* Adjust font size */
+ if (face->bbox.yMax != face->bbox.yMin) {
+ vfd->scale = (float)(1.0 / (double)(face->bbox.yMax - face->bbox.yMin));
+
+ if (complete_font) {
+ vfd->em_height = (float)(face->ascender - face->descender) /
+ (face->bbox.yMax - face->bbox.yMin);
+ }
+ }
+ else {
+ vfd->scale = 1.0f / 1000.0f;
+ }
+
+ /* Load characters */
+ vfd->characters = BLI_ghash_int_new_ex(__func__, charcode_reserve);
+
+ while (charcode < charcode_reserve) {
+ /* Generate the font data */
+ freetypechar_to_vchar(face, charcode, vfd);
+
+ /* Next glyph */
+ charcode = FT_Get_Next_Char(face, charcode, &glyph_index);
+
+ /* Check that we won't start infinite loop */
+ if (charcode <= lcode) {
+ break;
+ }
+ lcode = charcode;
+ }
+
+ return vfd;
}
-
static int check_freetypefont(PackedFile *pf)
{
- FT_Face face;
- FT_GlyphSlot glyph;
- FT_UInt glyph_index;
- int success = 0;
-
- err = FT_New_Memory_Face(library,
- pf->data,
- pf->size,
- 0,
- &face);
- if (err) {
- success = 0;
- //XXX error("This is not a valid font");
- }
- else {
- glyph_index = FT_Get_Char_Index(face, 'A');
- err = FT_Load_Glyph(face, glyph_index, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP);
- if (err) {
- success = 0;
- }
- else {
- glyph = face->glyph;
- if (glyph->format == ft_glyph_format_outline) {
- success = 1;
- }
- else {
- //XXX error("Selected Font has no outline data");
- success = 0;
- }
- }
- }
-
- return success;
+ FT_Face face;
+ FT_GlyphSlot glyph;
+ FT_UInt glyph_index;
+ int success = 0;
+
+ err = FT_New_Memory_Face(library, pf->data, pf->size, 0, &face);
+ if (err) {
+ success = 0;
+ //XXX error("This is not a valid font");
+ }
+ else {
+ glyph_index = FT_Get_Char_Index(face, 'A');
+ err = FT_Load_Glyph(face, glyph_index, FT_LOAD_NO_SCALE | FT_LOAD_NO_BITMAP);
+ if (err) {
+ success = 0;
+ }
+ else {
+ glyph = face->glyph;
+ if (glyph->format == ft_glyph_format_outline) {
+ success = 1;
+ }
+ else {
+ //XXX error("Selected Font has no outline data");
+ success = 0;
+ }
+ }
+ }
+
+ return success;
}
/**
@@ -427,66 +419,67 @@ static int check_freetypefont(PackedFile *pf)
*/
VFontData *BLI_vfontdata_from_freetypefont(PackedFile *pf)
{
- VFontData *vfd = NULL;
- int success = 0;
+ VFontData *vfd = NULL;
+ int success = 0;
- /* init Freetype */
- err = FT_Init_FreeType(&library);
- if (err) {
- /* XXX error("Failed to load the Freetype font library"); */
- return NULL;
- }
+ /* init Freetype */
+ err = FT_Init_FreeType(&library);
+ if (err) {
+ /* XXX error("Failed to load the Freetype font library"); */
+ return NULL;
+ }
- success = check_freetypefont(pf);
+ success = check_freetypefont(pf);
- if (success) {
- vfd = objfnt_to_ftvfontdata(pf);
- }
+ if (success) {
+ vfd = objfnt_to_ftvfontdata(pf);
+ }
- /* free Freetype */
- FT_Done_FreeType(library);
+ /* free Freetype */
+ FT_Done_FreeType(library);
- return vfd;
+ return vfd;
}
static void *vfontdata_copy_characters_value_cb(const void *src)
{
- return BLI_vfontchar_copy(src, 0);
+ return BLI_vfontchar_copy(src, 0);
}
VFontData *BLI_vfontdata_copy(const VFontData *vfont_src, const int UNUSED(flag))
{
- VFontData *vfont_dst = MEM_dupallocN(vfont_src);
+ VFontData *vfont_dst = MEM_dupallocN(vfont_src);
- if (vfont_src->characters != NULL) {
- vfont_dst->characters = BLI_ghash_copy(vfont_src->characters, NULL, vfontdata_copy_characters_value_cb);
- }
+ if (vfont_src->characters != NULL) {
+ vfont_dst->characters = BLI_ghash_copy(
+ vfont_src->characters, NULL, vfontdata_copy_characters_value_cb);
+ }
- return vfont_dst;
+ return vfont_dst;
}
VChar *BLI_vfontchar_from_freetypefont(VFont *vfont, unsigned long character)
{
- VChar *che = NULL;
+ VChar *che = NULL;
- if (!vfont) {
- return NULL;
- }
+ if (!vfont) {
+ return NULL;
+ }
- /* Init Freetype */
- err = FT_Init_FreeType(&library);
- if (err) {
- /* XXX error("Failed to load the Freetype font library"); */
- return NULL;
- }
+ /* Init Freetype */
+ err = FT_Init_FreeType(&library);
+ if (err) {
+ /* XXX error("Failed to load the Freetype font library"); */
+ return NULL;
+ }
- /* Load the character */
- che = objchr_to_ftvfontdata(vfont, character);
+ /* Load the character */
+ che = objchr_to_ftvfontdata(vfont, character);
- /* Free Freetype */
- FT_Done_FreeType(library);
+ /* Free Freetype */
+ FT_Done_FreeType(library);
- return che;
+ return che;
}
/* Yeah, this is very bad... But why is this in BLI in the first place, since it uses Nurb data?
@@ -496,15 +489,14 @@ VChar *BLI_vfontchar_from_freetypefont(VFont *vfont, unsigned long character)
VChar *BLI_vfontchar_copy(const VChar *vchar_src, const int UNUSED(flag))
{
- VChar *vchar_dst = MEM_dupallocN(vchar_src);
+ VChar *vchar_dst = MEM_dupallocN(vchar_src);
- BLI_listbase_clear(&vchar_dst->nurbsbase);
- BKE_nurbList_duplicate(&vchar_dst->nurbsbase, &vchar_src->nurbsbase);
+ BLI_listbase_clear(&vchar_dst->nurbsbase);
+ BKE_nurbList_duplicate(&vchar_dst->nurbsbase, &vchar_src->nurbsbase);
- return vchar_dst;
+ return vchar_dst;
}
-
/*
* from: http://www.freetype.org/freetype2/docs/glyphs/glyphs-6.html#section-1
*
diff --git a/source/blender/blenlib/intern/gsqueue.c b/source/blender/blenlib/intern/gsqueue.c
index 40890222e55..6d0fdfacb10 100644
--- a/source/blender/blenlib/intern/gsqueue.c
+++ b/source/blender/blenlib/intern/gsqueue.c
@@ -37,14 +37,14 @@
typedef struct _GSQueueElem GSQueueElem;
struct _GSQueueElem {
- GSQueueElem *next;
- char data[0];
+ GSQueueElem *next;
+ char data[0];
};
struct _GSQueue {
- GSQueueElem *head;
- GSQueueElem *tail;
- size_t elem_size;
+ GSQueueElem *head;
+ GSQueueElem *tail;
+ size_t elem_size;
};
/**
@@ -55,11 +55,11 @@ struct _GSQueue {
*/
GSQueue *BLI_gsqueue_new(size_t elem_size)
{
- GSQueue *gq = MEM_mallocN(sizeof(*gq), "gqueue_new");
- gq->head = gq->tail = NULL;
- gq->elem_size = elem_size;
+ GSQueue *gq = MEM_mallocN(sizeof(*gq), "gqueue_new");
+ gq->head = gq->tail = NULL;
+ gq->elem_size = elem_size;
- return gq;
+ return gq;
}
/**
@@ -67,7 +67,7 @@ GSQueue *BLI_gsqueue_new(size_t elem_size)
*/
bool BLI_gsqueue_is_empty(GSQueue *gq)
{
- return (gq->head == NULL);
+ return (gq->head == NULL);
}
/**
@@ -75,14 +75,14 @@ bool BLI_gsqueue_is_empty(GSQueue *gq)
*/
int BLI_gsqueue_len(GSQueue *gq)
{
- GSQueueElem *elem;
- int size = 0;
+ GSQueueElem *elem;
+ int size = 0;
- for (elem = gq->head; elem; elem = elem->next) {
- size++;
- }
+ for (elem = gq->head; elem; elem = elem->next) {
+ size++;
+ }
- return size;
+ return size;
}
/**
@@ -94,7 +94,7 @@ int BLI_gsqueue_len(GSQueue *gq)
*/
void BLI_gsqueue_peek(GSQueue *gq, void *r_item)
{
- memcpy(r_item, &gq->head->data, gq->elem_size);
+ memcpy(r_item, &gq->head->data, gq->elem_size);
}
/**
@@ -107,18 +107,18 @@ void BLI_gsqueue_peek(GSQueue *gq, void *r_item)
*/
void BLI_gsqueue_pop(GSQueue *gq, void *r_item)
{
- GSQueueElem *elem = gq->head;
- if (elem == gq->tail) {
- gq->head = gq->tail = NULL;
- }
- else {
- gq->head = gq->head->next;
- }
-
- if (r_item) {
- memcpy(r_item, elem->data, gq->elem_size);
- }
- MEM_freeN(elem);
+ GSQueueElem *elem = gq->head;
+ if (elem == gq->tail) {
+ gq->head = gq->tail = NULL;
+ }
+ else {
+ gq->head = gq->head->next;
+ }
+
+ if (r_item) {
+ memcpy(r_item, elem->data, gq->elem_size);
+ }
+ MEM_freeN(elem);
}
/**
@@ -129,24 +129,24 @@ void BLI_gsqueue_pop(GSQueue *gq, void *r_item)
*/
void BLI_gsqueue_push(GSQueue *gq, const void *item)
{
- GSQueueElem *elem;
-
- /* compare: prevent events added double in row */
- if (!BLI_gsqueue_is_empty(gq)) {
- if (0 == memcmp(item, gq->head->data, gq->elem_size)) {
- return;
- }
- }
- elem = MEM_mallocN(sizeof(*elem) + gq->elem_size, "gqueue_push");
- memcpy(elem->data, item, gq->elem_size);
- elem->next = NULL;
-
- if (BLI_gsqueue_is_empty(gq)) {
- gq->tail = gq->head = elem;
- }
- else {
- gq->tail = gq->tail->next = elem;
- }
+ GSQueueElem *elem;
+
+ /* compare: prevent events added double in row */
+ if (!BLI_gsqueue_is_empty(gq)) {
+ if (0 == memcmp(item, gq->head->data, gq->elem_size)) {
+ return;
+ }
+ }
+ elem = MEM_mallocN(sizeof(*elem) + gq->elem_size, "gqueue_push");
+ memcpy(elem->data, item, gq->elem_size);
+ elem->next = NULL;
+
+ if (BLI_gsqueue_is_empty(gq)) {
+ gq->tail = gq->head = elem;
+ }
+ else {
+ gq->tail = gq->tail->next = elem;
+ }
}
/**
@@ -158,16 +158,16 @@ void BLI_gsqueue_push(GSQueue *gq, const void *item)
*/
void BLI_gsqueue_push_back(GSQueue *gq, const void *item)
{
- GSQueueElem *elem = MEM_mallocN(sizeof(*elem) + gq->elem_size, "gqueue_push");
- memcpy(elem->data, item, gq->elem_size);
- elem->next = gq->head;
-
- if (BLI_gsqueue_is_empty(gq)) {
- gq->head = gq->tail = elem;
- }
- else {
- gq->head = elem;
- }
+ GSQueueElem *elem = MEM_mallocN(sizeof(*elem) + gq->elem_size, "gqueue_push");
+ memcpy(elem->data, item, gq->elem_size);
+ elem->next = gq->head;
+
+ if (BLI_gsqueue_is_empty(gq)) {
+ gq->head = gq->tail = elem;
+ }
+ else {
+ gq->head = elem;
+ }
}
/**
@@ -175,8 +175,8 @@ void BLI_gsqueue_push_back(GSQueue *gq, const void *item)
*/
void BLI_gsqueue_free(GSQueue *gq)
{
- while (gq->head) {
- BLI_gsqueue_pop(gq, NULL);
- }
- MEM_freeN(gq);
+ while (gq->head) {
+ BLI_gsqueue_pop(gq, NULL);
+ }
+ MEM_freeN(gq);
}
diff --git a/source/blender/blenlib/intern/hash_md5.c b/source/blender/blenlib/intern/hash_md5.c
index 1a8e78d4227..d3ba5ee1a3b 100644
--- a/source/blender/blenlib/intern/hash_md5.c
+++ b/source/blender/blenlib/intern/hash_md5.c
@@ -29,7 +29,7 @@
#include <stdio.h>
#include <sys/types.h>
-#include "BLI_hash_md5.h" /* own include */
+#include "BLI_hash_md5.h" /* own include */
#if defined HAVE_LIMITS_H || defined _LIBC
# include <limits.h>
@@ -58,34 +58,33 @@
#endif
#if UINT_MAX == UINT_MAX_32_BITS
- typedef unsigned int md5_uint32;
+typedef unsigned int md5_uint32;
#else
# if USHRT_MAX == UINT_MAX_32_BITS
- typedef unsigned short md5_uint32;
+typedef unsigned short md5_uint32;
# else
# if ULONG_MAX == UINT_MAX_32_BITS
- typedef unsigned long md5_uint32;
+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."
+/* 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
* 'BLI_hash_md5_stream' and 'BLI_hash_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;
+ 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))
+# define SWAP(n) (((n) << 24) | (((n)&0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
#else
# define SWAP(n) (n)
#endif
@@ -99,10 +98,10 @@ static const unsigned char fillbuf[64] = {0x80, 0 /* , 0, 0, ... */};
*/
static void md5_init_ctx(struct md5_ctx *ctx)
{
- ctx->A = 0x67452301;
- ctx->B = 0xefcdab89;
- ctx->C = 0x98badcfe;
- ctx->D = 0x10325476;
+ ctx->A = 0x67452301;
+ ctx->B = 0xefcdab89;
+ ctx->C = 0x98badcfe;
+ ctx->D = 0x10325476;
}
/**
@@ -118,7 +117,7 @@ static void md5_process_block(const void *buffer, size_t len, struct md5_ctx *ct
*/
/* #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 FG(b, c, d) FF(d, b, c)
#define FH(b, c, d) (b ^ c ^ d)
#define FI(b, c, d) (c ^ (b | ~d))
@@ -126,137 +125,137 @@ static void md5_process_block(const void *buffer, size_t len, struct md5_ctx *ct
* 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);
+ 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);
+ /* 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;
- }
+ /* 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;
+ /* Put checksum in context given as argument. */
+ ctx->A = A;
+ ctx->B = B;
+ ctx->C = C;
+ ctx->D = D;
#undef FF
#undef FG
@@ -272,13 +271,13 @@ static void md5_process_block(const void *buffer, size_t len, struct md5_ctx *ct
*/
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);
+ 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;
+ return resbuf;
}
/* Top level public functions. */
@@ -289,75 +288,75 @@ static void *md5_read_ctx(const struct md5_ctx *ctx, void *resbuf)
*/
int BLI_hash_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;
+#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'.
@@ -366,53 +365,53 @@ int BLI_hash_md5_stream(FILE *stream, void *resblock)
*/
void *BLI_hash_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);
+ 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 *BLI_hash_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;
+ 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
index ff604110f2b..ee4a6329f64 100644
--- a/source/blender/blenlib/intern/hash_mm2a.c
+++ b/source/blender/blenlib/intern/hash_mm2a.c
@@ -32,109 +32,111 @@
#include "BLI_compiler_attrs.h"
-#include "BLI_hash_mm2a.h" /* own include */
+#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
-
-#define MM2A_MIX_FINALIZE(h) \
-{ \
- (h) ^= (h) >> 13; \
- (h) *= MM2A_M; \
- (h) ^= (h) >> 15; \
-} (void)0
+#define MM2A_MIX(h, k) \
+ { \
+ (k) *= MM2A_M; \
+ (k) ^= (k) >> 24; \
+ (k) *= MM2A_M; \
+ (h) = ((h)*MM2A_M) ^ (k); \
+ } \
+ (void)0
+
+#define MM2A_MIX_FINALIZE(h) \
+ { \
+ (h) ^= (h) >> 13; \
+ (h) *= MM2A_M; \
+ (h) ^= (h) >> 15; \
+ } \
+ (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;
- }
- }
+ 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;
+ 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;
+ mm2->size += (uint32_t)len;
- mm2a_mix_tail(mm2, &data, &len);
+ mm2a_mix_tail(mm2, &data, &len);
- for (; len >= 4; data += 4, len -= 4) {
- uint32_t k = *(const uint32_t *)data;
+ for (; len >= 4; data += 4, len -= 4) {
+ uint32_t k = *(const uint32_t *)data;
- MM2A_MIX(mm2->hash, k);
- }
+ MM2A_MIX(mm2->hash, k);
+ }
- mm2a_mix_tail(mm2, &data, &len);
+ 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));
+ 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);
+ MM2A_MIX(mm2->hash, mm2->tail);
+ MM2A_MIX(mm2->hash, mm2->size);
- MM2A_MIX_FINALIZE(mm2->hash);
+ MM2A_MIX_FINALIZE(mm2->hash);
- return mm2->hash;
+ return mm2->hash;
}
/* Non-incremental version, quicker for small keys. */
uint32_t BLI_hash_mm2(const unsigned char *data, size_t len, uint32_t seed)
{
- /* Initialize the hash to a 'random' value */
- uint32_t h = seed ^ len;
-
- /* Mix 4 bytes at a time into the hash */
- for (; len >= 4; data += 4, len -= 4) {
- uint32_t k = *(uint32_t *)data;
-
- MM2A_MIX(h, k);
- }
-
- /* Handle the last few bytes of the input array */
- switch (len) {
- case 3:
- h ^= data[2] << 16;
- ATTR_FALLTHROUGH;
- case 2:
- h ^= data[1] << 8;
- ATTR_FALLTHROUGH;
- case 1:
- h ^= data[0];
- h *= MM2A_M;
- }
-
- /* Do a few final mixes of the hash to ensure the last few bytes are well-incorporated. */
- MM2A_MIX_FINALIZE(h);
-
- return h;
+ /* Initialize the hash to a 'random' value */
+ uint32_t h = seed ^ len;
+
+ /* Mix 4 bytes at a time into the hash */
+ for (; len >= 4; data += 4, len -= 4) {
+ uint32_t k = *(uint32_t *)data;
+
+ MM2A_MIX(h, k);
+ }
+
+ /* Handle the last few bytes of the input array */
+ switch (len) {
+ case 3:
+ h ^= data[2] << 16;
+ ATTR_FALLTHROUGH;
+ case 2:
+ h ^= data[1] << 8;
+ ATTR_FALLTHROUGH;
+ case 1:
+ h ^= data[0];
+ h *= MM2A_M;
+ }
+
+ /* Do a few final mixes of the hash to ensure the last few bytes are well-incorporated. */
+ MM2A_MIX_FINALIZE(h);
+
+ return h;
}
diff --git a/source/blender/blenlib/intern/hash_mm3.c b/source/blender/blenlib/intern/hash_mm3.c
index c788a6ae7c8..0dfb7ff414c 100644
--- a/source/blender/blenlib/intern/hash_mm3.c
+++ b/source/blender/blenlib/intern/hash_mm3.c
@@ -28,20 +28,20 @@
#include "BLI_compiler_compat.h"
#include "BLI_compiler_attrs.h"
-#include "BLI_hash_mm3.h" /* own include */
+#include "BLI_hash_mm3.h" /* own include */
#if defined(_MSC_VER)
# include <stdlib.h>
-# define ROTL32(x,y) _rotl(x,y)
+# define ROTL32(x, y) _rotl(x, y)
# define BIG_CONSTANT(x) (x)
/* Other compilers */
-#else /* defined(_MSC_VER) */
+#else /* defined(_MSC_VER) */
static inline uint32_t rotl32(uint32_t x, int8_t r)
{
- return (x << r) | (x >> (32 - r));
+ return (x << r) | (x >> (32 - r));
}
-# define ROTL32(x,y) rotl32(x,y)
+# define ROTL32(x, y) rotl32(x, y)
# define BIG_CONSTANT(x) (x##LLU)
#endif /* !defined(_MSC_VER) */
@@ -49,92 +49,92 @@ static inline uint32_t rotl32(uint32_t x, int8_t r)
* handle aligned reads, do the conversion here
*/
-BLI_INLINE uint32_t getblock32(const uint32_t * p, int i)
+BLI_INLINE uint32_t getblock32(const uint32_t *p, int i)
{
- return p[i];
+ return p[i];
}
-BLI_INLINE uint64_t getblock64(const uint64_t * p, int i)
+BLI_INLINE uint64_t getblock64(const uint64_t *p, int i)
{
- return p[i];
+ return p[i];
}
/* Finalization mix - force all bits of a hash block to avalanche */
BLI_INLINE uint32_t fmix32(uint32_t h)
{
- h ^= h >> 16;
- h *= 0x85ebca6b;
- h ^= h >> 13;
- h *= 0xc2b2ae35;
- h ^= h >> 16;
+ h ^= h >> 16;
+ h *= 0x85ebca6b;
+ h ^= h >> 13;
+ h *= 0xc2b2ae35;
+ h ^= h >> 16;
- return h;
+ return h;
}
BLI_INLINE uint64_t fmix64(uint64_t k)
{
- k ^= k >> 33;
- k *= BIG_CONSTANT(0xff51afd7ed558ccd);
- k ^= k >> 33;
- k *= BIG_CONSTANT(0xc4ceb9fe1a85ec53);
- k ^= k >> 33;
+ k ^= k >> 33;
+ k *= BIG_CONSTANT(0xff51afd7ed558ccd);
+ k ^= k >> 33;
+ k *= BIG_CONSTANT(0xc4ceb9fe1a85ec53);
+ k ^= k >> 33;
- return k;
+ return k;
}
uint32_t BLI_hash_mm3(const unsigned char *in, size_t len, uint32_t seed)
{
- const uint8_t *data = (const uint8_t *)in;
- const int nblocks = len / 4;
+ const uint8_t *data = (const uint8_t *)in;
+ const int nblocks = len / 4;
- uint32_t h1 = seed;
+ uint32_t h1 = seed;
- const uint32_t c1 = 0xcc9e2d51;
- const uint32_t c2 = 0x1b873593;
+ const uint32_t c1 = 0xcc9e2d51;
+ const uint32_t c2 = 0x1b873593;
- /* body */
+ /* body */
- const uint32_t *blocks = (const uint32_t *)(data + nblocks * 4);
+ const uint32_t *blocks = (const uint32_t *)(data + nblocks * 4);
- for (int i = -nblocks; i; i++) {
- uint32_t k1 = getblock32(blocks, i);
+ for (int i = -nblocks; i; i++) {
+ uint32_t k1 = getblock32(blocks, i);
- k1 *= c1;
- k1 = ROTL32(k1, 15);
- k1 *= c2;
+ k1 *= c1;
+ k1 = ROTL32(k1, 15);
+ k1 *= c2;
- h1 ^= k1;
- h1 = ROTL32(h1, 13);
- h1 = h1 * 5 + 0xe6546b64;
- }
+ h1 ^= k1;
+ h1 = ROTL32(h1, 13);
+ h1 = h1 * 5 + 0xe6546b64;
+ }
- /* tail */
+ /* tail */
- const uint8_t *tail = (const uint8_t *)(data + nblocks * 4);
+ const uint8_t *tail = (const uint8_t *)(data + nblocks * 4);
- uint32_t k1 = 0;
+ uint32_t k1 = 0;
- switch (len & 3) {
- case 3:
- k1 ^= tail[2] << 16;
- ATTR_FALLTHROUGH;
- case 2:
- k1 ^= tail[1] << 8;
- ATTR_FALLTHROUGH;
- case 1:
- k1 ^= tail[0];
- k1 *= c1;
- k1 = ROTL32(k1, 15);
- k1 *= c2;
- h1 ^= k1;
- }
+ switch (len & 3) {
+ case 3:
+ k1 ^= tail[2] << 16;
+ ATTR_FALLTHROUGH;
+ case 2:
+ k1 ^= tail[1] << 8;
+ ATTR_FALLTHROUGH;
+ case 1:
+ k1 ^= tail[0];
+ k1 *= c1;
+ k1 = ROTL32(k1, 15);
+ k1 *= c2;
+ h1 ^= k1;
+ }
- /* finalization */
+ /* finalization */
- h1 ^= len;
+ h1 ^= len;
- h1 = fmix32(h1);
+ h1 = fmix32(h1);
- return h1;
+ return h1;
}
diff --git a/source/blender/blenlib/intern/jitter_2d.c b/source/blender/blenlib/intern/jitter_2d.c
index bbf1948be4d..aed43657b3f 100644
--- a/source/blender/blenlib/intern/jitter_2d.c
+++ b/source/blender/blenlib/intern/jitter_2d.c
@@ -31,148 +31,157 @@
#include "BLI_strict_flags.h"
-
void BLI_jitterate1(float (*jit1)[2], float (*jit2)[2], int num, float rad1)
{
- int i, j, k;
- float vecx, vecy, dvecx, dvecy, x, y, len;
-
- for (i = num - 1; i >= 0; i--) {
- dvecx = dvecy = 0.0;
- x = jit1[i][0];
- y = jit1[i][1];
- for (j = num - 1; j >= 0; j--) {
- if (i != j) {
- vecx = jit1[j][0] - x - 1.0f;
- vecy = jit1[j][1] - y - 1.0f;
- for (k = 3; k > 0; k--) {
- if (fabsf(vecx) < rad1 && fabsf(vecy) < rad1) {
- len = sqrtf(vecx * vecx + vecy * vecy);
- if (len > 0 && len < rad1) {
- len = len / rad1;
- dvecx += vecx / len;
- dvecy += vecy / len;
- }
- }
- vecx += 1.0f;
-
- if (fabsf(vecx) < rad1 && fabsf(vecy) < rad1) {
- len = sqrtf(vecx * vecx + vecy * vecy);
- if (len > 0 && len < rad1) {
- len = len / rad1;
- dvecx += vecx / len;
- dvecy += vecy / len;
- }
- }
- vecx += 1.0f;
-
- if (fabsf(vecx) < rad1 && fabsf(vecy) < rad1) {
- len = sqrtf(vecx * vecx + vecy * vecy);
- if (len > 0 && len < rad1) {
- len = len / rad1;
- dvecx += vecx / len;
- dvecy += vecy / len;
- }
- }
- vecx -= 2.0f;
- vecy += 1.0f;
- }
- }
- }
-
- x -= dvecx / 18.0f;
- y -= dvecy / 18.0f;
- x -= floorf(x);
- y -= floorf(y);
- jit2[i][0] = x;
- jit2[i][1] = y;
- }
- memcpy(jit1, jit2, 2 * (unsigned int)num * sizeof(float));
+ int i, j, k;
+ float vecx, vecy, dvecx, dvecy, x, y, len;
+
+ for (i = num - 1; i >= 0; i--) {
+ dvecx = dvecy = 0.0;
+ x = jit1[i][0];
+ y = jit1[i][1];
+ for (j = num - 1; j >= 0; j--) {
+ if (i != j) {
+ vecx = jit1[j][0] - x - 1.0f;
+ vecy = jit1[j][1] - y - 1.0f;
+ for (k = 3; k > 0; k--) {
+ if (fabsf(vecx) < rad1 && fabsf(vecy) < rad1) {
+ len = sqrtf(vecx * vecx + vecy * vecy);
+ if (len > 0 && len < rad1) {
+ len = len / rad1;
+ dvecx += vecx / len;
+ dvecy += vecy / len;
+ }
+ }
+ vecx += 1.0f;
+
+ if (fabsf(vecx) < rad1 && fabsf(vecy) < rad1) {
+ len = sqrtf(vecx * vecx + vecy * vecy);
+ if (len > 0 && len < rad1) {
+ len = len / rad1;
+ dvecx += vecx / len;
+ dvecy += vecy / len;
+ }
+ }
+ vecx += 1.0f;
+
+ if (fabsf(vecx) < rad1 && fabsf(vecy) < rad1) {
+ len = sqrtf(vecx * vecx + vecy * vecy);
+ if (len > 0 && len < rad1) {
+ len = len / rad1;
+ dvecx += vecx / len;
+ dvecy += vecy / len;
+ }
+ }
+ vecx -= 2.0f;
+ vecy += 1.0f;
+ }
+ }
+ }
+
+ x -= dvecx / 18.0f;
+ y -= dvecy / 18.0f;
+ x -= floorf(x);
+ y -= floorf(y);
+ jit2[i][0] = x;
+ jit2[i][1] = y;
+ }
+ memcpy(jit1, jit2, 2 * (unsigned int)num * sizeof(float));
}
void BLI_jitterate2(float (*jit1)[2], float (*jit2)[2], int num, float rad2)
{
- int i, j;
- float vecx, vecy, dvecx, dvecy, x, y;
-
- for (i = num - 1; i >= 0; i--) {
- dvecx = dvecy = 0.0;
- x = jit1[i][0];
- y = jit1[i][1];
- for (j = num - 1; j >= 0; j--) {
- if (i != j) {
- vecx = jit1[j][0] - x - 1.0f;
- vecy = jit1[j][1] - y - 1.0f;
-
- if (fabsf(vecx) < rad2) { dvecx += vecx * rad2; }
- vecx += 1.0f;
- if (fabsf(vecx) < rad2) { dvecx += vecx * rad2; }
- vecx += 1.0f;
- if (fabsf(vecx) < rad2) { dvecx += vecx * rad2; }
-
- if (fabsf(vecy) < rad2) { dvecy += vecy * rad2; }
- vecy += 1.0f;
- if (fabsf(vecy) < rad2) { dvecy += vecy * rad2; }
- vecy += 1.0f;
- if (fabsf(vecy) < rad2) { dvecy += vecy * rad2; }
-
- }
- }
-
- x -= dvecx / 2.0f;
- y -= dvecy / 2.0f;
- x -= floorf(x);
- y -= floorf(y);
- jit2[i][0] = x;
- jit2[i][1] = y;
- }
- memcpy(jit1, jit2, (unsigned int)num * sizeof(float[2]));
+ int i, j;
+ float vecx, vecy, dvecx, dvecy, x, y;
+
+ for (i = num - 1; i >= 0; i--) {
+ dvecx = dvecy = 0.0;
+ x = jit1[i][0];
+ y = jit1[i][1];
+ for (j = num - 1; j >= 0; j--) {
+ if (i != j) {
+ vecx = jit1[j][0] - x - 1.0f;
+ vecy = jit1[j][1] - y - 1.0f;
+
+ if (fabsf(vecx) < rad2) {
+ dvecx += vecx * rad2;
+ }
+ vecx += 1.0f;
+ if (fabsf(vecx) < rad2) {
+ dvecx += vecx * rad2;
+ }
+ vecx += 1.0f;
+ if (fabsf(vecx) < rad2) {
+ dvecx += vecx * rad2;
+ }
+
+ if (fabsf(vecy) < rad2) {
+ dvecy += vecy * rad2;
+ }
+ vecy += 1.0f;
+ if (fabsf(vecy) < rad2) {
+ dvecy += vecy * rad2;
+ }
+ vecy += 1.0f;
+ if (fabsf(vecy) < rad2) {
+ dvecy += vecy * rad2;
+ }
+ }
+ }
+
+ x -= dvecx / 2.0f;
+ y -= dvecy / 2.0f;
+ x -= floorf(x);
+ y -= floorf(y);
+ jit2[i][0] = x;
+ jit2[i][1] = y;
+ }
+ memcpy(jit1, jit2, (unsigned int)num * sizeof(float[2]));
}
-
void BLI_jitter_init(float (*jitarr)[2], int num)
{
- float (*jit2)[2];
- float num_fl, num_fl_sqrt;
- float x, rad1, rad2, rad3;
- RNG *rng;
- int i;
-
- if (num == 0) {
- return;
- }
-
- num_fl = (float)num;
- num_fl_sqrt = sqrtf(num_fl);
-
- jit2 = MEM_mallocN(12 + (unsigned int)num * sizeof(float[2]), "initjit");
- rad1 = 1.0f / num_fl_sqrt;
- rad2 = 1.0f / num_fl;
- rad3 = num_fl_sqrt / num_fl;
-
- rng = BLI_rng_new(31415926 + (unsigned int)num);
-
- x = 0;
- for (i = 0; i < num; i++) {
- jitarr[i][0] = x + rad1 * (float)(0.5 - BLI_rng_get_double(rng));
- jitarr[i][1] = (float)i / num_fl + rad1 * (float)(0.5 - BLI_rng_get_double(rng));
- x += rad3;
- x -= floorf(x);
- }
-
- BLI_rng_free(rng);
-
- for (i = 0; i < 24; i++) {
- BLI_jitterate1(jitarr, jit2, num, rad1);
- BLI_jitterate1(jitarr, jit2, num, rad1);
- BLI_jitterate2(jitarr, jit2, num, rad2);
- }
-
- MEM_freeN(jit2);
-
- /* finally, move jittertab to be centered around (0, 0) */
- for (i = 0; i < num; i++) {
- jitarr[i][0] -= 0.5f;
- jitarr[i][1] -= 0.5f;
- }
+ float(*jit2)[2];
+ float num_fl, num_fl_sqrt;
+ float x, rad1, rad2, rad3;
+ RNG *rng;
+ int i;
+
+ if (num == 0) {
+ return;
+ }
+
+ num_fl = (float)num;
+ num_fl_sqrt = sqrtf(num_fl);
+
+ jit2 = MEM_mallocN(12 + (unsigned int)num * sizeof(float[2]), "initjit");
+ rad1 = 1.0f / num_fl_sqrt;
+ rad2 = 1.0f / num_fl;
+ rad3 = num_fl_sqrt / num_fl;
+
+ rng = BLI_rng_new(31415926 + (unsigned int)num);
+
+ x = 0;
+ for (i = 0; i < num; i++) {
+ jitarr[i][0] = x + rad1 * (float)(0.5 - BLI_rng_get_double(rng));
+ jitarr[i][1] = (float)i / num_fl + rad1 * (float)(0.5 - BLI_rng_get_double(rng));
+ x += rad3;
+ x -= floorf(x);
+ }
+
+ BLI_rng_free(rng);
+
+ for (i = 0; i < 24; i++) {
+ BLI_jitterate1(jitarr, jit2, num, rad1);
+ BLI_jitterate1(jitarr, jit2, num, rad1);
+ BLI_jitterate2(jitarr, jit2, num, rad2);
+ }
+
+ MEM_freeN(jit2);
+
+ /* finally, move jittertab to be centered around (0, 0) */
+ for (i = 0; i < num; i++) {
+ jitarr[i][0] -= 0.5f;
+ jitarr[i][1] -= 0.5f;
+ }
}
diff --git a/source/blender/blenlib/intern/kdtree_1d.c b/source/blender/blenlib/intern/kdtree_1d.c
index 95d440d3644..b5d5707df29 100644
--- a/source/blender/blenlib/intern/kdtree_1d.c
+++ b/source/blender/blenlib/intern/kdtree_1d.c
@@ -22,4 +22,4 @@
#define KDTREE_PREFIX_ID BLI_kdtree_1d
#define KDTree KDTree_1d
#define KDTreeNearest KDTreeNearest_1d
-# include "kdtree_impl.h"
+#include "kdtree_impl.h"
diff --git a/source/blender/blenlib/intern/kdtree_2d.c b/source/blender/blenlib/intern/kdtree_2d.c
index 8ad55e2d964..a9d1c953bff 100644
--- a/source/blender/blenlib/intern/kdtree_2d.c
+++ b/source/blender/blenlib/intern/kdtree_2d.c
@@ -22,4 +22,4 @@
#define KDTREE_PREFIX_ID BLI_kdtree_2d
#define KDTree KDTree_2d
#define KDTreeNearest KDTreeNearest_2d
-# include "kdtree_impl.h"
+#include "kdtree_impl.h"
diff --git a/source/blender/blenlib/intern/kdtree_3d.c b/source/blender/blenlib/intern/kdtree_3d.c
index 2f85755b676..7b24a249e18 100644
--- a/source/blender/blenlib/intern/kdtree_3d.c
+++ b/source/blender/blenlib/intern/kdtree_3d.c
@@ -22,4 +22,4 @@
#define KDTREE_PREFIX_ID BLI_kdtree_3d
#define KDTree KDTree_3d
#define KDTreeNearest KDTreeNearest_3d
-# include "kdtree_impl.h"
+#include "kdtree_impl.h"
diff --git a/source/blender/blenlib/intern/kdtree_impl.h b/source/blender/blenlib/intern/kdtree_impl.h
index 1bce3473bde..a4b1833e657 100644
--- a/source/blender/blenlib/intern/kdtree_impl.h
+++ b/source/blender/blenlib/intern/kdtree_impl.h
@@ -25,36 +25,36 @@
#include "BLI_utildefines.h"
#include "BLI_strict_flags.h"
-#define _CONCAT_AUX(MACRO_ARG1, MACRO_ARG2) MACRO_ARG1 ## MACRO_ARG2
+#define _CONCAT_AUX(MACRO_ARG1, MACRO_ARG2) MACRO_ARG1##MACRO_ARG2
#define _CONCAT(MACRO_ARG1, MACRO_ARG2) _CONCAT_AUX(MACRO_ARG1, MACRO_ARG2)
#define BLI_kdtree_nd_(id) _CONCAT(KDTREE_PREFIX_ID, _##id)
typedef struct KDTreeNode_head {
- uint left, right;
- float co[KD_DIMS];
- int index;
+ uint left, right;
+ float co[KD_DIMS];
+ int index;
} KDTreeNode_head;
typedef struct KDTreeNode {
- uint left, right;
- float co[KD_DIMS];
- int index;
- uint d; /* range is only (0..KD_DIMS - 1) */
+ uint left, right;
+ float co[KD_DIMS];
+ int index;
+ uint d; /* range is only (0..KD_DIMS - 1) */
} KDTreeNode;
struct KDTree {
- KDTreeNode *nodes;
- uint nodes_len;
- uint root;
+ KDTreeNode *nodes;
+ uint nodes_len;
+ uint root;
#ifdef DEBUG
- bool is_balanced; /* ensure we call balance first */
- uint nodes_len_capacity; /* max size of the tree */
+ bool is_balanced; /* ensure we call balance first */
+ uint nodes_len_capacity; /* max size of the tree */
#endif
};
-#define KD_STACK_INIT 100 /* initial size for array (on the stack) */
-#define KD_NEAR_ALLOC_INC 100 /* alloc increment for collecting nearest */
-#define KD_FOUND_ALLOC_INC 50 /* alloc increment for collecting nearest */
+#define KD_STACK_INIT 100 /* initial size for array (on the stack) */
+#define KD_NEAR_ALLOC_INC 100 /* alloc increment for collecting nearest */
+#define KD_FOUND_ALLOC_INC 50 /* alloc increment for collecting nearest */
#define KD_NODE_UNSET ((uint)-1)
@@ -67,23 +67,25 @@ struct KDTree {
static void copy_vn_vn(float v0[KD_DIMS], const float v1[KD_DIMS])
{
- for (uint j = 0; j < KD_DIMS; j++) {
- v0[j] = v1[j];
- }
+ for (uint j = 0; j < KD_DIMS; j++) {
+ v0[j] = v1[j];
+ }
}
static float len_squared_vnvn(const float v0[KD_DIMS], const float v1[KD_DIMS])
{
- float d = 0.0f;
- for (uint j = 0; j < KD_DIMS; j++) {
- d += SQUARE(v0[j] - v1[j]);
- }
- return d;
+ float d = 0.0f;
+ for (uint j = 0; j < KD_DIMS; j++) {
+ d += SQUARE(v0[j] - v1[j]);
+ }
+ return d;
}
-static float len_squared_vnvn_cb(const float co_kdtree[KD_DIMS], const float co_search[KD_DIMS], const void *UNUSED(user_data))
+static float len_squared_vnvn_cb(const float co_kdtree[KD_DIMS],
+ const float co_search[KD_DIMS],
+ const void *UNUSED(user_data))
{
- return len_squared_vnvn(co_kdtree, co_search);
+ return len_squared_vnvn(co_kdtree, co_search);
}
/** \} */
@@ -93,27 +95,27 @@ static float len_squared_vnvn_cb(const float co_kdtree[KD_DIMS], const float co_
*/
KDTree *BLI_kdtree_nd_(new)(uint nodes_len_capacity)
{
- KDTree *tree;
+ KDTree *tree;
- tree = MEM_mallocN(sizeof(KDTree), "KDTree");
- tree->nodes = MEM_mallocN(sizeof(KDTreeNode) * nodes_len_capacity, "KDTreeNode");
- tree->nodes_len = 0;
- tree->root = KD_NODE_ROOT_IS_INIT;
+ tree = MEM_mallocN(sizeof(KDTree), "KDTree");
+ tree->nodes = MEM_mallocN(sizeof(KDTreeNode) * nodes_len_capacity, "KDTreeNode");
+ tree->nodes_len = 0;
+ tree->root = KD_NODE_ROOT_IS_INIT;
#ifdef DEBUG
- tree->is_balanced = false;
- tree->nodes_len_capacity = nodes_len_capacity;
+ tree->is_balanced = false;
+ tree->nodes_len_capacity = nodes_len_capacity;
#endif
- return tree;
+ return tree;
}
void BLI_kdtree_nd_(free)(KDTree *tree)
{
- if (tree) {
- MEM_freeN(tree->nodes);
- MEM_freeN(tree);
- }
+ if (tree) {
+ MEM_freeN(tree->nodes);
+ MEM_freeN(tree);
+ }
}
/**
@@ -121,209 +123,212 @@ void BLI_kdtree_nd_(free)(KDTree *tree)
*/
void BLI_kdtree_nd_(insert)(KDTree *tree, int index, const float co[KD_DIMS])
{
- KDTreeNode *node = &tree->nodes[tree->nodes_len++];
+ KDTreeNode *node = &tree->nodes[tree->nodes_len++];
#ifdef DEBUG
- BLI_assert(tree->nodes_len <= tree->nodes_len_capacity);
+ BLI_assert(tree->nodes_len <= tree->nodes_len_capacity);
#endif
- /* note, array isn't calloc'd,
- * need to initialize all struct members */
+ /* note, array isn't calloc'd,
+ * need to initialize all struct members */
- node->left = node->right = KD_NODE_UNSET;
- copy_vn_vn(node->co, co);
- node->index = index;
- node->d = 0;
+ node->left = node->right = KD_NODE_UNSET;
+ copy_vn_vn(node->co, co);
+ node->index = index;
+ node->d = 0;
#ifdef DEBUG
- tree->is_balanced = false;
+ tree->is_balanced = false;
#endif
}
static uint kdtree_balance(KDTreeNode *nodes, uint nodes_len, uint axis, const uint ofs)
{
- KDTreeNode *node;
- float co;
- uint left, right, median, i, j;
-
- if (nodes_len <= 0) {
- return KD_NODE_UNSET;
- }
- else if (nodes_len == 1) {
- return 0 + ofs;
- }
-
- /* quicksort style sorting around median */
- left = 0;
- right = nodes_len - 1;
- median = nodes_len / 2;
-
- while (right > left) {
- co = nodes[right].co[axis];
- i = left - 1;
- j = right;
-
- while (1) {
- while (nodes[++i].co[axis] < co) { /* pass */ }
- while (nodes[--j].co[axis] > co && j > left) { /* pass */ }
-
- if (i >= j) {
- break;
- }
-
- SWAP(KDTreeNode_head, *(KDTreeNode_head *)&nodes[i], *(KDTreeNode_head *)&nodes[j]);
- }
-
- SWAP(KDTreeNode_head, *(KDTreeNode_head *)&nodes[i], *(KDTreeNode_head *)&nodes[right]);
- if (i >= median) {
- right = i - 1;
- }
- if (i <= median) {
- left = i + 1;
- }
- }
-
- /* set node and sort subnodes */
- node = &nodes[median];
- node->d = axis;
- axis = (axis + 1) % KD_DIMS;
- node->left = kdtree_balance(nodes, median, axis, ofs);
- node->right = kdtree_balance(nodes + median + 1, (nodes_len - (median + 1)), axis, (median + 1) + ofs);
-
- return median + ofs;
+ KDTreeNode *node;
+ float co;
+ uint left, right, median, i, j;
+
+ if (nodes_len <= 0) {
+ return KD_NODE_UNSET;
+ }
+ else if (nodes_len == 1) {
+ return 0 + ofs;
+ }
+
+ /* quicksort style sorting around median */
+ left = 0;
+ right = nodes_len - 1;
+ median = nodes_len / 2;
+
+ while (right > left) {
+ co = nodes[right].co[axis];
+ i = left - 1;
+ j = right;
+
+ while (1) {
+ while (nodes[++i].co[axis] < co) { /* pass */
+ }
+ while (nodes[--j].co[axis] > co && j > left) { /* pass */
+ }
+
+ if (i >= j) {
+ break;
+ }
+
+ SWAP(KDTreeNode_head, *(KDTreeNode_head *)&nodes[i], *(KDTreeNode_head *)&nodes[j]);
+ }
+
+ SWAP(KDTreeNode_head, *(KDTreeNode_head *)&nodes[i], *(KDTreeNode_head *)&nodes[right]);
+ if (i >= median) {
+ right = i - 1;
+ }
+ if (i <= median) {
+ left = i + 1;
+ }
+ }
+
+ /* set node and sort subnodes */
+ node = &nodes[median];
+ node->d = axis;
+ axis = (axis + 1) % KD_DIMS;
+ node->left = kdtree_balance(nodes, median, axis, ofs);
+ node->right = kdtree_balance(
+ nodes + median + 1, (nodes_len - (median + 1)), axis, (median + 1) + ofs);
+
+ return median + ofs;
}
void BLI_kdtree_nd_(balance)(KDTree *tree)
{
- if (tree->root != KD_NODE_ROOT_IS_INIT) {
- for (uint i = 0; i < tree->nodes_len; i++) {
- tree->nodes[i].left = KD_NODE_UNSET;
- tree->nodes[i].right = KD_NODE_UNSET;
- }
- }
+ if (tree->root != KD_NODE_ROOT_IS_INIT) {
+ for (uint i = 0; i < tree->nodes_len; i++) {
+ tree->nodes[i].left = KD_NODE_UNSET;
+ tree->nodes[i].right = KD_NODE_UNSET;
+ }
+ }
- tree->root = kdtree_balance(tree->nodes, tree->nodes_len, 0, 0);
+ tree->root = kdtree_balance(tree->nodes, tree->nodes_len, 0, 0);
#ifdef DEBUG
- tree->is_balanced = true;
+ tree->is_balanced = true;
#endif
}
static uint *realloc_nodes(uint *stack, uint *stack_len_capacity, const bool is_alloc)
{
- uint *stack_new = MEM_mallocN((*stack_len_capacity + KD_NEAR_ALLOC_INC) * sizeof(uint), "KDTree.treestack");
- memcpy(stack_new, stack, *stack_len_capacity * sizeof(uint));
- // memset(stack_new + *stack_len_capacity, 0, sizeof(uint) * KD_NEAR_ALLOC_INC);
- if (is_alloc) {
- MEM_freeN(stack);
- }
- *stack_len_capacity += KD_NEAR_ALLOC_INC;
- return stack_new;
+ uint *stack_new = MEM_mallocN((*stack_len_capacity + KD_NEAR_ALLOC_INC) * sizeof(uint),
+ "KDTree.treestack");
+ memcpy(stack_new, stack, *stack_len_capacity * sizeof(uint));
+ // memset(stack_new + *stack_len_capacity, 0, sizeof(uint) * KD_NEAR_ALLOC_INC);
+ if (is_alloc) {
+ MEM_freeN(stack);
+ }
+ *stack_len_capacity += KD_NEAR_ALLOC_INC;
+ return stack_new;
}
/**
* Find nearest returns index, and -1 if no node is found.
*/
-int BLI_kdtree_nd_(find_nearest)(
- const KDTree *tree, const float co[KD_DIMS],
- KDTreeNearest *r_nearest)
+int BLI_kdtree_nd_(find_nearest)(const KDTree *tree,
+ const float co[KD_DIMS],
+ KDTreeNearest *r_nearest)
{
- const KDTreeNode *nodes = tree->nodes;
- const KDTreeNode *root, *min_node;
- uint *stack, stack_default[KD_STACK_INIT];
- float min_dist, cur_dist;
- uint stack_len_capacity, cur = 0;
+ const KDTreeNode *nodes = tree->nodes;
+ const KDTreeNode *root, *min_node;
+ uint *stack, stack_default[KD_STACK_INIT];
+ float min_dist, cur_dist;
+ uint stack_len_capacity, cur = 0;
#ifdef DEBUG
- BLI_assert(tree->is_balanced == true);
+ BLI_assert(tree->is_balanced == true);
#endif
- if (UNLIKELY(tree->root == KD_NODE_UNSET)) {
- return -1;
- }
-
- stack = stack_default;
- stack_len_capacity = KD_STACK_INIT;
-
- root = &nodes[tree->root];
- min_node = root;
- min_dist = len_squared_vnvn(root->co, co);
-
- if (co[root->d] < root->co[root->d]) {
- if (root->right != KD_NODE_UNSET) {
- stack[cur++] = root->right;
- }
- if (root->left != KD_NODE_UNSET) {
- stack[cur++] = root->left;
- }
- }
- else {
- if (root->left != KD_NODE_UNSET) {
- stack[cur++] = root->left;
- }
- if (root->right != KD_NODE_UNSET) {
- stack[cur++] = root->right;
- }
- }
-
- while (cur--) {
- const KDTreeNode *node = &nodes[stack[cur]];
-
- cur_dist = node->co[node->d] - co[node->d];
-
- if (cur_dist < 0.0f) {
- cur_dist = -cur_dist * cur_dist;
-
- if (-cur_dist < min_dist) {
- cur_dist = len_squared_vnvn(node->co, co);
- if (cur_dist < min_dist) {
- min_dist = cur_dist;
- min_node = node;
- }
- if (node->left != KD_NODE_UNSET) {
- stack[cur++] = node->left;
- }
- }
- if (node->right != KD_NODE_UNSET) {
- stack[cur++] = node->right;
- }
- }
- else {
- cur_dist = cur_dist * cur_dist;
-
- if (cur_dist < min_dist) {
- cur_dist = len_squared_vnvn(node->co, co);
- if (cur_dist < min_dist) {
- min_dist = cur_dist;
- min_node = node;
- }
- if (node->right != KD_NODE_UNSET) {
- stack[cur++] = node->right;
- }
- }
- if (node->left != KD_NODE_UNSET) {
- stack[cur++] = node->left;
- }
- }
- if (UNLIKELY(cur + KD_DIMS > stack_len_capacity)) {
- stack = realloc_nodes(stack, &stack_len_capacity, stack_default != stack);
- }
- }
-
- if (r_nearest) {
- r_nearest->index = min_node->index;
- r_nearest->dist = sqrtf(min_dist);
- copy_vn_vn(r_nearest->co, min_node->co);
- }
-
- if (stack != stack_default) {
- MEM_freeN(stack);
- }
-
- return min_node->index;
+ if (UNLIKELY(tree->root == KD_NODE_UNSET)) {
+ return -1;
+ }
+
+ stack = stack_default;
+ stack_len_capacity = KD_STACK_INIT;
+
+ root = &nodes[tree->root];
+ min_node = root;
+ min_dist = len_squared_vnvn(root->co, co);
+
+ if (co[root->d] < root->co[root->d]) {
+ if (root->right != KD_NODE_UNSET) {
+ stack[cur++] = root->right;
+ }
+ if (root->left != KD_NODE_UNSET) {
+ stack[cur++] = root->left;
+ }
+ }
+ else {
+ if (root->left != KD_NODE_UNSET) {
+ stack[cur++] = root->left;
+ }
+ if (root->right != KD_NODE_UNSET) {
+ stack[cur++] = root->right;
+ }
+ }
+
+ while (cur--) {
+ const KDTreeNode *node = &nodes[stack[cur]];
+
+ cur_dist = node->co[node->d] - co[node->d];
+
+ if (cur_dist < 0.0f) {
+ cur_dist = -cur_dist * cur_dist;
+
+ if (-cur_dist < min_dist) {
+ cur_dist = len_squared_vnvn(node->co, co);
+ if (cur_dist < min_dist) {
+ min_dist = cur_dist;
+ min_node = node;
+ }
+ if (node->left != KD_NODE_UNSET) {
+ stack[cur++] = node->left;
+ }
+ }
+ if (node->right != KD_NODE_UNSET) {
+ stack[cur++] = node->right;
+ }
+ }
+ else {
+ cur_dist = cur_dist * cur_dist;
+
+ if (cur_dist < min_dist) {
+ cur_dist = len_squared_vnvn(node->co, co);
+ if (cur_dist < min_dist) {
+ min_dist = cur_dist;
+ min_node = node;
+ }
+ if (node->right != KD_NODE_UNSET) {
+ stack[cur++] = node->right;
+ }
+ }
+ if (node->left != KD_NODE_UNSET) {
+ stack[cur++] = node->left;
+ }
+ }
+ if (UNLIKELY(cur + KD_DIMS > stack_len_capacity)) {
+ stack = realloc_nodes(stack, &stack_len_capacity, stack_default != stack);
+ }
+ }
+
+ if (r_nearest) {
+ r_nearest->index = min_node->index;
+ r_nearest->dist = sqrtf(min_dist);
+ copy_vn_vn(r_nearest->co, min_node->co);
+ }
+
+ if (stack != stack_default) {
+ MEM_freeN(stack);
+ }
+
+ return min_node->index;
}
-
/**
* A version of #BLI_kdtree_3d_find_nearest which runs a callback
* to filter out values.
@@ -332,131 +337,136 @@ int BLI_kdtree_nd_(find_nearest)(
* Return codes: (1: accept, 0: skip, -1: immediate exit).
*/
int BLI_kdtree_nd_(find_nearest_cb)(
- const KDTree *tree, const float co[KD_DIMS],
- int (*filter_cb)(void *user_data, int index, const float co[KD_DIMS], float dist_sq), void *user_data,
- KDTreeNearest *r_nearest)
+ const KDTree *tree,
+ const float co[KD_DIMS],
+ int (*filter_cb)(void *user_data, int index, const float co[KD_DIMS], float dist_sq),
+ void *user_data,
+ KDTreeNearest *r_nearest)
{
- const KDTreeNode *nodes = tree->nodes;
- const KDTreeNode *min_node = NULL;
+ const KDTreeNode *nodes = tree->nodes;
+ const KDTreeNode *min_node = NULL;
- uint *stack, stack_default[KD_STACK_INIT];
- float min_dist = FLT_MAX, cur_dist;
- uint stack_len_capacity, cur = 0;
+ uint *stack, stack_default[KD_STACK_INIT];
+ float min_dist = FLT_MAX, cur_dist;
+ uint stack_len_capacity, cur = 0;
#ifdef DEBUG
- BLI_assert(tree->is_balanced == true);
+ BLI_assert(tree->is_balanced == true);
#endif
- if (UNLIKELY(tree->root == KD_NODE_UNSET)) {
- return -1;
- }
+ if (UNLIKELY(tree->root == KD_NODE_UNSET)) {
+ return -1;
+ }
- stack = stack_default;
- stack_len_capacity = ARRAY_SIZE(stack_default);
+ stack = stack_default;
+ stack_len_capacity = ARRAY_SIZE(stack_default);
#define NODE_TEST_NEAREST(node) \
-{ \
- const float dist_sq = len_squared_vnvn((node)->co, co); \
- if (dist_sq < min_dist) { \
- const int result = filter_cb(user_data, (node)->index, (node)->co, dist_sq); \
- if (result == 1) { \
- min_dist = dist_sq; \
- min_node = node; \
- } \
- else if (result == 0) { \
- /* pass */ \
- } \
- else { \
- BLI_assert(result == -1); \
- goto finally; \
- } \
- } \
-} ((void)0)
-
- stack[cur++] = tree->root;
-
- while (cur--) {
- const KDTreeNode *node = &nodes[stack[cur]];
-
- cur_dist = node->co[node->d] - co[node->d];
-
- if (cur_dist < 0.0f) {
- cur_dist = -cur_dist * cur_dist;
-
- if (-cur_dist < min_dist) {
- NODE_TEST_NEAREST(node);
-
- if (node->left != KD_NODE_UNSET) {
- stack[cur++] = node->left;
- }
- }
- if (node->right != KD_NODE_UNSET) {
- stack[cur++] = node->right;
- }
- }
- else {
- cur_dist = cur_dist * cur_dist;
-
- if (cur_dist < min_dist) {
- NODE_TEST_NEAREST(node);
-
- if (node->right != KD_NODE_UNSET) {
- stack[cur++] = node->right;
- }
- }
- if (node->left != KD_NODE_UNSET) {
- stack[cur++] = node->left;
- }
- }
- if (UNLIKELY(cur + KD_DIMS > stack_len_capacity)) {
- stack = realloc_nodes(stack, &stack_len_capacity, stack_default != stack);
- }
- }
+ { \
+ const float dist_sq = len_squared_vnvn((node)->co, co); \
+ if (dist_sq < min_dist) { \
+ const int result = filter_cb(user_data, (node)->index, (node)->co, dist_sq); \
+ if (result == 1) { \
+ min_dist = dist_sq; \
+ min_node = node; \
+ } \
+ else if (result == 0) { \
+ /* pass */ \
+ } \
+ else { \
+ BLI_assert(result == -1); \
+ goto finally; \
+ } \
+ } \
+ } \
+ ((void)0)
+
+ stack[cur++] = tree->root;
+
+ while (cur--) {
+ const KDTreeNode *node = &nodes[stack[cur]];
+
+ cur_dist = node->co[node->d] - co[node->d];
+
+ if (cur_dist < 0.0f) {
+ cur_dist = -cur_dist * cur_dist;
+
+ if (-cur_dist < min_dist) {
+ NODE_TEST_NEAREST(node);
+
+ if (node->left != KD_NODE_UNSET) {
+ stack[cur++] = node->left;
+ }
+ }
+ if (node->right != KD_NODE_UNSET) {
+ stack[cur++] = node->right;
+ }
+ }
+ else {
+ cur_dist = cur_dist * cur_dist;
+
+ if (cur_dist < min_dist) {
+ NODE_TEST_NEAREST(node);
+
+ if (node->right != KD_NODE_UNSET) {
+ stack[cur++] = node->right;
+ }
+ }
+ if (node->left != KD_NODE_UNSET) {
+ stack[cur++] = node->left;
+ }
+ }
+ if (UNLIKELY(cur + KD_DIMS > stack_len_capacity)) {
+ stack = realloc_nodes(stack, &stack_len_capacity, stack_default != stack);
+ }
+ }
#undef NODE_TEST_NEAREST
-
finally:
- if (stack != stack_default) {
- MEM_freeN(stack);
- }
-
- if (min_node) {
- if (r_nearest) {
- r_nearest->index = min_node->index;
- r_nearest->dist = sqrtf(min_dist);
- copy_vn_vn(r_nearest->co, min_node->co);
- }
-
- return min_node->index;
- }
- else {
- return -1;
- }
+ if (stack != stack_default) {
+ MEM_freeN(stack);
+ }
+
+ if (min_node) {
+ if (r_nearest) {
+ r_nearest->index = min_node->index;
+ r_nearest->dist = sqrtf(min_dist);
+ copy_vn_vn(r_nearest->co, min_node->co);
+ }
+
+ return min_node->index;
+ }
+ else {
+ return -1;
+ }
}
-static void nearest_ordered_insert(
- KDTreeNearest *nearest, uint *nearest_len, const uint nearest_len_capacity,
- const int index, const float dist, const float co[KD_DIMS])
+static void nearest_ordered_insert(KDTreeNearest *nearest,
+ uint *nearest_len,
+ const uint nearest_len_capacity,
+ const int index,
+ const float dist,
+ const float co[KD_DIMS])
{
- uint i;
-
- if (*nearest_len < nearest_len_capacity) {
- (*nearest_len)++;
- }
-
- for (i = *nearest_len - 1; i > 0; i--) {
- if (dist >= nearest[i - 1].dist) {
- break;
- }
- else {
- nearest[i] = nearest[i - 1];
- }
- }
-
- nearest[i].index = index;
- nearest[i].dist = dist;
- copy_vn_vn(nearest[i].co, co);
+ uint i;
+
+ if (*nearest_len < nearest_len_capacity) {
+ (*nearest_len)++;
+ }
+
+ for (i = *nearest_len - 1; i > 0; i--) {
+ if (dist >= nearest[i - 1].dist) {
+ break;
+ }
+ else {
+ nearest[i] = nearest[i - 1];
+ }
+ }
+
+ nearest[i].index = index;
+ nearest[i].dist = dist;
+ copy_vn_vn(nearest[i].co, co);
}
/**
@@ -465,158 +475,162 @@ static void nearest_ordered_insert(
* \param r_nearest: An array of nearest, sized at least \a nearest_len_capacity.
*/
int BLI_kdtree_nd_(find_nearest_n_with_len_squared_cb)(
- const KDTree *tree, const float co[KD_DIMS],
- KDTreeNearest r_nearest[],
- const uint nearest_len_capacity,
- float (*len_sq_fn)(const float co_search[KD_DIMS], const float co_test[KD_DIMS], const void *user_data),
- const void *user_data)
+ const KDTree *tree,
+ const float co[KD_DIMS],
+ KDTreeNearest r_nearest[],
+ const uint nearest_len_capacity,
+ float (*len_sq_fn)(const float co_search[KD_DIMS],
+ const float co_test[KD_DIMS],
+ const void *user_data),
+ const void *user_data)
{
- const KDTreeNode *nodes = tree->nodes;
- const KDTreeNode *root;
- uint *stack, stack_default[KD_STACK_INIT];
- float cur_dist;
- uint stack_len_capacity, cur = 0;
- uint i, nearest_len = 0;
+ const KDTreeNode *nodes = tree->nodes;
+ const KDTreeNode *root;
+ uint *stack, stack_default[KD_STACK_INIT];
+ float cur_dist;
+ uint stack_len_capacity, cur = 0;
+ uint i, nearest_len = 0;
#ifdef DEBUG
- BLI_assert(tree->is_balanced == true);
+ BLI_assert(tree->is_balanced == true);
#endif
- if (UNLIKELY((tree->root == KD_NODE_UNSET) || nearest_len_capacity == 0)) {
- return 0;
- }
-
- if (len_sq_fn == NULL) {
- len_sq_fn = len_squared_vnvn_cb;
- BLI_assert(user_data == NULL);
- }
-
- stack = stack_default;
- stack_len_capacity = ARRAY_SIZE(stack_default);
-
- root = &nodes[tree->root];
-
- cur_dist = len_sq_fn(co, root->co, user_data);
- nearest_ordered_insert(r_nearest, &nearest_len, nearest_len_capacity, root->index, cur_dist, root->co);
-
- if (co[root->d] < root->co[root->d]) {
- if (root->right != KD_NODE_UNSET) {
- stack[cur++] = root->right;
- }
- if (root->left != KD_NODE_UNSET) {
- stack[cur++] = root->left;
- }
- }
- else {
- if (root->left != KD_NODE_UNSET) {
- stack[cur++] = root->left;
- }
- if (root->right != KD_NODE_UNSET) {
- stack[cur++] = root->right;
- }
- }
-
- while (cur--) {
- const KDTreeNode *node = &nodes[stack[cur]];
-
- cur_dist = node->co[node->d] - co[node->d];
-
- if (cur_dist < 0.0f) {
- cur_dist = -cur_dist * cur_dist;
-
- if (nearest_len < nearest_len_capacity || -cur_dist < r_nearest[nearest_len - 1].dist) {
- cur_dist = len_sq_fn(co, node->co, user_data);
-
- if (nearest_len < nearest_len_capacity || cur_dist < r_nearest[nearest_len - 1].dist) {
- nearest_ordered_insert(r_nearest, &nearest_len, nearest_len_capacity, node->index, cur_dist, node->co);
- }
-
- if (node->left != KD_NODE_UNSET) {
- stack[cur++] = node->left;
- }
- }
- if (node->right != KD_NODE_UNSET) {
- stack[cur++] = node->right;
- }
- }
- else {
- cur_dist = cur_dist * cur_dist;
-
- if (nearest_len < nearest_len_capacity || cur_dist < r_nearest[nearest_len - 1].dist) {
- cur_dist = len_sq_fn(co, node->co, user_data);
- if (nearest_len < nearest_len_capacity || cur_dist < r_nearest[nearest_len - 1].dist) {
- nearest_ordered_insert(r_nearest, &nearest_len, nearest_len_capacity, node->index, cur_dist, node->co);
- }
-
- if (node->right != KD_NODE_UNSET) {
- stack[cur++] = node->right;
- }
- }
- if (node->left != KD_NODE_UNSET) {
- stack[cur++] = node->left;
- }
- }
- if (UNLIKELY(cur + KD_DIMS > stack_len_capacity)) {
- stack = realloc_nodes(stack, &stack_len_capacity, stack_default != stack);
- }
- }
-
- for (i = 0; i < nearest_len; i++) {
- r_nearest[i].dist = sqrtf(r_nearest[i].dist);
- }
-
- if (stack != stack_default) {
- MEM_freeN(stack);
- }
-
- return (int)nearest_len;
+ if (UNLIKELY((tree->root == KD_NODE_UNSET) || nearest_len_capacity == 0)) {
+ return 0;
+ }
+
+ if (len_sq_fn == NULL) {
+ len_sq_fn = len_squared_vnvn_cb;
+ BLI_assert(user_data == NULL);
+ }
+
+ stack = stack_default;
+ stack_len_capacity = ARRAY_SIZE(stack_default);
+
+ root = &nodes[tree->root];
+
+ cur_dist = len_sq_fn(co, root->co, user_data);
+ nearest_ordered_insert(
+ r_nearest, &nearest_len, nearest_len_capacity, root->index, cur_dist, root->co);
+
+ if (co[root->d] < root->co[root->d]) {
+ if (root->right != KD_NODE_UNSET) {
+ stack[cur++] = root->right;
+ }
+ if (root->left != KD_NODE_UNSET) {
+ stack[cur++] = root->left;
+ }
+ }
+ else {
+ if (root->left != KD_NODE_UNSET) {
+ stack[cur++] = root->left;
+ }
+ if (root->right != KD_NODE_UNSET) {
+ stack[cur++] = root->right;
+ }
+ }
+
+ while (cur--) {
+ const KDTreeNode *node = &nodes[stack[cur]];
+
+ cur_dist = node->co[node->d] - co[node->d];
+
+ if (cur_dist < 0.0f) {
+ cur_dist = -cur_dist * cur_dist;
+
+ if (nearest_len < nearest_len_capacity || -cur_dist < r_nearest[nearest_len - 1].dist) {
+ cur_dist = len_sq_fn(co, node->co, user_data);
+
+ if (nearest_len < nearest_len_capacity || cur_dist < r_nearest[nearest_len - 1].dist) {
+ nearest_ordered_insert(
+ r_nearest, &nearest_len, nearest_len_capacity, node->index, cur_dist, node->co);
+ }
+
+ if (node->left != KD_NODE_UNSET) {
+ stack[cur++] = node->left;
+ }
+ }
+ if (node->right != KD_NODE_UNSET) {
+ stack[cur++] = node->right;
+ }
+ }
+ else {
+ cur_dist = cur_dist * cur_dist;
+
+ if (nearest_len < nearest_len_capacity || cur_dist < r_nearest[nearest_len - 1].dist) {
+ cur_dist = len_sq_fn(co, node->co, user_data);
+ if (nearest_len < nearest_len_capacity || cur_dist < r_nearest[nearest_len - 1].dist) {
+ nearest_ordered_insert(
+ r_nearest, &nearest_len, nearest_len_capacity, node->index, cur_dist, node->co);
+ }
+
+ if (node->right != KD_NODE_UNSET) {
+ stack[cur++] = node->right;
+ }
+ }
+ if (node->left != KD_NODE_UNSET) {
+ stack[cur++] = node->left;
+ }
+ }
+ if (UNLIKELY(cur + KD_DIMS > stack_len_capacity)) {
+ stack = realloc_nodes(stack, &stack_len_capacity, stack_default != stack);
+ }
+ }
+
+ for (i = 0; i < nearest_len; i++) {
+ r_nearest[i].dist = sqrtf(r_nearest[i].dist);
+ }
+
+ if (stack != stack_default) {
+ MEM_freeN(stack);
+ }
+
+ return (int)nearest_len;
}
-int BLI_kdtree_nd_(find_nearest_n)(
- const KDTree *tree, const float co[KD_DIMS],
- KDTreeNearest r_nearest[],
- const uint nearest_len_capacity)
+int BLI_kdtree_nd_(find_nearest_n)(const KDTree *tree,
+ const float co[KD_DIMS],
+ KDTreeNearest r_nearest[],
+ const uint nearest_len_capacity)
{
- return BLI_kdtree_nd_(find_nearest_n_with_len_squared_cb)(
- tree, co, r_nearest, nearest_len_capacity,
- NULL, NULL);
+ return BLI_kdtree_nd_(find_nearest_n_with_len_squared_cb)(
+ tree, co, r_nearest, nearest_len_capacity, NULL, NULL);
}
static int nearest_cmp_dist(const void *a, const void *b)
{
- const KDTreeNearest *kda = a;
- const KDTreeNearest *kdb = b;
-
- if (kda->dist < kdb->dist) {
- return -1;
- }
- else if (kda->dist > kdb->dist) {
- return 1;
- }
- else {
- return 0;
- }
+ const KDTreeNearest *kda = a;
+ const KDTreeNearest *kdb = b;
+
+ if (kda->dist < kdb->dist) {
+ return -1;
+ }
+ else if (kda->dist > kdb->dist) {
+ return 1;
+ }
+ else {
+ return 0;
+ }
}
-static void nearest_add_in_range(
- KDTreeNearest **r_nearest,
- uint nearest_index,
- uint *nearest_len_capacity,
- const int index, const float dist, const float co[KD_DIMS])
+static void nearest_add_in_range(KDTreeNearest **r_nearest,
+ uint nearest_index,
+ uint *nearest_len_capacity,
+ const int index,
+ const float dist,
+ const float co[KD_DIMS])
{
- KDTreeNearest *to;
+ KDTreeNearest *to;
- if (UNLIKELY(nearest_index >= *nearest_len_capacity)) {
- *r_nearest = MEM_reallocN_id(
- *r_nearest,
- (*nearest_len_capacity += KD_FOUND_ALLOC_INC) * sizeof(KDTreeNode),
- __func__);
- }
+ if (UNLIKELY(nearest_index >= *nearest_len_capacity)) {
+ *r_nearest = MEM_reallocN_id(
+ *r_nearest, (*nearest_len_capacity += KD_FOUND_ALLOC_INC) * sizeof(KDTreeNode), __func__);
+ }
- to = (*r_nearest) + nearest_index;
+ to = (*r_nearest) + nearest_index;
- to->index = index;
- to->dist = sqrtf(dist);
- copy_vn_vn(to->co, co);
+ to->index = index;
+ to->dist = sqrtf(dist);
+ copy_vn_vn(to->co, co);
}
/**
@@ -625,89 +639,93 @@ static void nearest_add_in_range(
* \param r_nearest: Allocated array of nearest nearest_len (caller is responsible for freeing).
*/
int BLI_kdtree_nd_(range_search_with_len_squared_cb)(
- const KDTree *tree, const float co[KD_DIMS],
- KDTreeNearest **r_nearest, const float range,
- float (*len_sq_fn)(const float co_search[KD_DIMS], const float co_test[KD_DIMS], const void *user_data),
- const void *user_data)
+ const KDTree *tree,
+ const float co[KD_DIMS],
+ KDTreeNearest **r_nearest,
+ const float range,
+ float (*len_sq_fn)(const float co_search[KD_DIMS],
+ const float co_test[KD_DIMS],
+ const void *user_data),
+ const void *user_data)
{
- const KDTreeNode *nodes = tree->nodes;
- uint *stack, stack_default[KD_STACK_INIT];
- KDTreeNearest *nearest = NULL;
- const float range_sq = range * range;
- float dist_sq;
- uint stack_len_capacity, cur = 0;
- uint nearest_len = 0, nearest_len_capacity = 0;
+ const KDTreeNode *nodes = tree->nodes;
+ uint *stack, stack_default[KD_STACK_INIT];
+ KDTreeNearest *nearest = NULL;
+ const float range_sq = range * range;
+ float dist_sq;
+ uint stack_len_capacity, cur = 0;
+ uint nearest_len = 0, nearest_len_capacity = 0;
#ifdef DEBUG
- BLI_assert(tree->is_balanced == true);
+ BLI_assert(tree->is_balanced == true);
#endif
- if (UNLIKELY(tree->root == KD_NODE_UNSET)) {
- return 0;
- }
-
- if (len_sq_fn == NULL) {
- len_sq_fn = len_squared_vnvn_cb;
- BLI_assert(user_data == NULL);
- }
-
- stack = stack_default;
- stack_len_capacity = ARRAY_SIZE(stack_default);
-
- stack[cur++] = tree->root;
-
- while (cur--) {
- const KDTreeNode *node = &nodes[stack[cur]];
-
- if (co[node->d] + range < node->co[node->d]) {
- if (node->left != KD_NODE_UNSET) {
- stack[cur++] = node->left;
- }
- }
- else if (co[node->d] - range > node->co[node->d]) {
- if (node->right != KD_NODE_UNSET) {
- stack[cur++] = node->right;
- }
- }
- else {
- dist_sq = len_sq_fn(co, node->co, user_data);
- if (dist_sq <= range_sq) {
- nearest_add_in_range(&nearest, nearest_len++, &nearest_len_capacity, node->index, dist_sq, node->co);
- }
-
- if (node->left != KD_NODE_UNSET) {
- stack[cur++] = node->left;
- }
- if (node->right != KD_NODE_UNSET) {
- stack[cur++] = node->right;
- }
- }
-
- if (UNLIKELY(cur + KD_DIMS > stack_len_capacity)) {
- stack = realloc_nodes(stack, &stack_len_capacity, stack_default != stack);
- }
- }
-
- if (stack != stack_default) {
- MEM_freeN(stack);
- }
-
- if (nearest_len) {
- qsort(nearest, nearest_len, sizeof(KDTreeNearest), nearest_cmp_dist);
- }
-
- *r_nearest = nearest;
-
- return (int)nearest_len;
+ if (UNLIKELY(tree->root == KD_NODE_UNSET)) {
+ return 0;
+ }
+
+ if (len_sq_fn == NULL) {
+ len_sq_fn = len_squared_vnvn_cb;
+ BLI_assert(user_data == NULL);
+ }
+
+ stack = stack_default;
+ stack_len_capacity = ARRAY_SIZE(stack_default);
+
+ stack[cur++] = tree->root;
+
+ while (cur--) {
+ const KDTreeNode *node = &nodes[stack[cur]];
+
+ if (co[node->d] + range < node->co[node->d]) {
+ if (node->left != KD_NODE_UNSET) {
+ stack[cur++] = node->left;
+ }
+ }
+ else if (co[node->d] - range > node->co[node->d]) {
+ if (node->right != KD_NODE_UNSET) {
+ stack[cur++] = node->right;
+ }
+ }
+ else {
+ dist_sq = len_sq_fn(co, node->co, user_data);
+ if (dist_sq <= range_sq) {
+ nearest_add_in_range(
+ &nearest, nearest_len++, &nearest_len_capacity, node->index, dist_sq, node->co);
+ }
+
+ if (node->left != KD_NODE_UNSET) {
+ stack[cur++] = node->left;
+ }
+ if (node->right != KD_NODE_UNSET) {
+ stack[cur++] = node->right;
+ }
+ }
+
+ if (UNLIKELY(cur + KD_DIMS > stack_len_capacity)) {
+ stack = realloc_nodes(stack, &stack_len_capacity, stack_default != stack);
+ }
+ }
+
+ if (stack != stack_default) {
+ MEM_freeN(stack);
+ }
+
+ if (nearest_len) {
+ qsort(nearest, nearest_len, sizeof(KDTreeNearest), nearest_cmp_dist);
+ }
+
+ *r_nearest = nearest;
+
+ return (int)nearest_len;
}
-int BLI_kdtree_nd_(range_search)(
- const KDTree *tree, const float co[KD_DIMS],
- KDTreeNearest **r_nearest, const float range)
+int BLI_kdtree_nd_(range_search)(const KDTree *tree,
+ const float co[KD_DIMS],
+ KDTreeNearest **r_nearest,
+ const float range)
{
- return BLI_kdtree_nd_(range_search_with_len_squared_cb)(
- tree, co, r_nearest, range,
- NULL, NULL);
+ return BLI_kdtree_nd_(range_search_with_len_squared_cb)(tree, co, r_nearest, range, NULL, NULL);
}
/**
@@ -719,66 +737,69 @@ int BLI_kdtree_nd_(range_search)(
* \note the order of calls isn't sorted based on distance.
*/
void BLI_kdtree_nd_(range_search_cb)(
- const KDTree *tree, const float co[KD_DIMS], float range,
- bool (*search_cb)(void *user_data, int index, const float co[KD_DIMS], float dist_sq), void *user_data)
+ const KDTree *tree,
+ const float co[KD_DIMS],
+ float range,
+ bool (*search_cb)(void *user_data, int index, const float co[KD_DIMS], float dist_sq),
+ void *user_data)
{
- const KDTreeNode *nodes = tree->nodes;
+ const KDTreeNode *nodes = tree->nodes;
- uint *stack, stack_default[KD_STACK_INIT];
- float range_sq = range * range, dist_sq;
- uint stack_len_capacity, cur = 0;
+ uint *stack, stack_default[KD_STACK_INIT];
+ float range_sq = range * range, dist_sq;
+ uint stack_len_capacity, cur = 0;
#ifdef DEBUG
- BLI_assert(tree->is_balanced == true);
+ BLI_assert(tree->is_balanced == true);
#endif
- if (UNLIKELY(tree->root == KD_NODE_UNSET)) {
- return;
- }
-
- stack = stack_default;
- stack_len_capacity = ARRAY_SIZE(stack_default);
-
- stack[cur++] = tree->root;
-
- while (cur--) {
- const KDTreeNode *node = &nodes[stack[cur]];
-
- if (co[node->d] + range < node->co[node->d]) {
- if (node->left != KD_NODE_UNSET) {
- stack[cur++] = node->left;
- }
- }
- else if (co[node->d] - range > node->co[node->d]) {
- if (node->right != KD_NODE_UNSET) {
- stack[cur++] = node->right;
- }
- }
- else {
- dist_sq = len_squared_vnvn(node->co, co);
- if (dist_sq <= range_sq) {
- if (search_cb(user_data, node->index, node->co, dist_sq) == false) {
- goto finally;
- }
- }
-
- if (node->left != KD_NODE_UNSET) {
- stack[cur++] = node->left;
- }
- if (node->right != KD_NODE_UNSET) {
- stack[cur++] = node->right;
- }
- }
-
- if (UNLIKELY(cur + KD_DIMS > stack_len_capacity)) {
- stack = realloc_nodes(stack, &stack_len_capacity, stack_default != stack);
- }
- }
+ if (UNLIKELY(tree->root == KD_NODE_UNSET)) {
+ return;
+ }
+
+ stack = stack_default;
+ stack_len_capacity = ARRAY_SIZE(stack_default);
+
+ stack[cur++] = tree->root;
+
+ while (cur--) {
+ const KDTreeNode *node = &nodes[stack[cur]];
+
+ if (co[node->d] + range < node->co[node->d]) {
+ if (node->left != KD_NODE_UNSET) {
+ stack[cur++] = node->left;
+ }
+ }
+ else if (co[node->d] - range > node->co[node->d]) {
+ if (node->right != KD_NODE_UNSET) {
+ stack[cur++] = node->right;
+ }
+ }
+ else {
+ dist_sq = len_squared_vnvn(node->co, co);
+ if (dist_sq <= range_sq) {
+ if (search_cb(user_data, node->index, node->co, dist_sq) == false) {
+ goto finally;
+ }
+ }
+
+ if (node->left != KD_NODE_UNSET) {
+ stack[cur++] = node->left;
+ }
+ if (node->right != KD_NODE_UNSET) {
+ stack[cur++] = node->right;
+ }
+ }
+
+ if (UNLIKELY(cur + KD_DIMS > stack_len_capacity)) {
+ stack = realloc_nodes(stack, &stack_len_capacity, stack_default != stack);
+ }
+ }
finally:
- if (stack != stack_default) {
- MEM_freeN(stack);
- }
+ if (stack != stack_default) {
+ MEM_freeN(stack);
+ }
}
/**
@@ -787,12 +808,12 @@ finally:
*/
static uint *kdtree_order(const KDTree *tree)
{
- const KDTreeNode *nodes = tree->nodes;
- uint *order = MEM_mallocN(sizeof(uint) * tree->nodes_len, __func__);
- for (uint i = 0; i < tree->nodes_len; i++) {
- order[nodes[i].index] = i;
- }
- return order;
+ const KDTreeNode *nodes = tree->nodes;
+ uint *order = MEM_mallocN(sizeof(uint) * tree->nodes_len, __func__);
+ for (uint i = 0; i < tree->nodes_len; i++) {
+ order[nodes[i].index] = i;
+ }
+ return order;
}
/* -------------------------------------------------------------------- */
@@ -800,45 +821,45 @@ static uint *kdtree_order(const KDTree *tree)
* \{ */
struct DeDuplicateParams {
- /* Static */
- const KDTreeNode *nodes;
- float range;
- float range_sq;
- int *duplicates;
- int *duplicates_found;
-
- /* Per Search */
- float search_co[KD_DIMS];
- int search;
+ /* Static */
+ const KDTreeNode *nodes;
+ float range;
+ float range_sq;
+ int *duplicates;
+ int *duplicates_found;
+
+ /* Per Search */
+ float search_co[KD_DIMS];
+ int search;
};
static void deduplicate_recursive(const struct DeDuplicateParams *p, uint i)
{
- const KDTreeNode *node = &p->nodes[i];
- if (p->search_co[node->d] + p->range <= node->co[node->d]) {
- if (node->left != KD_NODE_UNSET) {
- deduplicate_recursive(p, node->left);
- }
- }
- else if (p->search_co[node->d] - p->range >= node->co[node->d]) {
- if (node->right != KD_NODE_UNSET) {
- deduplicate_recursive(p, node->right);
- }
- }
- else {
- if ((p->search != node->index) && (p->duplicates[node->index] == -1)) {
- if (len_squared_vnvn(node->co, p->search_co) <= p->range_sq) {
- p->duplicates[node->index] = (int)p->search;
- *p->duplicates_found += 1;
- }
- }
- if (node->left != KD_NODE_UNSET) {
- deduplicate_recursive(p, node->left);
- }
- if (node->right != KD_NODE_UNSET) {
- deduplicate_recursive(p, node->right);
- }
- }
+ const KDTreeNode *node = &p->nodes[i];
+ if (p->search_co[node->d] + p->range <= node->co[node->d]) {
+ if (node->left != KD_NODE_UNSET) {
+ deduplicate_recursive(p, node->left);
+ }
+ }
+ else if (p->search_co[node->d] - p->range >= node->co[node->d]) {
+ if (node->right != KD_NODE_UNSET) {
+ deduplicate_recursive(p, node->right);
+ }
+ }
+ else {
+ if ((p->search != node->index) && (p->duplicates[node->index] == -1)) {
+ if (len_squared_vnvn(node->co, p->search_co) <= p->range_sq) {
+ p->duplicates[node->index] = (int)p->search;
+ *p->duplicates_found += 1;
+ }
+ }
+ if (node->left != KD_NODE_UNSET) {
+ deduplicate_recursive(p, node->left);
+ }
+ if (node->right != KD_NODE_UNSET) {
+ deduplicate_recursive(p, node->right);
+ }
+ }
}
/**
@@ -859,54 +880,55 @@ static void deduplicate_recursive(const struct DeDuplicateParams *p, uint i)
*
* \note Merging is always a single step (target indices wont be marked for merging).
*/
-int BLI_kdtree_nd_(calc_duplicates_fast)(
- const KDTree *tree, const float range, bool use_index_order,
- int *duplicates)
+int BLI_kdtree_nd_(calc_duplicates_fast)(const KDTree *tree,
+ const float range,
+ bool use_index_order,
+ int *duplicates)
{
- int found = 0;
- struct DeDuplicateParams p = {
- .nodes = tree->nodes,
- .range = range,
- .range_sq = SQUARE(range),
- .duplicates = duplicates,
- .duplicates_found = &found,
- };
-
- if (use_index_order) {
- uint *order = kdtree_order(tree);
- for (uint i = 0; i < tree->nodes_len; i++) {
- const uint node_index = order[i];
- const int index = (int)i;
- if (ELEM(duplicates[index], -1, index)) {
- p.search = index;
- copy_vn_vn(p.search_co, tree->nodes[node_index].co);
- int found_prev = found;
- deduplicate_recursive(&p, tree->root);
- if (found != found_prev) {
- /* Prevent chains of doubles. */
- duplicates[index] = index;
- }
- }
- }
- MEM_freeN(order);
- }
- else {
- for (uint i = 0; i < tree->nodes_len; i++) {
- const uint node_index = i;
- const int index = p.nodes[node_index].index;
- if (ELEM(duplicates[index], -1, index)) {
- p.search = index;
- copy_vn_vn(p.search_co, tree->nodes[node_index].co);
- int found_prev = found;
- deduplicate_recursive(&p, tree->root);
- if (found != found_prev) {
- /* Prevent chains of doubles. */
- duplicates[index] = index;
- }
- }
- }
- }
- return found;
+ int found = 0;
+ struct DeDuplicateParams p = {
+ .nodes = tree->nodes,
+ .range = range,
+ .range_sq = SQUARE(range),
+ .duplicates = duplicates,
+ .duplicates_found = &found,
+ };
+
+ if (use_index_order) {
+ uint *order = kdtree_order(tree);
+ for (uint i = 0; i < tree->nodes_len; i++) {
+ const uint node_index = order[i];
+ const int index = (int)i;
+ if (ELEM(duplicates[index], -1, index)) {
+ p.search = index;
+ copy_vn_vn(p.search_co, tree->nodes[node_index].co);
+ int found_prev = found;
+ deduplicate_recursive(&p, tree->root);
+ if (found != found_prev) {
+ /* Prevent chains of doubles. */
+ duplicates[index] = index;
+ }
+ }
+ }
+ MEM_freeN(order);
+ }
+ else {
+ for (uint i = 0; i < tree->nodes_len; i++) {
+ const uint node_index = i;
+ const int index = p.nodes[node_index].index;
+ if (ELEM(duplicates[index], -1, index)) {
+ p.search = index;
+ copy_vn_vn(p.search_co, tree->nodes[node_index].co);
+ int found_prev = found;
+ deduplicate_recursive(&p, tree->root);
+ if (found != found_prev) {
+ /* Prevent chains of doubles. */
+ duplicates[index] = index;
+ }
+ }
+ }
+ }
+ return found;
}
/** \} */
@@ -917,27 +939,27 @@ int BLI_kdtree_nd_(calc_duplicates_fast)(
static int kdtree_node_cmp_deduplicate(const void *n0_p, const void *n1_p)
{
- const KDTreeNode *n0 = n0_p;
- const KDTreeNode *n1 = n1_p;
- for (uint j = 0; j < KD_DIMS; j++) {
- if (n0->co[j] < n1->co[j]) {
- return -1;
- }
- else if (n0->co[j] > n1->co[j]) {
- return 1;
- }
- }
- /* Sort by pointer so the first added will be used.
- * assignment below ignores const correctness,
- * however the values aren't used for sorting and are to be discarded. */
- if (n0 < n1) {
- ((KDTreeNode *)n1)->d = KD_DIMS; /* tag invalid */
- return -1;
- }
- else {
- ((KDTreeNode *)n0)->d = KD_DIMS; /* tag invalid */
- return 1;
- }
+ const KDTreeNode *n0 = n0_p;
+ const KDTreeNode *n1 = n1_p;
+ for (uint j = 0; j < KD_DIMS; j++) {
+ if (n0->co[j] < n1->co[j]) {
+ return -1;
+ }
+ else if (n0->co[j] > n1->co[j]) {
+ return 1;
+ }
+ }
+ /* Sort by pointer so the first added will be used.
+ * assignment below ignores const correctness,
+ * however the values aren't used for sorting and are to be discarded. */
+ if (n0 < n1) {
+ ((KDTreeNode *)n1)->d = KD_DIMS; /* tag invalid */
+ return -1;
+ }
+ else {
+ ((KDTreeNode *)n0)->d = KD_DIMS; /* tag invalid */
+ return 1;
+ }
}
/**
@@ -948,20 +970,20 @@ static int kdtree_node_cmp_deduplicate(const void *n0_p, const void *n1_p)
int BLI_kdtree_nd_(deduplicate)(KDTree *tree)
{
#ifdef DEBUG
- tree->is_balanced = false;
+ tree->is_balanced = false;
#endif
- qsort(tree->nodes, (size_t)tree->nodes_len, sizeof(*tree->nodes), kdtree_node_cmp_deduplicate);
- uint j = 0;
- for (uint i = 0; i < tree->nodes_len; i++) {
- if (tree->nodes[i].d != KD_DIMS) {
- if (i != j) {
- tree->nodes[j] = tree->nodes[i];
- }
- j++;
- }
- }
- tree->nodes_len = j;
- return (int)tree->nodes_len;
+ qsort(tree->nodes, (size_t)tree->nodes_len, sizeof(*tree->nodes), kdtree_node_cmp_deduplicate);
+ uint j = 0;
+ for (uint i = 0; i < tree->nodes_len; i++) {
+ if (tree->nodes[i].d != KD_DIMS) {
+ if (i != j) {
+ tree->nodes[j] = tree->nodes[i];
+ }
+ j++;
+ }
+ }
+ tree->nodes_len = j;
+ return (int)tree->nodes_len;
}
/** \} */
diff --git a/source/blender/blenlib/intern/lasso_2d.c b/source/blender/blenlib/intern/lasso_2d.c
index a8eb9f09041..f1e9b1e655f 100644
--- a/source/blender/blenlib/intern/lasso_2d.c
+++ b/source/blender/blenlib/intern/lasso_2d.c
@@ -30,63 +30,76 @@
void BLI_lasso_boundbox(rcti *rect, const int mcords[][2], const unsigned int moves)
{
- unsigned int a;
-
- rect->xmin = rect->xmax = mcords[0][0];
- rect->ymin = rect->ymax = mcords[0][1];
-
- for (a = 1; a < moves; a++) {
- if (mcords[a][0] < rect->xmin) { rect->xmin = mcords[a][0]; }
- else if (mcords[a][0] > rect->xmax) { rect->xmax = mcords[a][0]; }
- if (mcords[a][1] < rect->ymin) { rect->ymin = mcords[a][1]; }
- else if (mcords[a][1] > rect->ymax) { rect->ymax = mcords[a][1]; }
- }
+ unsigned int a;
+
+ rect->xmin = rect->xmax = mcords[0][0];
+ rect->ymin = rect->ymax = mcords[0][1];
+
+ for (a = 1; a < moves; a++) {
+ if (mcords[a][0] < rect->xmin) {
+ rect->xmin = mcords[a][0];
+ }
+ else if (mcords[a][0] > rect->xmax) {
+ rect->xmax = mcords[a][0];
+ }
+ if (mcords[a][1] < rect->ymin) {
+ rect->ymin = mcords[a][1];
+ }
+ else if (mcords[a][1] > rect->ymax) {
+ rect->ymax = mcords[a][1];
+ }
+ }
}
-
-bool BLI_lasso_is_point_inside(const int mcords[][2], const unsigned int moves,
- const int sx, const int sy,
+bool BLI_lasso_is_point_inside(const int mcords[][2],
+ const unsigned int moves,
+ const int sx,
+ const int sy,
const int error_value)
{
- if (sx == error_value || moves == 0) {
- return false;
- }
- else {
- int pt[2] = {sx, sy};
- return isect_point_poly_v2_int(pt, mcords, moves, true);
- }
+ if (sx == error_value || moves == 0) {
+ return false;
+ }
+ else {
+ int pt[2] = {sx, sy};
+ return isect_point_poly_v2_int(pt, mcords, moves, true);
+ }
}
/* edge version for lasso select. we assume boundbox check was done */
-bool BLI_lasso_is_edge_inside(const int mcords[][2], const unsigned int moves,
- int x0, int y0, int x1, int y1,
+bool BLI_lasso_is_edge_inside(const int mcords[][2],
+ const unsigned int moves,
+ int x0,
+ int y0,
+ int x1,
+ int y1,
const int error_value)
{
- if (x0 == error_value || x1 == error_value || moves == 0) {
- return false;
- }
+ if (x0 == error_value || x1 == error_value || moves == 0) {
+ return false;
+ }
- const int v1[2] = {x0, y0}, v2[2] = {x1, y1};
+ const int v1[2] = {x0, y0}, v2[2] = {x1, y1};
- /* check points in lasso */
- if (BLI_lasso_is_point_inside(mcords, moves, v1[0], v1[1], error_value)) {
- return true;
- }
- if (BLI_lasso_is_point_inside(mcords, moves, v2[0], v2[1], error_value)) {
- return true;
- }
+ /* check points in lasso */
+ if (BLI_lasso_is_point_inside(mcords, moves, v1[0], v1[1], error_value)) {
+ return true;
+ }
+ if (BLI_lasso_is_point_inside(mcords, moves, v2[0], v2[1], error_value)) {
+ return true;
+ }
- /* no points in lasso, so we have to intersect with lasso edge */
+ /* no points in lasso, so we have to intersect with lasso edge */
- if (isect_seg_seg_v2_int(mcords[0], mcords[moves - 1], v1, v2) > 0) {
- return true;
- }
- for (unsigned int a = 0; a < moves - 1; a++) {
- if (isect_seg_seg_v2_int(mcords[a], mcords[a + 1], v1, v2) > 0) {
- return true;
- }
- }
+ if (isect_seg_seg_v2_int(mcords[0], mcords[moves - 1], v1, v2) > 0) {
+ return true;
+ }
+ for (unsigned int a = 0; a < moves - 1; a++) {
+ if (isect_seg_seg_v2_int(mcords[a], mcords[a + 1], v1, v2) > 0) {
+ return true;
+ }
+ }
- return false;
+ return false;
}
diff --git a/source/blender/blenlib/intern/list_sort_impl.h b/source/blender/blenlib/intern/list_sort_impl.h
index 3da4c5ccd41..fac1ca8e983 100644
--- a/source/blender/blenlib/intern/list_sort_impl.h
+++ b/source/blender/blenlib/intern/list_sort_impl.h
@@ -68,25 +68,24 @@
# define THUNK_PREPEND2(thunk, a, b) a, b
#endif
-#define _CONCAT_AUX(MACRO_ARG1, MACRO_ARG2) MACRO_ARG1 ## MACRO_ARG2
+#define _CONCAT_AUX(MACRO_ARG1, MACRO_ARG2) MACRO_ARG1##MACRO_ARG2
#define _CONCAT(MACRO_ARG1, MACRO_ARG2) _CONCAT_AUX(MACRO_ARG1, MACRO_ARG2)
#define _SORT_PREFIX(id) _CONCAT(SORT_IMPL_FUNC, _##id)
/* local identifiers */
-#define SortInfo _SORT_PREFIX(SortInfo)
-#define CompareFn _SORT_PREFIX(CompareFn)
-#define init_sort_info _SORT_PREFIX(init_sort_info)
-#define merge_lists _SORT_PREFIX(merge_lists)
-#define sweep_up _SORT_PREFIX(sweep_up)
-#define insert_list _SORT_PREFIX(insert_list)
-
-typedef int (* CompareFn)(
+#define SortInfo _SORT_PREFIX(SortInfo)
+#define CompareFn _SORT_PREFIX(CompareFn)
+#define init_sort_info _SORT_PREFIX(init_sort_info)
+#define merge_lists _SORT_PREFIX(merge_lists)
+#define sweep_up _SORT_PREFIX(sweep_up)
+#define insert_list _SORT_PREFIX(insert_list)
+
+typedef int (*CompareFn)(
#ifdef SORT_IMPL_USE_THUNK
- void *thunk,
+ void *thunk,
#endif
- const void *,
- const void *);
-
+ const void *,
+ const void *);
/* -------------------------------------------------------------------- */
/* MIT license from original source */
@@ -125,69 +124,67 @@ typedef int (* CompareFn)(
* we can reduce the depth by 1.
*/
#define FLOOR_LOG2(x) \
- (((x) >= 2) + ((x) >= 4) + ((x) >= 8) + ((x) >= 16) + ((x) >= 32) + ((x) >= 64) + ((x) >= 128))
-#define MAX_RANKS \
- ((sizeof(size_t) * 8) - FLOOR_LOG2(sizeof(list_node)) - 1)
+ (((x) >= 2) + ((x) >= 4) + ((x) >= 8) + ((x) >= 16) + ((x) >= 32) + ((x) >= 64) + ((x) >= 128))
+#define MAX_RANKS ((sizeof(size_t) * 8) - FLOOR_LOG2(sizeof(list_node)) - 1)
struct SortInfo {
- unsigned int min_rank, n_ranks;
- CompareFn func;
+ unsigned int min_rank, n_ranks;
+ CompareFn func;
#ifdef SORT_IMPL_USE_THUNK
- void *thunk;
+ void *thunk;
#endif
- /**
- * Invariant: `ranks[i] == NULL || length(ranks[i]) >= 2**(i+1)`.
- *
- * ~ 128 bytes on 32bit, ~ 512 bytes on 64bit */
- list_node *ranks[MAX_RANKS];
+ /**
+ * Invariant: `ranks[i] == NULL || length(ranks[i]) >= 2**(i+1)`.
+ *
+ * ~ 128 bytes on 32bit, ~ 512 bytes on 64bit */
+ list_node *ranks[MAX_RANKS];
};
-BLI_INLINE void init_sort_info(
- struct SortInfo *si,
- CompareFn func
+BLI_INLINE void init_sort_info(struct SortInfo *si,
+ CompareFn func
#ifdef SORT_IMPL_USE_THUNK
- ,
- void *thunk
+ ,
+ void *thunk
#endif
- )
+)
{
- si->min_rank = si->n_ranks = 0;
- si->func = func;
- /* we don't need to initialize si->ranks,
- * since we never lookup past si->n_ranks. */
+ si->min_rank = si->n_ranks = 0;
+ si->func = func;
+ /* we don't need to initialize si->ranks,
+ * since we never lookup past si->n_ranks. */
#ifdef SORT_IMPL_USE_THUNK
- si->thunk = thunk;
+ si->thunk = thunk;
#endif
}
-BLI_INLINE list_node *merge_lists(
- list_node *first, list_node *second,
- CompareFn func
+BLI_INLINE list_node *merge_lists(list_node *first,
+ list_node *second,
+ CompareFn func
#ifdef SORT_IMPL_USE_THUNK
- ,
- void *thunk
+ ,
+ void *thunk
#endif
- )
+)
{
- /* merge the two lists */
- list_node *list = NULL;
- list_node **pos = &list;
- while (first && second) {
- if (func(THUNK_PREPEND2(thunk, SORT_ARG(first), SORT_ARG(second))) > 0) {
- *pos = second;
- second = second->next;
- }
- else {
- *pos = first;
- first = first->next;
- }
- pos = &((*pos)->next);
- }
- *pos = first ? first : second;
- return list;
+ /* merge the two lists */
+ list_node *list = NULL;
+ list_node **pos = &list;
+ while (first && second) {
+ if (func(THUNK_PREPEND2(thunk, SORT_ARG(first), SORT_ARG(second))) > 0) {
+ *pos = second;
+ second = second->next;
+ }
+ else {
+ *pos = first;
+ first = first->next;
+ }
+ pos = &((*pos)->next);
+ }
+ *pos = first ? first : second;
+ return list;
}
/**
@@ -196,12 +193,12 @@ BLI_INLINE list_node *merge_lists(
*/
BLI_INLINE list_node *sweep_up(struct SortInfo *si, list_node *list, unsigned int upto)
{
- unsigned int i;
- for (i = si->min_rank; i < upto; i++) {
- list = merge_lists(si->ranks[i], list, THUNK_APPEND1(si->func, si->thunk));
- si->ranks[i] = NULL;
- }
- return list;
+ unsigned int i;
+ for (i = si->min_rank; i < upto; i++) {
+ list = merge_lists(si->ranks[i], list, THUNK_APPEND1(si->func, si->thunk));
+ si->ranks[i] = NULL;
+ }
+ return list;
}
/**
@@ -233,44 +230,41 @@ BLI_INLINE list_node *sweep_up(struct SortInfo *si, list_node *list, unsigned in
* `2**(rank+1) <= length(list) < 2**(rank+2)`
* (therefore: `length(list) >= 2`)
*/
-BLI_INLINE void insert_list(
- struct SortInfo *si,
- list_node *list,
- unsigned int rank)
+BLI_INLINE void insert_list(struct SortInfo *si, list_node *list, unsigned int rank)
{
- unsigned int i;
-
- if (rank > si->n_ranks) {
- if (UNLIKELY(rank > MAX_RANKS)) {
- // printf("Rank '%d' should not exceed " STRINGIFY(MAX_RANKS), rank);
- rank = MAX_RANKS;
- }
- list = merge_lists(sweep_up(si, NULL, si->n_ranks), list, THUNK_APPEND1(si->func, si->thunk));
- for (i = si->n_ranks; i < rank; ++i) {
- si->ranks[i] = NULL;
- }
- }
- else {
- if (rank) {
- list = merge_lists(sweep_up(si, NULL, rank), list, THUNK_APPEND1(si->func, si->thunk));
- }
- for (i = rank; i < si->n_ranks && si->ranks[i]; ++i) {
- list = merge_lists(si->ranks[i], list, THUNK_APPEND1(si->func, si->thunk));
- si->ranks[i] = NULL;
- }
- }
-
- /* Will _never_ happen: so we can just devolve into quadratic ;-) */
- if (UNLIKELY(i == MAX_RANKS)) {
- i--;
- }
-
- if (i >= si->n_ranks) {
- si->n_ranks = i + 1;
- }
-
- si->min_rank = i;
- si->ranks[i] = list;
+ unsigned int i;
+
+ if (rank > si->n_ranks) {
+ if (UNLIKELY(rank > MAX_RANKS)) {
+ // printf("Rank '%d' should not exceed " STRINGIFY(MAX_RANKS), rank);
+ rank = MAX_RANKS;
+ }
+ list = merge_lists(sweep_up(si, NULL, si->n_ranks), list, THUNK_APPEND1(si->func, si->thunk));
+ for (i = si->n_ranks; i < rank; ++i) {
+ si->ranks[i] = NULL;
+ }
+ }
+ else {
+ if (rank) {
+ list = merge_lists(sweep_up(si, NULL, rank), list, THUNK_APPEND1(si->func, si->thunk));
+ }
+ for (i = rank; i < si->n_ranks && si->ranks[i]; ++i) {
+ list = merge_lists(si->ranks[i], list, THUNK_APPEND1(si->func, si->thunk));
+ si->ranks[i] = NULL;
+ }
+ }
+
+ /* Will _never_ happen: so we can just devolve into quadratic ;-) */
+ if (UNLIKELY(i == MAX_RANKS)) {
+ i--;
+ }
+
+ if (i >= si->n_ranks) {
+ si->n_ranks = i + 1;
+ }
+
+ si->min_rank = i;
+ si->ranks[i] = list;
}
#undef MAX_RANKS
@@ -279,43 +273,41 @@ BLI_INLINE void insert_list(
/**
* Main sort function.
*/
-BLI_INLINE list_node *list_sort_do(
- list_node *list,
- CompareFn func
+BLI_INLINE list_node *list_sort_do(list_node *list,
+ CompareFn func
#ifdef SORT_IMPL_USE_THUNK
- ,
- void *thunk
+ ,
+ void *thunk
#endif
- )
+)
{
- struct SortInfo si;
+ struct SortInfo si;
- init_sort_info(
- &si,
- func
+ init_sort_info(&si,
+ func
#ifdef SORT_IMPL_USE_THUNK
- ,
- thunk
+ ,
+ thunk
#endif
- );
+ );
- while (list && list->next) {
- list_node *next = list->next;
- list_node *tail = next->next;
+ while (list && list->next) {
+ list_node *next = list->next;
+ list_node *tail = next->next;
- if (func(THUNK_PREPEND2(thunk, SORT_ARG(list), SORT_ARG(next))) > 0) {
- next->next = list;
- next = list;
- list = list->next;
- }
- next->next = NULL;
+ if (func(THUNK_PREPEND2(thunk, SORT_ARG(list), SORT_ARG(next))) > 0) {
+ next->next = list;
+ next = list;
+ list = list->next;
+ }
+ next->next = NULL;
- insert_list(&si, list, 0);
+ insert_list(&si, list, 0);
- list = tail;
- }
+ list = tail;
+ }
- return sweep_up(&si, list, si.n_ranks);
+ return sweep_up(&si, list, si.n_ranks);
}
#undef _CONCAT_AUX
diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c
index e34f9d0ab10..ff9e21319da 100644
--- a/source/blender/blenlib/intern/listbase.c
+++ b/source/blender/blenlib/intern/listbase.c
@@ -28,7 +28,6 @@
#include <string.h>
#include <stdlib.h>
-
#include "MEM_guardedalloc.h"
#include "DNA_listBase.h"
@@ -44,20 +43,20 @@
*/
void BLI_movelisttolist(ListBase *dst, ListBase *src)
{
- if (src->first == NULL) {
- return;
- }
+ if (src->first == NULL) {
+ return;
+ }
- if (dst->first == NULL) {
- dst->first = src->first;
- dst->last = src->last;
- }
- else {
- ((Link *)dst->last)->next = src->first;
- ((Link *)src->first)->prev = dst->last;
- dst->last = src->last;
- }
- src->first = src->last = NULL;
+ if (dst->first == NULL) {
+ dst->first = src->first;
+ dst->last = src->last;
+ }
+ else {
+ ((Link *)dst->last)->next = src->first;
+ ((Link *)src->first)->prev = dst->last;
+ dst->last = src->last;
+ }
+ src->first = src->last = NULL;
}
/**
@@ -65,21 +64,21 @@ void BLI_movelisttolist(ListBase *dst, ListBase *src)
*/
void BLI_movelisttolist_reverse(ListBase *dst, ListBase *src)
{
- if (src->first == NULL) {
- return;
- }
+ if (src->first == NULL) {
+ return;
+ }
- if (dst->first == NULL) {
- dst->first = src->first;
- dst->last = src->last;
- }
- else {
- ((Link *)src->last)->next = dst->first;
- ((Link *)dst->first)->prev = src->last;
- dst->first = src->first;
- }
+ if (dst->first == NULL) {
+ dst->first = src->first;
+ dst->last = src->last;
+ }
+ else {
+ ((Link *)src->last)->next = dst->first;
+ ((Link *)dst->first)->prev = src->last;
+ dst->first = src->first;
+ }
- src->first = src->last = NULL;
+ src->first = src->last = NULL;
}
/**
@@ -87,73 +86,71 @@ void BLI_movelisttolist_reverse(ListBase *dst, ListBase *src)
*/
void BLI_addhead(ListBase *listbase, void *vlink)
{
- Link *link = vlink;
+ Link *link = vlink;
- if (link == NULL) {
- return;
- }
+ if (link == NULL) {
+ return;
+ }
- link->next = listbase->first;
- link->prev = NULL;
+ link->next = listbase->first;
+ link->prev = NULL;
- if (listbase->first) {
- ((Link *)listbase->first)->prev = link;
- }
- if (listbase->last == NULL) {
- listbase->last = link;
- }
- listbase->first = link;
+ if (listbase->first) {
+ ((Link *)listbase->first)->prev = link;
+ }
+ if (listbase->last == NULL) {
+ listbase->last = link;
+ }
+ listbase->first = link;
}
-
/**
* Appends \a vlink (assumed to begin with a Link) onto listbase.
*/
void BLI_addtail(ListBase *listbase, void *vlink)
{
- Link *link = vlink;
+ Link *link = vlink;
- if (link == NULL) {
- return;
- }
+ if (link == NULL) {
+ return;
+ }
- link->next = NULL;
- link->prev = listbase->last;
+ link->next = NULL;
+ link->prev = listbase->last;
- if (listbase->last) {
- ((Link *)listbase->last)->next = link;
- }
- if (listbase->first == NULL) {
- listbase->first = link;
- }
- listbase->last = link;
+ if (listbase->last) {
+ ((Link *)listbase->last)->next = link;
+ }
+ if (listbase->first == NULL) {
+ listbase->first = link;
+ }
+ listbase->last = link;
}
-
/**
* Removes \a vlink from \a listbase. Assumes it is linked into there!
*/
void BLI_remlink(ListBase *listbase, void *vlink)
{
- Link *link = vlink;
+ Link *link = vlink;
- if (link == NULL) {
- return;
- }
+ if (link == NULL) {
+ return;
+ }
- if (link->next) {
- link->next->prev = link->prev;
- }
- if (link->prev) {
- link->prev->next = link->next;
- }
+ if (link->next) {
+ link->next->prev = link->prev;
+ }
+ if (link->prev) {
+ link->prev->next = link->next;
+ }
- if (listbase->last == link) {
- listbase->last = link->prev;
- }
- if (listbase->first == link) {
- listbase->first = link->next;
- }
+ if (listbase->last == link) {
+ listbase->last = link->prev;
+ }
+ if (listbase->first == link) {
+ listbase->first = link->next;
+ }
}
/**
@@ -161,13 +158,13 @@ void BLI_remlink(ListBase *listbase, void *vlink)
*/
bool BLI_remlink_safe(ListBase *listbase, void *vlink)
{
- if (BLI_findindex(listbase, vlink) != -1) {
- BLI_remlink(listbase, vlink);
- return true;
- }
- else {
- return false;
- }
+ if (BLI_findindex(listbase, vlink) != -1) {
+ BLI_remlink(listbase, vlink);
+ return true;
+ }
+ else {
+ return false;
+ }
}
/**
@@ -175,55 +172,55 @@ bool BLI_remlink_safe(ListBase *listbase, void *vlink)
*/
void BLI_listbase_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;
- }
+ 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;
+ }
}
/**
@@ -231,27 +228,27 @@ void BLI_listbase_swaplinks(ListBase *listbase, void *vlinka, void *vlinkb)
*/
void BLI_listbases_swaplinks(ListBase *listbasea, ListBase *listbaseb, void *vlinka, void *vlinkb)
{
- Link *linka = vlinka;
- Link *linkb = vlinkb;
- Link linkc = {NULL};
+ Link *linka = vlinka;
+ Link *linkb = vlinkb;
+ Link linkc = {NULL};
- if (!linka || !linkb) {
- return;
- }
+ if (!linka || !linkb) {
+ return;
+ }
- /* Temporary link to use as placeholder of the links positions */
- BLI_insertlinkafter(listbasea, linka, &linkc);
+ /* Temporary link to use as placeholder of the links positions */
+ BLI_insertlinkafter(listbasea, linka, &linkc);
- /* Bring linka into linkb position */
- BLI_remlink(listbasea, linka);
- BLI_insertlinkafter(listbaseb, linkb, linka);
+ /* Bring linka into linkb position */
+ BLI_remlink(listbasea, linka);
+ BLI_insertlinkafter(listbaseb, linkb, linka);
- /* Bring linkb into linka position */
- BLI_remlink(listbaseb, linkb);
- BLI_insertlinkafter(listbasea, &linkc, linkb);
+ /* Bring linkb into linka position */
+ BLI_remlink(listbaseb, linkb);
+ BLI_insertlinkafter(listbasea, &linkc, linkb);
- /* Remove temporary link */
- BLI_remlink(listbasea, &linkc);
+ /* Remove temporary link */
+ BLI_remlink(listbasea, &linkc);
}
/**
@@ -259,24 +256,23 @@ void BLI_listbases_swaplinks(ListBase *listbasea, ListBase *listbaseb, void *vli
*/
void *BLI_pophead(ListBase *listbase)
{
- Link *link;
- if ((link = listbase->first)) {
- BLI_remlink(listbase, link);
- }
- return link;
+ Link *link;
+ if ((link = listbase->first)) {
+ BLI_remlink(listbase, link);
+ }
+ return link;
}
-
/**
* Removes the tail from \a listbase and returns it.
*/
void *BLI_poptail(ListBase *listbase)
{
- Link *link;
- if ((link = listbase->last)) {
- BLI_remlink(listbase, link);
- }
- return link;
+ Link *link;
+ if ((link = listbase->last)) {
+ BLI_remlink(listbase, link);
+ }
+ return link;
}
/**
@@ -284,14 +280,14 @@ void *BLI_poptail(ListBase *listbase)
*/
void BLI_freelinkN(ListBase *listbase, void *vlink)
{
- Link *link = vlink;
+ Link *link = vlink;
- if (link == NULL) {
- return;
- }
+ if (link == NULL) {
+ return;
+ }
- BLI_remlink(listbase, link);
- MEM_freeN(link);
+ BLI_remlink(listbase, link);
+ MEM_freeN(link);
}
/**
@@ -299,13 +295,13 @@ void BLI_freelinkN(ListBase *listbase, void *vlink)
*/
static void listbase_double_from_single(Link *iter, ListBase *listbase)
{
- Link *prev = NULL;
- listbase->first = iter;
- do {
- iter->prev = prev;
- prev = iter;
- } while ((iter = iter->next));
- listbase->last = prev;
+ Link *prev = NULL;
+ listbase->first = iter;
+ do {
+ iter->prev = prev;
+ prev = iter;
+ } while ((iter = iter->next));
+ listbase->last = prev;
}
#define SORT_IMPL_LINKTYPE Link
@@ -331,20 +327,22 @@ static void listbase_double_from_single(Link *iter, ListBase *listbase)
*/
void BLI_listbase_sort(ListBase *listbase, int (*cmp)(const void *, const void *))
{
- if (listbase->first != listbase->last) {
- Link *head = listbase->first;
- head = listbase_sort_fn(head, cmp);
- listbase_double_from_single(head, listbase);
- }
+ if (listbase->first != listbase->last) {
+ Link *head = listbase->first;
+ head = listbase_sort_fn(head, cmp);
+ listbase_double_from_single(head, listbase);
+ }
}
-void BLI_listbase_sort_r(ListBase *listbase, int (*cmp)(void *, const void *, const void *), void *thunk)
+void BLI_listbase_sort_r(ListBase *listbase,
+ int (*cmp)(void *, const void *, const void *),
+ void *thunk)
{
- if (listbase->first != listbase->last) {
- Link *head = listbase->first;
- head = listbase_sort_fn_r(head, cmp, thunk);
- listbase_double_from_single(head, listbase);
- }
+ if (listbase->first != listbase->last) {
+ Link *head = listbase->first;
+ head = listbase_sort_fn_r(head, cmp, thunk);
+ listbase_double_from_single(head, listbase);
+ }
}
/**
@@ -353,41 +351,41 @@ void BLI_listbase_sort_r(ListBase *listbase, int (*cmp)(void *, const void *, co
*/
void BLI_insertlinkafter(ListBase *listbase, void *vprevlink, void *vnewlink)
{
- Link *prevlink = vprevlink;
- Link *newlink = vnewlink;
+ Link *prevlink = vprevlink;
+ Link *newlink = vnewlink;
- /* newlink before nextlink */
- if (newlink == NULL) {
- return;
- }
+ /* newlink before nextlink */
+ if (newlink == NULL) {
+ return;
+ }
- /* empty list */
- if (listbase->first == NULL) {
- listbase->first = newlink;
- listbase->last = newlink;
- return;
- }
+ /* empty list */
+ if (listbase->first == NULL) {
+ listbase->first = newlink;
+ listbase->last = newlink;
+ return;
+ }
- /* insert at head of list */
- if (prevlink == NULL) {
- newlink->prev = NULL;
- newlink->next = listbase->first;
- newlink->next->prev = newlink;
- listbase->first = newlink;
- return;
- }
+ /* insert at head of list */
+ if (prevlink == NULL) {
+ newlink->prev = NULL;
+ newlink->next = listbase->first;
+ newlink->next->prev = newlink;
+ listbase->first = newlink;
+ return;
+ }
- /* at end of list */
- if (listbase->last == prevlink) {
- listbase->last = newlink;
- }
+ /* at end of list */
+ if (listbase->last == prevlink) {
+ listbase->last = newlink;
+ }
- newlink->next = prevlink->next;
- newlink->prev = prevlink;
- prevlink->next = newlink;
- if (newlink->next) {
- newlink->next->prev = newlink;
- }
+ newlink->next = prevlink->next;
+ newlink->prev = prevlink;
+ prevlink->next = newlink;
+ if (newlink->next) {
+ newlink->next->prev = newlink;
+ }
}
/**
@@ -396,44 +394,43 @@ void BLI_insertlinkafter(ListBase *listbase, void *vprevlink, void *vnewlink)
*/
void BLI_insertlinkbefore(ListBase *listbase, void *vnextlink, void *vnewlink)
{
- Link *nextlink = vnextlink;
- Link *newlink = vnewlink;
+ Link *nextlink = vnextlink;
+ Link *newlink = vnewlink;
- /* newlink before nextlink */
- if (newlink == NULL) {
- return;
- }
+ /* newlink before nextlink */
+ if (newlink == NULL) {
+ return;
+ }
- /* empty list */
- if (listbase->first == NULL) {
- listbase->first = newlink;
- listbase->last = newlink;
- return;
- }
+ /* empty list */
+ if (listbase->first == NULL) {
+ listbase->first = newlink;
+ listbase->last = newlink;
+ return;
+ }
- /* insert at end of list */
- if (nextlink == NULL) {
- newlink->prev = listbase->last;
- newlink->next = NULL;
- ((Link *)listbase->last)->next = newlink;
- listbase->last = newlink;
- return;
- }
+ /* insert at end of list */
+ if (nextlink == NULL) {
+ newlink->prev = listbase->last;
+ newlink->next = NULL;
+ ((Link *)listbase->last)->next = newlink;
+ listbase->last = newlink;
+ return;
+ }
- /* at beginning of list */
- if (listbase->first == nextlink) {
- listbase->first = newlink;
- }
+ /* at beginning of list */
+ if (listbase->first == nextlink) {
+ listbase->first = newlink;
+ }
- newlink->next = nextlink;
- newlink->prev = nextlink->prev;
- nextlink->prev = newlink;
- if (newlink->prev) {
- newlink->prev->next = newlink;
- }
+ newlink->next = nextlink;
+ newlink->prev = nextlink->prev;
+ nextlink->prev = newlink;
+ if (newlink->prev) {
+ newlink->prev->next = newlink;
+ }
}
-
/**
* Insert a link in place of another, without changing it's position in the list.
*
@@ -443,28 +440,28 @@ void BLI_insertlinkbefore(ListBase *listbase, void *vnextlink, void *vnewlink)
*/
void BLI_insertlinkreplace(ListBase *listbase, void *vreplacelink, void *vnewlink)
{
- Link *l_old = vreplacelink;
- Link *l_new = vnewlink;
+ Link *l_old = vreplacelink;
+ Link *l_new = vnewlink;
- /* update adjacent links */
- if (l_old->next != NULL) {
- l_old->next->prev = l_new;
- }
- if (l_old->prev != NULL) {
- l_old->prev->next = l_new;
- }
+ /* update adjacent links */
+ if (l_old->next != NULL) {
+ l_old->next->prev = l_new;
+ }
+ if (l_old->prev != NULL) {
+ l_old->prev->next = l_new;
+ }
- /* set direct links */
- l_new->next = l_old->next;
- l_new->prev = l_old->prev;
+ /* set direct links */
+ l_new->next = l_old->next;
+ l_new->prev = l_old->prev;
- /* update list */
- if (listbase->first == l_old) {
- listbase->first = l_new;
- }
- if (listbase->last == l_old) {
- listbase->last = l_new;
- }
+ /* update list */
+ if (listbase->first == l_old) {
+ listbase->first = l_new;
+ }
+ if (listbase->last == l_old) {
+ listbase->last = l_new;
+ }
}
/**
@@ -477,50 +474,49 @@ void BLI_insertlinkreplace(ListBase *listbase, void *vreplacelink, void *vnewlin
*/
bool BLI_listbase_link_move(ListBase *listbase, void *vlink, int step)
{
- Link *link = vlink;
- Link *hook = link;
- const bool is_up = step < 0;
+ Link *link = vlink;
+ Link *hook = link;
+ const bool is_up = step < 0;
- if (step == 0) {
- return false;
- }
- BLI_assert(BLI_findindex(listbase, link) != -1);
+ if (step == 0) {
+ return false;
+ }
+ BLI_assert(BLI_findindex(listbase, link) != -1);
- /* find link to insert before/after */
- for (int i = 0; i < ABS(step); i++) {
- hook = is_up ? hook->prev : hook->next;
- if (!hook) {
- return false;
- }
- }
+ /* find link to insert before/after */
+ for (int i = 0; i < ABS(step); i++) {
+ hook = is_up ? hook->prev : hook->next;
+ if (!hook) {
+ return false;
+ }
+ }
- /* reinsert link */
- BLI_remlink(listbase, vlink);
- if (is_up) {
- BLI_insertlinkbefore(listbase, hook, vlink);
- }
- else {
- BLI_insertlinkafter(listbase, hook, vlink);
- }
- return true;
+ /* reinsert link */
+ BLI_remlink(listbase, vlink);
+ if (is_up) {
+ BLI_insertlinkbefore(listbase, hook, vlink);
+ }
+ else {
+ BLI_insertlinkafter(listbase, hook, vlink);
+ }
+ return true;
}
-
/**
* Removes and disposes of the entire contents of listbase using direct free(3).
*/
void BLI_freelist(ListBase *listbase)
{
- Link *link, *next;
+ Link *link, *next;
- link = listbase->first;
- while (link) {
- next = link->next;
- free(link);
- link = next;
- }
+ link = listbase->first;
+ while (link) {
+ next = link->next;
+ free(link);
+ link = next;
+ }
- BLI_listbase_clear(listbase);
+ BLI_listbase_clear(listbase);
}
/**
@@ -528,16 +524,16 @@ void BLI_freelist(ListBase *listbase)
*/
void BLI_freelistN(ListBase *listbase)
{
- Link *link, *next;
+ Link *link, *next;
- link = listbase->first;
- while (link) {
- next = link->next;
- MEM_freeN(link);
- link = next;
- }
+ link = listbase->first;
+ while (link) {
+ next = link->next;
+ MEM_freeN(link);
+ link = next;
+ }
- BLI_listbase_clear(listbase);
+ BLI_listbase_clear(listbase);
}
/**
@@ -547,14 +543,14 @@ void BLI_freelistN(ListBase *listbase)
*/
int BLI_listbase_count_at_most(const ListBase *listbase, const int count_max)
{
- Link *link;
- int count = 0;
+ Link *link;
+ int count = 0;
- for (link = listbase->first; link && count != count_max; link = link->next) {
- count++;
- }
+ for (link = listbase->first; link && count != count_max; link = link->next) {
+ count++;
+ }
- return count;
+ return count;
}
/**
@@ -562,14 +558,14 @@ int BLI_listbase_count_at_most(const ListBase *listbase, const int count_max)
*/
int BLI_listbase_count(const ListBase *listbase)
{
- Link *link;
- int count = 0;
+ Link *link;
+ int count = 0;
- for (link = listbase->first; link; link = link->next) {
- count++;
- }
+ for (link = listbase->first; link; link = link->next) {
+ count++;
+ }
- return count;
+ return count;
}
/**
@@ -577,17 +573,17 @@ int BLI_listbase_count(const ListBase *listbase)
*/
void *BLI_findlink(const ListBase *listbase, int number)
{
- Link *link = NULL;
+ Link *link = NULL;
- if (number >= 0) {
- link = listbase->first;
- while (link != NULL && number != 0) {
- number--;
- link = link->next;
- }
- }
+ if (number >= 0) {
+ link = listbase->first;
+ while (link != NULL && number != 0) {
+ number--;
+ link = link->next;
+ }
+ }
- return link;
+ return link;
}
/**
@@ -595,17 +591,17 @@ void *BLI_findlink(const ListBase *listbase, int number)
*/
void *BLI_rfindlink(const ListBase *listbase, int number)
{
- Link *link = NULL;
+ Link *link = NULL;
- if (number >= 0) {
- link = listbase->last;
- while (link != NULL && number != 0) {
- number--;
- link = link->prev;
- }
- }
+ if (number >= 0) {
+ link = listbase->last;
+ while (link != NULL && number != 0) {
+ number--;
+ link = link->prev;
+ }
+ }
- return link;
+ return link;
}
/**
@@ -613,24 +609,24 @@ void *BLI_rfindlink(const ListBase *listbase, int number)
*/
int BLI_findindex(const ListBase *listbase, const void *vlink)
{
- Link *link = NULL;
- int number = 0;
+ Link *link = NULL;
+ int number = 0;
- if (vlink == NULL) {
- return -1;
- }
+ if (vlink == NULL) {
+ return -1;
+ }
- link = listbase->first;
- while (link) {
- if (link == vlink) {
- return number;
- }
+ link = listbase->first;
+ while (link) {
+ if (link == vlink) {
+ return number;
+ }
- number++;
- link = link->next;
- }
+ number++;
+ link = link->next;
+ }
- return -1;
+ return -1;
}
/**
@@ -639,22 +635,22 @@ int BLI_findindex(const ListBase *listbase, const void *vlink)
*/
void *BLI_findstring(const ListBase *listbase, const char *id, const int offset)
{
- Link *link = NULL;
- const char *id_iter;
+ Link *link = NULL;
+ const char *id_iter;
- if (id == NULL) {
- return NULL;
- }
+ if (id == NULL) {
+ return NULL;
+ }
- for (link = listbase->first; link; link = link->next) {
- id_iter = ((const char *)link) + offset;
+ for (link = listbase->first; link; link = link->next) {
+ id_iter = ((const char *)link) + offset;
- if (id[0] == id_iter[0] && STREQ(id, id_iter)) {
- return link;
- }
- }
+ if (id[0] == id_iter[0] && STREQ(id, id_iter)) {
+ return link;
+ }
+ }
- return NULL;
+ return NULL;
}
/* same as above but find reverse */
/**
@@ -663,18 +659,18 @@ void *BLI_findstring(const ListBase *listbase, const char *id, const int offset)
*/
void *BLI_rfindstring(const ListBase *listbase, const char *id, const int offset)
{
- Link *link = NULL;
- const char *id_iter;
+ Link *link = NULL;
+ const char *id_iter;
- for (link = listbase->last; link; link = link->prev) {
- id_iter = ((const char *)link) + offset;
+ for (link = listbase->last; link; link = link->prev) {
+ id_iter = ((const char *)link) + offset;
- if (id[0] == id_iter[0] && STREQ(id, id_iter)) {
- return link;
- }
- }
+ if (id[0] == id_iter[0] && STREQ(id, id_iter)) {
+ return link;
+ }
+ }
- return NULL;
+ return NULL;
}
/**
@@ -683,19 +679,19 @@ void *BLI_rfindstring(const ListBase *listbase, const char *id, const int offset
*/
void *BLI_findstring_ptr(const ListBase *listbase, const char *id, const int offset)
{
- Link *link = NULL;
- const char *id_iter;
+ Link *link = NULL;
+ const char *id_iter;
- for (link = listbase->first; link; link = link->next) {
- /* exact copy of BLI_findstring(), except for this line */
- id_iter = *((const char **)(((const char *)link) + offset));
+ for (link = listbase->first; link; link = link->next) {
+ /* exact copy of BLI_findstring(), except for this line */
+ id_iter = *((const char **)(((const char *)link) + offset));
- if (id[0] == id_iter[0] && STREQ(id, id_iter)) {
- return link;
- }
- }
+ if (id[0] == id_iter[0] && STREQ(id, id_iter)) {
+ return link;
+ }
+ }
- return NULL;
+ return NULL;
}
/* same as above but find reverse */
/**
@@ -704,19 +700,19 @@ void *BLI_findstring_ptr(const ListBase *listbase, const char *id, const int off
*/
void *BLI_rfindstring_ptr(const ListBase *listbase, const char *id, const int offset)
{
- Link *link = NULL;
- const char *id_iter;
+ Link *link = NULL;
+ const char *id_iter;
- for (link = listbase->last; link; link = link->prev) {
- /* exact copy of BLI_rfindstring(), except for this line */
- id_iter = *((const char **)(((const char *)link) + offset));
+ for (link = listbase->last; link; link = link->prev) {
+ /* exact copy of BLI_rfindstring(), except for this line */
+ id_iter = *((const char **)(((const char *)link) + offset));
- if (id[0] == id_iter[0] && STREQ(id, id_iter)) {
- return link;
- }
- }
+ if (id[0] == id_iter[0] && STREQ(id, id_iter)) {
+ return link;
+ }
+ }
- return NULL;
+ return NULL;
}
/**
@@ -725,19 +721,19 @@ void *BLI_rfindstring_ptr(const ListBase *listbase, const char *id, const int of
*/
void *BLI_findptr(const ListBase *listbase, const void *ptr, const int offset)
{
- Link *link = NULL;
- const void *ptr_iter;
+ Link *link = NULL;
+ const void *ptr_iter;
- for (link = listbase->first; link; link = link->next) {
- /* exact copy of BLI_findstring(), except for this line */
- ptr_iter = *((const void **)(((const char *)link) + offset));
+ for (link = listbase->first; link; link = link->next) {
+ /* exact copy of BLI_findstring(), except for this line */
+ ptr_iter = *((const void **)(((const char *)link) + offset));
- if (ptr == ptr_iter) {
- return link;
- }
- }
+ if (ptr == ptr_iter) {
+ return link;
+ }
+ }
- return NULL;
+ return NULL;
}
/* same as above but find reverse */
/**
@@ -746,59 +742,65 @@ void *BLI_findptr(const ListBase *listbase, const void *ptr, const int offset)
*/
void *BLI_rfindptr(const ListBase *listbase, const void *ptr, const int offset)
{
- Link *link = NULL;
- const void *ptr_iter;
+ Link *link = NULL;
+ const void *ptr_iter;
- for (link = listbase->last; link; link = link->prev) {
- /* exact copy of BLI_rfindstring(), except for this line */
- ptr_iter = *((const void **)(((const char *)link) + offset));
+ for (link = listbase->last; link; link = link->prev) {
+ /* exact copy of BLI_rfindstring(), except for this line */
+ ptr_iter = *((const void **)(((const char *)link) + offset));
- if (ptr == ptr_iter) {
- return link;
- }
- }
+ if (ptr == ptr_iter) {
+ return link;
+ }
+ }
- return NULL;
+ return NULL;
}
/**
* Finds the first element of listbase which contains the specified bytes
* at the specified offset, returning NULL if not found.
*/
-void *BLI_listbase_bytes_find(const ListBase *listbase, const void *bytes, const size_t bytes_size, const int offset)
+void *BLI_listbase_bytes_find(const ListBase *listbase,
+ const void *bytes,
+ const size_t bytes_size,
+ const int offset)
{
- Link *link = NULL;
- const void *ptr_iter;
+ Link *link = NULL;
+ const void *ptr_iter;
- for (link = listbase->first; link; link = link->next) {
- ptr_iter = (const void *)(((const char *)link) + offset);
+ for (link = listbase->first; link; link = link->next) {
+ ptr_iter = (const void *)(((const char *)link) + offset);
- if (memcmp(bytes, ptr_iter, bytes_size) == 0) {
- return link;
- }
- }
+ if (memcmp(bytes, ptr_iter, bytes_size) == 0) {
+ return link;
+ }
+ }
- return NULL;
+ return NULL;
}
/* same as above but find reverse */
/**
* Finds the last element of listbase which contains the specified bytes
* at the specified offset, returning NULL if not found.
*/
-void *BLI_listbase_bytes_rfind(const ListBase *listbase, const void *bytes, const size_t bytes_size, const int offset)
+void *BLI_listbase_bytes_rfind(const ListBase *listbase,
+ const void *bytes,
+ const size_t bytes_size,
+ const int offset)
{
- Link *link = NULL;
- const void *ptr_iter;
+ Link *link = NULL;
+ const void *ptr_iter;
- for (link = listbase->last; link; link = link->prev) {
- ptr_iter = (const void *)(((const char *)link) + offset);
+ for (link = listbase->last; link; link = link->prev) {
+ ptr_iter = (const void *)(((const char *)link) + offset);
- if (memcmp(bytes, ptr_iter, bytes_size) == 0) {
- return link;
- }
- }
+ if (memcmp(bytes, ptr_iter, bytes_size) == 0) {
+ return link;
+ }
+ }
- return NULL;
+ return NULL;
}
/**
@@ -807,22 +809,22 @@ void *BLI_listbase_bytes_rfind(const ListBase *listbase, const void *bytes, cons
*/
int BLI_findstringindex(const ListBase *listbase, const char *id, const int offset)
{
- Link *link = NULL;
- const char *id_iter;
- int i = 0;
+ Link *link = NULL;
+ const char *id_iter;
+ int i = 0;
- link = listbase->first;
- while (link) {
- id_iter = ((const char *)link) + offset;
+ link = listbase->first;
+ while (link) {
+ id_iter = ((const char *)link) + offset;
- if (id[0] == id_iter[0] && STREQ(id, id_iter)) {
- return i;
- }
- i++;
- link = link->next;
- }
+ if (id[0] == id_iter[0] && STREQ(id, id_iter)) {
+ return i;
+ }
+ i++;
+ link = link->next;
+ }
- return -1;
+ return -1;
}
/**
@@ -830,37 +832,37 @@ int BLI_findstringindex(const ListBase *listbase, const char *id, const int offs
*/
void BLI_duplicatelist(ListBase *dst, const ListBase *src)
{
- struct Link *dst_link, *src_link;
+ struct Link *dst_link, *src_link;
- /* in this order, to ensure it works if dst == src */
- src_link = src->first;
- dst->first = dst->last = NULL;
+ /* in this order, to ensure it works if dst == src */
+ src_link = src->first;
+ dst->first = dst->last = NULL;
- while (src_link) {
- dst_link = MEM_dupallocN(src_link);
- BLI_addtail(dst, dst_link);
+ while (src_link) {
+ dst_link = MEM_dupallocN(src_link);
+ BLI_addtail(dst, dst_link);
- src_link = src_link->next;
- }
+ src_link = src_link->next;
+ }
}
void BLI_listbase_reverse(ListBase *lb)
{
- struct Link *curr = lb->first;
- struct Link *prev = NULL;
- struct Link *next = NULL;
- while (curr) {
- next = curr->next;
- curr->next = prev;
- curr->prev = next;
- prev = curr;
- curr = next;
- }
+ struct Link *curr = lb->first;
+ struct Link *prev = NULL;
+ struct Link *next = NULL;
+ while (curr) {
+ next = curr->next;
+ curr->next = prev;
+ curr->prev = next;
+ prev = curr;
+ curr = next;
+ }
- /* swap first/last */
- curr = lb->first;
- lb->first = lb->last;
- lb->last = curr;
+ /* swap first/last */
+ curr = lb->first;
+ lb->first = lb->last;
+ lb->last = curr;
}
/**
@@ -868,15 +870,15 @@ void BLI_listbase_reverse(ListBase *lb)
*/
void BLI_listbase_rotate_first(ListBase *lb, void *vlink)
{
- /* make circular */
- ((Link *)lb->first)->prev = lb->last;
- ((Link *)lb->last)->next = lb->first;
+ /* make circular */
+ ((Link *)lb->first)->prev = lb->last;
+ ((Link *)lb->last)->next = lb->first;
- lb->first = vlink;
- lb->last = ((Link *)vlink)->prev;
+ lb->first = vlink;
+ lb->last = ((Link *)vlink)->prev;
- ((Link *)lb->first)->prev = NULL;
- ((Link *)lb->last)->next = NULL;
+ ((Link *)lb->first)->prev = NULL;
+ ((Link *)lb->last)->next = NULL;
}
/**
@@ -884,29 +886,29 @@ void BLI_listbase_rotate_first(ListBase *lb, void *vlink)
*/
void BLI_listbase_rotate_last(ListBase *lb, void *vlink)
{
- /* make circular */
- ((Link *)lb->first)->prev = lb->last;
- ((Link *)lb->last)->next = lb->first;
+ /* make circular */
+ ((Link *)lb->first)->prev = lb->last;
+ ((Link *)lb->last)->next = lb->first;
- lb->first = ((Link *)vlink)->next;
- lb->last = vlink;
+ lb->first = ((Link *)vlink)->next;
+ lb->last = vlink;
- ((Link *)lb->first)->prev = NULL;
- ((Link *)lb->last)->next = NULL;
+ ((Link *)lb->first)->prev = NULL;
+ ((Link *)lb->last)->next = NULL;
}
/* create a generic list node containing link to provided data */
LinkData *BLI_genericNodeN(void *data)
{
- LinkData *ld;
+ LinkData *ld;
- if (data == NULL) {
- return NULL;
- }
+ if (data == NULL) {
+ return NULL;
+ }
- /* create new link, and make it hold the given data */
- ld = MEM_callocN(sizeof(LinkData), __func__);
- ld->data = data;
+ /* create new link, and make it hold the given data */
+ ld = MEM_callocN(sizeof(LinkData), __func__);
+ ld->data = data;
- return ld;
+ return ld;
}
diff --git a/source/blender/blenlib/intern/math_base.c b/source/blender/blenlib/intern/math_base.c
index ed75cac2d0c..30267661ae7 100644
--- a/source/blender/blenlib/intern/math_base.c
+++ b/source/blender/blenlib/intern/math_base.c
@@ -30,52 +30,52 @@
int pow_i(int base, int exp)
{
- int result = 1;
- BLI_assert(exp >= 0);
- while (exp) {
- if (exp & 1) {
- result *= base;
- }
- exp >>= 1;
- base *= base;
- }
+ int result = 1;
+ BLI_assert(exp >= 0);
+ while (exp) {
+ if (exp & 1) {
+ result *= base;
+ }
+ exp >>= 1;
+ base *= base;
+ }
- return result;
+ return result;
}
/* from python 3.1 floatobject.c
* ndigits must be between 0 and 21 */
double double_round(double x, int ndigits)
{
- double pow1, pow2, y, z;
- if (ndigits >= 0) {
- pow1 = pow(10.0, (double)ndigits);
- pow2 = 1.0;
- y = (x * pow1) * pow2;
- /* if y overflows, then rounded value is exactly x */
- if (!isfinite(y)) {
- return x;
- }
- }
- else {
- pow1 = pow(10.0, (double)-ndigits);
- pow2 = 1.0; /* unused; silences a gcc compiler warning */
- y = x / pow1;
- }
+ double pow1, pow2, y, z;
+ if (ndigits >= 0) {
+ pow1 = pow(10.0, (double)ndigits);
+ pow2 = 1.0;
+ y = (x * pow1) * pow2;
+ /* if y overflows, then rounded value is exactly x */
+ if (!isfinite(y)) {
+ return x;
+ }
+ }
+ else {
+ pow1 = pow(10.0, (double)-ndigits);
+ pow2 = 1.0; /* unused; silences a gcc compiler warning */
+ y = x / pow1;
+ }
- z = round(y);
- if (fabs(y - z) == 0.5) {
- /* halfway between two integers; use round-half-even */
- z = 2.0 * round(y / 2.0);
- }
+ z = round(y);
+ if (fabs(y - z) == 0.5) {
+ /* halfway between two integers; use round-half-even */
+ z = 2.0 * round(y / 2.0);
+ }
- if (ndigits >= 0) {
- z = (z / pow2) / pow1;
- }
- else {
- z *= pow1;
- }
+ if (ndigits >= 0) {
+ z = (z / pow2) / pow1;
+ }
+ else {
+ z *= pow1;
+ }
- /* if computation resulted in overflow, raise OverflowError */
- return z;
+ /* if computation resulted in overflow, raise OverflowError */
+ return z;
}
diff --git a/source/blender/blenlib/intern/math_base_inline.c b/source/blender/blenlib/intern/math_base_inline.c
index b8a5a138eb4..f1ceaca4eb1 100644
--- a/source/blender/blenlib/intern/math_base_inline.c
+++ b/source/blender/blenlib/intern/math_base_inline.c
@@ -40,196 +40,269 @@
/* copied from BLI_utildefines.h */
#ifdef __GNUC__
-# define UNLIKELY(x) __builtin_expect(!!(x), 0)
+# define UNLIKELY(x) __builtin_expect(!!(x), 0)
#else
-# define UNLIKELY(x) (x)
+# define UNLIKELY(x) (x)
#endif
/* powf is really slow for raising to integer powers. */
MINLINE float pow2f(float x)
{
- return x * x;
+ return x * x;
}
MINLINE float pow3f(float x)
{
- return pow2f(x) * x;
+ return pow2f(x) * x;
}
MINLINE float pow4f(float x)
{
- return pow2f(pow2f(x));
+ return pow2f(pow2f(x));
}
MINLINE float pow7f(float x)
{
- return pow2f(pow3f(x)) * x;
+ return pow2f(pow3f(x)) * x;
}
MINLINE float sqrt3f(float f)
{
- if (UNLIKELY(f == 0.0f)) { return 0.0f; }
- else if (UNLIKELY(f < 0.0f)) { return -(float)(exp(log(-f) / 3.0)); }
- else { return (float)(exp(log( f) / 3.0)); }
+ if (UNLIKELY(f == 0.0f)) {
+ return 0.0f;
+ }
+ else if (UNLIKELY(f < 0.0f)) {
+ return -(float)(exp(log(-f) / 3.0));
+ }
+ else {
+ return (float)(exp(log(f) / 3.0));
+ }
}
MINLINE double sqrt3d(double d)
{
- if (UNLIKELY(d == 0.0)) { return 0.0; }
- else if (UNLIKELY(d < 0.0)) { return -exp(log(-d) / 3.0); }
- else { return exp(log( d) / 3.0); }
+ if (UNLIKELY(d == 0.0)) {
+ return 0.0;
+ }
+ else if (UNLIKELY(d < 0.0)) {
+ return -exp(log(-d) / 3.0);
+ }
+ else {
+ return exp(log(d) / 3.0);
+ }
}
MINLINE float sqrtf_signed(float f)
{
- return (f >= 0.0f) ? sqrtf(f) : -sqrtf(-f);
+ return (f >= 0.0f) ? sqrtf(f) : -sqrtf(-f);
}
MINLINE float saacos(float fac)
{
- if (UNLIKELY(fac <= -1.0f)) { return (float)M_PI; }
- else if (UNLIKELY(fac >= 1.0f)) { return 0.0f; }
- else { return acosf(fac); }
+ if (UNLIKELY(fac <= -1.0f)) {
+ return (float)M_PI;
+ }
+ else if (UNLIKELY(fac >= 1.0f)) {
+ return 0.0f;
+ }
+ else {
+ return acosf(fac);
+ }
}
MINLINE float saasin(float fac)
{
- if (UNLIKELY(fac <= -1.0f)) { return (float)-M_PI / 2.0f; }
- else if (UNLIKELY(fac >= 1.0f)) { return (float) M_PI / 2.0f; }
- else { return asinf(fac); }
+ if (UNLIKELY(fac <= -1.0f)) {
+ return (float)-M_PI / 2.0f;
+ }
+ else if (UNLIKELY(fac >= 1.0f)) {
+ return (float)M_PI / 2.0f;
+ }
+ else {
+ return asinf(fac);
+ }
}
MINLINE float sasqrt(float fac)
{
- if (UNLIKELY(fac <= 0.0f)) { return 0.0f; }
- else { return sqrtf(fac); }
+ if (UNLIKELY(fac <= 0.0f)) {
+ return 0.0f;
+ }
+ else {
+ return sqrtf(fac);
+ }
}
MINLINE float saacosf(float fac)
{
- if (UNLIKELY(fac <= -1.0f)) { return (float)M_PI; }
- else if (UNLIKELY(fac >= 1.0f)) { return 0.0f; }
- else { return acosf(fac); }
+ if (UNLIKELY(fac <= -1.0f)) {
+ return (float)M_PI;
+ }
+ else if (UNLIKELY(fac >= 1.0f)) {
+ return 0.0f;
+ }
+ else {
+ return acosf(fac);
+ }
}
MINLINE float saasinf(float fac)
{
- if (UNLIKELY(fac <= -1.0f)) { return (float)-M_PI / 2.0f; }
- else if (UNLIKELY(fac >= 1.0f)) { return (float) M_PI / 2.0f; }
- else { return asinf(fac); }
+ if (UNLIKELY(fac <= -1.0f)) {
+ return (float)-M_PI / 2.0f;
+ }
+ else if (UNLIKELY(fac >= 1.0f)) {
+ return (float)M_PI / 2.0f;
+ }
+ else {
+ return asinf(fac);
+ }
}
MINLINE float sasqrtf(float fac)
{
- if (UNLIKELY(fac <= 0.0f)) { return 0.0f; }
- else { return sqrtf(fac); }
+ if (UNLIKELY(fac <= 0.0f)) {
+ return 0.0f;
+ }
+ else {
+ return sqrtf(fac);
+ }
}
MINLINE float interpf(float target, float origin, float fac)
{
- return (fac * target) + (1.0f - fac) * origin;
+ return (fac * target) + (1.0f - fac) * origin;
}
/* used for zoom values*/
MINLINE float power_of_2(float val)
{
- return (float)pow(2.0, ceil(log((double)val) / M_LN2));
+ return (float)pow(2.0, ceil(log((double)val) / M_LN2));
}
MINLINE int is_power_of_2_i(int n)
{
- return (n & (n - 1)) == 0;
+ return (n & (n - 1)) == 0;
}
MINLINE int power_of_2_max_i(int n)
{
- if (is_power_of_2_i(n)) {
- return n;
- }
+ if (is_power_of_2_i(n)) {
+ return n;
+ }
- do {
- n = n & (n - 1);
- } while (!is_power_of_2_i(n));
+ do {
+ n = n & (n - 1);
+ } while (!is_power_of_2_i(n));
- return n * 2;
+ return n * 2;
}
MINLINE int power_of_2_min_i(int n)
{
- while (!is_power_of_2_i(n)) {
- n = n & (n - 1);
- }
+ while (!is_power_of_2_i(n)) {
+ n = n & (n - 1);
+ }
- return n;
+ return n;
}
MINLINE unsigned int power_of_2_max_u(unsigned int x)
{
- x -= 1;
- x |= (x >> 1);
- x |= (x >> 2);
- x |= (x >> 4);
- x |= (x >> 8);
- x |= (x >> 16);
- return x + 1;
+ x -= 1;
+ x |= (x >> 1);
+ x |= (x >> 2);
+ x |= (x >> 4);
+ x |= (x >> 8);
+ x |= (x >> 16);
+ return x + 1;
}
MINLINE unsigned power_of_2_min_u(unsigned x)
{
- x |= (x >> 1);
- x |= (x >> 2);
- x |= (x >> 4);
- x |= (x >> 8);
- x |= (x >> 16);
- return x - (x >> 1);
+ x |= (x >> 1);
+ x |= (x >> 2);
+ x |= (x >> 4);
+ x |= (x >> 8);
+ x |= (x >> 16);
+ return x - (x >> 1);
}
/* rounding and clamping */
-#define _round_clamp_fl_impl(arg, ty, min, max) { \
- float r = floorf(arg + 0.5f); \
- if (UNLIKELY(r <= (float)min)) return (ty)min; \
- else if (UNLIKELY(r >= (float)max)) return (ty)max; \
- else return (ty)r; \
+#define _round_clamp_fl_impl(arg, ty, min, max) \
+ { \
+ float r = floorf(arg + 0.5f); \
+ if (UNLIKELY(r <= (float)min)) \
+ return (ty)min; \
+ else if (UNLIKELY(r >= (float)max)) \
+ return (ty)max; \
+ else \
+ return (ty)r; \
+ }
+
+#define _round_clamp_db_impl(arg, ty, min, max) \
+ { \
+ double r = floor(arg + 0.5); \
+ if (UNLIKELY(r <= (double)min)) \
+ return (ty)min; \
+ else if (UNLIKELY(r >= (double)max)) \
+ return (ty)max; \
+ else \
+ return (ty)r; \
+ }
+
+#define _round_fl_impl(arg, ty) \
+ { \
+ return (ty)floorf(arg + 0.5f); \
+ }
+#define _round_db_impl(arg, ty) \
+ { \
+ return (ty)floor(arg + 0.5); \
+ }
+
+MINLINE signed char round_fl_to_char(float a){_round_fl_impl(a, signed char)} MINLINE
+ unsigned char round_fl_to_uchar(float a){_round_fl_impl(a, unsigned char)} MINLINE
+ short round_fl_to_short(float a){_round_fl_impl(a, short)} MINLINE
+ unsigned short round_fl_to_ushort(float a){_round_fl_impl(a, unsigned short)} MINLINE
+ int round_fl_to_int(float a){_round_fl_impl(a, int)} MINLINE
+ unsigned int round_fl_to_uint(float a){_round_fl_impl(a, unsigned int)}
+
+MINLINE signed char round_db_to_char(double a){_round_db_impl(a, signed char)} MINLINE
+ unsigned char round_db_to_uchar(double a){_round_db_impl(a, unsigned char)} MINLINE
+ short round_db_to_short(double a){_round_db_impl(a, short)} MINLINE
+ unsigned short round_db_to_ushort(double a){_round_db_impl(a, unsigned short)} MINLINE
+ int round_db_to_int(double a){_round_db_impl(a, int)} MINLINE
+ unsigned int round_db_to_uint(double a)
+{
+ _round_db_impl(a, unsigned int)
}
-#define _round_clamp_db_impl(arg, ty, min, max) { \
- double r = floor(arg + 0.5); \
- if (UNLIKELY(r <= (double)min)) return (ty)min; \
- else if (UNLIKELY(r >= (double)max)) return (ty)max; \
- else return (ty)r; \
-}
-
-#define _round_fl_impl(arg, ty) { return (ty)floorf(arg + 0.5f); }
-#define _round_db_impl(arg, ty) { return (ty)floor(arg + 0.5); }
-
-MINLINE signed char round_fl_to_char(float a) { _round_fl_impl(a, signed char) }
-MINLINE unsigned char round_fl_to_uchar(float a) { _round_fl_impl(a, unsigned char) }
-MINLINE short round_fl_to_short(float a) { _round_fl_impl(a, short) }
-MINLINE unsigned short round_fl_to_ushort(float a) { _round_fl_impl(a, unsigned short) }
-MINLINE int round_fl_to_int(float a) { _round_fl_impl(a, int) }
-MINLINE unsigned int round_fl_to_uint(float a) { _round_fl_impl(a, unsigned int) }
-
-MINLINE signed char round_db_to_char(double a) { _round_db_impl(a, signed char) }
-MINLINE unsigned char round_db_to_uchar(double a) { _round_db_impl(a, unsigned char) }
-MINLINE short round_db_to_short(double a) { _round_db_impl(a, short) }
-MINLINE unsigned short round_db_to_ushort(double a) { _round_db_impl(a, unsigned short) }
-MINLINE int round_db_to_int(double a) { _round_db_impl(a, int) }
-MINLINE unsigned int round_db_to_uint(double a) { _round_db_impl(a, unsigned int) }
-
#undef _round_fl_impl
#undef _round_db_impl
-MINLINE signed char round_fl_to_char_clamp(float a) { _round_clamp_fl_impl(a, signed char, SCHAR_MIN, SCHAR_MAX) }
-MINLINE unsigned char round_fl_to_uchar_clamp(float a) { _round_clamp_fl_impl(a, unsigned char, 0, UCHAR_MAX) }
-MINLINE short round_fl_to_short_clamp(float a) { _round_clamp_fl_impl(a, short, SHRT_MIN, SHRT_MAX) }
-MINLINE unsigned short round_fl_to_ushort_clamp(float a) { _round_clamp_fl_impl(a, unsigned short, 0, USHRT_MAX) }
-MINLINE int round_fl_to_int_clamp(float a) { _round_clamp_fl_impl(a, int, INT_MIN, INT_MAX) }
-MINLINE unsigned int round_fl_to_uint_clamp(float a) { _round_clamp_fl_impl(a, unsigned int, 0, UINT_MAX) }
-
-MINLINE signed char round_db_to_char_clamp(double a) { _round_clamp_db_impl(a, signed char, SCHAR_MIN, SCHAR_MAX) }
-MINLINE unsigned char round_db_to_uchar_clamp(double a) { _round_clamp_db_impl(a, unsigned char, 0, UCHAR_MAX) }
-MINLINE short round_db_to_short_clamp(double a) { _round_clamp_db_impl(a, short, SHRT_MIN, SHRT_MAX) }
-MINLINE unsigned short round_db_to_ushort_clamp(double a) { _round_clamp_db_impl(a, unsigned short, 0, USHRT_MAX) }
-MINLINE int round_db_to_int_clamp(double a) { _round_clamp_db_impl(a, int, INT_MIN, INT_MAX) }
-MINLINE unsigned int round_db_to_uint_clamp(double a) { _round_clamp_db_impl(a, unsigned int, 0, UINT_MAX) }
+MINLINE signed char round_fl_to_char_clamp(float a){
+ _round_clamp_fl_impl(a, signed char, SCHAR_MIN, SCHAR_MAX)} MINLINE
+ unsigned char round_fl_to_uchar_clamp(float a){
+ _round_clamp_fl_impl(a, unsigned char, 0, UCHAR_MAX)} MINLINE
+ short round_fl_to_short_clamp(float a){
+ _round_clamp_fl_impl(a, short, SHRT_MIN, SHRT_MAX)} MINLINE
+ unsigned short round_fl_to_ushort_clamp(float a){
+ _round_clamp_fl_impl(a, unsigned short, 0, USHRT_MAX)} MINLINE
+ int round_fl_to_int_clamp(float a){_round_clamp_fl_impl(a, int, INT_MIN, INT_MAX)} MINLINE
+ unsigned int round_fl_to_uint_clamp(float a){
+ _round_clamp_fl_impl(a, unsigned int, 0, UINT_MAX)}
+
+MINLINE signed char round_db_to_char_clamp(double a){
+ _round_clamp_db_impl(a, signed char, SCHAR_MIN, SCHAR_MAX)} MINLINE
+ unsigned char round_db_to_uchar_clamp(double a){
+ _round_clamp_db_impl(a, unsigned char, 0, UCHAR_MAX)} MINLINE
+ short round_db_to_short_clamp(double a){
+ _round_clamp_db_impl(a, short, SHRT_MIN, SHRT_MAX)} MINLINE
+ unsigned short round_db_to_ushort_clamp(double a){
+ _round_clamp_db_impl(a, unsigned short, 0, USHRT_MAX)} MINLINE
+ int round_db_to_int_clamp(double a){_round_clamp_db_impl(a, int, INT_MIN, INT_MAX)} MINLINE
+ unsigned int round_db_to_uint_clamp(double a)
+{
+ _round_clamp_db_impl(a, unsigned int, 0, UINT_MAX)
+}
#undef _round_clamp_fl_impl
#undef _round_clamp_db_impl
@@ -238,7 +311,7 @@ MINLINE unsigned int round_db_to_uint_clamp(double a) { _round_clamp_db_impl(a
* with integers, to avoid gradual darkening when rounding down */
MINLINE int divide_round_i(int a, int b)
{
- return (2 * a + b) / (2 * b);
+ return (2 * a + b) / (2 * b);
}
/**
@@ -247,9 +320,9 @@ MINLINE int divide_round_i(int a, int b)
*/
MINLINE int divide_floor_i(int a, int b)
{
- int d = a / b;
- int r = a % b; /* Optimizes into a single division. */
- return r ? d - ((a < 0) ^ (b < 0)) : d;
+ int d = a / b;
+ int r = a % b; /* Optimizes into a single division. */
+ return r ? d - ((a < 0) ^ (b < 0)) : d;
}
/**
@@ -257,91 +330,91 @@ MINLINE int divide_floor_i(int a, int b)
*/
MINLINE int mod_i(int i, int n)
{
- return (i % n + n) % n;
+ return (i % n + n) % n;
}
MINLINE float min_ff(float a, float b)
{
- return (a < b) ? a : b;
+ return (a < b) ? a : b;
}
MINLINE float max_ff(float a, float b)
{
- return (a > b) ? a : b;
+ return (a > b) ? a : b;
}
MINLINE int min_ii(int a, int b)
{
- return (a < b) ? a : b;
+ return (a < b) ? a : b;
}
MINLINE int max_ii(int a, int b)
{
- return (b < a) ? a : b;
+ return (b < a) ? a : b;
}
MINLINE float min_fff(float a, float b, float c)
{
- return min_ff(min_ff(a, b), c);
+ return min_ff(min_ff(a, b), c);
}
MINLINE float max_fff(float a, float b, float c)
{
- return max_ff(max_ff(a, b), c);
+ return max_ff(max_ff(a, b), c);
}
MINLINE int min_iii(int a, int b, int c)
{
- return min_ii(min_ii(a, b), c);
+ return min_ii(min_ii(a, b), c);
}
MINLINE int max_iii(int a, int b, int c)
{
- return max_ii(max_ii(a, b), c);
+ return max_ii(max_ii(a, b), c);
}
MINLINE float min_ffff(float a, float b, float c, float d)
{
- return min_ff(min_fff(a, b, c), d);
+ return min_ff(min_fff(a, b, c), d);
}
MINLINE float max_ffff(float a, float b, float c, float d)
{
- return max_ff(max_fff(a, b, c), d);
+ return max_ff(max_fff(a, b, c), d);
}
MINLINE int min_iiii(int a, int b, int c, int d)
{
- return min_ii(min_iii(a, b, c), d);
+ return min_ii(min_iii(a, b, c), d);
}
MINLINE int max_iiii(int a, int b, int c, int d)
{
- return max_ii(max_iii(a, b, c), d);
+ return max_ii(max_iii(a, b, c), d);
}
MINLINE size_t min_zz(size_t a, size_t b)
{
- return (a < b) ? a : b;
+ return (a < b) ? a : b;
}
MINLINE size_t max_zz(size_t a, size_t b)
{
- return (b < a) ? a : b;
+ return (b < a) ? a : b;
}
MINLINE int clamp_i(int value, int min, int max)
{
- return min_ii(max_ii(value, min), max);
+ return min_ii(max_ii(value, min), max);
}
MINLINE float clamp_f(float value, float min, float max)
{
- if (value > max) {
- return max;
- }
- else if (value < min) {
- return min;
- }
- return value;
+ if (value > max) {
+ return max;
+ }
+ else if (value < min) {
+ return min;
+ }
+ return value;
}
MINLINE size_t clamp_z(size_t value, size_t min, size_t max)
{
- return min_zz(max_zz(value, min), max);
+ return min_zz(max_zz(value, min), max);
}
/**
@@ -351,7 +424,7 @@ MINLINE size_t clamp_z(size_t value, size_t min, size_t max)
*/
MINLINE int compare_ff(float a, float b, const float max_diff)
{
- return fabsf(a - b) <= max_diff;
+ return fabsf(a - b) <= max_diff;
}
/**
@@ -365,59 +438,74 @@ MINLINE int compare_ff(float a, float b, const float max_diff)
*/
MINLINE int compare_ff_relative(float a, float b, const float max_diff, const int max_ulps)
{
- union {float f; int i;} ua, ub;
+ union {
+ float f;
+ int i;
+ } ua, ub;
- BLI_assert(sizeof(float) == sizeof(int));
- BLI_assert(max_ulps < (1 << 22));
+ BLI_assert(sizeof(float) == sizeof(int));
+ BLI_assert(max_ulps < (1 << 22));
- if (fabsf(a - b) <= max_diff) {
- return 1;
- }
+ if (fabsf(a - b) <= max_diff) {
+ return 1;
+ }
- ua.f = a;
- ub.f = b;
+ ua.f = a;
+ ub.f = b;
- /* Important to compare sign from integers, since (-0.0f < 0) is false
- * (though this shall not be an issue in common cases)... */
- return ((ua.i < 0) != (ub.i < 0)) ? 0 : (abs(ua.i - ub.i) <= max_ulps) ? 1 : 0;
+ /* Important to compare sign from integers, since (-0.0f < 0) is false
+ * (though this shall not be an issue in common cases)... */
+ return ((ua.i < 0) != (ub.i < 0)) ? 0 : (abs(ua.i - ub.i) <= max_ulps) ? 1 : 0;
}
MINLINE float signf(float f)
{
- return (f < 0.f) ? -1.f : 1.f;
+ return (f < 0.f) ? -1.f : 1.f;
}
MINLINE int signum_i_ex(float a, float eps)
{
- if (a > eps) { return 1; }
- if (a < -eps) { return -1; }
- else { return 0; }
+ if (a > eps) {
+ return 1;
+ }
+ if (a < -eps) {
+ return -1;
+ }
+ else {
+ return 0;
+ }
}
MINLINE int signum_i(float a)
{
- if (a > 0.0f) { return 1; }
- if (a < 0.0f) { return -1; }
- else { return 0; }
+ if (a > 0.0f) {
+ return 1;
+ }
+ if (a < 0.0f) {
+ return -1;
+ }
+ else {
+ return 0;
+ }
}
/** Returns number of (base ten) *significant* digits of integer part of given float
* (negative in case of decimal-only floats, 0.01 returns -1 e.g.). */
MINLINE int integer_digits_f(const float f)
{
- return (f == 0.0f) ? 0 : (int)floor(log10(fabs(f))) + 1;
+ return (f == 0.0f) ? 0 : (int)floor(log10(fabs(f))) + 1;
}
/** Returns number of (base ten) *significant* digits of integer part of given double
* (negative in case of decimal-only floats, 0.01 returns -1 e.g.). */
MINLINE int integer_digits_d(const double d)
{
- return (d == 0.0) ? 0 : (int)floor(log10(fabs(d))) + 1;
+ return (d == 0.0) ? 0 : (int)floor(log10(fabs(d))) + 1;
}
MINLINE int integer_digits_i(const int i)
{
- return (int)log10((double)i) + 1;
+ return (int)log10((double)i) + 1;
}
/* Internal helpers for SSE2 implementation.
@@ -437,112 +525,116 @@ MINLINE int integer_digits_i(const int i)
*
* We hope that exp and e2coeff gets properly inlined
*/
-MALWAYS_INLINE __m128 _bli_math_fastpow(const int exp,
- const int e2coeff,
- const __m128 arg)
+MALWAYS_INLINE __m128 _bli_math_fastpow(const int exp, const int e2coeff, const __m128 arg)
{
- __m128 ret;
- ret = _mm_mul_ps(arg, _mm_castsi128_ps(_mm_set1_epi32(e2coeff)));
- ret = _mm_cvtepi32_ps(_mm_castps_si128(ret));
- ret = _mm_mul_ps(ret, _mm_castsi128_ps(_mm_set1_epi32(exp)));
- ret = _mm_castsi128_ps(_mm_cvtps_epi32(ret));
- return ret;
+ __m128 ret;
+ ret = _mm_mul_ps(arg, _mm_castsi128_ps(_mm_set1_epi32(e2coeff)));
+ ret = _mm_cvtepi32_ps(_mm_castps_si128(ret));
+ ret = _mm_mul_ps(ret, _mm_castsi128_ps(_mm_set1_epi32(exp)));
+ ret = _mm_castsi128_ps(_mm_cvtps_epi32(ret));
+ return ret;
}
/* Improve x ^ 1.0f/5.0f solution with Newton-Raphson method */
-MALWAYS_INLINE __m128 _bli_math_improve_5throot_solution(
- const __m128 old_result,
- const __m128 x)
+MALWAYS_INLINE __m128 _bli_math_improve_5throot_solution(const __m128 old_result, const __m128 x)
{
- __m128 approx2 = _mm_mul_ps(old_result, old_result);
- __m128 approx4 = _mm_mul_ps(approx2, approx2);
- __m128 t = _mm_div_ps(x, approx4);
- __m128 summ = _mm_add_ps(_mm_mul_ps(_mm_set1_ps(4.0f), old_result), t); /* fma */
- return _mm_mul_ps(summ, _mm_set1_ps(1.0f / 5.0f));
+ __m128 approx2 = _mm_mul_ps(old_result, old_result);
+ __m128 approx4 = _mm_mul_ps(approx2, approx2);
+ __m128 t = _mm_div_ps(x, approx4);
+ __m128 summ = _mm_add_ps(_mm_mul_ps(_mm_set1_ps(4.0f), old_result), t); /* fma */
+ return _mm_mul_ps(summ, _mm_set1_ps(1.0f / 5.0f));
}
/* Calculate powf(x, 2.4). Working domain: 1e-10 < x < 1e+10 */
MALWAYS_INLINE __m128 _bli_math_fastpow24(const __m128 arg)
{
- /* max, avg and |avg| errors were calculated in gcc without FMA instructions
- * The final precision should be better than powf in glibc */
-
- /* Calculate x^4/5, coefficient 0.994 was constructed manually to minimize
- * avg error.
- */
- /* 0x3F4CCCCD = 4/5 */
- /* 0x4F55A7FB = 2^(127/(4/5) - 127) * 0.994^(1/(4/5)) */
- /* error max = 0.17, avg = 0.0018, |avg| = 0.05 */
- __m128 x = _bli_math_fastpow(0x3F4CCCCD, 0x4F55A7FB, arg);
- __m128 arg2 = _mm_mul_ps(arg, arg);
- __m128 arg4 = _mm_mul_ps(arg2, arg2);
- /* error max = 0.018 avg = 0.0031 |avg| = 0.0031 */
- x = _bli_math_improve_5throot_solution(x, arg4);
- /* error max = 0.00021 avg = 1.6e-05 |avg| = 1.6e-05 */
- x = _bli_math_improve_5throot_solution(x, arg4);
- /* error max = 6.1e-07 avg = 5.2e-08 |avg| = 1.1e-07 */
- x = _bli_math_improve_5throot_solution(x, arg4);
- return _mm_mul_ps(x, _mm_mul_ps(x, x));
+ /* max, avg and |avg| errors were calculated in gcc without FMA instructions
+ * The final precision should be better than powf in glibc */
+
+ /* Calculate x^4/5, coefficient 0.994 was constructed manually to minimize
+ * avg error.
+ */
+ /* 0x3F4CCCCD = 4/5 */
+ /* 0x4F55A7FB = 2^(127/(4/5) - 127) * 0.994^(1/(4/5)) */
+ /* error max = 0.17, avg = 0.0018, |avg| = 0.05 */
+ __m128 x = _bli_math_fastpow(0x3F4CCCCD, 0x4F55A7FB, arg);
+ __m128 arg2 = _mm_mul_ps(arg, arg);
+ __m128 arg4 = _mm_mul_ps(arg2, arg2);
+ /* error max = 0.018 avg = 0.0031 |avg| = 0.0031 */
+ x = _bli_math_improve_5throot_solution(x, arg4);
+ /* error max = 0.00021 avg = 1.6e-05 |avg| = 1.6e-05 */
+ x = _bli_math_improve_5throot_solution(x, arg4);
+ /* error max = 6.1e-07 avg = 5.2e-08 |avg| = 1.1e-07 */
+ x = _bli_math_improve_5throot_solution(x, arg4);
+ return _mm_mul_ps(x, _mm_mul_ps(x, x));
}
/* Calculate powf(x, 1.0f / 2.4) */
MALWAYS_INLINE __m128 _bli_math_fastpow512(const __m128 arg)
{
- /* 5/12 is too small, so compute the 4th root of 20/12 instead.
- * 20/12 = 5/3 = 1 + 2/3 = 2 - 1/3. 2/3 is a suitable argument for fastpow.
- * weighting coefficient: a^-1/2 = 2 a; a = 2^-2/3
- */
- __m128 xf = _bli_math_fastpow(0x3f2aaaab, 0x5eb504f3, arg);
- __m128 xover = _mm_mul_ps(arg, xf);
- __m128 xfm1 = _mm_rsqrt_ps(xf);
- __m128 x2 = _mm_mul_ps(arg, arg);
- __m128 xunder = _mm_mul_ps(x2, xfm1);
- /* sqrt2 * over + 2 * sqrt2 * under */
- __m128 xavg = _mm_mul_ps(_mm_set1_ps(1.0f / (3.0f * 0.629960524947437f) * 0.999852f),
- _mm_add_ps(xover, xunder));
- xavg = _mm_mul_ps(xavg, _mm_rsqrt_ps(xavg));
- xavg = _mm_mul_ps(xavg, _mm_rsqrt_ps(xavg));
- return xavg;
+ /* 5/12 is too small, so compute the 4th root of 20/12 instead.
+ * 20/12 = 5/3 = 1 + 2/3 = 2 - 1/3. 2/3 is a suitable argument for fastpow.
+ * weighting coefficient: a^-1/2 = 2 a; a = 2^-2/3
+ */
+ __m128 xf = _bli_math_fastpow(0x3f2aaaab, 0x5eb504f3, arg);
+ __m128 xover = _mm_mul_ps(arg, xf);
+ __m128 xfm1 = _mm_rsqrt_ps(xf);
+ __m128 x2 = _mm_mul_ps(arg, arg);
+ __m128 xunder = _mm_mul_ps(x2, xfm1);
+ /* sqrt2 * over + 2 * sqrt2 * under */
+ __m128 xavg = _mm_mul_ps(_mm_set1_ps(1.0f / (3.0f * 0.629960524947437f) * 0.999852f),
+ _mm_add_ps(xover, xunder));
+ xavg = _mm_mul_ps(xavg, _mm_rsqrt_ps(xavg));
+ xavg = _mm_mul_ps(xavg, _mm_rsqrt_ps(xavg));
+ return xavg;
}
-MALWAYS_INLINE __m128 _bli_math_blend_sse(const __m128 mask,
- const __m128 a,
- const __m128 b)
+MALWAYS_INLINE __m128 _bli_math_blend_sse(const __m128 mask, const __m128 a, const __m128 b)
{
- return _mm_or_ps(_mm_and_ps(mask, a), _mm_andnot_ps(mask, b));
+ return _mm_or_ps(_mm_and_ps(mask, a), _mm_andnot_ps(mask, b));
}
-#endif /* __SSE2__ */
+#endif /* __SSE2__ */
/* Low level conversion functions */
MINLINE unsigned char unit_float_to_uchar_clamp(float val)
{
- return (unsigned char)(((val <= 0.0f) ? 0 : ((val > (1.0f - 0.5f / 255.0f)) ? 255 : ((255.0f * val) + 0.5f))));
+ return (unsigned char)((
+ (val <= 0.0f) ? 0 : ((val > (1.0f - 0.5f / 255.0f)) ? 255 : ((255.0f * val) + 0.5f))));
}
-#define unit_float_to_uchar_clamp(val) ((CHECK_TYPE_INLINE(val, float)), unit_float_to_uchar_clamp(val))
+#define unit_float_to_uchar_clamp(val) \
+ ((CHECK_TYPE_INLINE(val, float)), unit_float_to_uchar_clamp(val))
MINLINE unsigned short unit_float_to_ushort_clamp(float val)
{
- return (unsigned short)((val >= 1.0f - 0.5f / 65535) ? 65535 : (val <= 0.0f) ? 0 : (val * 65535.0f + 0.5f));
+ return (unsigned short)((val >= 1.0f - 0.5f / 65535) ?
+ 65535 :
+ (val <= 0.0f) ? 0 : (val * 65535.0f + 0.5f));
}
-#define unit_float_to_ushort_clamp(val) ((CHECK_TYPE_INLINE(val, float)), unit_float_to_ushort_clamp(val))
+#define unit_float_to_ushort_clamp(val) \
+ ((CHECK_TYPE_INLINE(val, float)), unit_float_to_ushort_clamp(val))
MINLINE unsigned char unit_ushort_to_uchar(unsigned short val)
{
- return (unsigned char)(((val) >= 65535 - 128) ? 255 : ((val) + 128) >> 8);
-}
-#define unit_ushort_to_uchar(val) ((CHECK_TYPE_INLINE(val, unsigned short)), unit_ushort_to_uchar(val))
-
-#define unit_float_to_uchar_clamp_v3(v1, v2) { \
- (v1)[0] = unit_float_to_uchar_clamp((v2[0])); \
- (v1)[1] = unit_float_to_uchar_clamp((v2[1])); \
- (v1)[2] = unit_float_to_uchar_clamp((v2[2])); \
-} ((void)0)
-#define unit_float_to_uchar_clamp_v4(v1, v2) { \
- (v1)[0] = unit_float_to_uchar_clamp((v2[0])); \
- (v1)[1] = unit_float_to_uchar_clamp((v2[1])); \
- (v1)[2] = unit_float_to_uchar_clamp((v2[2])); \
- (v1)[3] = unit_float_to_uchar_clamp((v2[3])); \
-} ((void)0)
+ return (unsigned char)(((val) >= 65535 - 128) ? 255 : ((val) + 128) >> 8);
+}
+#define unit_ushort_to_uchar(val) \
+ ((CHECK_TYPE_INLINE(val, unsigned short)), unit_ushort_to_uchar(val))
+
+#define unit_float_to_uchar_clamp_v3(v1, v2) \
+ { \
+ (v1)[0] = unit_float_to_uchar_clamp((v2[0])); \
+ (v1)[1] = unit_float_to_uchar_clamp((v2[1])); \
+ (v1)[2] = unit_float_to_uchar_clamp((v2[2])); \
+ } \
+ ((void)0)
+#define unit_float_to_uchar_clamp_v4(v1, v2) \
+ { \
+ (v1)[0] = unit_float_to_uchar_clamp((v2[0])); \
+ (v1)[1] = unit_float_to_uchar_clamp((v2[1])); \
+ (v1)[2] = unit_float_to_uchar_clamp((v2[2])); \
+ (v1)[3] = unit_float_to_uchar_clamp((v2[3])); \
+ } \
+ ((void)0)
#endif /* __MATH_BASE_INLINE_C__ */
diff --git a/source/blender/blenlib/intern/math_bits_inline.c b/source/blender/blenlib/intern/math_bits_inline.c
index d86b2924e17..ec2408e30a1 100644
--- a/source/blender/blenlib/intern/math_bits_inline.c
+++ b/source/blender/blenlib/intern/math_bits_inline.c
@@ -30,121 +30,133 @@
MINLINE int bitscan_forward_i(int a)
{
- BLI_assert(a != 0);
+ BLI_assert(a != 0);
#ifdef _MSC_VER
- unsigned long ctz;
- _BitScanForward(&ctz, a);
- return ctz;
+ unsigned long ctz;
+ _BitScanForward(&ctz, a);
+ return ctz;
#else
- return __builtin_ctz((unsigned int)a);
+ return __builtin_ctz((unsigned int)a);
#endif
}
MINLINE unsigned int bitscan_forward_uint(unsigned int a)
{
- return (unsigned int)bitscan_forward_i((int)a);
+ return (unsigned int)bitscan_forward_i((int)a);
}
MINLINE int bitscan_forward_clear_i(int *a)
{
- int i = bitscan_forward_i(*a);
- *a &= (*a) - 1;
- return i;
+ int i = bitscan_forward_i(*a);
+ *a &= (*a) - 1;
+ return i;
}
MINLINE unsigned int bitscan_forward_clear_uint(unsigned int *a)
{
- return (unsigned int)bitscan_forward_clear_i((int *)a);
+ return (unsigned int)bitscan_forward_clear_i((int *)a);
}
MINLINE int bitscan_reverse_i(int a)
{
- BLI_assert(a != 0);
+ BLI_assert(a != 0);
#ifdef _MSC_VER
- unsigned long clz;
- _BitScanReverse(&clz, a);
- return clz;
+ unsigned long clz;
+ _BitScanReverse(&clz, a);
+ return clz;
#else
- return __builtin_clz((unsigned int)a);
+ return __builtin_clz((unsigned int)a);
#endif
}
MINLINE unsigned int bitscan_reverse_uint(unsigned int a)
{
- return (unsigned int)bitscan_reverse_i((int)a);
+ return (unsigned int)bitscan_reverse_i((int)a);
}
MINLINE int bitscan_reverse_clear_i(int *a)
{
- int i = bitscan_reverse_i(*a);
- /* TODO(sergey): This could probably be optimized. */
- *a &= ~(1 << (sizeof(int) * 8 - i - 1));
- return i;
+ int i = bitscan_reverse_i(*a);
+ /* TODO(sergey): This could probably be optimized. */
+ *a &= ~(1 << (sizeof(int) * 8 - i - 1));
+ return i;
}
MINLINE unsigned int bitscan_reverse_clear_uint(unsigned int *a)
{
- return (unsigned int)bitscan_reverse_clear_i((int *)a);
+ return (unsigned int)bitscan_reverse_clear_i((int *)a);
}
MINLINE unsigned int highest_order_bit_uint(unsigned int n)
{
- if (n == 0) {
- return 0;
- }
- return 1 << (sizeof(unsigned int) * 8 - bitscan_reverse_uint(n));
+ if (n == 0) {
+ return 0;
+ }
+ return 1 << (sizeof(unsigned int) * 8 - bitscan_reverse_uint(n));
}
MINLINE unsigned short highest_order_bit_s(unsigned short n)
{
- n |= (n >> 1);
- n |= (n >> 2);
- n |= (n >> 4);
- n |= (n >> 8);
- return (unsigned short)(n - (n >> 1));
+ n |= (n >> 1);
+ n |= (n >> 2);
+ n |= (n >> 4);
+ n |= (n >> 8);
+ return (unsigned short)(n - (n >> 1));
}
#ifndef __GNUC__
MINLINE int count_bits_i(unsigned int i)
{
- /* variable-precision SWAR algorithm. */
- i = i - ((i >> 1) & 0x55555555);
- i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
- return (((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
+ /* variable-precision SWAR algorithm. */
+ i = i - ((i >> 1) & 0x55555555);
+ i = (i & 0x33333333) + ((i >> 2) & 0x33333333);
+ return (((i + (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
}
#endif
MINLINE int float_as_int(float f)
{
- union { int i; float f; } u;
- u.f = f;
- return u.i;
+ union {
+ int i;
+ float f;
+ } u;
+ u.f = f;
+ return u.i;
}
MINLINE unsigned int float_as_uint(float f)
{
- union { unsigned int i; float f; } u;
- u.f = f;
- return u.i;
+ union {
+ unsigned int i;
+ float f;
+ } u;
+ u.f = f;
+ return u.i;
}
MINLINE float int_as_float(int i)
{
- union { int i; float f; } u;
- u.i = i;
- return u.f;
+ union {
+ int i;
+ float f;
+ } u;
+ u.i = i;
+ return u.f;
}
MINLINE float uint_as_float(unsigned int i)
{
- union { unsigned int i; float f; } u;
- u.i = i;
- return u.f;
+ union {
+ unsigned int i;
+ float f;
+ } u;
+ u.i = i;
+ return u.f;
}
MINLINE float xor_fl(float x, int y)
{
- return int_as_float(float_as_int(x) ^ y);
+ return int_as_float(float_as_int(x) ^ y);
}
#endif /* __MATH_BITS_INLINE_C__ */
diff --git a/source/blender/blenlib/intern/math_color.c b/source/blender/blenlib/intern/math_color.c
index 54698ddf7ca..bc1699451f3 100644
--- a/source/blender/blenlib/intern/math_color.c
+++ b/source/blender/blenlib/intern/math_color.c
@@ -26,7 +26,6 @@
#include <assert.h>
-
#include "BLI_math.h"
#include "BLI_utildefines.h"
@@ -34,95 +33,95 @@
void hsv_to_rgb(float h, float s, float v, float *r, float *g, float *b)
{
- float nr, ng, nb;
+ float nr, ng, nb;
- nr = fabsf(h * 6.0f - 3.0f) - 1.0f;
- ng = 2.0f - fabsf(h * 6.0f - 2.0f);
- nb = 2.0f - fabsf(h * 6.0f - 4.0f);
+ nr = fabsf(h * 6.0f - 3.0f) - 1.0f;
+ ng = 2.0f - fabsf(h * 6.0f - 2.0f);
+ nb = 2.0f - fabsf(h * 6.0f - 4.0f);
- CLAMP(nr, 0.0f, 1.0f);
- CLAMP(nb, 0.0f, 1.0f);
- CLAMP(ng, 0.0f, 1.0f);
+ CLAMP(nr, 0.0f, 1.0f);
+ CLAMP(nb, 0.0f, 1.0f);
+ CLAMP(ng, 0.0f, 1.0f);
- *r = ((nr - 1.0f) * s + 1.0f) * v;
- *g = ((ng - 1.0f) * s + 1.0f) * v;
- *b = ((nb - 1.0f) * s + 1.0f) * v;
+ *r = ((nr - 1.0f) * s + 1.0f) * v;
+ *g = ((ng - 1.0f) * s + 1.0f) * v;
+ *b = ((nb - 1.0f) * s + 1.0f) * v;
}
void hsl_to_rgb(float h, float s, float l, float *r, float *g, float *b)
{
- float nr, ng, nb, chroma;
+ float nr, ng, nb, chroma;
- nr = fabsf(h * 6.0f - 3.0f) - 1.0f;
- ng = 2.0f - fabsf(h * 6.0f - 2.0f);
- nb = 2.0f - fabsf(h * 6.0f - 4.0f);
+ nr = fabsf(h * 6.0f - 3.0f) - 1.0f;
+ ng = 2.0f - fabsf(h * 6.0f - 2.0f);
+ nb = 2.0f - fabsf(h * 6.0f - 4.0f);
- CLAMP(nr, 0.0f, 1.0f);
- CLAMP(nb, 0.0f, 1.0f);
- CLAMP(ng, 0.0f, 1.0f);
+ CLAMP(nr, 0.0f, 1.0f);
+ CLAMP(nb, 0.0f, 1.0f);
+ CLAMP(ng, 0.0f, 1.0f);
- chroma = (1.0f - fabsf(2.0f * l - 1.0f)) * s;
+ chroma = (1.0f - fabsf(2.0f * l - 1.0f)) * s;
- *r = (nr - 0.5f) * chroma + l;
- *g = (ng - 0.5f) * chroma + l;
- *b = (nb - 0.5f) * chroma + l;
+ *r = (nr - 0.5f) * chroma + l;
+ *g = (ng - 0.5f) * chroma + l;
+ *b = (nb - 0.5f) * chroma + l;
}
/* convenience function for now */
void hsv_to_rgb_v(const float hsv[3], float r_rgb[3])
{
- hsv_to_rgb(hsv[0], hsv[1], hsv[2], &r_rgb[0], &r_rgb[1], &r_rgb[2]);
+ hsv_to_rgb(hsv[0], hsv[1], hsv[2], &r_rgb[0], &r_rgb[1], &r_rgb[2]);
}
/* convenience function for now */
void hsl_to_rgb_v(const float hsl[3], float r_rgb[3])
{
- hsl_to_rgb(hsl[0], hsl[1], hsl[2], &r_rgb[0], &r_rgb[1], &r_rgb[2]);
+ hsl_to_rgb(hsl[0], hsl[1], hsl[2], &r_rgb[0], &r_rgb[1], &r_rgb[2]);
}
void rgb_to_yuv(float r, float g, float b, float *ly, float *lu, float *lv, int colorspace)
{
- float y, u, v;
+ float y, u, v;
- switch (colorspace) {
- case BLI_YUV_ITU_BT601:
- y = 0.299f * r + 0.587f * g + 0.114f * b;
- u = -0.147f * r - 0.289f * g + 0.436f * b;
- v = 0.615f * r - 0.515f * g - 0.100f * b;
- break;
- case BLI_YUV_ITU_BT709:
- default:
- y = 0.2126f * r + 0.7152f * g + 0.0722f * b;
- u = -0.09991f * r - 0.33609f * g + 0.436f * b;
- v = 0.615f * r - 0.55861f * g - 0.05639f * b;
- break;
- }
+ switch (colorspace) {
+ case BLI_YUV_ITU_BT601:
+ y = 0.299f * r + 0.587f * g + 0.114f * b;
+ u = -0.147f * r - 0.289f * g + 0.436f * b;
+ v = 0.615f * r - 0.515f * g - 0.100f * b;
+ break;
+ case BLI_YUV_ITU_BT709:
+ default:
+ y = 0.2126f * r + 0.7152f * g + 0.0722f * b;
+ u = -0.09991f * r - 0.33609f * g + 0.436f * b;
+ v = 0.615f * r - 0.55861f * g - 0.05639f * b;
+ break;
+ }
- *ly = y;
- *lu = u;
- *lv = v;
+ *ly = y;
+ *lu = u;
+ *lv = v;
}
void yuv_to_rgb(float y, float u, float v, float *lr, float *lg, float *lb, int colorspace)
{
- float r, g, b;
+ float r, g, b;
- switch (colorspace) {
- case BLI_YUV_ITU_BT601:
- r = y + 1.140f * v;
- g = y - 0.394f * u - 0.581f * v;
- b = y + 2.032f * u;
- break;
- case BLI_YUV_ITU_BT709:
- r = y + 1.28033f * v;
- g = y - 0.21482f * u - 0.38059f * v;
- b = y + 2.12798f * u;
- break;
- }
+ switch (colorspace) {
+ case BLI_YUV_ITU_BT601:
+ r = y + 1.140f * v;
+ g = y - 0.394f * u - 0.581f * v;
+ b = y + 2.032f * u;
+ break;
+ case BLI_YUV_ITU_BT709:
+ r = y + 1.28033f * v;
+ g = y - 0.21482f * u - 0.38059f * v;
+ b = y + 2.12798f * u;
+ break;
+ }
- *lr = r;
- *lg = g;
- *lb = b;
+ *lr = r;
+ *lg = g;
+ *lb = b;
}
/* The RGB inputs are supposed gamma corrected and in the range 0 - 1.0f
@@ -130,231 +129,229 @@ void yuv_to_rgb(float y, float u, float v, float *lr, float *lg, float *lb, int
* Output YCC have a range of 16-235 and 16-240 except with JFIF_0_255 where the range is 0-255 */
void rgb_to_ycc(float r, float g, float b, float *ly, float *lcb, float *lcr, int colorspace)
{
- float sr, sg, sb;
- float y = 128.0f, cr = 128.0f, cb = 128.0f;
-
- sr = 255.0f * r;
- sg = 255.0f * g;
- sb = 255.0f * b;
-
- switch (colorspace) {
- case BLI_YCC_ITU_BT601:
- y = (0.257f * sr) + (0.504f * sg) + (0.098f * sb) + 16.0f;
- cb = (-0.148f * sr) - (0.291f * sg) + (0.439f * sb) + 128.0f;
- cr = (0.439f * sr) - (0.368f * sg) - (0.071f * sb) + 128.0f;
- break;
- case BLI_YCC_ITU_BT709:
- y = (0.183f * sr) + (0.614f * sg) + (0.062f * sb) + 16.0f;
- cb = (-0.101f * sr) - (0.338f * sg) + (0.439f * sb) + 128.0f;
- cr = (0.439f * sr) - (0.399f * sg) - (0.040f * sb) + 128.0f;
- break;
- case BLI_YCC_JFIF_0_255:
- y = (0.299f * sr) + (0.587f * sg) + (0.114f * sb);
- cb = (-0.16874f * sr) - (0.33126f * sg) + (0.5f * sb) + 128.0f;
- cr = (0.5f * sr) - (0.41869f * sg) - (0.08131f * sb) + 128.0f;
- break;
- default:
- assert(!"invalid colorspace");
- break;
- }
-
- *ly = y;
- *lcb = cb;
- *lcr = cr;
+ float sr, sg, sb;
+ float y = 128.0f, cr = 128.0f, cb = 128.0f;
+
+ sr = 255.0f * r;
+ sg = 255.0f * g;
+ sb = 255.0f * b;
+
+ switch (colorspace) {
+ case BLI_YCC_ITU_BT601:
+ y = (0.257f * sr) + (0.504f * sg) + (0.098f * sb) + 16.0f;
+ cb = (-0.148f * sr) - (0.291f * sg) + (0.439f * sb) + 128.0f;
+ cr = (0.439f * sr) - (0.368f * sg) - (0.071f * sb) + 128.0f;
+ break;
+ case BLI_YCC_ITU_BT709:
+ y = (0.183f * sr) + (0.614f * sg) + (0.062f * sb) + 16.0f;
+ cb = (-0.101f * sr) - (0.338f * sg) + (0.439f * sb) + 128.0f;
+ cr = (0.439f * sr) - (0.399f * sg) - (0.040f * sb) + 128.0f;
+ break;
+ case BLI_YCC_JFIF_0_255:
+ y = (0.299f * sr) + (0.587f * sg) + (0.114f * sb);
+ cb = (-0.16874f * sr) - (0.33126f * sg) + (0.5f * sb) + 128.0f;
+ cr = (0.5f * sr) - (0.41869f * sg) - (0.08131f * sb) + 128.0f;
+ break;
+ default:
+ assert(!"invalid colorspace");
+ break;
+ }
+
+ *ly = y;
+ *lcb = cb;
+ *lcr = cr;
}
-
/* YCC input have a range of 16-235 and 16-240 except with JFIF_0_255 where the range is 0-255 */
/* RGB outputs are in the range 0 - 1.0f */
/* FIXME comment above must be wrong because BLI_YCC_ITU_BT601 y 16.0 cr 16.0 -> r -0.7009 */
void ycc_to_rgb(float y, float cb, float cr, float *lr, float *lg, float *lb, int colorspace)
{
- float r = 128.0f, g = 128.0f, b = 128.0f;
-
- switch (colorspace) {
- case BLI_YCC_ITU_BT601:
- r = 1.164f * (y - 16.0f) + 1.596f * (cr - 128.0f);
- g = 1.164f * (y - 16.0f) - 0.813f * (cr - 128.0f) - 0.392f * (cb - 128.0f);
- b = 1.164f * (y - 16.0f) + 2.017f * (cb - 128.0f);
- break;
- case BLI_YCC_ITU_BT709:
- r = 1.164f * (y - 16.0f) + 1.793f * (cr - 128.0f);
- g = 1.164f * (y - 16.0f) - 0.534f * (cr - 128.0f) - 0.213f * (cb - 128.0f);
- b = 1.164f * (y - 16.0f) + 2.115f * (cb - 128.0f);
- break;
- case BLI_YCC_JFIF_0_255:
- r = y + 1.402f * cr - 179.456f;
- g = y - 0.34414f * cb - 0.71414f * cr + 135.45984f;
- b = y + 1.772f * cb - 226.816f;
- break;
- default:
- BLI_assert(0);
- break;
- }
- *lr = r / 255.0f;
- *lg = g / 255.0f;
- *lb = b / 255.0f;
+ float r = 128.0f, g = 128.0f, b = 128.0f;
+
+ switch (colorspace) {
+ case BLI_YCC_ITU_BT601:
+ r = 1.164f * (y - 16.0f) + 1.596f * (cr - 128.0f);
+ g = 1.164f * (y - 16.0f) - 0.813f * (cr - 128.0f) - 0.392f * (cb - 128.0f);
+ b = 1.164f * (y - 16.0f) + 2.017f * (cb - 128.0f);
+ break;
+ case BLI_YCC_ITU_BT709:
+ r = 1.164f * (y - 16.0f) + 1.793f * (cr - 128.0f);
+ g = 1.164f * (y - 16.0f) - 0.534f * (cr - 128.0f) - 0.213f * (cb - 128.0f);
+ b = 1.164f * (y - 16.0f) + 2.115f * (cb - 128.0f);
+ break;
+ case BLI_YCC_JFIF_0_255:
+ r = y + 1.402f * cr - 179.456f;
+ g = y - 0.34414f * cb - 0.71414f * cr + 135.45984f;
+ b = y + 1.772f * cb - 226.816f;
+ break;
+ default:
+ BLI_assert(0);
+ break;
+ }
+ *lr = r / 255.0f;
+ *lg = g / 255.0f;
+ *lb = b / 255.0f;
}
void hex_to_rgb(char *hexcol, float *r, float *g, float *b)
{
- unsigned int ri, gi, bi;
-
- if (hexcol[0] == '#') {
- hexcol++;
- }
-
- if (sscanf(hexcol, "%02x%02x%02x", &ri, &gi, &bi) == 3) {
- /* six digit hex colors */
- }
- else if (sscanf(hexcol, "%01x%01x%01x", &ri, &gi, &bi) == 3) {
- /* three digit hex colors (#123 becomes #112233) */
- ri += ri << 4;
- gi += gi << 4;
- bi += bi << 4;
- }
- else {
- /* avoid using un-initialized vars */
- *r = *g = *b = 0.0f;
- return;
- }
-
- *r = (float)ri * (1.0f / 255.0f);
- *g = (float)gi * (1.0f / 255.0f);
- *b = (float)bi * (1.0f / 255.0f);
- CLAMP(*r, 0.0f, 1.0f);
- CLAMP(*g, 0.0f, 1.0f);
- CLAMP(*b, 0.0f, 1.0f);
+ unsigned int ri, gi, bi;
+
+ if (hexcol[0] == '#') {
+ hexcol++;
+ }
+
+ if (sscanf(hexcol, "%02x%02x%02x", &ri, &gi, &bi) == 3) {
+ /* six digit hex colors */
+ }
+ else if (sscanf(hexcol, "%01x%01x%01x", &ri, &gi, &bi) == 3) {
+ /* three digit hex colors (#123 becomes #112233) */
+ ri += ri << 4;
+ gi += gi << 4;
+ bi += bi << 4;
+ }
+ else {
+ /* avoid using un-initialized vars */
+ *r = *g = *b = 0.0f;
+ return;
+ }
+
+ *r = (float)ri * (1.0f / 255.0f);
+ *g = (float)gi * (1.0f / 255.0f);
+ *b = (float)bi * (1.0f / 255.0f);
+ CLAMP(*r, 0.0f, 1.0f);
+ CLAMP(*g, 0.0f, 1.0f);
+ CLAMP(*b, 0.0f, 1.0f);
}
void rgb_to_hsv(float r, float g, float b, float *lh, float *ls, float *lv)
{
- float k = 0.0f;
- float chroma;
- float min_gb;
+ float k = 0.0f;
+ float chroma;
+ float min_gb;
- if (g < b) {
- SWAP(float, g, b);
- k = -1.0f;
- }
- min_gb = b;
- if (r < g) {
- SWAP(float, r, g);
- k = -2.0f / 6.0f - k;
- min_gb = min_ff(g, b);
- }
+ if (g < b) {
+ SWAP(float, g, b);
+ k = -1.0f;
+ }
+ min_gb = b;
+ if (r < g) {
+ SWAP(float, r, g);
+ k = -2.0f / 6.0f - k;
+ min_gb = min_ff(g, b);
+ }
- chroma = r - min_gb;
+ chroma = r - min_gb;
- *lh = fabsf(k + (g - b) / (6.0f * chroma + 1e-20f));
- *ls = chroma / (r + 1e-20f);
- *lv = r;
+ *lh = fabsf(k + (g - b) / (6.0f * chroma + 1e-20f));
+ *ls = chroma / (r + 1e-20f);
+ *lv = r;
}
/* convenience function for now */
void rgb_to_hsv_v(const float rgb[3], float r_hsv[3])
{
- rgb_to_hsv(rgb[0], rgb[1], rgb[2], &r_hsv[0], &r_hsv[1], &r_hsv[2]);
+ rgb_to_hsv(rgb[0], rgb[1], rgb[2], &r_hsv[0], &r_hsv[1], &r_hsv[2]);
}
void rgb_to_hsl(float r, float g, float b, float *lh, float *ls, float *ll)
{
- const float cmax = max_fff(r, g, b);
- const float cmin = min_fff(r, g, b);
- float h, s, l = min_ff(1.0, (cmax + cmin) / 2.0f);
-
- if (cmax == cmin) {
- h = s = 0.0f; // achromatic
- }
- else {
- float d = cmax - cmin;
- s = l > 0.5f ? d / (2.0f - cmax - cmin) : d / (cmax + cmin);
- if (cmax == r) {
- h = (g - b) / d + (g < b ? 6.0f : 0.0f);
- }
- else if (cmax == g) {
- h = (b - r) / d + 2.0f;
- }
- else {
- h = (r - g) / d + 4.0f;
- }
- }
- h /= 6.0f;
-
- *lh = h;
- *ls = s;
- *ll = l;
+ const float cmax = max_fff(r, g, b);
+ const float cmin = min_fff(r, g, b);
+ float h, s, l = min_ff(1.0, (cmax + cmin) / 2.0f);
+
+ if (cmax == cmin) {
+ h = s = 0.0f; // achromatic
+ }
+ else {
+ float d = cmax - cmin;
+ s = l > 0.5f ? d / (2.0f - cmax - cmin) : d / (cmax + cmin);
+ if (cmax == r) {
+ h = (g - b) / d + (g < b ? 6.0f : 0.0f);
+ }
+ else if (cmax == g) {
+ h = (b - r) / d + 2.0f;
+ }
+ else {
+ h = (r - g) / d + 4.0f;
+ }
+ }
+ h /= 6.0f;
+
+ *lh = h;
+ *ls = s;
+ *ll = l;
}
void rgb_to_hsl_compat(float r, float g, float b, float *lh, float *ls, float *ll)
{
- const float orig_s = *ls;
- const float orig_h = *lh;
+ const float orig_s = *ls;
+ const float orig_h = *lh;
- rgb_to_hsl(r, g, b, lh, ls, ll);
+ rgb_to_hsl(r, g, b, lh, ls, ll);
- if (*ll <= 0.0f) {
- *lh = orig_h;
- *ls = orig_s;
- }
- else if (*ls <= 0.0f) {
- *lh = orig_h;
- *ls = orig_s;
- }
+ if (*ll <= 0.0f) {
+ *lh = orig_h;
+ *ls = orig_s;
+ }
+ else if (*ls <= 0.0f) {
+ *lh = orig_h;
+ *ls = orig_s;
+ }
- if (*lh == 0.0f && orig_h >= 1.0f) {
- *lh = 1.0f;
- }
+ if (*lh == 0.0f && orig_h >= 1.0f) {
+ *lh = 1.0f;
+ }
}
void rgb_to_hsl_compat_v(const float rgb[3], float r_hsl[3])
{
- rgb_to_hsl_compat(rgb[0], rgb[1], rgb[2], &r_hsl[0], &r_hsl[1], &r_hsl[2]);
+ rgb_to_hsl_compat(rgb[0], rgb[1], rgb[2], &r_hsl[0], &r_hsl[1], &r_hsl[2]);
}
-
/* convenience function for now */
void rgb_to_hsl_v(const float rgb[3], float r_hsl[3])
{
- rgb_to_hsl(rgb[0], rgb[1], rgb[2], &r_hsl[0], &r_hsl[1], &r_hsl[2]);
+ rgb_to_hsl(rgb[0], rgb[1], rgb[2], &r_hsl[0], &r_hsl[1], &r_hsl[2]);
}
void rgb_to_hsv_compat(float r, float g, float b, float *lh, float *ls, float *lv)
{
- const float orig_h = *lh;
- const float orig_s = *ls;
+ const float orig_h = *lh;
+ const float orig_s = *ls;
- rgb_to_hsv(r, g, b, lh, ls, lv);
+ rgb_to_hsv(r, g, b, lh, ls, lv);
- if (*lv <= 1e-8) {
- /* Very low v values will affect the hs values, correct them in post. */
- *lh = orig_h;
- *ls = orig_s;
- }
- else if (*ls <= 1e-8) {
- *lh = orig_h;
- }
+ if (*lv <= 1e-8) {
+ /* Very low v values will affect the hs values, correct them in post. */
+ *lh = orig_h;
+ *ls = orig_s;
+ }
+ else if (*ls <= 1e-8) {
+ *lh = orig_h;
+ }
- if (*lh == 0.0f && orig_h >= 1.0f) {
- *lh = 1.0f;
- }
+ if (*lh == 0.0f && orig_h >= 1.0f) {
+ *lh = 1.0f;
+ }
}
/* convenience function for now */
void rgb_to_hsv_compat_v(const float rgb[3], float r_hsv[3])
{
- rgb_to_hsv_compat(rgb[0], rgb[1], rgb[2], &r_hsv[0], &r_hsv[1], &r_hsv[2]);
+ rgb_to_hsv_compat(rgb[0], rgb[1], rgb[2], &r_hsv[0], &r_hsv[1], &r_hsv[2]);
}
/* clamp hsv to usable values */
void hsv_clamp_v(float hsv[3], float v_max)
{
- if (UNLIKELY(hsv[0] < 0.0f || hsv[0] > 1.0f)) {
- hsv[0] = hsv[0] - floorf(hsv[0]);
- }
- CLAMP(hsv[1], 0.0f, 1.0f);
- CLAMP(hsv[2], 0.0f, v_max);
+ if (UNLIKELY(hsv[0] < 0.0f || hsv[0] > 1.0f)) {
+ hsv[0] = hsv[0] - floorf(hsv[0]);
+ }
+ CLAMP(hsv[1], 0.0f, 1.0f);
+ CLAMP(hsv[2], 0.0f, v_max);
}
/**
@@ -365,112 +362,117 @@ void hsv_clamp_v(float hsv[3], float v_max)
unsigned int hsv_to_cpack(float h, float s, float v)
{
- unsigned int r, g, b;
- float rf, gf, bf;
- unsigned int col;
+ unsigned int r, g, b;
+ float rf, gf, bf;
+ unsigned int col;
- hsv_to_rgb(h, s, v, &rf, &gf, &bf);
+ hsv_to_rgb(h, s, v, &rf, &gf, &bf);
- r = (unsigned int) (rf * 255.0f);
- g = (unsigned int) (gf * 255.0f);
- b = (unsigned int) (bf * 255.0f);
+ r = (unsigned int)(rf * 255.0f);
+ g = (unsigned int)(gf * 255.0f);
+ b = (unsigned int)(bf * 255.0f);
- col = (r + (g * 256) + (b * 256 * 256));
- return col;
+ col = (r + (g * 256) + (b * 256 * 256));
+ return col;
}
unsigned int rgb_to_cpack(float r, float g, float b)
{
- unsigned int ir, ig, ib;
+ unsigned int ir, ig, ib;
- ir = (unsigned int)floorf(255.0f * max_ff(r, 0.0f));
- ig = (unsigned int)floorf(255.0f * max_ff(g, 0.0f));
- ib = (unsigned int)floorf(255.0f * max_ff(b, 0.0f));
+ ir = (unsigned int)floorf(255.0f * max_ff(r, 0.0f));
+ ig = (unsigned int)floorf(255.0f * max_ff(g, 0.0f));
+ ib = (unsigned int)floorf(255.0f * max_ff(b, 0.0f));
- if (ir > 255) { ir = 255; }
- if (ig > 255) { ig = 255; }
- if (ib > 255) { ib = 255; }
+ if (ir > 255) {
+ ir = 255;
+ }
+ if (ig > 255) {
+ ig = 255;
+ }
+ if (ib > 255) {
+ ib = 255;
+ }
- return (ir + (ig * 256) + (ib * 256 * 256));
+ return (ir + (ig * 256) + (ib * 256 * 256));
}
void cpack_to_rgb(unsigned int col, float *r, float *g, float *b)
{
- *r = ((float)(((col) ) & 0xFF)) * (1.0f / 255.0f);
- *g = ((float)(((col) >> 8) & 0xFF)) * (1.0f / 255.0f);
- *b = ((float)(((col) >> 16) & 0xFF)) * (1.0f / 255.0f);
+ *r = ((float)(((col)) & 0xFF)) * (1.0f / 255.0f);
+ *g = ((float)(((col) >> 8) & 0xFF)) * (1.0f / 255.0f);
+ *b = ((float)(((col) >> 16) & 0xFF)) * (1.0f / 255.0f);
}
void rgb_uchar_to_float(float r_col[3], const unsigned char col_ub[3])
{
- r_col[0] = ((float)col_ub[0]) * (1.0f / 255.0f);
- r_col[1] = ((float)col_ub[1]) * (1.0f / 255.0f);
- r_col[2] = ((float)col_ub[2]) * (1.0f / 255.0f);
+ r_col[0] = ((float)col_ub[0]) * (1.0f / 255.0f);
+ r_col[1] = ((float)col_ub[1]) * (1.0f / 255.0f);
+ r_col[2] = ((float)col_ub[2]) * (1.0f / 255.0f);
}
void rgba_uchar_to_float(float r_col[4], const unsigned char col_ub[4])
{
- r_col[0] = ((float)col_ub[0]) * (1.0f / 255.0f);
- r_col[1] = ((float)col_ub[1]) * (1.0f / 255.0f);
- r_col[2] = ((float)col_ub[2]) * (1.0f / 255.0f);
- r_col[3] = ((float)col_ub[3]) * (1.0f / 255.0f);
+ r_col[0] = ((float)col_ub[0]) * (1.0f / 255.0f);
+ r_col[1] = ((float)col_ub[1]) * (1.0f / 255.0f);
+ r_col[2] = ((float)col_ub[2]) * (1.0f / 255.0f);
+ r_col[3] = ((float)col_ub[3]) * (1.0f / 255.0f);
}
void rgb_float_to_uchar(unsigned char r_col[3], const float col_f[3])
{
- unit_float_to_uchar_clamp_v3(r_col, col_f);
+ unit_float_to_uchar_clamp_v3(r_col, col_f);
}
void rgba_float_to_uchar(unsigned char r_col[4], const float col_f[4])
{
- unit_float_to_uchar_clamp_v4(r_col, col_f);
+ unit_float_to_uchar_clamp_v4(r_col, col_f);
}
/* ********************************* color transforms ********************************* */
-
float srgb_to_linearrgb(float c)
{
- if (c < 0.04045f) {
- return (c < 0.0f) ? 0.0f : c * (1.0f / 12.92f);
- }
- else {
- return powf((c + 0.055f) * (1.0f / 1.055f), 2.4f);
- }
+ if (c < 0.04045f) {
+ return (c < 0.0f) ? 0.0f : c * (1.0f / 12.92f);
+ }
+ else {
+ return powf((c + 0.055f) * (1.0f / 1.055f), 2.4f);
+ }
}
float linearrgb_to_srgb(float c)
{
- if (c < 0.0031308f) {
- return (c < 0.0f) ? 0.0f : c * 12.92f;
- }
- else {
- return 1.055f * powf(c, 1.0f / 2.4f) - 0.055f;
- }
+ if (c < 0.0031308f) {
+ return (c < 0.0f) ? 0.0f : c * 12.92f;
+ }
+ else {
+ return 1.055f * powf(c, 1.0f / 2.4f) - 0.055f;
+ }
}
void minmax_rgb(short c[3])
{
- if (c[0] > 255) {
- c[0] = 255;
- }
- else if (c[0] < 0) {
- c[0] = 0;
- }
+ if (c[0] > 255) {
+ c[0] = 255;
+ }
+ else if (c[0] < 0) {
+ c[0] = 0;
+ }
- if (c[1] > 255) {
- c[1] = 255;
- }
- else if (c[1] < 0) {
- c[1] = 0;
- }
+ if (c[1] > 255) {
+ c[1] = 255;
+ }
+ else if (c[1] < 0) {
+ c[1] = 0;
+ }
- if (c[2] > 255) {
- c[2] = 255;
- }
- else if (c[2] < 0) {
- c[2] = 0;
- }
+ if (c[2] > 255) {
+ c[2] = 255;
+ }
+ else if (c[2] < 0) {
+ c[2] = 0;
+ }
}
/* If the requested RGB shade contains a negative weight for
@@ -481,36 +483,37 @@ void minmax_rgb(short c[3])
* components were modified, zero otherwise.*/
int constrain_rgb(float *r, float *g, float *b)
{
- /* Amount of white needed */
- const float w = -min_ffff(0.0f, *r, *g, *b);
+ /* Amount of white needed */
+ const float w = -min_ffff(0.0f, *r, *g, *b);
- /* Add just enough white to make r, g, b all positive. */
- if (w > 0.0f) {
- *r += w;
- *g += w;
- *b += w;
+ /* Add just enough white to make r, g, b all positive. */
+ if (w > 0.0f) {
+ *r += w;
+ *g += w;
+ *b += w;
- return 1; /* Color modified to fit RGB gamut */
- }
+ return 1; /* Color modified to fit RGB gamut */
+ }
- return 0; /* Color within RGB gamut */
+ return 0; /* Color within RGB gamut */
}
/* ********************** lift/gamma/gain / ASC-CDL conversion ********************************* */
-void lift_gamma_gain_to_asc_cdl(float *lift, float *gamma, float *gain, float *offset, float *slope, float *power)
+void lift_gamma_gain_to_asc_cdl(
+ float *lift, float *gamma, float *gain, float *offset, float *slope, float *power)
{
- int c;
- for (c = 0; c < 3; c++) {
- offset[c] = lift[c] * gain[c];
- slope[c] = gain[c] * (1.0f - lift[c]);
- if (gamma[c] == 0) {
- power[c] = FLT_MAX;
- }
- else {
- power[c] = 1.0f / gamma[c];
- }
- }
+ int c;
+ for (c = 0; c < 3; c++) {
+ offset[c] = lift[c] * gain[c];
+ slope[c] = gain[c] * (1.0f - lift[c]);
+ if (gamma[c] == 0) {
+ power[c] = FLT_MAX;
+ }
+ else {
+ power[c] = 1.0f / gamma[c];
+ }
+ }
}
/* ************************************* other ************************************************* */
@@ -518,32 +521,31 @@ void lift_gamma_gain_to_asc_cdl(float *lift, float *gamma, float *gain, float *o
/* Applies an hue offset to a float rgb color */
void rgb_float_set_hue_float_offset(float rgb[3], float hue_offset)
{
- float hsv[3];
+ float hsv[3];
- rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv + 1, hsv + 2);
+ rgb_to_hsv(rgb[0], rgb[1], rgb[2], hsv, hsv + 1, hsv + 2);
- hsv[0] += hue_offset;
- if (hsv[0] > 1.0f) {
- hsv[0] -= 1.0f;
- }
- else if (hsv[0] < 0.0f) {
- hsv[0] += 1.0f;
- }
+ hsv[0] += hue_offset;
+ if (hsv[0] > 1.0f) {
+ hsv[0] -= 1.0f;
+ }
+ else if (hsv[0] < 0.0f) {
+ hsv[0] += 1.0f;
+ }
- hsv_to_rgb(hsv[0], hsv[1], hsv[2], rgb, rgb + 1, rgb + 2);
+ hsv_to_rgb(hsv[0], hsv[1], hsv[2], rgb, rgb + 1, rgb + 2);
}
/* Applies an hue offset to a byte rgb color */
void rgb_byte_set_hue_float_offset(unsigned char rgb[3], float hue_offset)
{
- float rgb_float[3];
+ float rgb_float[3];
- rgb_uchar_to_float(rgb_float, rgb);
- rgb_float_set_hue_float_offset(rgb_float, hue_offset);
- rgb_float_to_uchar(rgb, rgb_float);
+ rgb_uchar_to_float(rgb_float, rgb);
+ rgb_float_set_hue_float_offset(rgb_float, hue_offset);
+ rgb_float_to_uchar(rgb, rgb_float);
}
-
/* fast sRGB conversion
* LUT from linear float to 16-bit short
* based on http://mysite.verizon.net/spitzak/conversion/
@@ -554,83 +556,83 @@ unsigned short BLI_color_to_srgb_table[0x10000];
static unsigned short hipart(const float f)
{
- union {
- float f;
- unsigned short us[2];
- } tmp;
+ union {
+ float f;
+ unsigned short us[2];
+ } tmp;
- tmp.f = f;
+ tmp.f = f;
#ifdef __BIG_ENDIAN__
- return tmp.us[0];
+ return tmp.us[0];
#else
- return tmp.us[1];
+ return tmp.us[1];
#endif
}
static float index_to_float(const unsigned short i)
{
- union {
- float f;
- unsigned short us[2];
- } tmp;
+ union {
+ float f;
+ unsigned short us[2];
+ } tmp;
- /* positive and negative zeros, and all gradual underflow, turn into zero: */
- if (i < 0x80 || (i >= 0x8000 && i < 0x8080)) {
- return 0;
- }
- /* All NaN's and infinity turn into the largest possible legal float: */
- if (i >= 0x7f80 && i < 0x8000) {
- return FLT_MAX;
- }
- if (i >= 0xff80) {
- return -FLT_MAX;
- }
+ /* positive and negative zeros, and all gradual underflow, turn into zero: */
+ if (i < 0x80 || (i >= 0x8000 && i < 0x8080)) {
+ return 0;
+ }
+ /* All NaN's and infinity turn into the largest possible legal float: */
+ if (i >= 0x7f80 && i < 0x8000) {
+ return FLT_MAX;
+ }
+ if (i >= 0xff80) {
+ return -FLT_MAX;
+ }
#ifdef __BIG_ENDIAN__
- tmp.us[0] = i;
- tmp.us[1] = 0x8000;
+ tmp.us[0] = i;
+ tmp.us[1] = 0x8000;
#else
- tmp.us[0] = 0x8000;
- tmp.us[1] = i;
+ tmp.us[0] = 0x8000;
+ tmp.us[1] = i;
#endif
- return tmp.f;
+ return tmp.f;
}
void BLI_init_srgb_conversion(void)
{
- static bool initialized = false;
- unsigned int i, b;
-
- if (initialized) {
- return;
- }
- initialized = true;
-
- /* Fill in the lookup table to convert floats to bytes: */
- for (i = 0; i < 0x10000; i++) {
- float f = linearrgb_to_srgb(index_to_float((unsigned short)i)) * 255.0f;
- if (f <= 0) {
- BLI_color_to_srgb_table[i] = 0;
- }
- else if (f < 255) {
- BLI_color_to_srgb_table[i] = (unsigned short) (f * 0x100 + 0.5f);
- }
- else {
- BLI_color_to_srgb_table[i] = 0xff00;
- }
- }
-
- /* Fill in the lookup table to convert bytes to float: */
- for (b = 0; b <= 255; b++) {
- float f = srgb_to_linearrgb(((float)b) * (1.0f / 255.0f));
- BLI_color_from_srgb_table[b] = f;
- i = hipart(f);
- /* replace entries so byte->float->byte does not change the data: */
- BLI_color_to_srgb_table[i] = (unsigned short)(b * 0x100);
- }
+ static bool initialized = false;
+ unsigned int i, b;
+
+ if (initialized) {
+ return;
+ }
+ initialized = true;
+
+ /* Fill in the lookup table to convert floats to bytes: */
+ for (i = 0; i < 0x10000; i++) {
+ float f = linearrgb_to_srgb(index_to_float((unsigned short)i)) * 255.0f;
+ if (f <= 0) {
+ BLI_color_to_srgb_table[i] = 0;
+ }
+ else if (f < 255) {
+ BLI_color_to_srgb_table[i] = (unsigned short)(f * 0x100 + 0.5f);
+ }
+ else {
+ BLI_color_to_srgb_table[i] = 0xff00;
+ }
+ }
+
+ /* Fill in the lookup table to convert bytes to float: */
+ for (b = 0; b <= 255; b++) {
+ float f = srgb_to_linearrgb(((float)b) * (1.0f / 255.0f));
+ BLI_color_from_srgb_table[b] = f;
+ i = hipart(f);
+ /* replace entries so byte->float->byte does not change the data: */
+ BLI_color_to_srgb_table[i] = (unsigned short)(b * 0x100);
+ }
}
/* ****************************** blackbody ******************************** */
@@ -642,71 +644,70 @@ void BLI_init_srgb_conversion(void)
*/
static const float blackbody_table_r[6][3] = {
- { 2.52432244e+03f, -1.06185848e-03f, 3.11067539e+00f },
- { 3.37763626e+03f, -4.34581697e-04f, 1.64843306e+00f },
- { 4.10671449e+03f, -8.61949938e-05f, 6.41423749e-01f },
- { 4.66849800e+03f, 2.85655028e-05f, 1.29075375e-01f },
- { 4.60124770e+03f, 2.89727618e-05f, 1.48001316e-01f },
- { 3.78765709e+03f, 9.36026367e-06f, 3.98995841e-01f },
+ {2.52432244e+03f, -1.06185848e-03f, 3.11067539e+00f},
+ {3.37763626e+03f, -4.34581697e-04f, 1.64843306e+00f},
+ {4.10671449e+03f, -8.61949938e-05f, 6.41423749e-01f},
+ {4.66849800e+03f, 2.85655028e-05f, 1.29075375e-01f},
+ {4.60124770e+03f, 2.89727618e-05f, 1.48001316e-01f},
+ {3.78765709e+03f, 9.36026367e-06f, 3.98995841e-01f},
};
static const float blackbody_table_g[6][3] = {
- { -7.50343014e+02f, 3.15679613e-04f, 4.73464526e-01f },
- { -1.00402363e+03f, 1.29189794e-04f, 9.08181524e-01f },
- { -1.22075471e+03f, 2.56245413e-05f, 1.20753416e+00f },
- { -1.42546105e+03f, -4.01730887e-05f, 1.44002695e+00f },
- { -1.18134453e+03f, -2.18913373e-05f, 1.30656109e+00f },
- { -5.00279505e+02f, -4.59745390e-06f, 1.09090465e+00f },
+ {-7.50343014e+02f, 3.15679613e-04f, 4.73464526e-01f},
+ {-1.00402363e+03f, 1.29189794e-04f, 9.08181524e-01f},
+ {-1.22075471e+03f, 2.56245413e-05f, 1.20753416e+00f},
+ {-1.42546105e+03f, -4.01730887e-05f, 1.44002695e+00f},
+ {-1.18134453e+03f, -2.18913373e-05f, 1.30656109e+00f},
+ {-5.00279505e+02f, -4.59745390e-06f, 1.09090465e+00f},
};
static const float blackbody_table_b[6][4] = {
- { 0.0f, 0.0f, 0.0f, 0.0f },
- { 0.0f, 0.0f, 0.0f, 0.0f },
- { 0.0f, 0.0f, 0.0f, 0.0f },
- { -2.02524603e-11f, 1.79435860e-07f, -2.60561875e-04f, -1.41761141e-02f },
- { -2.22463426e-13f, -1.55078698e-08f, 3.81675160e-04f, -7.30646033e-01f },
- { 6.72595954e-13f, -2.73059993e-08f, 4.24068546e-04f, -7.52204323e-01f },
+ {0.0f, 0.0f, 0.0f, 0.0f},
+ {0.0f, 0.0f, 0.0f, 0.0f},
+ {0.0f, 0.0f, 0.0f, 0.0f},
+ {-2.02524603e-11f, 1.79435860e-07f, -2.60561875e-04f, -1.41761141e-02f},
+ {-2.22463426e-13f, -1.55078698e-08f, 3.81675160e-04f, -7.30646033e-01f},
+ {6.72595954e-13f, -2.73059993e-08f, 4.24068546e-04f, -7.52204323e-01f},
};
static void blackbody_temperature_to_rgb(float rgb[3], float t)
{
- if (t >= 12000.0f) {
- rgb[0] = 0.826270103f;
- rgb[1] = 0.994478524f;
- rgb[2] = 1.56626022f;
- }
- else if (t < 965.0f) {
- rgb[0] = 4.70366907f;
- rgb[1] = 0.0f;
- rgb[2] = 0.0f;
- }
- else {
- int i = (t >= 6365.0f) ? 5 :
- (t >= 3315.0f) ? 4 :
- (t >= 1902.0f) ? 3 :
- (t >= 1449.0f) ? 2 :
- (t >= 1167.0f) ? 1 : 0;
-
- const float *r = blackbody_table_r[i];
- const float *g = blackbody_table_g[i];
- const float *b = blackbody_table_b[i];
-
- const float t_inv = 1.0f / t;
- rgb[0] = r[0] * t_inv + r[1] * t + r[2];
- rgb[1] = g[0] * t_inv + g[1] * t + g[2];
- rgb[2] = ((b[0] * t + b[1]) * t + b[2]) * t + b[3];
- }
+ if (t >= 12000.0f) {
+ rgb[0] = 0.826270103f;
+ rgb[1] = 0.994478524f;
+ rgb[2] = 1.56626022f;
+ }
+ else if (t < 965.0f) {
+ rgb[0] = 4.70366907f;
+ rgb[1] = 0.0f;
+ rgb[2] = 0.0f;
+ }
+ else {
+ int i = (t >= 6365.0f) ?
+ 5 :
+ (t >= 3315.0f) ? 4 :
+ (t >= 1902.0f) ? 3 : (t >= 1449.0f) ? 2 : (t >= 1167.0f) ? 1 : 0;
+
+ const float *r = blackbody_table_r[i];
+ const float *g = blackbody_table_g[i];
+ const float *b = blackbody_table_b[i];
+
+ const float t_inv = 1.0f / t;
+ rgb[0] = r[0] * t_inv + r[1] * t + r[2];
+ rgb[1] = g[0] * t_inv + g[1] * t + g[2];
+ rgb[2] = ((b[0] * t + b[1]) * t + b[2]) * t + b[3];
+ }
}
void blackbody_temperature_to_rgb_table(float *r_table, int width, float min, float max)
{
- for (int i = 0; i < width; i++) {
- float temperature = min + (max - min) / (float)width * (float)i;
+ for (int i = 0; i < width; i++) {
+ float temperature = min + (max - min) / (float)width * (float)i;
- float rgb[3];
- blackbody_temperature_to_rgb(rgb, temperature);
+ float rgb[3];
+ blackbody_temperature_to_rgb(rgb, temperature);
- copy_v3_v3(&r_table[i * 4], rgb);
- r_table[i * 4 + 3] = 0.0f;
- }
+ copy_v3_v3(&r_table[i * 4], rgb);
+ r_table[i * 4 + 3] = 0.0f;
+ }
}
diff --git a/source/blender/blenlib/intern/math_color_blend_inline.c b/source/blender/blenlib/intern/math_color_blend_inline.c
index f3e6ff8b110..7241779b32a 100644
--- a/source/blender/blenlib/intern/math_color_blend_inline.c
+++ b/source/blender/blenlib/intern/math_color_blend_inline.c
@@ -31,11 +31,11 @@
#include "BLI_utildefines.h"
#ifndef __MATH_COLOR_BLEND_INLINE_C__
-#define __MATH_COLOR_BLEND_INLINE_C__
+# define __MATH_COLOR_BLEND_INLINE_C__
/* don't add any saturation to a completely black and white image */
-#define EPS_SATURATION 0.0005f
-#define EPS_ALPHA 0.0005f
+# define EPS_SATURATION 0.0005f
+# define EPS_ALPHA 0.0005f
/***************************** Color Blending ********************************
*
@@ -49,1123 +49,1154 @@
/* straight alpha byte blending modes */
-MINLINE void blend_color_mix_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4])
+MINLINE void blend_color_mix_byte(unsigned char dst[4],
+ const unsigned char src1[4],
+ const unsigned char src2[4])
{
- if (src2[3] != 0) {
- /* straight over operation */
- const int t = src2[3];
- const int mt = 255 - t;
- int tmp[4];
-
- tmp[0] = (mt * src1[3] * src1[0]) + (t * 255 * src2[0]);
- tmp[1] = (mt * src1[3] * src1[1]) + (t * 255 * src2[1]);
- tmp[2] = (mt * src1[3] * src1[2]) + (t * 255 * src2[2]);
- tmp[3] = (mt * src1[3]) + (t * 255);
-
- dst[0] = (unsigned char)divide_round_i(tmp[0], tmp[3]);
- dst[1] = (unsigned char)divide_round_i(tmp[1], tmp[3]);
- dst[2] = (unsigned char)divide_round_i(tmp[2], tmp[3]);
- dst[3] = (unsigned char)divide_round_i(tmp[3], 255);
- }
- else {
- /* no op */
- copy_v4_v4_uchar(dst, src1);
- }
+ if (src2[3] != 0) {
+ /* straight over operation */
+ const int t = src2[3];
+ const int mt = 255 - t;
+ int tmp[4];
+
+ tmp[0] = (mt * src1[3] * src1[0]) + (t * 255 * src2[0]);
+ tmp[1] = (mt * src1[3] * src1[1]) + (t * 255 * src2[1]);
+ tmp[2] = (mt * src1[3] * src1[2]) + (t * 255 * src2[2]);
+ tmp[3] = (mt * src1[3]) + (t * 255);
+
+ dst[0] = (unsigned char)divide_round_i(tmp[0], tmp[3]);
+ dst[1] = (unsigned char)divide_round_i(tmp[1], tmp[3]);
+ dst[2] = (unsigned char)divide_round_i(tmp[2], tmp[3]);
+ dst[3] = (unsigned char)divide_round_i(tmp[3], 255);
+ }
+ else {
+ /* no op */
+ copy_v4_v4_uchar(dst, src1);
+ }
}
-MINLINE void blend_color_add_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4])
+MINLINE void blend_color_add_byte(unsigned char dst[4],
+ const unsigned char src1[4],
+ const unsigned char src2[4])
{
- if (src2[3] != 0) {
- /* straight add operation */
- const int t = src2[3];
- int tmp[3];
-
- tmp[0] = (src1[0] * 255) + (src2[0] * t);
- tmp[1] = (src1[1] * 255) + (src2[1] * t);
- tmp[2] = (src1[2] * 255) + (src2[2] * t);
-
- dst[0] = (unsigned char)min_ii(divide_round_i(tmp[0], 255), 255);
- dst[1] = (unsigned char)min_ii(divide_round_i(tmp[1], 255), 255);
- dst[2] = (unsigned char)min_ii(divide_round_i(tmp[2], 255), 255);
- dst[3] = src1[3];
- }
- else {
- /* no op */
- copy_v4_v4_uchar(dst, src1);
- }
+ if (src2[3] != 0) {
+ /* straight add operation */
+ const int t = src2[3];
+ int tmp[3];
+
+ tmp[0] = (src1[0] * 255) + (src2[0] * t);
+ tmp[1] = (src1[1] * 255) + (src2[1] * t);
+ tmp[2] = (src1[2] * 255) + (src2[2] * t);
+
+ dst[0] = (unsigned char)min_ii(divide_round_i(tmp[0], 255), 255);
+ dst[1] = (unsigned char)min_ii(divide_round_i(tmp[1], 255), 255);
+ dst[2] = (unsigned char)min_ii(divide_round_i(tmp[2], 255), 255);
+ dst[3] = src1[3];
+ }
+ else {
+ /* no op */
+ copy_v4_v4_uchar(dst, src1);
+ }
}
-MINLINE void blend_color_sub_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4])
+MINLINE void blend_color_sub_byte(unsigned char dst[4],
+ const unsigned char src1[4],
+ const unsigned char src2[4])
{
- if (src2[3] != 0) {
- /* straight sub operation */
- const int t = src2[3];
- int tmp[3];
-
- tmp[0] = (src1[0] * 255) - (src2[0] * t);
- tmp[1] = (src1[1] * 255) - (src2[1] * t);
- tmp[2] = (src1[2] * 255) - (src2[2] * t);
-
- dst[0] = (unsigned char)max_ii(divide_round_i(tmp[0], 255), 0);
- dst[1] = (unsigned char)max_ii(divide_round_i(tmp[1], 255), 0);
- dst[2] = (unsigned char)max_ii(divide_round_i(tmp[2], 255), 0);
- dst[3] = src1[3];
- }
- else {
- /* no op */
- copy_v4_v4_uchar(dst, src1);
- }
+ if (src2[3] != 0) {
+ /* straight sub operation */
+ const int t = src2[3];
+ int tmp[3];
+
+ tmp[0] = (src1[0] * 255) - (src2[0] * t);
+ tmp[1] = (src1[1] * 255) - (src2[1] * t);
+ tmp[2] = (src1[2] * 255) - (src2[2] * t);
+
+ dst[0] = (unsigned char)max_ii(divide_round_i(tmp[0], 255), 0);
+ dst[1] = (unsigned char)max_ii(divide_round_i(tmp[1], 255), 0);
+ dst[2] = (unsigned char)max_ii(divide_round_i(tmp[2], 255), 0);
+ dst[3] = src1[3];
+ }
+ else {
+ /* no op */
+ copy_v4_v4_uchar(dst, src1);
+ }
}
-MINLINE void blend_color_mul_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4])
+MINLINE void blend_color_mul_byte(unsigned char dst[4],
+ const unsigned char src1[4],
+ const unsigned char src2[4])
{
- if (src2[3] != 0) {
- /* straight multiply operation */
- const int t = src2[3];
- const int mt = 255 - t;
- int tmp[3];
-
- tmp[0] = (mt * src1[0] * 255) + (t * src1[0] * src2[0]);
- tmp[1] = (mt * src1[1] * 255) + (t * src1[1] * src2[1]);
- tmp[2] = (mt * src1[2] * 255) + (t * src1[2] * src2[2]);
-
- dst[0] = (unsigned char)divide_round_i(tmp[0], 255 * 255);
- dst[1] = (unsigned char)divide_round_i(tmp[1], 255 * 255);
- dst[2] = (unsigned char)divide_round_i(tmp[2], 255 * 255);
- dst[3] = src1[3];
- }
- else {
- /* no op */
- copy_v4_v4_uchar(dst, src1);
- }
+ if (src2[3] != 0) {
+ /* straight multiply operation */
+ const int t = src2[3];
+ const int mt = 255 - t;
+ int tmp[3];
+
+ tmp[0] = (mt * src1[0] * 255) + (t * src1[0] * src2[0]);
+ tmp[1] = (mt * src1[1] * 255) + (t * src1[1] * src2[1]);
+ tmp[2] = (mt * src1[2] * 255) + (t * src1[2] * src2[2]);
+
+ dst[0] = (unsigned char)divide_round_i(tmp[0], 255 * 255);
+ dst[1] = (unsigned char)divide_round_i(tmp[1], 255 * 255);
+ dst[2] = (unsigned char)divide_round_i(tmp[2], 255 * 255);
+ dst[3] = src1[3];
+ }
+ else {
+ /* no op */
+ copy_v4_v4_uchar(dst, src1);
+ }
}
-MINLINE void blend_color_lighten_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4])
+MINLINE void blend_color_lighten_byte(unsigned char dst[4],
+ const unsigned char src1[4],
+ const unsigned char src2[4])
{
- if (src2[3] != 0) {
- /* straight lighten operation */
- const int t = src2[3];
- const int mt = 255 - t;
- int tmp[3];
-
- tmp[0] = (mt * src1[0]) + (t * max_ii(src1[0], src2[0]));
- tmp[1] = (mt * src1[1]) + (t * max_ii(src1[1], src2[1]));
- tmp[2] = (mt * src1[2]) + (t * max_ii(src1[2], src2[2]));
-
- dst[0] = (unsigned char)divide_round_i(tmp[0], 255);
- dst[1] = (unsigned char)divide_round_i(tmp[1], 255);
- dst[2] = (unsigned char)divide_round_i(tmp[2], 255);
- dst[3] = src1[3];
- }
- else {
- /* no op */
- copy_v4_v4_uchar(dst, src1);
- }
+ if (src2[3] != 0) {
+ /* straight lighten operation */
+ const int t = src2[3];
+ const int mt = 255 - t;
+ int tmp[3];
+
+ tmp[0] = (mt * src1[0]) + (t * max_ii(src1[0], src2[0]));
+ tmp[1] = (mt * src1[1]) + (t * max_ii(src1[1], src2[1]));
+ tmp[2] = (mt * src1[2]) + (t * max_ii(src1[2], src2[2]));
+
+ dst[0] = (unsigned char)divide_round_i(tmp[0], 255);
+ dst[1] = (unsigned char)divide_round_i(tmp[1], 255);
+ dst[2] = (unsigned char)divide_round_i(tmp[2], 255);
+ dst[3] = src1[3];
+ }
+ else {
+ /* no op */
+ copy_v4_v4_uchar(dst, src1);
+ }
}
-MINLINE void blend_color_darken_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4])
+MINLINE void blend_color_darken_byte(unsigned char dst[4],
+ const unsigned char src1[4],
+ const unsigned char src2[4])
{
- if (src2[3] != 0) {
- /* straight darken operation */
- const int t = src2[3];
- const int mt = 255 - t;
- int tmp[3];
-
- tmp[0] = (mt * src1[0]) + (t * min_ii(src1[0], src2[0]));
- tmp[1] = (mt * src1[1]) + (t * min_ii(src1[1], src2[1]));
- tmp[2] = (mt * src1[2]) + (t * min_ii(src1[2], src2[2]));
-
- dst[0] = (unsigned char)divide_round_i(tmp[0], 255);
- dst[1] = (unsigned char)divide_round_i(tmp[1], 255);
- dst[2] = (unsigned char)divide_round_i(tmp[2], 255);
- dst[3] = src1[3];
- }
- else {
- /* no op */
- copy_v4_v4_uchar(dst, src1);
- }
+ if (src2[3] != 0) {
+ /* straight darken operation */
+ const int t = src2[3];
+ const int mt = 255 - t;
+ int tmp[3];
+
+ tmp[0] = (mt * src1[0]) + (t * min_ii(src1[0], src2[0]));
+ tmp[1] = (mt * src1[1]) + (t * min_ii(src1[1], src2[1]));
+ tmp[2] = (mt * src1[2]) + (t * min_ii(src1[2], src2[2]));
+
+ dst[0] = (unsigned char)divide_round_i(tmp[0], 255);
+ dst[1] = (unsigned char)divide_round_i(tmp[1], 255);
+ dst[2] = (unsigned char)divide_round_i(tmp[2], 255);
+ dst[3] = src1[3];
+ }
+ else {
+ /* no op */
+ copy_v4_v4_uchar(dst, src1);
+ }
}
-MINLINE void blend_color_erase_alpha_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4])
+MINLINE void blend_color_erase_alpha_byte(unsigned char dst[4],
+ const unsigned char src1[4],
+ const unsigned char src2[4])
{
- if (src2[3] != 0) {
- /* straight so just modify alpha channel */
- const int t = src2[3];
-
- dst[0] = src1[0];
- dst[1] = src1[1];
- dst[2] = src1[2];
- dst[3] = (unsigned char)max_ii(src1[3] - divide_round_i(t * src2[3], 255), 0);
- }
- else {
- /* no op */
- copy_v4_v4_uchar(dst, src1);
- }
+ if (src2[3] != 0) {
+ /* straight so just modify alpha channel */
+ const int t = src2[3];
+
+ dst[0] = src1[0];
+ dst[1] = src1[1];
+ dst[2] = src1[2];
+ dst[3] = (unsigned char)max_ii(src1[3] - divide_round_i(t * src2[3], 255), 0);
+ }
+ else {
+ /* no op */
+ copy_v4_v4_uchar(dst, src1);
+ }
}
-MINLINE void blend_color_add_alpha_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4])
+MINLINE void blend_color_add_alpha_byte(unsigned char dst[4],
+ const unsigned char src1[4],
+ const unsigned char src2[4])
{
- if (src2[3] != 0) {
- /* straight so just modify alpha channel */
- const int t = src2[3];
-
- dst[0] = src1[0];
- dst[1] = src1[1];
- dst[2] = src1[2];
- dst[3] = (unsigned char)min_ii(src1[3] + divide_round_i(t * src2[3], 255), 255);
- }
- else {
- /* no op */
- copy_v4_v4_uchar(dst, src1);
- }
+ if (src2[3] != 0) {
+ /* straight so just modify alpha channel */
+ const int t = src2[3];
+
+ dst[0] = src1[0];
+ dst[1] = src1[1];
+ dst[2] = src1[2];
+ dst[3] = (unsigned char)min_ii(src1[3] + divide_round_i(t * src2[3], 255), 255);
+ }
+ else {
+ /* no op */
+ copy_v4_v4_uchar(dst, src1);
+ }
}
-MINLINE void blend_color_overlay_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4])
+MINLINE void blend_color_overlay_byte(unsigned char dst[4],
+ unsigned const char src1[4],
+ unsigned const char src2[4])
{
- const int fac = (int)src2[3];
- if (fac != 0) {
- const int mfac = 255 - fac;
- int i = 3;
-
- while (i--) {
- int temp;
-
- if (src1[i] > 127) {
- temp = 255 - ((255 - 2 * (src1[i] - 127)) * (255 - src2[i]) / 255);
- }
- else {
- temp = (2 * src1[i] * src2[i]) >> 8;
- }
- dst[i] = (unsigned char)min_ii((temp * fac + src1[i] * mfac) / 255, 255);
- }
- }
- else {
- /* no op */
- copy_v4_v4_uchar(dst, src1);
- }
+ const int fac = (int)src2[3];
+ if (fac != 0) {
+ const int mfac = 255 - fac;
+ int i = 3;
+
+ while (i--) {
+ int temp;
+
+ if (src1[i] > 127) {
+ temp = 255 - ((255 - 2 * (src1[i] - 127)) * (255 - src2[i]) / 255);
+ }
+ else {
+ temp = (2 * src1[i] * src2[i]) >> 8;
+ }
+ dst[i] = (unsigned char)min_ii((temp * fac + src1[i] * mfac) / 255, 255);
+ }
+ }
+ else {
+ /* no op */
+ copy_v4_v4_uchar(dst, src1);
+ }
}
-
-MINLINE void blend_color_hardlight_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4])
+MINLINE void blend_color_hardlight_byte(unsigned char dst[4],
+ unsigned const char src1[4],
+ unsigned const char src2[4])
{
- const int fac = (int)src2[3];
- if (fac != 0) {
- const int mfac = 255 - fac;
- int i = 3;
-
- while (i--) {
- int temp;
-
- if (src2[i] > 127) {
- temp = 255 - ((255 - 2 * (src2[i] - 127)) * (255 - src1[i]) / 255);
- }
- else {
- temp = (2 * src2[i] * src1[i]) >> 8;
- }
- dst[i] = (unsigned char)min_ii((temp * fac + src1[i] * mfac) / 255, 255);
- }
- }
- else {
- /* no op */
- copy_v4_v4_uchar(dst, src1);
- }
+ const int fac = (int)src2[3];
+ if (fac != 0) {
+ const int mfac = 255 - fac;
+ int i = 3;
+
+ while (i--) {
+ int temp;
+
+ if (src2[i] > 127) {
+ temp = 255 - ((255 - 2 * (src2[i] - 127)) * (255 - src1[i]) / 255);
+ }
+ else {
+ temp = (2 * src2[i] * src1[i]) >> 8;
+ }
+ dst[i] = (unsigned char)min_ii((temp * fac + src1[i] * mfac) / 255, 255);
+ }
+ }
+ else {
+ /* no op */
+ copy_v4_v4_uchar(dst, src1);
+ }
}
-
-MINLINE void blend_color_burn_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4])
+MINLINE void blend_color_burn_byte(unsigned char dst[4],
+ unsigned const char src1[4],
+ unsigned const char src2[4])
{
- const int fac = src2[3];
- if (fac != 0) {
- const int mfac = 255 - fac;
- int i = 3;
-
- while (i--) {
- const int temp = (src2[i] == 0) ? 0 : max_ii(255 - ((255 - src1[i]) * 255) / src2[i], 0);
- dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255);
- }
- }
- else {
- /* no op */
- copy_v4_v4_uchar(dst, src1);
- }
+ const int fac = src2[3];
+ if (fac != 0) {
+ const int mfac = 255 - fac;
+ int i = 3;
+
+ while (i--) {
+ const int temp = (src2[i] == 0) ? 0 : max_ii(255 - ((255 - src1[i]) * 255) / src2[i], 0);
+ dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255);
+ }
+ }
+ else {
+ /* no op */
+ copy_v4_v4_uchar(dst, src1);
+ }
}
-
-MINLINE void blend_color_linearburn_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4])
+MINLINE void blend_color_linearburn_byte(unsigned char dst[4],
+ unsigned const char src1[4],
+ unsigned const char src2[4])
{
- const int fac = src2[3];
- if (fac != 0) {
- const int mfac = 255 - fac;
- int i = 3;
-
- while (i--) {
- const int temp = max_ii(src1[i] + src2[i] - 255, 0);
- dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255);
- }
- }
- else {
- /* no op */
- copy_v4_v4_uchar(dst, src1);
- }
+ const int fac = src2[3];
+ if (fac != 0) {
+ const int mfac = 255 - fac;
+ int i = 3;
+
+ while (i--) {
+ const int temp = max_ii(src1[i] + src2[i] - 255, 0);
+ dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255);
+ }
+ }
+ else {
+ /* no op */
+ copy_v4_v4_uchar(dst, src1);
+ }
}
-
-MINLINE void blend_color_dodge_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4])
+MINLINE void blend_color_dodge_byte(unsigned char dst[4],
+ unsigned const char src1[4],
+ unsigned const char src2[4])
{
- const int fac = src2[3];
- if (fac != 0) {
- const int mfac = 255 - fac;
- int i = 3;
-
- while (i--) {
- const int temp = (src2[i] == 255) ? 255 : min_ii((src1[i] * 255) / (255 - src2[i]), 255);
- dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255);
- }
- }
- else {
- /* no op */
- copy_v4_v4_uchar(dst, src1);
- }
+ const int fac = src2[3];
+ if (fac != 0) {
+ const int mfac = 255 - fac;
+ int i = 3;
+
+ while (i--) {
+ const int temp = (src2[i] == 255) ? 255 : min_ii((src1[i] * 255) / (255 - src2[i]), 255);
+ dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255);
+ }
+ }
+ else {
+ /* no op */
+ copy_v4_v4_uchar(dst, src1);
+ }
}
-MINLINE void blend_color_screen_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4])
+MINLINE void blend_color_screen_byte(unsigned char dst[4],
+ unsigned const char src1[4],
+ unsigned const char src2[4])
{
- const int fac = src2[3];
- if (fac != 0) {
- const int mfac = 255 - fac;
- int i = 3;
-
- while (i--) {
- const int temp = max_ii(255 - (((255 - src1[i]) * (255 - src2[i])) / 255), 0);
- dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255);
- }
- }
- else {
- /* no op */
- copy_v4_v4_uchar(dst, src1);
- }
+ const int fac = src2[3];
+ if (fac != 0) {
+ const int mfac = 255 - fac;
+ int i = 3;
+
+ while (i--) {
+ const int temp = max_ii(255 - (((255 - src1[i]) * (255 - src2[i])) / 255), 0);
+ dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255);
+ }
+ }
+ else {
+ /* no op */
+ copy_v4_v4_uchar(dst, src1);
+ }
}
-
-MINLINE void blend_color_softlight_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4])
+MINLINE void blend_color_softlight_byte(unsigned char dst[4],
+ unsigned const char src1[4],
+ unsigned const char src2[4])
{
- const int fac = src2[3];
- if (fac != 0) {
- const int mfac = 255 - fac;
- int i = 3;
-
- while (i--) {
- int temp;
-
- if (src1[i] < 127) {
- temp = ((2 * ((src2[i] / 2) + 64)) * src1[i]) / 255;
- }
- else {
- temp = 255 - (2 * (255 - ((src2[i] / 2) + 64)) * (255 - src1[i]) / 255);
- }
- dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255);
- }
- }
- else {
- /* no op */
- copy_v4_v4_uchar(dst, src1);
- }
+ const int fac = src2[3];
+ if (fac != 0) {
+ const int mfac = 255 - fac;
+ int i = 3;
+
+ while (i--) {
+ int temp;
+
+ if (src1[i] < 127) {
+ temp = ((2 * ((src2[i] / 2) + 64)) * src1[i]) / 255;
+ }
+ else {
+ temp = 255 - (2 * (255 - ((src2[i] / 2) + 64)) * (255 - src1[i]) / 255);
+ }
+ dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255);
+ }
+ }
+ else {
+ /* no op */
+ copy_v4_v4_uchar(dst, src1);
+ }
}
-
-MINLINE void blend_color_pinlight_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4])
+MINLINE void blend_color_pinlight_byte(unsigned char dst[4],
+ unsigned const char src1[4],
+ unsigned const char src2[4])
{
- const int fac = src2[3];
- if (fac != 0) {
- const int mfac = 255 - fac;
- int i = 3;
-
- while (i--) {
- int temp;
-
- if (src2[i] > 127) {
- temp = max_ii(2 * (src2[i] - 127), src1[i]);
- }
- else {
- temp = min_ii(2 * src2[i], src1[i]);
- }
- dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255);
- }
- }
- else {
- /* no op */
- copy_v4_v4_uchar(dst, src1);
- }
+ const int fac = src2[3];
+ if (fac != 0) {
+ const int mfac = 255 - fac;
+ int i = 3;
+
+ while (i--) {
+ int temp;
+
+ if (src2[i] > 127) {
+ temp = max_ii(2 * (src2[i] - 127), src1[i]);
+ }
+ else {
+ temp = min_ii(2 * src2[i], src1[i]);
+ }
+ dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255);
+ }
+ }
+ else {
+ /* no op */
+ copy_v4_v4_uchar(dst, src1);
+ }
}
-
-MINLINE void blend_color_linearlight_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4])
+MINLINE void blend_color_linearlight_byte(unsigned char dst[4],
+ unsigned const char src1[4],
+ unsigned const char src2[4])
{
- const int fac = src2[3];
- if (fac != 0) {
- const int mfac = 255 - fac;
- int i = 3;
-
- while (i--) {
- int temp;
-
- if (src2[i] > 127) {
- temp = min_ii(src1[i] + 2 * (src2[i] - 127), 255);
- }
- else {
- temp = max_ii(src1[i] + 2 * src2[i] - 255, 0);
- }
- dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255);
- }
- }
- else {
- /* no op */
- copy_v4_v4_uchar(dst, src1);
- }
+ const int fac = src2[3];
+ if (fac != 0) {
+ const int mfac = 255 - fac;
+ int i = 3;
+
+ while (i--) {
+ int temp;
+
+ if (src2[i] > 127) {
+ temp = min_ii(src1[i] + 2 * (src2[i] - 127), 255);
+ }
+ else {
+ temp = max_ii(src1[i] + 2 * src2[i] - 255, 0);
+ }
+ dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255);
+ }
+ }
+ else {
+ /* no op */
+ copy_v4_v4_uchar(dst, src1);
+ }
}
-
-MINLINE void blend_color_vividlight_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4])
+MINLINE void blend_color_vividlight_byte(unsigned char dst[4],
+ unsigned const char src1[4],
+ unsigned const char src2[4])
{
- const int fac = src2[3];
- if (fac != 0) {
- const int mfac = 255 - fac;
- int i = 3;
-
- while (i--) {
- int temp;
-
- if (src2[i] == 255) {
- temp = (src1[i] == 0) ? 127 : 255;
- }
- else if (src2[i] == 0) {
- temp = (src1[i] == 255) ? 127 : 0;
- }
- else if (src2[i] > 127) {
- temp = min_ii(((src1[i]) * 255) / (2 * (255 - src2[i])), 255);
- }
- else {
- temp = max_ii(255 - ((255 - src1[i]) * 255 / (2 * src2[i])), 0);
- }
- dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255);
- }
- }
- else {
- /* no op */
- copy_v4_v4_uchar(dst, src1);
- }
+ const int fac = src2[3];
+ if (fac != 0) {
+ const int mfac = 255 - fac;
+ int i = 3;
+
+ while (i--) {
+ int temp;
+
+ if (src2[i] == 255) {
+ temp = (src1[i] == 0) ? 127 : 255;
+ }
+ else if (src2[i] == 0) {
+ temp = (src1[i] == 255) ? 127 : 0;
+ }
+ else if (src2[i] > 127) {
+ temp = min_ii(((src1[i]) * 255) / (2 * (255 - src2[i])), 255);
+ }
+ else {
+ temp = max_ii(255 - ((255 - src1[i]) * 255 / (2 * src2[i])), 0);
+ }
+ dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255);
+ }
+ }
+ else {
+ /* no op */
+ copy_v4_v4_uchar(dst, src1);
+ }
}
-
-
-MINLINE void blend_color_difference_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4])
+MINLINE void blend_color_difference_byte(unsigned char dst[4],
+ unsigned const char src1[4],
+ unsigned const char src2[4])
{
- const int fac = src2[3];
- if (fac != 0) {
- const int mfac = 255 - fac;
- int i = 3;
-
- while (i--) {
- const int temp = abs(src1[i] - src2[i]);
- dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255);
- }
- }
- else {
- /* no op */
- copy_v4_v4_uchar(dst, src1);
- }
+ const int fac = src2[3];
+ if (fac != 0) {
+ const int mfac = 255 - fac;
+ int i = 3;
+
+ while (i--) {
+ const int temp = abs(src1[i] - src2[i]);
+ dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255);
+ }
+ }
+ else {
+ /* no op */
+ copy_v4_v4_uchar(dst, src1);
+ }
}
-
-MINLINE void blend_color_exclusion_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4])
+MINLINE void blend_color_exclusion_byte(unsigned char dst[4],
+ unsigned const char src1[4],
+ unsigned const char src2[4])
{
- const int fac = src2[3];
- if (fac != 0) {
- const int mfac = 255 - fac;
- int i = 3;
-
- while (i--) {
- const int temp = 127 - ((2 * (src1[i] - 127) * (src2[i] - 127)) / 255);
- dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255);
- }
- }
- else {
- /* no op */
- copy_v4_v4_uchar(dst, src1);
- }
+ const int fac = src2[3];
+ if (fac != 0) {
+ const int mfac = 255 - fac;
+ int i = 3;
+
+ while (i--) {
+ const int temp = 127 - ((2 * (src1[i] - 127) * (src2[i] - 127)) / 255);
+ dst[i] = (unsigned char)((temp * fac + src1[i] * mfac) / 255);
+ }
+ }
+ else {
+ /* no op */
+ copy_v4_v4_uchar(dst, src1);
+ }
}
-MINLINE void blend_color_color_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4])
+MINLINE void blend_color_color_byte(unsigned char dst[4],
+ unsigned const char src1[4],
+ unsigned const char src2[4])
{
- const int fac = src2[3];
- if (fac != 0) {
- const int mfac = 255 - fac;
- float h1, s1, v1;
- float h2, s2, v2;
- float r, g, b;
- rgb_to_hsv(src1[0] / 255.0f, src1[1] / 255.0f, src1[2] / 255.0f, &h1, &s1, &v1);
- rgb_to_hsv(src2[0] / 255.0f, src2[1] / 255.0f, src2[2] / 255.0f, &h2, &s2, &v2);
-
-
- h1 = h2;
- s1 = s2;
-
- hsv_to_rgb(h1, s1, v1, &r, &g, &b);
-
- dst[0] = (unsigned char)(((int)(r * 255.0f) * fac + src1[0] * mfac) / 255);
- dst[1] = (unsigned char)(((int)(g * 255.0f) * fac + src1[1] * mfac) / 255);
- dst[2] = (unsigned char)(((int)(b * 255.0f) * fac + src1[2] * mfac) / 255);
- }
- else {
- /* no op */
- copy_v4_v4_uchar(dst, src1);
- }
+ const int fac = src2[3];
+ if (fac != 0) {
+ const int mfac = 255 - fac;
+ float h1, s1, v1;
+ float h2, s2, v2;
+ float r, g, b;
+ rgb_to_hsv(src1[0] / 255.0f, src1[1] / 255.0f, src1[2] / 255.0f, &h1, &s1, &v1);
+ rgb_to_hsv(src2[0] / 255.0f, src2[1] / 255.0f, src2[2] / 255.0f, &h2, &s2, &v2);
+
+ h1 = h2;
+ s1 = s2;
+
+ hsv_to_rgb(h1, s1, v1, &r, &g, &b);
+
+ dst[0] = (unsigned char)(((int)(r * 255.0f) * fac + src1[0] * mfac) / 255);
+ dst[1] = (unsigned char)(((int)(g * 255.0f) * fac + src1[1] * mfac) / 255);
+ dst[2] = (unsigned char)(((int)(b * 255.0f) * fac + src1[2] * mfac) / 255);
+ }
+ else {
+ /* no op */
+ copy_v4_v4_uchar(dst, src1);
+ }
}
-MINLINE void blend_color_hue_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4])
+MINLINE void blend_color_hue_byte(unsigned char dst[4],
+ unsigned const char src1[4],
+ unsigned const char src2[4])
{
- const int fac = src2[3];
- if (fac != 0) {
- const int mfac = 255 - fac;
- float h1, s1, v1;
- float h2, s2, v2;
- float r, g, b;
- rgb_to_hsv(src1[0] / 255.0f, src1[1] / 255.0f, src1[2] / 255.0f, &h1, &s1, &v1);
- rgb_to_hsv(src2[0] / 255.0f, src2[1] / 255.0f, src2[2] / 255.0f, &h2, &s2, &v2);
-
-
- h1 = h2;
-
- hsv_to_rgb(h1, s1, v1, &r, &g, &b);
-
- dst[0] = (unsigned char)(((int)(r * 255.0f) * fac + src1[0] * mfac) / 255);
- dst[1] = (unsigned char)(((int)(g * 255.0f) * fac + src1[1] * mfac) / 255);
- dst[2] = (unsigned char)(((int)(b * 255.0f) * fac + src1[2] * mfac) / 255);
- }
- else {
- /* no op */
- copy_v4_v4_uchar(dst, src1);
- }
-
+ const int fac = src2[3];
+ if (fac != 0) {
+ const int mfac = 255 - fac;
+ float h1, s1, v1;
+ float h2, s2, v2;
+ float r, g, b;
+ rgb_to_hsv(src1[0] / 255.0f, src1[1] / 255.0f, src1[2] / 255.0f, &h1, &s1, &v1);
+ rgb_to_hsv(src2[0] / 255.0f, src2[1] / 255.0f, src2[2] / 255.0f, &h2, &s2, &v2);
+
+ h1 = h2;
+
+ hsv_to_rgb(h1, s1, v1, &r, &g, &b);
+
+ dst[0] = (unsigned char)(((int)(r * 255.0f) * fac + src1[0] * mfac) / 255);
+ dst[1] = (unsigned char)(((int)(g * 255.0f) * fac + src1[1] * mfac) / 255);
+ dst[2] = (unsigned char)(((int)(b * 255.0f) * fac + src1[2] * mfac) / 255);
+ }
+ else {
+ /* no op */
+ copy_v4_v4_uchar(dst, src1);
+ }
}
-MINLINE void blend_color_saturation_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4])
+MINLINE void blend_color_saturation_byte(unsigned char dst[4],
+ unsigned const char src1[4],
+ unsigned const char src2[4])
{
- const int fac = src2[3];
- if (fac != 0) {
- const int mfac = 255 - fac;
- float h1, s1, v1;
- float h2, s2, v2;
- float r, g, b;
- rgb_to_hsv(src1[0] / 255.0f, src1[1] / 255.0f, src1[2] / 255.0f, &h1, &s1, &v1);
- rgb_to_hsv(src2[0] / 255.0f, src2[1] / 255.0f, src2[2] / 255.0f, &h2, &s2, &v2);
-
- if (s1 > EPS_SATURATION) {
- s1 = s2;
- }
-
- hsv_to_rgb(h1, s1, v1, &r, &g, &b);
-
- dst[0] = (unsigned char)(((int)(r * 255.0f) * fac + src1[0] * mfac) / 255);
- dst[1] = (unsigned char)(((int)(g * 255.0f) * fac + src1[1] * mfac) / 255);
- dst[2] = (unsigned char)(((int)(b * 255.0f) * fac + src1[2] * mfac) / 255);
- }
- else {
- /* no op */
- copy_v4_v4_uchar(dst, src1);
- }
+ const int fac = src2[3];
+ if (fac != 0) {
+ const int mfac = 255 - fac;
+ float h1, s1, v1;
+ float h2, s2, v2;
+ float r, g, b;
+ rgb_to_hsv(src1[0] / 255.0f, src1[1] / 255.0f, src1[2] / 255.0f, &h1, &s1, &v1);
+ rgb_to_hsv(src2[0] / 255.0f, src2[1] / 255.0f, src2[2] / 255.0f, &h2, &s2, &v2);
+
+ if (s1 > EPS_SATURATION) {
+ s1 = s2;
+ }
+
+ hsv_to_rgb(h1, s1, v1, &r, &g, &b);
+
+ dst[0] = (unsigned char)(((int)(r * 255.0f) * fac + src1[0] * mfac) / 255);
+ dst[1] = (unsigned char)(((int)(g * 255.0f) * fac + src1[1] * mfac) / 255);
+ dst[2] = (unsigned char)(((int)(b * 255.0f) * fac + src1[2] * mfac) / 255);
+ }
+ else {
+ /* no op */
+ copy_v4_v4_uchar(dst, src1);
+ }
}
-MINLINE void blend_color_luminosity_byte(unsigned char dst[4], unsigned const char src1[4], unsigned const char src2[4])
+MINLINE void blend_color_luminosity_byte(unsigned char dst[4],
+ unsigned const char src1[4],
+ unsigned const char src2[4])
{
- const int fac = src2[3];
- if (fac != 0) {
- const int mfac = 255 - fac;
- float h1, s1, v1;
- float h2, s2, v2;
- float r, g, b;
- rgb_to_hsv(src1[0] / 255.0f, src1[1] / 255.0f, src1[2] / 255.0f, &h1, &s1, &v1);
- rgb_to_hsv(src2[0] / 255.0f, src2[1] / 255.0f, src2[2] / 255.0f, &h2, &s2, &v2);
-
- v1 = v2;
-
- hsv_to_rgb(h1, s1, v1, &r, &g, &b);
-
- dst[0] = (unsigned char)(((int)(r * 255.0f) * fac + src1[0] * mfac) / 255);
- dst[1] = (unsigned char)(((int)(g * 255.0f) * fac + src1[1] * mfac) / 255);
- dst[2] = (unsigned char)(((int)(b * 255.0f) * fac + src1[2] * mfac) / 255);
-
- }
- else {
- /* no op */
- copy_v4_v4_uchar(dst, src1);
- }
-
+ const int fac = src2[3];
+ if (fac != 0) {
+ const int mfac = 255 - fac;
+ float h1, s1, v1;
+ float h2, s2, v2;
+ float r, g, b;
+ rgb_to_hsv(src1[0] / 255.0f, src1[1] / 255.0f, src1[2] / 255.0f, &h1, &s1, &v1);
+ rgb_to_hsv(src2[0] / 255.0f, src2[1] / 255.0f, src2[2] / 255.0f, &h2, &s2, &v2);
+
+ v1 = v2;
+
+ hsv_to_rgb(h1, s1, v1, &r, &g, &b);
+
+ dst[0] = (unsigned char)(((int)(r * 255.0f) * fac + src1[0] * mfac) / 255);
+ dst[1] = (unsigned char)(((int)(g * 255.0f) * fac + src1[1] * mfac) / 255);
+ dst[2] = (unsigned char)(((int)(b * 255.0f) * fac + src1[2] * mfac) / 255);
+ }
+ else {
+ /* no op */
+ copy_v4_v4_uchar(dst, src1);
+ }
}
-MINLINE void blend_color_interpolate_byte(unsigned char dst[4], const unsigned char src1[4], const unsigned char src2[4], float ft)
+MINLINE void blend_color_interpolate_byte(unsigned char dst[4],
+ const unsigned char src1[4],
+ const unsigned char src2[4],
+ float ft)
{
- /* do color interpolation, but in premultiplied space so that RGB colors
- * from zero alpha regions have no influence */
- const int t = (int)(255 * ft);
- const int mt = 255 - t;
- int tmp = (mt * src1[3] + t * src2[3]);
-
- if (tmp > 0) {
- dst[0] = (unsigned char)divide_round_i(mt * src1[0] * src1[3] + t * src2[0] * src2[3], tmp);
- dst[1] = (unsigned char)divide_round_i(mt * src1[1] * src1[3] + t * src2[1] * src2[3], tmp);
- dst[2] = (unsigned char)divide_round_i(mt * src1[2] * src1[3] + t * src2[2] * src2[3], tmp);
- dst[3] = (unsigned char)divide_round_i(tmp, 255);
- }
- else {
- copy_v4_v4_uchar(dst, src1);
- }
+ /* do color interpolation, but in premultiplied space so that RGB colors
+ * from zero alpha regions have no influence */
+ const int t = (int)(255 * ft);
+ const int mt = 255 - t;
+ int tmp = (mt * src1[3] + t * src2[3]);
+
+ if (tmp > 0) {
+ dst[0] = (unsigned char)divide_round_i(mt * src1[0] * src1[3] + t * src2[0] * src2[3], tmp);
+ dst[1] = (unsigned char)divide_round_i(mt * src1[1] * src1[3] + t * src2[1] * src2[3], tmp);
+ dst[2] = (unsigned char)divide_round_i(mt * src1[2] * src1[3] + t * src2[2] * src2[3], tmp);
+ dst[3] = (unsigned char)divide_round_i(tmp, 255);
+ }
+ else {
+ copy_v4_v4_uchar(dst, src1);
+ }
}
/* premultiplied alpha float blending modes */
MINLINE void blend_color_mix_float(float dst[4], const float src1[4], const float src2[4])
{
- if (src2[3] != 0.0f) {
- /* premul over operation */
- const float t = src2[3];
- const float mt = 1.0f - t;
-
- dst[0] = mt * src1[0] + src2[0];
- dst[1] = mt * src1[1] + src2[1];
- dst[2] = mt * src1[2] + src2[2];
- dst[3] = mt * src1[3] + t;
- }
- else {
- /* no op */
- copy_v4_v4(dst, src1);
- }
+ if (src2[3] != 0.0f) {
+ /* premul over operation */
+ const float t = src2[3];
+ const float mt = 1.0f - t;
+
+ dst[0] = mt * src1[0] + src2[0];
+ dst[1] = mt * src1[1] + src2[1];
+ dst[2] = mt * src1[2] + src2[2];
+ dst[3] = mt * src1[3] + t;
+ }
+ else {
+ /* no op */
+ copy_v4_v4(dst, src1);
+ }
}
MINLINE void blend_color_add_float(float dst[4], const float src1[4], const float src2[4])
{
- if (src2[3] != 0.0f) {
- /* unpremul > add > premul, simplified */
- dst[0] = src1[0] + src2[0] * src1[3];
- dst[1] = src1[1] + src2[1] * src1[3];
- dst[2] = src1[2] + src2[2] * src1[3];
- dst[3] = src1[3];
- }
- else {
- /* no op */
- copy_v4_v4(dst, src1);
- }
+ if (src2[3] != 0.0f) {
+ /* unpremul > add > premul, simplified */
+ dst[0] = src1[0] + src2[0] * src1[3];
+ dst[1] = src1[1] + src2[1] * src1[3];
+ dst[2] = src1[2] + src2[2] * src1[3];
+ dst[3] = src1[3];
+ }
+ else {
+ /* no op */
+ copy_v4_v4(dst, src1);
+ }
}
MINLINE void blend_color_sub_float(float dst[4], const float src1[4], const float src2[4])
{
- if (src2[3] != 0.0f) {
- /* unpremul > subtract > premul, simplified */
- dst[0] = max_ff(src1[0] - src2[0] * src1[3], 0.0f);
- dst[1] = max_ff(src1[1] - src2[1] * src1[3], 0.0f);
- dst[2] = max_ff(src1[2] - src2[2] * src1[3], 0.0f);
- dst[3] = src1[3];
- }
- else {
- /* no op */
- copy_v4_v4(dst, src1);
- }
+ if (src2[3] != 0.0f) {
+ /* unpremul > subtract > premul, simplified */
+ dst[0] = max_ff(src1[0] - src2[0] * src1[3], 0.0f);
+ dst[1] = max_ff(src1[1] - src2[1] * src1[3], 0.0f);
+ dst[2] = max_ff(src1[2] - src2[2] * src1[3], 0.0f);
+ dst[3] = src1[3];
+ }
+ else {
+ /* no op */
+ copy_v4_v4(dst, src1);
+ }
}
MINLINE void blend_color_mul_float(float dst[4], const float src1[4], const float src2[4])
{
- if (src2[3] != 0.0f) {
- /* unpremul > multiply > premul, simplified */
- const float t = src2[3];
- const float mt = 1.0f - t;
-
- dst[0] = mt * src1[0] + src1[0] * src2[0] * src1[3];
- dst[1] = mt * src1[1] + src1[1] * src2[1] * src1[3];
- dst[2] = mt * src1[2] + src1[2] * src2[2] * src1[3];
- dst[3] = src1[3];
- }
- else {
- /* no op */
- copy_v4_v4(dst, src1);
- }
+ if (src2[3] != 0.0f) {
+ /* unpremul > multiply > premul, simplified */
+ const float t = src2[3];
+ const float mt = 1.0f - t;
+
+ dst[0] = mt * src1[0] + src1[0] * src2[0] * src1[3];
+ dst[1] = mt * src1[1] + src1[1] * src2[1] * src1[3];
+ dst[2] = mt * src1[2] + src1[2] * src2[2] * src1[3];
+ dst[3] = src1[3];
+ }
+ else {
+ /* no op */
+ copy_v4_v4(dst, src1);
+ }
}
MINLINE void blend_color_lighten_float(float dst[4], const float src1[4], const float src2[4])
{
- if (src2[3] != 0.0f) {
- /* remap src2 to have same alpha as src1 premultiplied, take maximum of
- * src1 and src2, then blend it with src1 */
- const float t = src2[3];
- const float mt = 1.0f - t;
- const float map_alpha = src1[3] / src2[3];
-
- dst[0] = mt * src1[0] + t * max_ff(src1[0], src2[0] * map_alpha);
- dst[1] = mt * src1[1] + t * max_ff(src1[1], src2[1] * map_alpha);
- dst[2] = mt * src1[2] + t * max_ff(src1[2], src2[2] * map_alpha);
- dst[3] = src1[3];
- }
- else {
- /* no op */
- copy_v4_v4(dst, src1);
- }
+ if (src2[3] != 0.0f) {
+ /* remap src2 to have same alpha as src1 premultiplied, take maximum of
+ * src1 and src2, then blend it with src1 */
+ const float t = src2[3];
+ const float mt = 1.0f - t;
+ const float map_alpha = src1[3] / src2[3];
+
+ dst[0] = mt * src1[0] + t * max_ff(src1[0], src2[0] * map_alpha);
+ dst[1] = mt * src1[1] + t * max_ff(src1[1], src2[1] * map_alpha);
+ dst[2] = mt * src1[2] + t * max_ff(src1[2], src2[2] * map_alpha);
+ dst[3] = src1[3];
+ }
+ else {
+ /* no op */
+ copy_v4_v4(dst, src1);
+ }
}
MINLINE void blend_color_darken_float(float dst[4], const float src1[4], const float src2[4])
{
- if (src2[3] != 0.0f) {
- /* remap src2 to have same alpha as src1 premultiplied, take minimum of
- * src1 and src2, then blend it with src1 */
- const float t = src2[3];
- const float mt = 1.0f - t;
- const float map_alpha = src1[3] / src2[3];
-
- dst[0] = mt * src1[0] + t * min_ff(src1[0], src2[0] * map_alpha);
- dst[1] = mt * src1[1] + t * min_ff(src1[1], src2[1] * map_alpha);
- dst[2] = mt * src1[2] + t * min_ff(src1[2], src2[2] * map_alpha);
- dst[3] = src1[3];
- }
- else {
- /* no op */
- copy_v4_v4(dst, src1);
- }
+ if (src2[3] != 0.0f) {
+ /* remap src2 to have same alpha as src1 premultiplied, take minimum of
+ * src1 and src2, then blend it with src1 */
+ const float t = src2[3];
+ const float mt = 1.0f - t;
+ const float map_alpha = src1[3] / src2[3];
+
+ dst[0] = mt * src1[0] + t * min_ff(src1[0], src2[0] * map_alpha);
+ dst[1] = mt * src1[1] + t * min_ff(src1[1], src2[1] * map_alpha);
+ dst[2] = mt * src1[2] + t * min_ff(src1[2], src2[2] * map_alpha);
+ dst[3] = src1[3];
+ }
+ else {
+ /* no op */
+ copy_v4_v4(dst, src1);
+ }
}
MINLINE void blend_color_erase_alpha_float(float dst[4], const float src1[4], const float src2[4])
{
- if (src2[3] != 0.0f && src1[3] > 0.0f) {
- /* subtract alpha and remap RGB channels to match */
- float alpha = max_ff(src1[3] - src2[3], 0.0f);
- float map_alpha;
-
- if (alpha <= EPS_ALPHA) {
- alpha = 0.0f;
- }
-
- map_alpha = alpha / src1[3];
-
- dst[0] = src1[0] * map_alpha;
- dst[1] = src1[1] * map_alpha;
- dst[2] = src1[2] * map_alpha;
- dst[3] = alpha;
- }
- else {
- /* no op */
- copy_v4_v4(dst, src1);
- }
+ if (src2[3] != 0.0f && src1[3] > 0.0f) {
+ /* subtract alpha and remap RGB channels to match */
+ float alpha = max_ff(src1[3] - src2[3], 0.0f);
+ float map_alpha;
+
+ if (alpha <= EPS_ALPHA) {
+ alpha = 0.0f;
+ }
+
+ map_alpha = alpha / src1[3];
+
+ dst[0] = src1[0] * map_alpha;
+ dst[1] = src1[1] * map_alpha;
+ dst[2] = src1[2] * map_alpha;
+ dst[3] = alpha;
+ }
+ else {
+ /* no op */
+ copy_v4_v4(dst, src1);
+ }
}
MINLINE void blend_color_add_alpha_float(float dst[4], const float src1[4], const float src2[4])
{
- if (src2[3] != 0.0f && src1[3] < 1.0f) {
- /* add alpha and remap RGB channels to match */
- float alpha = min_ff(src1[3] + src2[3], 1.0f);
- float map_alpha;
-
- if (alpha >= 1.0f - EPS_ALPHA) {
- alpha = 1.0f;
- }
-
- map_alpha = (src1[3] > 0.0f) ? alpha / src1[3] : 1.0f;
-
- dst[0] = src1[0] * map_alpha;
- dst[1] = src1[1] * map_alpha;
- dst[2] = src1[2] * map_alpha;
- dst[3] = alpha;
- }
- else {
- /* no op */
- copy_v4_v4(dst, src1);
- }
+ if (src2[3] != 0.0f && src1[3] < 1.0f) {
+ /* add alpha and remap RGB channels to match */
+ float alpha = min_ff(src1[3] + src2[3], 1.0f);
+ float map_alpha;
+
+ if (alpha >= 1.0f - EPS_ALPHA) {
+ alpha = 1.0f;
+ }
+
+ map_alpha = (src1[3] > 0.0f) ? alpha / src1[3] : 1.0f;
+
+ dst[0] = src1[0] * map_alpha;
+ dst[1] = src1[1] * map_alpha;
+ dst[2] = src1[2] * map_alpha;
+ dst[3] = alpha;
+ }
+ else {
+ /* no op */
+ copy_v4_v4(dst, src1);
+ }
}
MINLINE void blend_color_overlay_float(float dst[4], const float src1[4], const float src2[4])
{
- const float fac = src2[3];
- if (fac != 0.0f) {
- const float mfac = 1.0f - fac;
- int i = 3;
-
- while (i--) {
- float temp;
-
- if (src1[i] > 0.5f) {
- temp = 1.0f - (1.0f - 2.0f * (src1[i] - 0.5f)) * (1.0f - src2[i]);
- }
- else {
- temp = 2.0f * src1[i] * src2[i];
- }
- dst[i] = min_ff(temp * fac + src1[i] * mfac, 1.0f);
- }
- }
- else {
- /* no op */
- copy_v4_v4(dst, src1);
- }
+ const float fac = src2[3];
+ if (fac != 0.0f) {
+ const float mfac = 1.0f - fac;
+ int i = 3;
+
+ while (i--) {
+ float temp;
+
+ if (src1[i] > 0.5f) {
+ temp = 1.0f - (1.0f - 2.0f * (src1[i] - 0.5f)) * (1.0f - src2[i]);
+ }
+ else {
+ temp = 2.0f * src1[i] * src2[i];
+ }
+ dst[i] = min_ff(temp * fac + src1[i] * mfac, 1.0f);
+ }
+ }
+ else {
+ /* no op */
+ copy_v4_v4(dst, src1);
+ }
}
-
MINLINE void blend_color_hardlight_float(float dst[4], const float src1[4], const float src2[4])
{
- const float fac = src2[3];
- if (fac != 0.0f) {
- const float mfac = 1.0f - fac;
- int i = 3;
-
- while (i--) {
- float temp;
-
- if (src2[i] > 0.5f) {
- temp = 1.0f - ((1.0f - 2.0f * (src2[i] - 0.5f)) * (1.0f - src1[i]));
- }
- else {
- temp = 2.0f * src2[i] * src1[i];
- }
- dst[i] = min_ff((temp * fac + src1[i] * mfac) / 1.0f, 1.0f);
- }
- }
- else {
- /* no op */
- copy_v4_v4(dst, src1);
- }
+ const float fac = src2[3];
+ if (fac != 0.0f) {
+ const float mfac = 1.0f - fac;
+ int i = 3;
+
+ while (i--) {
+ float temp;
+
+ if (src2[i] > 0.5f) {
+ temp = 1.0f - ((1.0f - 2.0f * (src2[i] - 0.5f)) * (1.0f - src1[i]));
+ }
+ else {
+ temp = 2.0f * src2[i] * src1[i];
+ }
+ dst[i] = min_ff((temp * fac + src1[i] * mfac) / 1.0f, 1.0f);
+ }
+ }
+ else {
+ /* no op */
+ copy_v4_v4(dst, src1);
+ }
}
MINLINE void blend_color_burn_float(float dst[4], const float src1[4], const float src2[4])
{
- const float fac = src2[3];
- if (fac != 0.0f) {
- const float mfac = 1.0f - fac;
- int i = 3;
-
- while (i--) {
- const float temp = (src2[i] == 0.0f) ? 0.0f : max_ff(1.0f - ((1.0f - src1[i]) / src2[i]), 0.0f);
- dst[i] = (temp * fac + src1[i] * mfac);
- }
- }
- else {
- /* no op */
- copy_v4_v4(dst, src1);
- }
+ const float fac = src2[3];
+ if (fac != 0.0f) {
+ const float mfac = 1.0f - fac;
+ int i = 3;
+
+ while (i--) {
+ const float temp = (src2[i] == 0.0f) ? 0.0f :
+ max_ff(1.0f - ((1.0f - src1[i]) / src2[i]), 0.0f);
+ dst[i] = (temp * fac + src1[i] * mfac);
+ }
+ }
+ else {
+ /* no op */
+ copy_v4_v4(dst, src1);
+ }
}
MINLINE void blend_color_linearburn_float(float dst[4], const float src1[4], const float src2[4])
{
- const float fac = src2[3];
- if (fac != 0.0f) {
- const float mfac = 1.0f - fac;
- int i = 3;
-
- while (i--) {
- const float temp = max_ff(src1[i] + src2[i] - 1.0f, 0.0f);
- dst[i] = (temp * fac + src1[i] * mfac);
- }
- }
- else {
- /* no op */
- copy_v4_v4(dst, src1);
- }
+ const float fac = src2[3];
+ if (fac != 0.0f) {
+ const float mfac = 1.0f - fac;
+ int i = 3;
+
+ while (i--) {
+ const float temp = max_ff(src1[i] + src2[i] - 1.0f, 0.0f);
+ dst[i] = (temp * fac + src1[i] * mfac);
+ }
+ }
+ else {
+ /* no op */
+ copy_v4_v4(dst, src1);
+ }
}
-
MINLINE void blend_color_dodge_float(float dst[4], const float src1[4], const float src2[4])
{
- const float fac = src2[3];
- if (fac != 0.0f) {
- const float mfac = 1.0f - fac;
- int i = 3;
-
- while (i--) {
- const float temp = (src2[i] >= 1.0f) ? 1.0f : min_ff(src1[i] / (1.0f - src2[i]), 1.0f);
- dst[i] = (temp * fac + src1[i] * mfac);
- }
- }
- else {
- /* no op */
- copy_v4_v4(dst, src1);
- }
+ const float fac = src2[3];
+ if (fac != 0.0f) {
+ const float mfac = 1.0f - fac;
+ int i = 3;
+
+ while (i--) {
+ const float temp = (src2[i] >= 1.0f) ? 1.0f : min_ff(src1[i] / (1.0f - src2[i]), 1.0f);
+ dst[i] = (temp * fac + src1[i] * mfac);
+ }
+ }
+ else {
+ /* no op */
+ copy_v4_v4(dst, src1);
+ }
}
MINLINE void blend_color_screen_float(float dst[4], const float src1[4], const float src2[4])
{
- const float fac = src2[3];
- if (fac != 0.0f) {
- const float mfac = 1.0f - fac;
- int i = 3;
-
- while (i--) {
- const float temp = max_ff(1.0f - ((1.0f - src1[i]) * (1.0f - src2[i])), 0.0f);
- dst[i] = (temp * fac + src1[i] * mfac);
- }
- }
- else {
- /* no op */
- copy_v4_v4(dst, src1);
- }
+ const float fac = src2[3];
+ if (fac != 0.0f) {
+ const float mfac = 1.0f - fac;
+ int i = 3;
+
+ while (i--) {
+ const float temp = max_ff(1.0f - ((1.0f - src1[i]) * (1.0f - src2[i])), 0.0f);
+ dst[i] = (temp * fac + src1[i] * mfac);
+ }
+ }
+ else {
+ /* no op */
+ copy_v4_v4(dst, src1);
+ }
}
MINLINE void blend_color_softlight_float(float dst[4], const float src1[4], const float src2[4])
{
- const float fac = src2[3];
- if (fac != 0.0f) {
- const float mfac = 1.0f - fac;
- int i = 3;
-
- while (i--) {
- float temp;
-
- if (src1[i] < 0.5f) {
- temp = (src2[i] + 0.5f) * src1[i];
- }
- else {
- temp = 1.0f - ((1.0f - (src2[i] + 0.5f)) * (1.0f - src1[i]));
- }
- dst[i] = (temp * fac + src1[i] * mfac);
- }
- }
- else {
- /* no op */
- copy_v4_v4(dst, src1);
- }
+ const float fac = src2[3];
+ if (fac != 0.0f) {
+ const float mfac = 1.0f - fac;
+ int i = 3;
+
+ while (i--) {
+ float temp;
+
+ if (src1[i] < 0.5f) {
+ temp = (src2[i] + 0.5f) * src1[i];
+ }
+ else {
+ temp = 1.0f - ((1.0f - (src2[i] + 0.5f)) * (1.0f - src1[i]));
+ }
+ dst[i] = (temp * fac + src1[i] * mfac);
+ }
+ }
+ else {
+ /* no op */
+ copy_v4_v4(dst, src1);
+ }
}
MINLINE void blend_color_pinlight_float(float dst[4], const float src1[4], const float src2[4])
{
- const float fac = src2[3];
- if (fac != 0.0f) {
- const float mfac = 1.0f - fac;
- int i = 3;
-
- while (i--) {
- float temp;
-
- if (src2[i] > 0.5f) {
- temp = max_ff(2.0f * (src2[i] - 0.5f), src1[i]);
- }
- else {
- temp = min_ff(2.0f * src2[i], src1[i]);
- }
- dst[i] = (temp * fac + src1[i] * mfac);
- }
- }
- else {
- /* no op */
- copy_v4_v4(dst, src1);
- }
+ const float fac = src2[3];
+ if (fac != 0.0f) {
+ const float mfac = 1.0f - fac;
+ int i = 3;
+
+ while (i--) {
+ float temp;
+
+ if (src2[i] > 0.5f) {
+ temp = max_ff(2.0f * (src2[i] - 0.5f), src1[i]);
+ }
+ else {
+ temp = min_ff(2.0f * src2[i], src1[i]);
+ }
+ dst[i] = (temp * fac + src1[i] * mfac);
+ }
+ }
+ else {
+ /* no op */
+ copy_v4_v4(dst, src1);
+ }
}
-
MINLINE void blend_color_linearlight_float(float dst[4], const float src1[4], const float src2[4])
{
- const float fac = src2[3];
- if (fac != 0.0f) {
- const float mfac = 1.0f - fac;
- int i = 3;
-
- while (i--) {
- float temp;
-
- if (src2[i] > 0.5f) {
- temp = min_ff(src1[i] + 2.0f * (src2[i] - 0.5f), 1.0f);
- }
- else {
- temp = max_ff(src1[i] + 2.0f * src2[i] - 1.0f, 0.0f);
- }
- dst[i] = (temp * fac + src1[i] * mfac);
- }
- }
- else {
- /* no op */
- copy_v4_v4(dst, src1);
- }
+ const float fac = src2[3];
+ if (fac != 0.0f) {
+ const float mfac = 1.0f - fac;
+ int i = 3;
+
+ while (i--) {
+ float temp;
+
+ if (src2[i] > 0.5f) {
+ temp = min_ff(src1[i] + 2.0f * (src2[i] - 0.5f), 1.0f);
+ }
+ else {
+ temp = max_ff(src1[i] + 2.0f * src2[i] - 1.0f, 0.0f);
+ }
+ dst[i] = (temp * fac + src1[i] * mfac);
+ }
+ }
+ else {
+ /* no op */
+ copy_v4_v4(dst, src1);
+ }
}
-
MINLINE void blend_color_vividlight_float(float dst[4], const float src1[4], const float src2[4])
{
- const float fac = src2[3];
- if (fac != 0.0f) {
- const float mfac = 1.0f - fac;
- int i = 3;
-
- while (i--) {
- float temp;
-
- if (src2[i] == 1.0f) {
- temp = (src1[i] == 0.0f) ? 0.5f : 1.0f;
- }
- else if (src2[i] == 0.0f) {
- temp = (src1[i] == 1.0f) ? 0.5f : 0.0f;
- }
- else if (src2[i] > 0.5f) {
- temp = min_ff(((src1[i]) * 1.0f) / (2.0f * (1.0f - src2[i])), 1.0f);
- }
- else {
- temp = max_ff(1.0f - ((1.0f - src1[i]) * 1.0f / (2.0f * src2[i])), 0.0f);
- }
- dst[i] = (temp * fac + src1[i] * mfac);
- }
- }
- else {
- /* no op */
- copy_v4_v4(dst, src1);
- }
+ const float fac = src2[3];
+ if (fac != 0.0f) {
+ const float mfac = 1.0f - fac;
+ int i = 3;
+
+ while (i--) {
+ float temp;
+
+ if (src2[i] == 1.0f) {
+ temp = (src1[i] == 0.0f) ? 0.5f : 1.0f;
+ }
+ else if (src2[i] == 0.0f) {
+ temp = (src1[i] == 1.0f) ? 0.5f : 0.0f;
+ }
+ else if (src2[i] > 0.5f) {
+ temp = min_ff(((src1[i]) * 1.0f) / (2.0f * (1.0f - src2[i])), 1.0f);
+ }
+ else {
+ temp = max_ff(1.0f - ((1.0f - src1[i]) * 1.0f / (2.0f * src2[i])), 0.0f);
+ }
+ dst[i] = (temp * fac + src1[i] * mfac);
+ }
+ }
+ else {
+ /* no op */
+ copy_v4_v4(dst, src1);
+ }
}
MINLINE void blend_color_difference_float(float dst[4], const float src1[4], const float src2[4])
{
- const float fac = src2[3];
- if (fac != 0.0f) {
- const float mfac = 1.0f - fac;
- int i = 3;
-
- while (i--) {
- dst[i] = (fabsf(src1[i] - src2[i]) * fac + src1[i] * mfac);
- }
- }
- else {
- /* no op */
- copy_v4_v4(dst, src1);
- }
+ const float fac = src2[3];
+ if (fac != 0.0f) {
+ const float mfac = 1.0f - fac;
+ int i = 3;
+
+ while (i--) {
+ dst[i] = (fabsf(src1[i] - src2[i]) * fac + src1[i] * mfac);
+ }
+ }
+ else {
+ /* no op */
+ copy_v4_v4(dst, src1);
+ }
}
-
MINLINE void blend_color_exclusion_float(float dst[4], const float src1[4], const float src2[4])
{
- const float fac = src2[3];
- if (fac != 0.0f) {
- const float mfac = 1.0f - fac;
- int i = 3;
-
- while (i--) {
- const float temp = 0.5f - ((2 * (src1[i] - 0.5f) * (src2[i] - 0.5f)));
- dst[i] = (temp * fac + src1[i] * mfac);
- }
- }
- else {
- /* no op */
- copy_v4_v4(dst, src1);
- }
-
+ const float fac = src2[3];
+ if (fac != 0.0f) {
+ const float mfac = 1.0f - fac;
+ int i = 3;
+
+ while (i--) {
+ const float temp = 0.5f - ((2 * (src1[i] - 0.5f) * (src2[i] - 0.5f)));
+ dst[i] = (temp * fac + src1[i] * mfac);
+ }
+ }
+ else {
+ /* no op */
+ copy_v4_v4(dst, src1);
+ }
}
MINLINE void blend_color_color_float(float dst[4], const float src1[4], const float src2[4])
{
- const float fac = src2[3];
- if (fac != 0.0f) {
- const float mfac = 1.0f - fac;
- float h1, s1, v1;
- float h2, s2, v2;
- float r, g, b;
-
- rgb_to_hsv(src1[0], src1[1], src1[2], &h1, &s1, &v1);
- rgb_to_hsv(src2[0], src2[1], src2[2], &h2, &s2, &v2);
-
- h1 = h2;
- s1 = s2;
-
- hsv_to_rgb(h1, s1, v1, &r, &g, &b);
-
- dst[0] = (r * fac + src1[0] * mfac);
- dst[1] = (g * fac + src1[1] * mfac);
- dst[2] = (b * fac + src1[2] * mfac);
- }
- else {
- /* no op */
- copy_v4_v4(dst, src1);
- }
+ const float fac = src2[3];
+ if (fac != 0.0f) {
+ const float mfac = 1.0f - fac;
+ float h1, s1, v1;
+ float h2, s2, v2;
+ float r, g, b;
+
+ rgb_to_hsv(src1[0], src1[1], src1[2], &h1, &s1, &v1);
+ rgb_to_hsv(src2[0], src2[1], src2[2], &h2, &s2, &v2);
+
+ h1 = h2;
+ s1 = s2;
+
+ hsv_to_rgb(h1, s1, v1, &r, &g, &b);
+
+ dst[0] = (r * fac + src1[0] * mfac);
+ dst[1] = (g * fac + src1[1] * mfac);
+ dst[2] = (b * fac + src1[2] * mfac);
+ }
+ else {
+ /* no op */
+ copy_v4_v4(dst, src1);
+ }
}
-
MINLINE void blend_color_hue_float(float dst[4], const float src1[4], const float src2[4])
{
- const float fac = src2[3];
- if (fac != 0.0f) {
- const float mfac = 1.0f - fac;
- float h1, s1, v1;
- float h2, s2, v2;
- float r, g, b;
-
- rgb_to_hsv(src1[0], src1[1], src1[2], &h1, &s1, &v1);
- rgb_to_hsv(src2[0], src2[1], src2[2], &h2, &s2, &v2);
-
- h1 = h2;
-
- hsv_to_rgb(h1, s1, v1, &r, &g, &b);
-
- dst[0] = (r * fac + src1[0] * mfac);
- dst[1] = (g * fac + src1[1] * mfac);
- dst[2] = (b * fac + src1[2] * mfac);
- }
- else {
- /* no op */
- copy_v4_v4(dst, src1);
- }
+ const float fac = src2[3];
+ if (fac != 0.0f) {
+ const float mfac = 1.0f - fac;
+ float h1, s1, v1;
+ float h2, s2, v2;
+ float r, g, b;
+
+ rgb_to_hsv(src1[0], src1[1], src1[2], &h1, &s1, &v1);
+ rgb_to_hsv(src2[0], src2[1], src2[2], &h2, &s2, &v2);
+
+ h1 = h2;
+
+ hsv_to_rgb(h1, s1, v1, &r, &g, &b);
+
+ dst[0] = (r * fac + src1[0] * mfac);
+ dst[1] = (g * fac + src1[1] * mfac);
+ dst[2] = (b * fac + src1[2] * mfac);
+ }
+ else {
+ /* no op */
+ copy_v4_v4(dst, src1);
+ }
}
MINLINE void blend_color_saturation_float(float dst[4], const float src1[4], const float src2[4])
{
- const float fac = src2[3];
- if (fac != 0.0f) {
- const float mfac = 1.0f - fac;
- float h1, s1, v1;
- float h2, s2, v2;
- float r, g, b;
-
- rgb_to_hsv(src1[0], src1[1], src1[2], &h1, &s1, &v1);
- rgb_to_hsv(src2[0], src2[1], src2[2], &h2, &s2, &v2);
-
- if (s1 > EPS_SATURATION) {
- s1 = s2;
- }
- hsv_to_rgb(h1, s1, v1, &r, &g, &b);
-
- dst[0] = (r * fac + src1[0] * mfac);
- dst[1] = (g * fac + src1[1] * mfac);
- dst[2] = (b * fac + src1[2] * mfac);
- }
- else {
- /* no op */
- copy_v4_v4(dst, src1);
- }
+ const float fac = src2[3];
+ if (fac != 0.0f) {
+ const float mfac = 1.0f - fac;
+ float h1, s1, v1;
+ float h2, s2, v2;
+ float r, g, b;
+
+ rgb_to_hsv(src1[0], src1[1], src1[2], &h1, &s1, &v1);
+ rgb_to_hsv(src2[0], src2[1], src2[2], &h2, &s2, &v2);
+
+ if (s1 > EPS_SATURATION) {
+ s1 = s2;
+ }
+ hsv_to_rgb(h1, s1, v1, &r, &g, &b);
+
+ dst[0] = (r * fac + src1[0] * mfac);
+ dst[1] = (g * fac + src1[1] * mfac);
+ dst[2] = (b * fac + src1[2] * mfac);
+ }
+ else {
+ /* no op */
+ copy_v4_v4(dst, src1);
+ }
}
MINLINE void blend_color_luminosity_float(float dst[4], const float src1[4], const float src2[4])
{
- const float fac = src2[3];
- if (fac != 0.0f) {
- const float mfac = 1.0f - fac;
- float h1, s1, v1;
- float h2, s2, v2;
- float r, g, b;
-
- rgb_to_hsv(src1[0], src1[1], src1[2], &h1, &s1, &v1);
- rgb_to_hsv(src2[0], src2[1], src2[2], &h2, &s2, &v2);
-
- v1 = v2;
- hsv_to_rgb(h1, s1, v1, &r, &g, &b);
-
- dst[0] = (r * fac + src1[0] * mfac);
- dst[1] = (g * fac + src1[1] * mfac);
- dst[2] = (b * fac + src1[2] * mfac);
- }
- else {
- /* no op */
- copy_v4_v4(dst, src1);
- }
+ const float fac = src2[3];
+ if (fac != 0.0f) {
+ const float mfac = 1.0f - fac;
+ float h1, s1, v1;
+ float h2, s2, v2;
+ float r, g, b;
+
+ rgb_to_hsv(src1[0], src1[1], src1[2], &h1, &s1, &v1);
+ rgb_to_hsv(src2[0], src2[1], src2[2], &h2, &s2, &v2);
+
+ v1 = v2;
+ hsv_to_rgb(h1, s1, v1, &r, &g, &b);
+
+ dst[0] = (r * fac + src1[0] * mfac);
+ dst[1] = (g * fac + src1[1] * mfac);
+ dst[2] = (b * fac + src1[2] * mfac);
+ }
+ else {
+ /* no op */
+ copy_v4_v4(dst, src1);
+ }
}
-
-MINLINE void blend_color_interpolate_float(float dst[4], const float src1[4], const float src2[4], float t)
+MINLINE void blend_color_interpolate_float(float dst[4],
+ const float src1[4],
+ const float src2[4],
+ float t)
{
- /* interpolation, colors are premultiplied so it goes fine */
- const float mt = 1.0f - t;
+ /* interpolation, colors are premultiplied so it goes fine */
+ const float mt = 1.0f - t;
- dst[0] = mt * src1[0] + t * src2[0];
- dst[1] = mt * src1[1] + t * src2[1];
- dst[2] = mt * src1[2] + t * src2[2];
- dst[3] = mt * src1[3] + t * src2[3];
+ dst[0] = mt * src1[0] + t * src2[0];
+ dst[1] = mt * src1[1] + t * src2[1];
+ dst[2] = mt * src1[2] + t * src2[2];
+ dst[3] = mt * src1[3] + t * src2[3];
}
-#undef EPS_SATURATION
-#undef EPS_ALPHA
+# undef EPS_SATURATION
+# undef EPS_ALPHA
#endif /* __MATH_COLOR_BLEND_INLINE_C__ */
diff --git a/source/blender/blenlib/intern/math_color_inline.c b/source/blender/blenlib/intern/math_color_inline.c
index bfe060a8826..1309eb12e4d 100644
--- a/source/blender/blenlib/intern/math_color_inline.c
+++ b/source/blender/blenlib/intern/math_color_inline.c
@@ -24,7 +24,6 @@
* \ingroup bli
*/
-
#include "BLI_math_base.h"
#include "BLI_math_color.h"
#include "BLI_utildefines.h"
@@ -32,97 +31,94 @@
#include "math.h"
#ifndef __MATH_COLOR_INLINE_C__
-#define __MATH_COLOR_INLINE_C__
+# define __MATH_COLOR_INLINE_C__
/******************************** Color Space ********************************/
-#ifdef __SSE2__
+# ifdef __SSE2__
MALWAYS_INLINE __m128 srgb_to_linearrgb_v4_simd(const __m128 c)
{
- __m128 cmp = _mm_cmplt_ps(c, _mm_set1_ps(0.04045f));
- __m128 lt = _mm_max_ps(_mm_mul_ps(c, _mm_set1_ps(1.0f / 12.92f)),
- _mm_set1_ps(0.0f));
- __m128 gtebase = _mm_mul_ps(_mm_add_ps(c, _mm_set1_ps(0.055f)),
- _mm_set1_ps(1.0f / 1.055f)); /* fma */
- __m128 gte = _bli_math_fastpow24(gtebase);
- return _bli_math_blend_sse(cmp, lt, gte);
+ __m128 cmp = _mm_cmplt_ps(c, _mm_set1_ps(0.04045f));
+ __m128 lt = _mm_max_ps(_mm_mul_ps(c, _mm_set1_ps(1.0f / 12.92f)), _mm_set1_ps(0.0f));
+ __m128 gtebase = _mm_mul_ps(_mm_add_ps(c, _mm_set1_ps(0.055f)),
+ _mm_set1_ps(1.0f / 1.055f)); /* fma */
+ __m128 gte = _bli_math_fastpow24(gtebase);
+ return _bli_math_blend_sse(cmp, lt, gte);
}
MALWAYS_INLINE __m128 linearrgb_to_srgb_v4_simd(const __m128 c)
{
- __m128 cmp = _mm_cmplt_ps(c, _mm_set1_ps(0.0031308f));
- __m128 lt = _mm_max_ps(_mm_mul_ps(c, _mm_set1_ps(12.92f)),
- _mm_set1_ps(0.0f));
- __m128 gte = _mm_add_ps(_mm_mul_ps(_mm_set1_ps(1.055f),
- _bli_math_fastpow512(c)),
- _mm_set1_ps(-0.055f));
- return _bli_math_blend_sse(cmp, lt, gte);
+ __m128 cmp = _mm_cmplt_ps(c, _mm_set1_ps(0.0031308f));
+ __m128 lt = _mm_max_ps(_mm_mul_ps(c, _mm_set1_ps(12.92f)), _mm_set1_ps(0.0f));
+ __m128 gte = _mm_add_ps(_mm_mul_ps(_mm_set1_ps(1.055f), _bli_math_fastpow512(c)),
+ _mm_set1_ps(-0.055f));
+ return _bli_math_blend_sse(cmp, lt, gte);
}
MINLINE void srgb_to_linearrgb_v3_v3(float linear[3], const float srgb[3])
{
- float r[4] = {srgb[0], srgb[1], srgb[2], 1.0f};
- __m128 *rv = (__m128 *)&r;
- *rv = srgb_to_linearrgb_v4_simd(*rv);
- linear[0] = r[0];
- linear[1] = r[1];
- linear[2] = r[2];
+ float r[4] = {srgb[0], srgb[1], srgb[2], 1.0f};
+ __m128 *rv = (__m128 *)&r;
+ *rv = srgb_to_linearrgb_v4_simd(*rv);
+ linear[0] = r[0];
+ linear[1] = r[1];
+ linear[2] = r[2];
}
MINLINE void linearrgb_to_srgb_v3_v3(float srgb[3], const float linear[3])
{
- float r[4] = {linear[0], linear[1], linear[2], 1.0f};
- __m128 *rv = (__m128 *)&r;
- *rv = linearrgb_to_srgb_v4_simd(*rv);
- srgb[0] = r[0];
- srgb[1] = r[1];
- srgb[2] = r[2];
+ float r[4] = {linear[0], linear[1], linear[2], 1.0f};
+ __m128 *rv = (__m128 *)&r;
+ *rv = linearrgb_to_srgb_v4_simd(*rv);
+ srgb[0] = r[0];
+ srgb[1] = r[1];
+ srgb[2] = r[2];
}
-#else /* __SSE2__ */
+# else /* __SSE2__ */
MINLINE void srgb_to_linearrgb_v3_v3(float linear[3], const float srgb[3])
{
- linear[0] = srgb_to_linearrgb(srgb[0]);
- linear[1] = srgb_to_linearrgb(srgb[1]);
- linear[2] = srgb_to_linearrgb(srgb[2]);
+ linear[0] = srgb_to_linearrgb(srgb[0]);
+ linear[1] = srgb_to_linearrgb(srgb[1]);
+ linear[2] = srgb_to_linearrgb(srgb[2]);
}
MINLINE void linearrgb_to_srgb_v3_v3(float srgb[3], const float linear[3])
{
- srgb[0] = linearrgb_to_srgb(linear[0]);
- srgb[1] = linearrgb_to_srgb(linear[1]);
- srgb[2] = linearrgb_to_srgb(linear[2]);
+ srgb[0] = linearrgb_to_srgb(linear[0]);
+ srgb[1] = linearrgb_to_srgb(linear[1]);
+ srgb[2] = linearrgb_to_srgb(linear[2]);
}
-#endif /* __SSE2__ */
+# endif /* __SSE2__ */
MINLINE void srgb_to_linearrgb_v4(float linear[4], const float srgb[4])
{
- srgb_to_linearrgb_v3_v3(linear, srgb);
- linear[3] = srgb[3];
+ srgb_to_linearrgb_v3_v3(linear, srgb);
+ linear[3] = srgb[3];
}
MINLINE void linearrgb_to_srgb_v4(float srgb[4], const float linear[4])
{
- linearrgb_to_srgb_v3_v3(srgb, linear);
- srgb[3] = linear[3];
+ linearrgb_to_srgb_v3_v3(srgb, linear);
+ srgb[3] = linear[3];
}
MINLINE void linearrgb_to_srgb_uchar3(unsigned char srgb[3], const float linear[3])
{
- float srgb_f[3];
+ float srgb_f[3];
- linearrgb_to_srgb_v3_v3(srgb_f, linear);
- unit_float_to_uchar_clamp_v3(srgb, srgb_f);
+ linearrgb_to_srgb_v3_v3(srgb_f, linear);
+ unit_float_to_uchar_clamp_v3(srgb, srgb_f);
}
MINLINE void linearrgb_to_srgb_uchar4(unsigned char srgb[4], const float linear[4])
{
- float srgb_f[4];
+ float srgb_f[4];
- linearrgb_to_srgb_v4(srgb_f, linear);
- unit_float_to_uchar_clamp_v4(srgb, srgb_f);
+ linearrgb_to_srgb_v4(srgb_f, linear);
+ unit_float_to_uchar_clamp_v4(srgb, srgb_f);
}
/* predivide versions to work on associated/pre-multiplied alpha. if this should
@@ -132,48 +128,48 @@ MINLINE void linearrgb_to_srgb_uchar4(unsigned char srgb[4], const float linear[
MINLINE void srgb_to_linearrgb_predivide_v4(float linear[4], const float srgb[4])
{
- float alpha, inv_alpha;
-
- if (srgb[3] == 1.0f || srgb[3] == 0.0f) {
- alpha = 1.0f;
- inv_alpha = 1.0f;
- }
- else {
- alpha = srgb[3];
- inv_alpha = 1.0f / alpha;
- }
-
- linear[0] = srgb[0] * inv_alpha;
- linear[1] = srgb[1] * inv_alpha;
- linear[2] = srgb[2] * inv_alpha;
- linear[3] = srgb[3];
- srgb_to_linearrgb_v3_v3(linear, linear);
- linear[0] *= alpha;
- linear[1] *= alpha;
- linear[2] *= alpha;
+ float alpha, inv_alpha;
+
+ if (srgb[3] == 1.0f || srgb[3] == 0.0f) {
+ alpha = 1.0f;
+ inv_alpha = 1.0f;
+ }
+ else {
+ alpha = srgb[3];
+ inv_alpha = 1.0f / alpha;
+ }
+
+ linear[0] = srgb[0] * inv_alpha;
+ linear[1] = srgb[1] * inv_alpha;
+ linear[2] = srgb[2] * inv_alpha;
+ linear[3] = srgb[3];
+ srgb_to_linearrgb_v3_v3(linear, linear);
+ linear[0] *= alpha;
+ linear[1] *= alpha;
+ linear[2] *= alpha;
}
MINLINE void linearrgb_to_srgb_predivide_v4(float srgb[4], const float linear[4])
{
- float alpha, inv_alpha;
-
- if (linear[3] == 1.0f || linear[3] == 0.0f) {
- alpha = 1.0f;
- inv_alpha = 1.0f;
- }
- else {
- alpha = linear[3];
- inv_alpha = 1.0f / alpha;
- }
-
- srgb[0] = linear[0] * inv_alpha;
- srgb[1] = linear[1] * inv_alpha;
- srgb[2] = linear[2] * inv_alpha;
- srgb[3] = linear[3];
- linearrgb_to_srgb_v3_v3(srgb, srgb);
- srgb[0] *= alpha;
- srgb[1] *= alpha;
- srgb[2] *= alpha;
+ float alpha, inv_alpha;
+
+ if (linear[3] == 1.0f || linear[3] == 0.0f) {
+ alpha = 1.0f;
+ inv_alpha = 1.0f;
+ }
+ else {
+ alpha = linear[3];
+ inv_alpha = 1.0f / alpha;
+ }
+
+ srgb[0] = linear[0] * inv_alpha;
+ srgb[1] = linear[1] * inv_alpha;
+ srgb[2] = linear[2] * inv_alpha;
+ srgb[3] = linear[3];
+ linearrgb_to_srgb_v3_v3(srgb, srgb);
+ srgb[0] *= alpha;
+ srgb[1] *= alpha;
+ srgb[2] *= alpha;
}
/* LUT accelerated conversions */
@@ -184,85 +180,87 @@ extern unsigned short BLI_color_to_srgb_table[0x10000];
MINLINE unsigned short to_srgb_table_lookup(const float f)
{
- union {
- float f;
- unsigned short us[2];
- } tmp;
- tmp.f = f;
-#ifdef __BIG_ENDIAN__
- return BLI_color_to_srgb_table[tmp.us[0]];
-#else
- return BLI_color_to_srgb_table[tmp.us[1]];
-#endif
+ union {
+ float f;
+ unsigned short us[2];
+ } tmp;
+ tmp.f = f;
+# ifdef __BIG_ENDIAN__
+ return BLI_color_to_srgb_table[tmp.us[0]];
+# else
+ return BLI_color_to_srgb_table[tmp.us[1]];
+# endif
}
MINLINE void linearrgb_to_srgb_ushort4(unsigned short srgb[4], const float linear[4])
{
- srgb[0] = to_srgb_table_lookup(linear[0]);
- srgb[1] = to_srgb_table_lookup(linear[1]);
- srgb[2] = to_srgb_table_lookup(linear[2]);
- srgb[3] = unit_float_to_ushort_clamp(linear[3]);
+ srgb[0] = to_srgb_table_lookup(linear[0]);
+ srgb[1] = to_srgb_table_lookup(linear[1]);
+ srgb[2] = to_srgb_table_lookup(linear[2]);
+ srgb[3] = unit_float_to_ushort_clamp(linear[3]);
}
MINLINE void srgb_to_linearrgb_uchar4(float linear[4], const unsigned char srgb[4])
{
- linear[0] = BLI_color_from_srgb_table[srgb[0]];
- linear[1] = BLI_color_from_srgb_table[srgb[1]];
- linear[2] = BLI_color_from_srgb_table[srgb[2]];
- linear[3] = srgb[3] * (1.0f / 255.0f);
+ linear[0] = BLI_color_from_srgb_table[srgb[0]];
+ linear[1] = BLI_color_from_srgb_table[srgb[1]];
+ linear[2] = BLI_color_from_srgb_table[srgb[2]];
+ linear[3] = srgb[3] * (1.0f / 255.0f);
}
MINLINE void srgb_to_linearrgb_uchar4_predivide(float linear[4], const unsigned char srgb[4])
{
- float fsrgb[4];
- int i;
+ float fsrgb[4];
+ int i;
- if (srgb[3] == 255 || srgb[3] == 0) {
- srgb_to_linearrgb_uchar4(linear, srgb);
- return;
- }
+ if (srgb[3] == 255 || srgb[3] == 0) {
+ srgb_to_linearrgb_uchar4(linear, srgb);
+ return;
+ }
- for (i = 0; i < 4; i++) {
- fsrgb[i] = srgb[i] * (1.0f / 255.0f);
- }
+ for (i = 0; i < 4; i++) {
+ fsrgb[i] = srgb[i] * (1.0f / 255.0f);
+ }
- srgb_to_linearrgb_predivide_v4(linear, fsrgb);
+ srgb_to_linearrgb_predivide_v4(linear, fsrgb);
}
-MINLINE void rgba_char_args_set(char col[4], const char r, const char g, const char b, const char a)
+MINLINE void rgba_char_args_set(
+ char col[4], const char r, const char g, const char b, const char a)
{
- col[0] = r;
- col[1] = g;
- col[2] = b;
- col[3] = a;
+ col[0] = r;
+ col[1] = g;
+ col[2] = b;
+ col[3] = a;
}
-MINLINE void rgba_float_args_set(float col[4], const float r, const float g, const float b, const float a)
+MINLINE void rgba_float_args_set(
+ float col[4], const float r, const float g, const float b, const float a)
{
- col[0] = r;
- col[1] = g;
- col[2] = b;
- col[3] = a;
+ col[0] = r;
+ col[1] = g;
+ col[2] = b;
+ col[3] = a;
}
-MINLINE void rgba_char_args_test_set(char col[4], const char r, const char g, const char b, const char a)
+MINLINE void rgba_char_args_test_set(
+ char col[4], const char r, const char g, const char b, const char a)
{
- if (col[3] == 0) {
- col[0] = r;
- col[1] = g;
- col[2] = b;
- col[3] = a;
- }
+ if (col[3] == 0) {
+ col[0] = r;
+ col[1] = g;
+ col[2] = b;
+ col[3] = a;
+ }
}
MINLINE void cpack_cpy_3ub(unsigned char r_col[3], const unsigned int pack)
{
- r_col[0] = ((pack) >> 0) & 0xFF;
- r_col[1] = ((pack) >> 8) & 0xFF;
- r_col[2] = ((pack) >> 16) & 0xFF;
+ r_col[0] = ((pack) >> 0) & 0xFF;
+ r_col[1] = ((pack) >> 8) & 0xFF;
+ r_col[2] = ((pack) >> 16) & 0xFF;
}
-
/** \name RGB/Grayscale Functions
*
* \warning
@@ -289,120 +287,121 @@ MINLINE void cpack_cpy_3ub(unsigned char r_col[3], const unsigned int pack)
*/
MINLINE float rgb_to_grayscale(const float rgb[3])
{
- return (0.2126f * rgb[0]) + (0.7152f * rgb[1]) + (0.0722f * rgb[2]);
+ return (0.2126f * rgb[0]) + (0.7152f * rgb[1]) + (0.0722f * rgb[2]);
}
MINLINE unsigned char rgb_to_grayscale_byte(const unsigned char rgb[3])
{
- return (unsigned char)(((54 * (unsigned short)rgb[0]) +
- (182 * (unsigned short)rgb[1]) +
- (19 * (unsigned short)rgb[2])) / 255);
+ return (unsigned char)(((54 * (unsigned short)rgb[0]) + (182 * (unsigned short)rgb[1]) +
+ (19 * (unsigned short)rgb[2])) /
+ 255);
}
/** \} */
-
-
-MINLINE int compare_rgb_uchar(const unsigned char col_a[3], const unsigned char col_b[3], const int limit)
+MINLINE int compare_rgb_uchar(const unsigned char col_a[3],
+ const unsigned char col_b[3],
+ const int limit)
{
- const int r = (int)col_a[0] - (int)col_b[0];
- if (ABS(r) < limit) {
- const int g = (int)col_a[1] - (int)col_b[1];
- if (ABS(g) < limit) {
- const int b = (int)col_a[2] - (int)col_b[2];
- if (ABS(b) < limit) {
- return 1;
- }
- }
- }
-
- return 0;
+ const int r = (int)col_a[0] - (int)col_b[0];
+ if (ABS(r) < limit) {
+ const int g = (int)col_a[1] - (int)col_b[1];
+ if (ABS(g) < limit) {
+ const int b = (int)col_a[2] - (int)col_b[2];
+ if (ABS(b) < limit) {
+ return 1;
+ }
+ }
+ }
+
+ return 0;
}
MINLINE float dither_random_value(float s, float t)
{
- static float vec[2] = {12.9898f, 78.233f};
- float value;
+ static float vec[2] = {12.9898f, 78.233f};
+ float value;
- value = sinf(s * vec[0] + t * vec[1]) * 43758.5453f;
- return value - floorf(value);
+ value = sinf(s * vec[0] + t * vec[1]) * 43758.5453f;
+ return value - floorf(value);
}
-MINLINE void float_to_byte_dither_v3(unsigned char b[3], const float f[3], float dither, float s, float t)
+MINLINE void float_to_byte_dither_v3(
+ unsigned char b[3], const float f[3], float dither, float s, float t)
{
- float dither_value = dither_random_value(s, t) * 0.005f * dither;
+ float dither_value = dither_random_value(s, t) * 0.005f * dither;
- b[0] = unit_float_to_uchar_clamp(dither_value + f[0]);
- b[1] = unit_float_to_uchar_clamp(dither_value + f[1]);
- b[2] = unit_float_to_uchar_clamp(dither_value + f[2]);
+ b[0] = unit_float_to_uchar_clamp(dither_value + f[0]);
+ b[1] = unit_float_to_uchar_clamp(dither_value + f[1]);
+ b[2] = unit_float_to_uchar_clamp(dither_value + f[2]);
}
/**************** Alpha Transformations *****************/
MINLINE void premul_to_straight_v4_v4(float straight[4], const float premul[4])
{
- if (premul[3] == 0.0f || premul[3] == 1.0f) {
- straight[0] = premul[0];
- straight[1] = premul[1];
- straight[2] = premul[2];
- straight[3] = premul[3];
- }
- else {
- const float alpha_inv = 1.0f / premul[3];
- straight[0] = premul[0] * alpha_inv;
- straight[1] = premul[1] * alpha_inv;
- straight[2] = premul[2] * alpha_inv;
- straight[3] = premul[3];
- }
+ if (premul[3] == 0.0f || premul[3] == 1.0f) {
+ straight[0] = premul[0];
+ straight[1] = premul[1];
+ straight[2] = premul[2];
+ straight[3] = premul[3];
+ }
+ else {
+ const float alpha_inv = 1.0f / premul[3];
+ straight[0] = premul[0] * alpha_inv;
+ straight[1] = premul[1] * alpha_inv;
+ straight[2] = premul[2] * alpha_inv;
+ straight[3] = premul[3];
+ }
}
MINLINE void premul_to_straight_v4(float color[4])
{
- premul_to_straight_v4_v4(color, color);
+ premul_to_straight_v4_v4(color, color);
}
MINLINE void straight_to_premul_v4_v4(float premul[4], const float straight[4])
{
- const float alpha = straight[3];
- premul[0] = straight[0] * alpha;
- premul[1] = straight[1] * alpha;
- premul[2] = straight[2] * alpha;
- premul[3] = straight[3];
+ const float alpha = straight[3];
+ premul[0] = straight[0] * alpha;
+ premul[1] = straight[1] * alpha;
+ premul[2] = straight[2] * alpha;
+ premul[3] = straight[3];
}
MINLINE void straight_to_premul_v4(float color[4])
{
- straight_to_premul_v4_v4(color, color);
+ straight_to_premul_v4_v4(color, color);
}
MINLINE void straight_uchar_to_premul_float(float result[4], const unsigned char color[4])
{
- const float alpha = color[3] * (1.0f / 255.0f);
- const float fac = alpha * (1.0f / 255.0f);
+ const float alpha = color[3] * (1.0f / 255.0f);
+ const float fac = alpha * (1.0f / 255.0f);
- result[0] = color[0] * fac;
- result[1] = color[1] * fac;
- result[2] = color[2] * fac;
- result[3] = alpha;
+ result[0] = color[0] * fac;
+ result[1] = color[1] * fac;
+ result[2] = color[2] * fac;
+ result[3] = alpha;
}
MINLINE void premul_float_to_straight_uchar(unsigned char *result, const float color[4])
{
- if (color[3] == 0.0f || color[3] == 1.0f) {
- result[0] = unit_float_to_uchar_clamp(color[0]);
- result[1] = unit_float_to_uchar_clamp(color[1]);
- result[2] = unit_float_to_uchar_clamp(color[2]);
- result[3] = unit_float_to_uchar_clamp(color[3]);
- }
- else {
- const float alpha_inv = 1.0f / color[3];
-
- /* hopefully this would be optimized */
- result[0] = unit_float_to_uchar_clamp(color[0] * alpha_inv);
- result[1] = unit_float_to_uchar_clamp(color[1] * alpha_inv);
- result[2] = unit_float_to_uchar_clamp(color[2] * alpha_inv);
- result[3] = unit_float_to_uchar_clamp(color[3]);
- }
+ if (color[3] == 0.0f || color[3] == 1.0f) {
+ result[0] = unit_float_to_uchar_clamp(color[0]);
+ result[1] = unit_float_to_uchar_clamp(color[1]);
+ result[2] = unit_float_to_uchar_clamp(color[2]);
+ result[3] = unit_float_to_uchar_clamp(color[3]);
+ }
+ else {
+ const float alpha_inv = 1.0f / color[3];
+
+ /* hopefully this would be optimized */
+ result[0] = unit_float_to_uchar_clamp(color[0] * alpha_inv);
+ result[1] = unit_float_to_uchar_clamp(color[1] * alpha_inv);
+ result[2] = unit_float_to_uchar_clamp(color[2] * alpha_inv);
+ result[3] = unit_float_to_uchar_clamp(color[3]);
+ }
}
#endif /* __MATH_COLOR_INLINE_C__ */
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index 7c9c3844843..7d7ff3f450f 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -36,54 +36,55 @@
void cross_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
{
- float n1[3], n2[3];
+ float n1[3], n2[3];
- n1[0] = v1[0] - v2[0];
- n2[0] = v2[0] - v3[0];
- n1[1] = v1[1] - v2[1];
- n2[1] = v2[1] - v3[1];
- n1[2] = v1[2] - v2[2];
- n2[2] = v2[2] - v3[2];
- n[0] = n1[1] * n2[2] - n1[2] * n2[1];
- n[1] = n1[2] * n2[0] - n1[0] * n2[2];
- n[2] = n1[0] * n2[1] - n1[1] * n2[0];
+ n1[0] = v1[0] - v2[0];
+ n2[0] = v2[0] - v3[0];
+ n1[1] = v1[1] - v2[1];
+ n2[1] = v2[1] - v3[1];
+ n1[2] = v1[2] - v2[2];
+ n2[2] = v2[2] - v3[2];
+ n[0] = n1[1] * n2[2] - n1[2] * n2[1];
+ n[1] = n1[2] * n2[0] - n1[0] * n2[2];
+ n[2] = n1[0] * n2[1] - n1[1] * n2[0];
}
float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
{
- float n1[3], n2[3];
+ float n1[3], n2[3];
- n1[0] = v1[0] - v2[0];
- n2[0] = v2[0] - v3[0];
- n1[1] = v1[1] - v2[1];
- n2[1] = v2[1] - v3[1];
- n1[2] = v1[2] - v2[2];
- n2[2] = v2[2] - v3[2];
- n[0] = n1[1] * n2[2] - n1[2] * n2[1];
- n[1] = n1[2] * n2[0] - n1[0] * n2[2];
- n[2] = n1[0] * n2[1] - n1[1] * n2[0];
+ n1[0] = v1[0] - v2[0];
+ n2[0] = v2[0] - v3[0];
+ n1[1] = v1[1] - v2[1];
+ n2[1] = v2[1] - v3[1];
+ n1[2] = v1[2] - v2[2];
+ n2[2] = v2[2] - v3[2];
+ n[0] = n1[1] * n2[2] - n1[2] * n2[1];
+ n[1] = n1[2] * n2[0] - n1[0] * n2[2];
+ n[2] = n1[0] * n2[1] - n1[1] * n2[0];
- return normalize_v3(n);
+ return normalize_v3(n);
}
-float normal_quad_v3(float n[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3])
+float normal_quad_v3(
+ float n[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3])
{
- /* real cross! */
- float n1[3], n2[3];
+ /* real cross! */
+ float n1[3], n2[3];
- n1[0] = v1[0] - v3[0];
- n1[1] = v1[1] - v3[1];
- n1[2] = v1[2] - v3[2];
+ n1[0] = v1[0] - v3[0];
+ n1[1] = v1[1] - v3[1];
+ n1[2] = v1[2] - v3[2];
- n2[0] = v2[0] - v4[0];
- n2[1] = v2[1] - v4[1];
- n2[2] = v2[2] - v4[2];
+ n2[0] = v2[0] - v4[0];
+ n2[1] = v2[1] - v4[1];
+ n2[2] = v2[2] - v4[2];
- n[0] = n1[1] * n2[2] - n1[2] * n2[1];
- n[1] = n1[2] * n2[0] - n1[0] * n2[2];
- n[2] = n1[0] * n2[1] - n1[1] * n2[0];
+ n[0] = n1[1] * n2[2] - n1[2] * n2[1];
+ n[1] = n1[2] * n2[0] - n1[0] * n2[2];
+ n[2] = n1[0] * n2[1] - n1[1] * n2[0];
- return normalize_v3(n);
+ return normalize_v3(n);
}
/**
@@ -93,67 +94,73 @@ float normal_quad_v3(float n[3], const float v1[3], const float v2[3], const flo
*/
float normal_poly_v3(float n[3], const float verts[][3], unsigned int nr)
{
- cross_poly_v3(n, verts, nr);
- return normalize_v3(n);
+ cross_poly_v3(n, verts, nr);
+ return normalize_v3(n);
}
float area_quad_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3])
{
- const float verts[4][3] = {{UNPACK3(v1)}, {UNPACK3(v2)}, {UNPACK3(v3)}, {UNPACK3(v4)}};
- return area_poly_v3(verts, 4);
+ const float verts[4][3] = {{UNPACK3(v1)}, {UNPACK3(v2)}, {UNPACK3(v3)}, {UNPACK3(v4)}};
+ return area_poly_v3(verts, 4);
}
-float area_squared_quad_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3])
+float area_squared_quad_v3(const float v1[3],
+ const float v2[3],
+ const float v3[3],
+ const float v4[3])
{
- const float verts[4][3] = {{UNPACK3(v1)}, {UNPACK3(v2)}, {UNPACK3(v3)}, {UNPACK3(v4)}};
- return area_squared_poly_v3(verts, 4);
+ const float verts[4][3] = {{UNPACK3(v1)}, {UNPACK3(v2)}, {UNPACK3(v3)}, {UNPACK3(v4)}};
+ return area_squared_poly_v3(verts, 4);
}
/* Triangles */
float area_tri_v3(const float v1[3], const float v2[3], const float v3[3])
{
- float n[3];
- cross_tri_v3(n, v1, v2, v3);
- return len_v3(n) * 0.5f;
+ float n[3];
+ cross_tri_v3(n, v1, v2, v3);
+ return len_v3(n) * 0.5f;
}
float area_squared_tri_v3(const float v1[3], const float v2[3], const float v3[3])
{
- float n[3];
- cross_tri_v3(n, v1, v2, v3);
- mul_v3_fl(n, 0.5f);
- return len_squared_v3(n);
+ float n[3];
+ cross_tri_v3(n, v1, v2, v3);
+ mul_v3_fl(n, 0.5f);
+ return len_squared_v3(n);
}
-float area_tri_signed_v3(const float v1[3], const float v2[3], const float v3[3], const float normal[3])
+float area_tri_signed_v3(const float v1[3],
+ const float v2[3],
+ const float v3[3],
+ const float normal[3])
{
- float area, n[3];
+ float area, n[3];
- cross_tri_v3(n, v1, v2, v3);
- area = len_v3(n) * 0.5f;
+ cross_tri_v3(n, v1, v2, v3);
+ area = len_v3(n) * 0.5f;
- /* negate area for flipped triangles */
- if (dot_v3v3(n, normal) < 0.0f) {
- area = -area;
- }
+ /* negate area for flipped triangles */
+ if (dot_v3v3(n, normal) < 0.0f) {
+ area = -area;
+ }
- return area;
+ return area;
}
float area_poly_v3(const float verts[][3], unsigned int nr)
{
- float n[3];
- cross_poly_v3(n, verts, nr);
- return len_v3(n) * 0.5f;
+ float n[3];
+ cross_poly_v3(n, verts, nr);
+ return len_v3(n) * 0.5f;
}
float area_squared_poly_v3(const float verts[][3], unsigned int nr)
{
- float n[3];
+ float n[3];
- cross_poly_v3(n, verts, nr);
- mul_v3_fl(n, 0.5f);
- return len_squared_v3(n);
+ cross_poly_v3(n, verts, nr);
+ mul_v3_fl(n, 0.5f);
+ return len_squared_v3(n);
}
/**
@@ -164,69 +171,69 @@ float area_squared_poly_v3(const float verts[][3], unsigned int nr)
*/
float cross_poly_v2(const float verts[][2], unsigned int nr)
{
- unsigned int a;
- float cross;
- const float *co_curr, *co_prev;
+ unsigned int a;
+ float cross;
+ const float *co_curr, *co_prev;
- /* The Trapezium Area Rule */
- co_prev = verts[nr - 1];
- co_curr = verts[0];
- cross = 0.0f;
- for (a = 0; a < nr; a++) {
- cross += (co_curr[0] - co_prev[0]) * (co_curr[1] + co_prev[1]);
- co_prev = co_curr;
- co_curr += 2;
- }
+ /* The Trapezium Area Rule */
+ co_prev = verts[nr - 1];
+ co_curr = verts[0];
+ cross = 0.0f;
+ for (a = 0; a < nr; a++) {
+ cross += (co_curr[0] - co_prev[0]) * (co_curr[1] + co_prev[1]);
+ co_prev = co_curr;
+ co_curr += 2;
+ }
- return cross;
+ return cross;
}
void cross_poly_v3(float n[3], const float verts[][3], unsigned int nr)
{
- const float *v_prev = verts[nr - 1];
- const float *v_curr = verts[0];
- unsigned int i;
+ const float *v_prev = verts[nr - 1];
+ const float *v_curr = verts[0];
+ unsigned int i;
- zero_v3(n);
+ zero_v3(n);
- /* Newell's Method */
- for (i = 0; i < nr; v_prev = v_curr, v_curr = verts[++i]) {
- add_newell_cross_v3_v3v3(n, v_prev, v_curr);
- }
+ /* Newell's Method */
+ for (i = 0; i < nr; v_prev = v_curr, v_curr = verts[++i]) {
+ add_newell_cross_v3_v3v3(n, v_prev, v_curr);
+ }
}
float area_poly_v2(const float verts[][2], unsigned int nr)
{
- return fabsf(0.5f * cross_poly_v2(verts, nr));
+ return fabsf(0.5f * cross_poly_v2(verts, nr));
}
float area_poly_signed_v2(const float verts[][2], unsigned int nr)
{
- return (0.5f * cross_poly_v2(verts, nr));
+ return (0.5f * cross_poly_v2(verts, nr));
}
float area_squared_poly_v2(const float verts[][2], unsigned int nr)
{
- float area = area_poly_signed_v2(verts, nr);
- return area * area;
+ float area = area_poly_signed_v2(verts, nr);
+ return area * area;
}
float cotangent_tri_weight_v3(const float v1[3], const float v2[3], const float v3[3])
{
- float a[3], b[3], c[3], c_len;
+ float a[3], b[3], c[3], c_len;
- sub_v3_v3v3(a, v2, v1);
- sub_v3_v3v3(b, v3, v1);
- cross_v3_v3v3(c, a, b);
+ sub_v3_v3v3(a, v2, v1);
+ sub_v3_v3v3(b, v3, v1);
+ cross_v3_v3v3(c, a, b);
- c_len = len_v3(c);
+ c_len = len_v3(c);
- if (c_len > FLT_EPSILON) {
- return dot_v3v3(a, b) / c_len;
- }
- else {
- return 0.0f;
- }
+ if (c_len > FLT_EPSILON) {
+ return dot_v3v3(a, b) / c_len;
+ }
+ else {
+ return 0.0f;
+ }
}
/********************************* Planes **********************************/
@@ -237,8 +244,8 @@ float cotangent_tri_weight_v3(const float v1[3], const float v2[3], const float
*/
void plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const float plane_no[3])
{
- copy_v3_v3(r_plane, plane_no);
- r_plane[3] = -dot_v3v3(r_plane, plane_co);
+ copy_v3_v3(r_plane, plane_no);
+ r_plane[3] = -dot_v3v3(r_plane, plane_co);
}
/**
@@ -246,17 +253,19 @@ void plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const
*/
void plane_to_point_vector_v3(const float plane[4], float r_plane_co[3], float r_plane_no[3])
{
- mul_v3_v3fl(r_plane_co, plane, (-plane[3] / len_squared_v3(plane)));
- copy_v3_v3(r_plane_no, plane);
+ mul_v3_v3fl(r_plane_co, plane, (-plane[3] / len_squared_v3(plane)));
+ copy_v3_v3(r_plane_no, plane);
}
/**
* version of #plane_to_point_vector_v3 that gets a unit length vector.
*/
-void plane_to_point_vector_v3_normalized(const float plane[4], float r_plane_co[3], float r_plane_no[3])
+void plane_to_point_vector_v3_normalized(const float plane[4],
+ float r_plane_co[3],
+ float r_plane_no[3])
{
- const float length = normalize_v3_v3(r_plane_no, plane);
- mul_v3_v3fl(r_plane_co, r_plane_no, (-plane[3] / length));
+ const float length = normalize_v3_v3(r_plane_no, plane);
+ mul_v3_v3fl(r_plane_co, r_plane_no, (-plane[3] / length));
}
/********************************* Volume **********************************/
@@ -264,96 +273,107 @@ void plane_to_point_vector_v3_normalized(const float plane[4], float r_plane_co[
/**
* The volume from a tetrahedron, points can be in any order
*/
-float volume_tetrahedron_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3])
+float volume_tetrahedron_v3(const float v1[3],
+ const float v2[3],
+ const float v3[3],
+ const float v4[3])
{
- float m[3][3];
- sub_v3_v3v3(m[0], v1, v2);
- sub_v3_v3v3(m[1], v2, v3);
- sub_v3_v3v3(m[2], v3, v4);
- return fabsf(determinant_m3_array(m)) / 6.0f;
+ float m[3][3];
+ sub_v3_v3v3(m[0], v1, v2);
+ sub_v3_v3v3(m[1], v2, v3);
+ sub_v3_v3v3(m[2], v3, v4);
+ return fabsf(determinant_m3_array(m)) / 6.0f;
}
/**
* The volume from a tetrahedron, normal pointing inside gives negative volume
*/
-float volume_tetrahedron_signed_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3])
+float volume_tetrahedron_signed_v3(const float v1[3],
+ const float v2[3],
+ const float v3[3],
+ const float v4[3])
{
- float m[3][3];
- sub_v3_v3v3(m[0], v1, v2);
- sub_v3_v3v3(m[1], v2, v3);
- sub_v3_v3v3(m[2], v3, v4);
- return determinant_m3_array(m) / 6.0f;
+ float m[3][3];
+ sub_v3_v3v3(m[0], v1, v2);
+ sub_v3_v3v3(m[1], v2, v3);
+ sub_v3_v3v3(m[2], v3, v4);
+ return determinant_m3_array(m) / 6.0f;
}
-
/********************************* Distance **********************************/
/* distance p to line v1-v2
* using Hesse formula, NO LINE PIECE! */
float dist_squared_to_line_v2(const float p[2], const float l1[2], const float l2[2])
{
- float closest[2];
+ float closest[2];
- closest_to_line_v2(closest, p, l1, l2);
+ closest_to_line_v2(closest, p, l1, l2);
- return len_squared_v2v2(closest, p);
+ return len_squared_v2v2(closest, p);
}
float dist_to_line_v2(const float p[2], const float l1[2], const float l2[2])
{
- return sqrtf(dist_squared_to_line_v2(p, l1, l2));
+ return sqrtf(dist_squared_to_line_v2(p, l1, l2));
}
/* distance p to line-piece v1-v2 */
float dist_squared_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2])
{
- float closest[2];
+ float closest[2];
- closest_to_line_segment_v2(closest, p, l1, l2);
+ closest_to_line_segment_v2(closest, p, l1, l2);
- return len_squared_v2v2(closest, p);
+ return len_squared_v2v2(closest, p);
}
float dist_to_line_segment_v2(const float p[2], const float l1[2], const float l2[2])
{
- return sqrtf(dist_squared_to_line_segment_v2(p, l1, l2));
+ return sqrtf(dist_squared_to_line_segment_v2(p, l1, l2));
}
/* point closest to v1 on line v2-v3 in 2D */
-void closest_to_line_segment_v2(float r_close[2], const float p[2], const float l1[2], const float l2[2])
+void closest_to_line_segment_v2(float r_close[2],
+ const float p[2],
+ const float l1[2],
+ const float l2[2])
{
- float lambda, cp[2];
+ float lambda, cp[2];
- lambda = closest_to_line_v2(cp, p, l1, l2);
+ lambda = closest_to_line_v2(cp, p, l1, l2);
- /* flip checks for !finite case (when segment is a point) */
- if (!(lambda > 0.0f)) {
- copy_v2_v2(r_close, l1);
- }
- else if (!(lambda < 1.0f)) {
- copy_v2_v2(r_close, l2);
- }
- else {
- copy_v2_v2(r_close, cp);
- }
+ /* flip checks for !finite case (when segment is a point) */
+ if (!(lambda > 0.0f)) {
+ copy_v2_v2(r_close, l1);
+ }
+ else if (!(lambda < 1.0f)) {
+ copy_v2_v2(r_close, l2);
+ }
+ else {
+ copy_v2_v2(r_close, cp);
+ }
}
/* point closest to v1 on line v2-v3 in 3D */
-void closest_to_line_segment_v3(float r_close[3], const float p[3], const float l1[3], const float l2[3])
+void closest_to_line_segment_v3(float r_close[3],
+ const float p[3],
+ const float l1[3],
+ const float l2[3])
{
- float lambda, cp[3];
+ float lambda, cp[3];
- lambda = closest_to_line_v3(cp, p, l1, l2);
+ lambda = closest_to_line_v3(cp, p, l1, l2);
- /* flip checks for !finite case (when segment is a point) */
- if (!(lambda > 0.0f)) {
- copy_v3_v3(r_close, l1);
- }
- else if (!(lambda < 1.0f)) {
- copy_v3_v3(r_close, l2);
- }
- else {
- copy_v3_v3(r_close, cp);
- }
+ /* flip checks for !finite case (when segment is a point) */
+ if (!(lambda > 0.0f)) {
+ copy_v3_v3(r_close, l1);
+ }
+ else if (!(lambda < 1.0f)) {
+ copy_v3_v3(r_close, l2);
+ }
+ else {
+ copy_v3_v3(r_close, cp);
+ }
}
/**
@@ -367,62 +387,62 @@ void closest_to_line_segment_v3(float r_close[3], const float p[3], const float
*/
void closest_to_plane_v3(float r_close[3], const float plane[4], const float pt[3])
{
- const float len_sq = len_squared_v3(plane);
- const float side = plane_point_side_v3(plane, pt);
- madd_v3_v3v3fl(r_close, pt, plane, -side / len_sq);
+ const float len_sq = len_squared_v3(plane);
+ const float side = plane_point_side_v3(plane, pt);
+ madd_v3_v3v3fl(r_close, pt, plane, -side / len_sq);
}
void closest_to_plane_normalized_v3(float r_close[3], const float plane[4], const float pt[3])
{
- const float side = plane_point_side_v3(plane, pt);
- BLI_ASSERT_UNIT_V3(plane);
- madd_v3_v3v3fl(r_close, pt, plane, -side);
+ const float side = plane_point_side_v3(plane, pt);
+ BLI_ASSERT_UNIT_V3(plane);
+ madd_v3_v3v3fl(r_close, pt, plane, -side);
}
void closest_to_plane3_v3(float r_close[3], const float plane[3], const float pt[3])
{
- const float len_sq = len_squared_v3(plane);
- const float side = dot_v3v3(plane, pt);
- madd_v3_v3v3fl(r_close, pt, plane, -side / len_sq);
+ const float len_sq = len_squared_v3(plane);
+ const float side = dot_v3v3(plane, pt);
+ madd_v3_v3v3fl(r_close, pt, plane, -side / len_sq);
}
void closest_to_plane3_normalized_v3(float r_close[3], const float plane[3], const float pt[3])
{
- const float side = dot_v3v3(plane, pt);
- BLI_ASSERT_UNIT_V3(plane);
- madd_v3_v3v3fl(r_close, pt, plane, -side);
+ const float side = dot_v3v3(plane, pt);
+ BLI_ASSERT_UNIT_V3(plane);
+ madd_v3_v3v3fl(r_close, pt, plane, -side);
}
float dist_signed_squared_to_plane_v3(const float pt[3], const float plane[4])
{
- const float len_sq = len_squared_v3(plane);
- const float side = plane_point_side_v3(plane, pt);
- const float fac = side / len_sq;
- return copysignf(len_sq * (fac * fac), side);
+ const float len_sq = len_squared_v3(plane);
+ const float side = plane_point_side_v3(plane, pt);
+ const float fac = side / len_sq;
+ return copysignf(len_sq * (fac * fac), side);
}
float dist_squared_to_plane_v3(const float pt[3], const float plane[4])
{
- const float len_sq = len_squared_v3(plane);
- const float side = plane_point_side_v3(plane, pt);
- const float fac = side / len_sq;
- /* only difference to code above - no 'copysignf' */
- return len_sq * (fac * fac);
+ const float len_sq = len_squared_v3(plane);
+ const float side = plane_point_side_v3(plane, pt);
+ const float fac = side / len_sq;
+ /* only difference to code above - no 'copysignf' */
+ return len_sq * (fac * fac);
}
float dist_signed_squared_to_plane3_v3(const float pt[3], const float plane[3])
{
- const float len_sq = len_squared_v3(plane);
- const float side = dot_v3v3(plane, pt); /* only difference with 'plane[4]' version */
- const float fac = side / len_sq;
- return copysignf(len_sq * (fac * fac), side);
+ const float len_sq = len_squared_v3(plane);
+ const float side = dot_v3v3(plane, pt); /* only difference with 'plane[4]' version */
+ const float fac = side / len_sq;
+ return copysignf(len_sq * (fac * fac), side);
}
float dist_squared_to_plane3_v3(const float pt[3], const float plane[3])
{
- const float len_sq = len_squared_v3(plane);
- const float side = dot_v3v3(plane, pt); /* only difference with 'plane[4]' version */
- const float fac = side / len_sq;
- /* only difference to code above - no 'copysignf' */
- return len_sq * (fac * fac);
+ const float len_sq = len_squared_v3(plane);
+ const float side = dot_v3v3(plane, pt); /* only difference with 'plane[4]' version */
+ const float fac = side / len_sq;
+ /* only difference to code above - no 'copysignf' */
+ return len_sq * (fac * fac);
}
/**
@@ -430,54 +450,54 @@ float dist_squared_to_plane3_v3(const float pt[3], const float plane[3])
*/
float dist_signed_to_plane_v3(const float pt[3], const float plane[4])
{
- const float len_sq = len_squared_v3(plane);
- const float side = plane_point_side_v3(plane, pt);
- const float fac = side / len_sq;
- return sqrtf(len_sq) * fac;
+ const float len_sq = len_squared_v3(plane);
+ const float side = plane_point_side_v3(plane, pt);
+ const float fac = side / len_sq;
+ return sqrtf(len_sq) * fac;
}
float dist_to_plane_v3(const float pt[3], const float plane[4])
{
- return fabsf(dist_signed_to_plane_v3(pt, plane));
+ return fabsf(dist_signed_to_plane_v3(pt, plane));
}
float dist_signed_to_plane3_v3(const float pt[3], const float plane[3])
{
- const float len_sq = len_squared_v3(plane);
- const float side = dot_v3v3(plane, pt); /* only difference with 'plane[4]' version */
- const float fac = side / len_sq;
- return sqrtf(len_sq) * fac;
+ const float len_sq = len_squared_v3(plane);
+ const float side = dot_v3v3(plane, pt); /* only difference with 'plane[4]' version */
+ const float fac = side / len_sq;
+ return sqrtf(len_sq) * fac;
}
float dist_to_plane3_v3(const float pt[3], const float plane[3])
{
- return fabsf(dist_signed_to_plane3_v3(pt, plane));
+ return fabsf(dist_signed_to_plane3_v3(pt, plane));
}
/* distance v1 to line-piece l1-l2 in 3D */
float dist_squared_to_line_segment_v3(const float p[3], const float l1[3], const float l2[3])
{
- float closest[3];
+ float closest[3];
- closest_to_line_segment_v3(closest, p, l1, l2);
+ closest_to_line_segment_v3(closest, p, l1, l2);
- return len_squared_v3v3(closest, p);
+ return len_squared_v3v3(closest, p);
}
float dist_to_line_segment_v3(const float p[3], const float l1[3], const float l2[3])
{
- return sqrtf(dist_squared_to_line_segment_v3(p, l1, l2));
+ return sqrtf(dist_squared_to_line_segment_v3(p, l1, l2));
}
float dist_squared_to_line_v3(const float p[3], const float l1[3], const float l2[3])
{
- float closest[3];
+ float closest[3];
- closest_to_line_v3(closest, p, l1, l2);
+ closest_to_line_v3(closest, p, l1, l2);
- return len_squared_v3v3(closest, p);
+ return len_squared_v3v3(closest, p);
}
float dist_to_line_v3(const float p[3], const float l1[3], const float l2[3])
{
- return sqrtf(dist_squared_to_line_v3(p, l1, l2));
+ return sqrtf(dist_squared_to_line_v3(p, l1, l2));
}
/**
@@ -503,55 +523,56 @@ float dist_to_line_v3(const float p[3], const float l1[3], const float l2[3])
* x - also outside
* </pre>
*/
-float dist_signed_squared_to_corner_v3v3v3(
- const float p[3],
- const float v1[3], const float v2[3], const float v3[3],
- const float axis_ref[3])
-{
- float dir_a[3], dir_b[3];
- float plane_a[3], plane_b[3];
- float dist_a, dist_b;
- float axis[3];
- float s_p_v2[3];
- bool flip = false;
-
- sub_v3_v3v3(dir_a, v1, v2);
- sub_v3_v3v3(dir_b, v3, v2);
-
- cross_v3_v3v3(axis, dir_a, dir_b);
-
- if ((len_squared_v3(axis) < FLT_EPSILON)) {
- copy_v3_v3(axis, axis_ref);
- }
- else if (dot_v3v3(axis, axis_ref) < 0.0f) {
- /* concave */
- flip = true;
- negate_v3(axis);
- }
-
- cross_v3_v3v3(plane_a, dir_a, axis);
- cross_v3_v3v3(plane_b, axis, dir_b);
+float dist_signed_squared_to_corner_v3v3v3(const float p[3],
+ const float v1[3],
+ const float v2[3],
+ const float v3[3],
+ const float axis_ref[3])
+{
+ float dir_a[3], dir_b[3];
+ float plane_a[3], plane_b[3];
+ float dist_a, dist_b;
+ float axis[3];
+ float s_p_v2[3];
+ bool flip = false;
+
+ sub_v3_v3v3(dir_a, v1, v2);
+ sub_v3_v3v3(dir_b, v3, v2);
+
+ cross_v3_v3v3(axis, dir_a, dir_b);
+
+ if ((len_squared_v3(axis) < FLT_EPSILON)) {
+ copy_v3_v3(axis, axis_ref);
+ }
+ else if (dot_v3v3(axis, axis_ref) < 0.0f) {
+ /* concave */
+ flip = true;
+ negate_v3(axis);
+ }
+
+ cross_v3_v3v3(plane_a, dir_a, axis);
+ cross_v3_v3v3(plane_b, axis, dir_b);
#if 0
- plane_from_point_normal_v3(plane_a, v2, plane_a);
- plane_from_point_normal_v3(plane_b, v2, plane_b);
+ plane_from_point_normal_v3(plane_a, v2, plane_a);
+ plane_from_point_normal_v3(plane_b, v2, plane_b);
- dist_a = dist_signed_squared_to_plane_v3(p, plane_a);
- dist_b = dist_signed_squared_to_plane_v3(p, plane_b);
+ dist_a = dist_signed_squared_to_plane_v3(p, plane_a);
+ dist_b = dist_signed_squared_to_plane_v3(p, plane_b);
#else
- /* calculate without the planes 4th component to avoid float precision issues */
- sub_v3_v3v3(s_p_v2, p, v2);
+ /* calculate without the planes 4th component to avoid float precision issues */
+ sub_v3_v3v3(s_p_v2, p, v2);
- dist_a = dist_signed_squared_to_plane3_v3(s_p_v2, plane_a);
- dist_b = dist_signed_squared_to_plane3_v3(s_p_v2, plane_b);
+ dist_a = dist_signed_squared_to_plane3_v3(s_p_v2, plane_a);
+ dist_b = dist_signed_squared_to_plane3_v3(s_p_v2, plane_b);
#endif
- if (flip) {
- return min_ff(dist_a, dist_b);
- }
- else {
- return max_ff(dist_a, dist_b);
- }
+ if (flip) {
+ return min_ff(dist_a, dist_b);
+ }
+ else {
+ return max_ff(dist_a, dist_b);
+ }
}
/**
@@ -560,220 +581,220 @@ float dist_signed_squared_to_corner_v3v3v3(
* \param ray_direction: Normalized direction of the line.
* \param co: Point to which the distance is to be calculated.
*/
-float dist_squared_to_ray_v3_normalized(
- const float ray_origin[3], const float ray_direction[3],
- const float co[3])
+float dist_squared_to_ray_v3_normalized(const float ray_origin[3],
+ const float ray_direction[3],
+ const float co[3])
{
- float origin_to_co[3];
- sub_v3_v3v3(origin_to_co, co, ray_origin);
+ float origin_to_co[3];
+ sub_v3_v3v3(origin_to_co, co, ray_origin);
- float origin_to_proj[3];
- project_v3_v3v3_normalized(origin_to_proj, origin_to_co, ray_direction);
+ float origin_to_proj[3];
+ project_v3_v3v3_normalized(origin_to_proj, origin_to_co, ray_direction);
- float co_projected_on_ray[3];
- add_v3_v3v3(co_projected_on_ray, ray_origin, origin_to_proj);
+ float co_projected_on_ray[3];
+ add_v3_v3v3(co_projected_on_ray, ray_origin, origin_to_proj);
- return len_squared_v3v3(co, co_projected_on_ray);
+ return len_squared_v3v3(co, co_projected_on_ray);
}
-
/**
* Find the closest point in a seg to a ray and return the distance squared.
* \param r_point: Is the point on segment closest to ray (or to ray_origin if the ray and the segment are parallel).
* \param r_depth: the distance of r_point projection on ray to the ray_origin.
*/
-float dist_squared_ray_to_seg_v3(
- const float ray_origin[3], const float ray_direction[3],
- const float v0[3], const float v1[3],
- float r_point[3], float *r_depth)
-{
- float lambda, depth;
- if (isect_ray_seg_v3(
- ray_origin, ray_direction, v0, v1, &lambda))
- {
- if (lambda <= 0.0f) {
- copy_v3_v3(r_point, v0);
- }
- else if (lambda >= 1.0f) {
- copy_v3_v3(r_point, v1);
- }
- else {
- interp_v3_v3v3(r_point, v0, v1, lambda);
- }
- }
- else {
- /* has no nearest point, only distance squared. */
- /* Calculate the distance to the point v0 then */
- copy_v3_v3(r_point, v0);
- }
-
- float dvec[3];
- sub_v3_v3v3(dvec, r_point, ray_origin);
- depth = dot_v3v3(dvec, ray_direction);
-
- if (r_depth) {
- *r_depth = depth;
- }
-
- return len_squared_v3(dvec) - SQUARE(depth);
+float dist_squared_ray_to_seg_v3(const float ray_origin[3],
+ const float ray_direction[3],
+ const float v0[3],
+ const float v1[3],
+ float r_point[3],
+ float *r_depth)
+{
+ float lambda, depth;
+ if (isect_ray_seg_v3(ray_origin, ray_direction, v0, v1, &lambda)) {
+ if (lambda <= 0.0f) {
+ copy_v3_v3(r_point, v0);
+ }
+ else if (lambda >= 1.0f) {
+ copy_v3_v3(r_point, v1);
+ }
+ else {
+ interp_v3_v3v3(r_point, v0, v1, lambda);
+ }
+ }
+ else {
+ /* has no nearest point, only distance squared. */
+ /* Calculate the distance to the point v0 then */
+ copy_v3_v3(r_point, v0);
+ }
+
+ float dvec[3];
+ sub_v3_v3v3(dvec, r_point, ray_origin);
+ depth = dot_v3v3(dvec, ray_direction);
+
+ if (r_depth) {
+ *r_depth = depth;
+ }
+
+ return len_squared_v3(dvec) - SQUARE(depth);
}
-
/* Returns the coordinates of the nearest vertex and
* the farthest vertex from a plane (or normal). */
-void aabb_get_near_far_from_plane(
- const float plane_no[3], const float bbmin[3], const float bbmax[3],
- float bb_near[3], float bb_afar[3])
-{
- if (plane_no[0] < 0.0f) {
- bb_near[0] = bbmax[0];
- bb_afar[0] = bbmin[0];
- }
- else {
- bb_near[0] = bbmin[0];
- bb_afar[0] = bbmax[0];
- }
- if (plane_no[1] < 0.0f) {
- bb_near[1] = bbmax[1];
- bb_afar[1] = bbmin[1];
- }
- else {
- bb_near[1] = bbmin[1];
- bb_afar[1] = bbmax[1];
- }
- if (plane_no[2] < 0.0f) {
- bb_near[2] = bbmax[2];
- bb_afar[2] = bbmin[2];
- }
- else {
- bb_near[2] = bbmin[2];
- bb_afar[2] = bbmax[2];
- }
+void aabb_get_near_far_from_plane(const float plane_no[3],
+ const float bbmin[3],
+ const float bbmax[3],
+ float bb_near[3],
+ float bb_afar[3])
+{
+ if (plane_no[0] < 0.0f) {
+ bb_near[0] = bbmax[0];
+ bb_afar[0] = bbmin[0];
+ }
+ else {
+ bb_near[0] = bbmin[0];
+ bb_afar[0] = bbmax[0];
+ }
+ if (plane_no[1] < 0.0f) {
+ bb_near[1] = bbmax[1];
+ bb_afar[1] = bbmin[1];
+ }
+ else {
+ bb_near[1] = bbmin[1];
+ bb_afar[1] = bbmax[1];
+ }
+ if (plane_no[2] < 0.0f) {
+ bb_near[2] = bbmax[2];
+ bb_afar[2] = bbmin[2];
+ }
+ else {
+ bb_near[2] = bbmin[2];
+ bb_afar[2] = bbmax[2];
+ }
}
/* -------------------------------------------------------------------- */
/** \name dist_squared_to_ray_to_aabb and helpers
* \{ */
-void dist_squared_ray_to_aabb_v3_precalc(
- struct DistRayAABB_Precalc *neasrest_precalc,
- const float ray_origin[3], const float ray_direction[3])
+void dist_squared_ray_to_aabb_v3_precalc(struct DistRayAABB_Precalc *neasrest_precalc,
+ const float ray_origin[3],
+ const float ray_direction[3])
{
- copy_v3_v3(neasrest_precalc->ray_origin, ray_origin);
- copy_v3_v3(neasrest_precalc->ray_direction, ray_direction);
+ copy_v3_v3(neasrest_precalc->ray_origin, ray_origin);
+ copy_v3_v3(neasrest_precalc->ray_direction, ray_direction);
- for (int i = 0; i < 3; i++) {
- neasrest_precalc->ray_inv_dir[i] =
- (neasrest_precalc->ray_direction[i] != 0.0f) ?
- (1.0f / neasrest_precalc->ray_direction[i]) : FLT_MAX;
- }
+ for (int i = 0; i < 3; i++) {
+ neasrest_precalc->ray_inv_dir[i] = (neasrest_precalc->ray_direction[i] != 0.0f) ?
+ (1.0f / neasrest_precalc->ray_direction[i]) :
+ FLT_MAX;
+ }
}
/**
* Returns the distance from a ray to a bound-box (projected on ray)
*/
-float dist_squared_ray_to_aabb_v3(
- const struct DistRayAABB_Precalc *data,
- const float bb_min[3], const float bb_max[3],
- float r_point[3], float *r_depth)
-{
- // bool r_axis_closest[3];
- float local_bvmin[3], local_bvmax[3];
- aabb_get_near_far_from_plane(
- data->ray_direction, bb_min, bb_max, local_bvmin, local_bvmax);
-
- const float tmin[3] = {
- (local_bvmin[0] - data->ray_origin[0]) * data->ray_inv_dir[0],
- (local_bvmin[1] - data->ray_origin[1]) * data->ray_inv_dir[1],
- (local_bvmin[2] - data->ray_origin[2]) * data->ray_inv_dir[2],
- };
- const float tmax[3] = {
- (local_bvmax[0] - data->ray_origin[0]) * data->ray_inv_dir[0],
- (local_bvmax[1] - data->ray_origin[1]) * data->ray_inv_dir[1],
- (local_bvmax[2] - data->ray_origin[2]) * data->ray_inv_dir[2],
- };
- /* `va` and `vb` are the coordinates of the AABB edge closest to the ray */
- float va[3], vb[3];
- /* `rtmin` and `rtmax` are the minimum and maximum distances of the ray hits on the AABB */
- float rtmin, rtmax;
- int main_axis;
-
- if ((tmax[0] <= tmax[1]) && (tmax[0] <= tmax[2])) {
- rtmax = tmax[0];
- va[0] = vb[0] = local_bvmax[0];
- main_axis = 3;
- // r_axis_closest[0] = neasrest_precalc->ray_direction[0] < 0.0f;
- }
- else if ((tmax[1] <= tmax[0]) && (tmax[1] <= tmax[2])) {
- rtmax = tmax[1];
- va[1] = vb[1] = local_bvmax[1];
- main_axis = 2;
- // r_axis_closest[1] = neasrest_precalc->ray_direction[1] < 0.0f;
- }
- else {
- rtmax = tmax[2];
- va[2] = vb[2] = local_bvmax[2];
- main_axis = 1;
- // r_axis_closest[2] = neasrest_precalc->ray_direction[2] < 0.0f;
- }
-
- if ((tmin[0] >= tmin[1]) && (tmin[0] >= tmin[2])) {
- rtmin = tmin[0];
- va[0] = vb[0] = local_bvmin[0];
- main_axis -= 3;
- // r_axis_closest[0] = neasrest_precalc->ray_direction[0] >= 0.0f;
- }
- else if ((tmin[1] >= tmin[0]) && (tmin[1] >= tmin[2])) {
- rtmin = tmin[1];
- va[1] = vb[1] = local_bvmin[1];
- main_axis -= 1;
- // r_axis_closest[1] = neasrest_precalc->ray_direction[1] >= 0.0f;
- }
- else {
- rtmin = tmin[2];
- va[2] = vb[2] = local_bvmin[2];
- main_axis -= 2;
- // r_axis_closest[2] = neasrest_precalc->ray_direction[2] >= 0.0f;
- }
- if (main_axis < 0) {
- main_axis += 3;
- }
-
- /* if rtmin <= rtmax, ray intersect `AABB` */
- if (rtmin <= rtmax) {
- float dvec[3];
- copy_v3_v3(r_point, local_bvmax);
- sub_v3_v3v3(dvec, local_bvmax, data->ray_origin);
- *r_depth = dot_v3v3(dvec, data->ray_direction);
- return 0.0f;
- }
-
- if (data->ray_direction[main_axis] >= 0.0f) {
- va[main_axis] = local_bvmin[main_axis];
- vb[main_axis] = local_bvmax[main_axis];
- }
- else {
- va[main_axis] = local_bvmax[main_axis];
- vb[main_axis] = local_bvmin[main_axis];
- }
-
- return dist_squared_ray_to_seg_v3(
- data->ray_origin, data->ray_direction, va, vb,
- r_point, r_depth);
-}
-
-float dist_squared_ray_to_aabb_v3_simple(
- const float ray_origin[3], const float ray_direction[3],
- const float bbmin[3], const float bbmax[3],
- float r_point[3], float *r_depth)
-{
- struct DistRayAABB_Precalc data;
- dist_squared_ray_to_aabb_v3_precalc(&data, ray_origin, ray_direction);
- return dist_squared_ray_to_aabb_v3(&data, bbmin, bbmax, r_point, r_depth);
+float dist_squared_ray_to_aabb_v3(const struct DistRayAABB_Precalc *data,
+ const float bb_min[3],
+ const float bb_max[3],
+ float r_point[3],
+ float *r_depth)
+{
+ // bool r_axis_closest[3];
+ float local_bvmin[3], local_bvmax[3];
+ aabb_get_near_far_from_plane(data->ray_direction, bb_min, bb_max, local_bvmin, local_bvmax);
+
+ const float tmin[3] = {
+ (local_bvmin[0] - data->ray_origin[0]) * data->ray_inv_dir[0],
+ (local_bvmin[1] - data->ray_origin[1]) * data->ray_inv_dir[1],
+ (local_bvmin[2] - data->ray_origin[2]) * data->ray_inv_dir[2],
+ };
+ const float tmax[3] = {
+ (local_bvmax[0] - data->ray_origin[0]) * data->ray_inv_dir[0],
+ (local_bvmax[1] - data->ray_origin[1]) * data->ray_inv_dir[1],
+ (local_bvmax[2] - data->ray_origin[2]) * data->ray_inv_dir[2],
+ };
+ /* `va` and `vb` are the coordinates of the AABB edge closest to the ray */
+ float va[3], vb[3];
+ /* `rtmin` and `rtmax` are the minimum and maximum distances of the ray hits on the AABB */
+ float rtmin, rtmax;
+ int main_axis;
+
+ if ((tmax[0] <= tmax[1]) && (tmax[0] <= tmax[2])) {
+ rtmax = tmax[0];
+ va[0] = vb[0] = local_bvmax[0];
+ main_axis = 3;
+ // r_axis_closest[0] = neasrest_precalc->ray_direction[0] < 0.0f;
+ }
+ else if ((tmax[1] <= tmax[0]) && (tmax[1] <= tmax[2])) {
+ rtmax = tmax[1];
+ va[1] = vb[1] = local_bvmax[1];
+ main_axis = 2;
+ // r_axis_closest[1] = neasrest_precalc->ray_direction[1] < 0.0f;
+ }
+ else {
+ rtmax = tmax[2];
+ va[2] = vb[2] = local_bvmax[2];
+ main_axis = 1;
+ // r_axis_closest[2] = neasrest_precalc->ray_direction[2] < 0.0f;
+ }
+
+ if ((tmin[0] >= tmin[1]) && (tmin[0] >= tmin[2])) {
+ rtmin = tmin[0];
+ va[0] = vb[0] = local_bvmin[0];
+ main_axis -= 3;
+ // r_axis_closest[0] = neasrest_precalc->ray_direction[0] >= 0.0f;
+ }
+ else if ((tmin[1] >= tmin[0]) && (tmin[1] >= tmin[2])) {
+ rtmin = tmin[1];
+ va[1] = vb[1] = local_bvmin[1];
+ main_axis -= 1;
+ // r_axis_closest[1] = neasrest_precalc->ray_direction[1] >= 0.0f;
+ }
+ else {
+ rtmin = tmin[2];
+ va[2] = vb[2] = local_bvmin[2];
+ main_axis -= 2;
+ // r_axis_closest[2] = neasrest_precalc->ray_direction[2] >= 0.0f;
+ }
+ if (main_axis < 0) {
+ main_axis += 3;
+ }
+
+ /* if rtmin <= rtmax, ray intersect `AABB` */
+ if (rtmin <= rtmax) {
+ float dvec[3];
+ copy_v3_v3(r_point, local_bvmax);
+ sub_v3_v3v3(dvec, local_bvmax, data->ray_origin);
+ *r_depth = dot_v3v3(dvec, data->ray_direction);
+ return 0.0f;
+ }
+
+ if (data->ray_direction[main_axis] >= 0.0f) {
+ va[main_axis] = local_bvmin[main_axis];
+ vb[main_axis] = local_bvmax[main_axis];
+ }
+ else {
+ va[main_axis] = local_bvmax[main_axis];
+ vb[main_axis] = local_bvmin[main_axis];
+ }
+
+ return dist_squared_ray_to_seg_v3(
+ data->ray_origin, data->ray_direction, va, vb, r_point, r_depth);
+}
+
+float dist_squared_ray_to_aabb_v3_simple(const float ray_origin[3],
+ const float ray_direction[3],
+ const float bbmin[3],
+ const float bbmax[3],
+ float r_point[3],
+ float *r_depth)
+{
+ struct DistRayAABB_Precalc data;
+ dist_squared_ray_to_aabb_v3_precalc(&data, ray_origin, ray_direction);
+ return dist_squared_ray_to_aabb_v3(&data, bbmin, bbmax, r_point, r_depth);
}
/** \} */
-
/* -------------------------------------------------------------------- */
/** \name dist_squared_to_projected_aabb and helpers
* \{ */
@@ -782,290 +803,287 @@ float dist_squared_ray_to_aabb_v3_simple(
* \param projmat: Projection Matrix (usually perspective
* matrix multiplied by object matrix).
*/
-void dist_squared_to_projected_aabb_precalc(
- struct DistProjectedAABBPrecalc *precalc,
- const float projmat[4][4], const float winsize[2], const float mval[2])
+void dist_squared_to_projected_aabb_precalc(struct DistProjectedAABBPrecalc *precalc,
+ const float projmat[4][4],
+ const float winsize[2],
+ const float mval[2])
{
- float win_half[2], relative_mval[2], px[4], py[4];
+ float win_half[2], relative_mval[2], px[4], py[4];
- mul_v2_v2fl(win_half, winsize, 0.5f);
- sub_v2_v2v2(precalc->mval, mval, win_half);
+ mul_v2_v2fl(win_half, winsize, 0.5f);
+ sub_v2_v2v2(precalc->mval, mval, win_half);
- relative_mval[0] = precalc->mval[0] / win_half[0];
- relative_mval[1] = precalc->mval[1] / win_half[1];
+ relative_mval[0] = precalc->mval[0] / win_half[0];
+ relative_mval[1] = precalc->mval[1] / win_half[1];
- copy_m4_m4(precalc->pmat, projmat);
- for (int i = 0; i < 4; i++) {
- px[i] = precalc->pmat[i][0] - precalc->pmat[i][3] * relative_mval[0];
- py[i] = precalc->pmat[i][1] - precalc->pmat[i][3] * relative_mval[1];
+ copy_m4_m4(precalc->pmat, projmat);
+ for (int i = 0; i < 4; i++) {
+ px[i] = precalc->pmat[i][0] - precalc->pmat[i][3] * relative_mval[0];
+ py[i] = precalc->pmat[i][1] - precalc->pmat[i][3] * relative_mval[1];
- precalc->pmat[i][0] *= win_half[0];
- precalc->pmat[i][1] *= win_half[1];
- }
+ precalc->pmat[i][0] *= win_half[0];
+ precalc->pmat[i][1] *= win_half[1];
+ }
#if 0
- float projmat_trans[4][4];
- transpose_m4_m4(projmat_trans, projmat);
- if (!isect_plane_plane_plane_v3(
- projmat_trans[0], projmat_trans[1], projmat_trans[3],
- precalc->ray_origin))
- {
- /* Orthographic projection. */
- isect_plane_plane_v3(
- px, py,
- precalc->ray_origin,
- precalc->ray_direction);
- }
- else {
- /* Perspective projection. */
- cross_v3_v3v3(precalc->ray_direction, py, px);
- //normalize_v3(precalc->ray_direction);
- }
+ float projmat_trans[4][4];
+ transpose_m4_m4(projmat_trans, projmat);
+ if (!isect_plane_plane_plane_v3(
+ projmat_trans[0], projmat_trans[1], projmat_trans[3],
+ precalc->ray_origin))
+ {
+ /* Orthographic projection. */
+ isect_plane_plane_v3(
+ px, py,
+ precalc->ray_origin,
+ precalc->ray_direction);
+ }
+ else {
+ /* Perspective projection. */
+ cross_v3_v3v3(precalc->ray_direction, py, px);
+ //normalize_v3(precalc->ray_direction);
+ }
#else
- if (!isect_plane_plane_v3(
- px, py,
- precalc->ray_origin,
- precalc->ray_direction))
- {
- /* Matrix with weird coplanar planes. Undetermined origin.*/
- zero_v3(precalc->ray_origin);
- precalc->ray_direction[0] = precalc->pmat[0][3];
- precalc->ray_direction[1] = precalc->pmat[1][3];
- precalc->ray_direction[2] = precalc->pmat[2][3];
- }
+ if (!isect_plane_plane_v3(px, py, precalc->ray_origin, precalc->ray_direction)) {
+ /* Matrix with weird coplanar planes. Undetermined origin.*/
+ zero_v3(precalc->ray_origin);
+ precalc->ray_direction[0] = precalc->pmat[0][3];
+ precalc->ray_direction[1] = precalc->pmat[1][3];
+ precalc->ray_direction[2] = precalc->pmat[2][3];
+ }
#endif
- for (int i = 0; i < 3; i++) {
- precalc->ray_inv_dir[i] =
- (precalc->ray_direction[i] != 0.0f) ?
- (1.0f / precalc->ray_direction[i]) : FLT_MAX;
- }
+ for (int i = 0; i < 3; i++) {
+ precalc->ray_inv_dir[i] = (precalc->ray_direction[i] != 0.0f) ?
+ (1.0f / precalc->ray_direction[i]) :
+ FLT_MAX;
+ }
}
/* Returns the distance from a 2d coordinate to a BoundBox (Projected) */
-float dist_squared_to_projected_aabb(
- struct DistProjectedAABBPrecalc *data,
- const float bbmin[3], const float bbmax[3],
- bool r_axis_closest[3])
-{
- float local_bvmin[3], local_bvmax[3];
- aabb_get_near_far_from_plane(
- data->ray_direction, bbmin, bbmax, local_bvmin, local_bvmax);
-
- const float tmin[3] = {
- (local_bvmin[0] - data->ray_origin[0]) * data->ray_inv_dir[0],
- (local_bvmin[1] - data->ray_origin[1]) * data->ray_inv_dir[1],
- (local_bvmin[2] - data->ray_origin[2]) * data->ray_inv_dir[2],
- };
- const float tmax[3] = {
- (local_bvmax[0] - data->ray_origin[0]) * data->ray_inv_dir[0],
- (local_bvmax[1] - data->ray_origin[1]) * data->ray_inv_dir[1],
- (local_bvmax[2] - data->ray_origin[2]) * data->ray_inv_dir[2],
- };
- /* `va` and `vb` are the coordinates of the AABB edge closest to the ray */
- float va[3], vb[3];
- /* `rtmin` and `rtmax` are the minimum and maximum distances of the ray hits on the AABB */
- float rtmin, rtmax;
- int main_axis;
-
- r_axis_closest[0] = false;
- r_axis_closest[1] = false;
- r_axis_closest[2] = false;
-
- if ((tmax[0] <= tmax[1]) && (tmax[0] <= tmax[2])) {
- rtmax = tmax[0];
- va[0] = vb[0] = local_bvmax[0];
- main_axis = 3;
- r_axis_closest[0] = data->ray_direction[0] < 0.0f;
- }
- else if ((tmax[1] <= tmax[0]) && (tmax[1] <= tmax[2])) {
- rtmax = tmax[1];
- va[1] = vb[1] = local_bvmax[1];
- main_axis = 2;
- r_axis_closest[1] = data->ray_direction[1] < 0.0f;
- }
- else {
- rtmax = tmax[2];
- va[2] = vb[2] = local_bvmax[2];
- main_axis = 1;
- r_axis_closest[2] = data->ray_direction[2] < 0.0f;
- }
-
- if ((tmin[0] >= tmin[1]) && (tmin[0] >= tmin[2])) {
- rtmin = tmin[0];
- va[0] = vb[0] = local_bvmin[0];
- main_axis -= 3;
- r_axis_closest[0] = data->ray_direction[0] >= 0.0f;
- }
- else if ((tmin[1] >= tmin[0]) && (tmin[1] >= tmin[2])) {
- rtmin = tmin[1];
- va[1] = vb[1] = local_bvmin[1];
- main_axis -= 1;
- r_axis_closest[1] = data->ray_direction[1] >= 0.0f;
- }
- else {
- rtmin = tmin[2];
- va[2] = vb[2] = local_bvmin[2];
- main_axis -= 2;
- r_axis_closest[2] = data->ray_direction[2] >= 0.0f;
- }
- if (main_axis < 0) {
- main_axis += 3;
- }
-
- /* if rtmin <= rtmax, ray intersect `AABB` */
- if (rtmin <= rtmax) {
- return 0;
- }
-
- if (data->ray_direction[main_axis] >= 0.0f) {
- va[main_axis] = local_bvmin[main_axis];
- vb[main_axis] = local_bvmax[main_axis];
- }
- else {
- va[main_axis] = local_bvmax[main_axis];
- vb[main_axis] = local_bvmin[main_axis];
- }
- float scale = fabsf(local_bvmax[main_axis] - local_bvmin[main_axis]);
-
- float va2d[2] = {
- (dot_m4_v3_row_x(data->pmat, va) + data->pmat[3][0]),
- (dot_m4_v3_row_y(data->pmat, va) + data->pmat[3][1]),
- };
- float vb2d[2] = {
- (va2d[0] + data->pmat[main_axis][0] * scale),
- (va2d[1] + data->pmat[main_axis][1] * scale),
- };
-
- float w_a = mul_project_m4_v3_zfac(data->pmat, va);
- if (w_a != 1.0f) {
- /* Perspective Projection. */
- float w_b = w_a + data->pmat[main_axis][3] * scale;
- va2d[0] /= w_a;
- va2d[1] /= w_a;
- vb2d[0] /= w_b;
- vb2d[1] /= w_b;
- }
-
- float dvec[2], edge[2], lambda, rdist_sq;
- sub_v2_v2v2(dvec, data->mval, va2d);
- sub_v2_v2v2(edge, vb2d, va2d);
- lambda = dot_v2v2(dvec, edge);
- if (lambda != 0.0f) {
- lambda /= len_squared_v2(edge);
- if (lambda <= 0.0f) {
- rdist_sq = len_squared_v2v2(data->mval, va2d);
- r_axis_closest[main_axis] = true;
- }
- else if (lambda >= 1.0f) {
- rdist_sq = len_squared_v2v2(data->mval, vb2d);
- r_axis_closest[main_axis] = false;
- }
- else {
- madd_v2_v2fl(va2d, edge, lambda);
- rdist_sq = len_squared_v2v2(data->mval, va2d);
- r_axis_closest[main_axis] = lambda < 0.5f;
- }
- }
- else {
- rdist_sq = len_squared_v2v2(data->mval, va2d);
- }
-
- return rdist_sq;
-}
-
-float dist_squared_to_projected_aabb_simple(
- const float projmat[4][4], const float winsize[2], const float mval[2],
- const float bbmin[3], const float bbmax[3])
-{
- struct DistProjectedAABBPrecalc data;
- dist_squared_to_projected_aabb_precalc(&data, projmat, winsize, mval);
-
- bool dummy[3] = {true, true, true};
- return dist_squared_to_projected_aabb(&data, bbmin, bbmax, dummy);
+float dist_squared_to_projected_aabb(struct DistProjectedAABBPrecalc *data,
+ const float bbmin[3],
+ const float bbmax[3],
+ bool r_axis_closest[3])
+{
+ float local_bvmin[3], local_bvmax[3];
+ aabb_get_near_far_from_plane(data->ray_direction, bbmin, bbmax, local_bvmin, local_bvmax);
+
+ const float tmin[3] = {
+ (local_bvmin[0] - data->ray_origin[0]) * data->ray_inv_dir[0],
+ (local_bvmin[1] - data->ray_origin[1]) * data->ray_inv_dir[1],
+ (local_bvmin[2] - data->ray_origin[2]) * data->ray_inv_dir[2],
+ };
+ const float tmax[3] = {
+ (local_bvmax[0] - data->ray_origin[0]) * data->ray_inv_dir[0],
+ (local_bvmax[1] - data->ray_origin[1]) * data->ray_inv_dir[1],
+ (local_bvmax[2] - data->ray_origin[2]) * data->ray_inv_dir[2],
+ };
+ /* `va` and `vb` are the coordinates of the AABB edge closest to the ray */
+ float va[3], vb[3];
+ /* `rtmin` and `rtmax` are the minimum and maximum distances of the ray hits on the AABB */
+ float rtmin, rtmax;
+ int main_axis;
+
+ r_axis_closest[0] = false;
+ r_axis_closest[1] = false;
+ r_axis_closest[2] = false;
+
+ if ((tmax[0] <= tmax[1]) && (tmax[0] <= tmax[2])) {
+ rtmax = tmax[0];
+ va[0] = vb[0] = local_bvmax[0];
+ main_axis = 3;
+ r_axis_closest[0] = data->ray_direction[0] < 0.0f;
+ }
+ else if ((tmax[1] <= tmax[0]) && (tmax[1] <= tmax[2])) {
+ rtmax = tmax[1];
+ va[1] = vb[1] = local_bvmax[1];
+ main_axis = 2;
+ r_axis_closest[1] = data->ray_direction[1] < 0.0f;
+ }
+ else {
+ rtmax = tmax[2];
+ va[2] = vb[2] = local_bvmax[2];
+ main_axis = 1;
+ r_axis_closest[2] = data->ray_direction[2] < 0.0f;
+ }
+
+ if ((tmin[0] >= tmin[1]) && (tmin[0] >= tmin[2])) {
+ rtmin = tmin[0];
+ va[0] = vb[0] = local_bvmin[0];
+ main_axis -= 3;
+ r_axis_closest[0] = data->ray_direction[0] >= 0.0f;
+ }
+ else if ((tmin[1] >= tmin[0]) && (tmin[1] >= tmin[2])) {
+ rtmin = tmin[1];
+ va[1] = vb[1] = local_bvmin[1];
+ main_axis -= 1;
+ r_axis_closest[1] = data->ray_direction[1] >= 0.0f;
+ }
+ else {
+ rtmin = tmin[2];
+ va[2] = vb[2] = local_bvmin[2];
+ main_axis -= 2;
+ r_axis_closest[2] = data->ray_direction[2] >= 0.0f;
+ }
+ if (main_axis < 0) {
+ main_axis += 3;
+ }
+
+ /* if rtmin <= rtmax, ray intersect `AABB` */
+ if (rtmin <= rtmax) {
+ return 0;
+ }
+
+ if (data->ray_direction[main_axis] >= 0.0f) {
+ va[main_axis] = local_bvmin[main_axis];
+ vb[main_axis] = local_bvmax[main_axis];
+ }
+ else {
+ va[main_axis] = local_bvmax[main_axis];
+ vb[main_axis] = local_bvmin[main_axis];
+ }
+ float scale = fabsf(local_bvmax[main_axis] - local_bvmin[main_axis]);
+
+ float va2d[2] = {
+ (dot_m4_v3_row_x(data->pmat, va) + data->pmat[3][0]),
+ (dot_m4_v3_row_y(data->pmat, va) + data->pmat[3][1]),
+ };
+ float vb2d[2] = {
+ (va2d[0] + data->pmat[main_axis][0] * scale),
+ (va2d[1] + data->pmat[main_axis][1] * scale),
+ };
+
+ float w_a = mul_project_m4_v3_zfac(data->pmat, va);
+ if (w_a != 1.0f) {
+ /* Perspective Projection. */
+ float w_b = w_a + data->pmat[main_axis][3] * scale;
+ va2d[0] /= w_a;
+ va2d[1] /= w_a;
+ vb2d[0] /= w_b;
+ vb2d[1] /= w_b;
+ }
+
+ float dvec[2], edge[2], lambda, rdist_sq;
+ sub_v2_v2v2(dvec, data->mval, va2d);
+ sub_v2_v2v2(edge, vb2d, va2d);
+ lambda = dot_v2v2(dvec, edge);
+ if (lambda != 0.0f) {
+ lambda /= len_squared_v2(edge);
+ if (lambda <= 0.0f) {
+ rdist_sq = len_squared_v2v2(data->mval, va2d);
+ r_axis_closest[main_axis] = true;
+ }
+ else if (lambda >= 1.0f) {
+ rdist_sq = len_squared_v2v2(data->mval, vb2d);
+ r_axis_closest[main_axis] = false;
+ }
+ else {
+ madd_v2_v2fl(va2d, edge, lambda);
+ rdist_sq = len_squared_v2v2(data->mval, va2d);
+ r_axis_closest[main_axis] = lambda < 0.5f;
+ }
+ }
+ else {
+ rdist_sq = len_squared_v2v2(data->mval, va2d);
+ }
+
+ return rdist_sq;
+}
+
+float dist_squared_to_projected_aabb_simple(const float projmat[4][4],
+ const float winsize[2],
+ const float mval[2],
+ const float bbmin[3],
+ const float bbmax[3])
+{
+ struct DistProjectedAABBPrecalc data;
+ dist_squared_to_projected_aabb_precalc(&data, projmat, winsize, mval);
+
+ bool dummy[3] = {true, true, true};
+ return dist_squared_to_projected_aabb(&data, bbmin, bbmax, dummy);
}
/** \} */
-
/* Adapted from "Real-Time Collision Detection" by Christer Ericson,
* published by Morgan Kaufmann Publishers, copyright 2005 Elsevier Inc.
*
* Set 'r' to the point in triangle (a, b, c) closest to point 'p' */
-void closest_on_tri_to_point_v3(float r[3], const float p[3],
- const float a[3], const float b[3], const float c[3])
-{
- float ab[3], ac[3], ap[3], d1, d2;
- float bp[3], d3, d4, vc, cp[3], d5, d6, vb, va;
- float denom, v, w;
-
- /* Check if P in vertex region outside A */
- sub_v3_v3v3(ab, b, a);
- sub_v3_v3v3(ac, c, a);
- sub_v3_v3v3(ap, p, a);
- d1 = dot_v3v3(ab, ap);
- d2 = dot_v3v3(ac, ap);
- if (d1 <= 0.0f && d2 <= 0.0f) {
- /* barycentric coordinates (1,0,0) */
- copy_v3_v3(r, a);
- return;
- }
-
- /* Check if P in vertex region outside B */
- sub_v3_v3v3(bp, p, b);
- d3 = dot_v3v3(ab, bp);
- d4 = dot_v3v3(ac, bp);
- if (d3 >= 0.0f && d4 <= d3) {
- /* barycentric coordinates (0,1,0) */
- copy_v3_v3(r, b);
- return;
- }
- /* Check if P in edge region of AB, if so return projection of P onto AB */
- vc = d1 * d4 - d3 * d2;
- if (vc <= 0.0f && d1 >= 0.0f && d3 <= 0.0f) {
- v = d1 / (d1 - d3);
- /* barycentric coordinates (1-v,v,0) */
- madd_v3_v3v3fl(r, a, ab, v);
- return;
- }
- /* Check if P in vertex region outside C */
- sub_v3_v3v3(cp, p, c);
- d5 = dot_v3v3(ab, cp);
- d6 = dot_v3v3(ac, cp);
- if (d6 >= 0.0f && d5 <= d6) {
- /* barycentric coordinates (0,0,1) */
- copy_v3_v3(r, c);
- return;
- }
- /* Check if P in edge region of AC, if so return projection of P onto AC */
- vb = d5 * d2 - d1 * d6;
- if (vb <= 0.0f && d2 >= 0.0f && d6 <= 0.0f) {
- w = d2 / (d2 - d6);
- /* barycentric coordinates (1-w,0,w) */
- madd_v3_v3v3fl(r, a, ac, w);
- return;
- }
- /* Check if P in edge region of BC, if so return projection of P onto BC */
- va = d3 * d6 - d5 * d4;
- if (va <= 0.0f && (d4 - d3) >= 0.0f && (d5 - d6) >= 0.0f) {
- w = (d4 - d3) / ((d4 - d3) + (d5 - d6));
- /* barycentric coordinates (0,1-w,w) */
- sub_v3_v3v3(r, c, b);
- mul_v3_fl(r, w);
- add_v3_v3(r, b);
- return;
- }
-
- /* P inside face region. Compute Q through its barycentric coordinates (u,v,w) */
- denom = 1.0f / (va + vb + vc);
- v = vb * denom;
- w = vc * denom;
-
- /* = u*a + v*b + w*c, u = va * denom = 1.0f - v - w */
- /* ac * w */
- mul_v3_fl(ac, w);
- /* a + ab * v */
- madd_v3_v3v3fl(r, a, ab, v);
- /* a + ab * v + ac * w */
- add_v3_v3(r, ac);
+void closest_on_tri_to_point_v3(
+ float r[3], const float p[3], const float a[3], const float b[3], const float c[3])
+{
+ float ab[3], ac[3], ap[3], d1, d2;
+ float bp[3], d3, d4, vc, cp[3], d5, d6, vb, va;
+ float denom, v, w;
+
+ /* Check if P in vertex region outside A */
+ sub_v3_v3v3(ab, b, a);
+ sub_v3_v3v3(ac, c, a);
+ sub_v3_v3v3(ap, p, a);
+ d1 = dot_v3v3(ab, ap);
+ d2 = dot_v3v3(ac, ap);
+ if (d1 <= 0.0f && d2 <= 0.0f) {
+ /* barycentric coordinates (1,0,0) */
+ copy_v3_v3(r, a);
+ return;
+ }
+
+ /* Check if P in vertex region outside B */
+ sub_v3_v3v3(bp, p, b);
+ d3 = dot_v3v3(ab, bp);
+ d4 = dot_v3v3(ac, bp);
+ if (d3 >= 0.0f && d4 <= d3) {
+ /* barycentric coordinates (0,1,0) */
+ copy_v3_v3(r, b);
+ return;
+ }
+ /* Check if P in edge region of AB, if so return projection of P onto AB */
+ vc = d1 * d4 - d3 * d2;
+ if (vc <= 0.0f && d1 >= 0.0f && d3 <= 0.0f) {
+ v = d1 / (d1 - d3);
+ /* barycentric coordinates (1-v,v,0) */
+ madd_v3_v3v3fl(r, a, ab, v);
+ return;
+ }
+ /* Check if P in vertex region outside C */
+ sub_v3_v3v3(cp, p, c);
+ d5 = dot_v3v3(ab, cp);
+ d6 = dot_v3v3(ac, cp);
+ if (d6 >= 0.0f && d5 <= d6) {
+ /* barycentric coordinates (0,0,1) */
+ copy_v3_v3(r, c);
+ return;
+ }
+ /* Check if P in edge region of AC, if so return projection of P onto AC */
+ vb = d5 * d2 - d1 * d6;
+ if (vb <= 0.0f && d2 >= 0.0f && d6 <= 0.0f) {
+ w = d2 / (d2 - d6);
+ /* barycentric coordinates (1-w,0,w) */
+ madd_v3_v3v3fl(r, a, ac, w);
+ return;
+ }
+ /* Check if P in edge region of BC, if so return projection of P onto BC */
+ va = d3 * d6 - d5 * d4;
+ if (va <= 0.0f && (d4 - d3) >= 0.0f && (d5 - d6) >= 0.0f) {
+ w = (d4 - d3) / ((d4 - d3) + (d5 - d6));
+ /* barycentric coordinates (0,1-w,w) */
+ sub_v3_v3v3(r, c, b);
+ mul_v3_fl(r, w);
+ add_v3_v3(r, b);
+ return;
+ }
+
+ /* P inside face region. Compute Q through its barycentric coordinates (u,v,w) */
+ denom = 1.0f / (va + vb + vc);
+ v = vb * denom;
+ w = vc * denom;
+
+ /* = u*a + v*b + w*c, u = va * denom = 1.0f - v - w */
+ /* ac * w */
+ mul_v3_fl(ac, w);
+ /* a + ab * v */
+ madd_v3_v3v3fl(r, a, ab, v);
+ /* a + ab * v + ac * w */
+ add_v3_v3(r, ac);
}
/******************************* Intersection ********************************/
@@ -1073,135 +1091,138 @@ void closest_on_tri_to_point_v3(float r[3], const float p[3],
/* intersect Line-Line, shorts */
int isect_seg_seg_v2_int(const int v1[2], const int v2[2], const int v3[2], const int v4[2])
{
- float div, lambda, mu;
+ float div, lambda, mu;
- div = (float)((v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0]));
- if (div == 0.0f) {
- return ISECT_LINE_LINE_COLINEAR;
- }
+ div = (float)((v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0]));
+ if (div == 0.0f) {
+ return ISECT_LINE_LINE_COLINEAR;
+ }
- lambda = (float)((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div;
+ lambda = (float)((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div;
- mu = (float)((v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div;
+ mu = (float)((v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div;
- if (lambda >= 0.0f && lambda <= 1.0f && mu >= 0.0f && mu <= 1.0f) {
- if (lambda == 0.0f || lambda == 1.0f || mu == 0.0f || mu == 1.0f) {
- return ISECT_LINE_LINE_EXACT;
- }
- return ISECT_LINE_LINE_CROSS;
- }
- return ISECT_LINE_LINE_NONE;
+ if (lambda >= 0.0f && lambda <= 1.0f && mu >= 0.0f && mu <= 1.0f) {
+ if (lambda == 0.0f || lambda == 1.0f || mu == 0.0f || mu == 1.0f) {
+ return ISECT_LINE_LINE_EXACT;
+ }
+ return ISECT_LINE_LINE_CROSS;
+ }
+ return ISECT_LINE_LINE_NONE;
}
/* intersect Line-Line, floats - gives intersection point */
-int isect_line_line_v2_point(const float v0[2], const float v1[2], const float v2[2], const float v3[2], float r_vi[2])
+int isect_line_line_v2_point(
+ const float v0[2], const float v1[2], const float v2[2], const float v3[2], float r_vi[2])
{
- float s10[2], s32[2];
- float div;
+ float s10[2], s32[2];
+ float div;
- sub_v2_v2v2(s10, v1, v0);
- sub_v2_v2v2(s32, v3, v2);
+ sub_v2_v2v2(s10, v1, v0);
+ sub_v2_v2v2(s32, v3, v2);
- div = cross_v2v2(s10, s32);
- if (div != 0.0f) {
- const float u = cross_v2v2(v1, v0);
- const float v = cross_v2v2(v3, v2);
+ div = cross_v2v2(s10, s32);
+ if (div != 0.0f) {
+ const float u = cross_v2v2(v1, v0);
+ const float v = cross_v2v2(v3, v2);
- r_vi[0] = ((s32[0] * u) - (s10[0] * v)) / div;
- r_vi[1] = ((s32[1] * u) - (s10[1] * v)) / div;
+ r_vi[0] = ((s32[0] * u) - (s10[0] * v)) / div;
+ r_vi[1] = ((s32[1] * u) - (s10[1] * v)) / div;
- return ISECT_LINE_LINE_CROSS;
- }
- else {
- return ISECT_LINE_LINE_COLINEAR;
- }
+ return ISECT_LINE_LINE_CROSS;
+ }
+ else {
+ return ISECT_LINE_LINE_COLINEAR;
+ }
}
/* intersect Line-Line, floats */
int isect_seg_seg_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2])
{
- float div, lambda, mu;
+ float div, lambda, mu;
- div = (v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0]);
- if (div == 0.0f) {
- return ISECT_LINE_LINE_COLINEAR;
- }
+ div = (v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0]);
+ if (div == 0.0f) {
+ return ISECT_LINE_LINE_COLINEAR;
+ }
- lambda = ((float)(v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div;
+ lambda = ((float)(v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div;
- mu = ((float)(v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div;
+ mu = ((float)(v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div;
- if (lambda >= 0.0f && lambda <= 1.0f && mu >= 0.0f && mu <= 1.0f) {
- if (lambda == 0.0f || lambda == 1.0f || mu == 0.0f || mu == 1.0f) {
- return ISECT_LINE_LINE_EXACT;
- }
- return ISECT_LINE_LINE_CROSS;
- }
- return ISECT_LINE_LINE_NONE;
+ if (lambda >= 0.0f && lambda <= 1.0f && mu >= 0.0f && mu <= 1.0f) {
+ if (lambda == 0.0f || lambda == 1.0f || mu == 0.0f || mu == 1.0f) {
+ return ISECT_LINE_LINE_EXACT;
+ }
+ return ISECT_LINE_LINE_CROSS;
+ }
+ return ISECT_LINE_LINE_NONE;
}
/* Returns a point on each segment that is closest to the other. */
-void isect_seg_seg_v3(
- const float a0[3], const float a1[3],
- const float b0[3], const float b1[3],
- float r_a[3], float r_b[3])
-{
- float fac_a, fac_b;
- float a_dir[3], b_dir[3], a0b0[3], crs_ab[3];
- sub_v3_v3v3(a_dir, a1, a0);
- sub_v3_v3v3(b_dir, b1, b0);
- sub_v3_v3v3(a0b0, b0, a0);
- cross_v3_v3v3(crs_ab, b_dir, a_dir);
- const float nlen = len_squared_v3(crs_ab);
-
- if (nlen == 0.0f) {
- /* Parallel Lines */
- /* In this case return any point that
- * is between the closest segments. */
- float a0b1[3], a1b0[3], len_a, len_b, fac1, fac2;
- sub_v3_v3v3(a0b1, b1, a0);
- sub_v3_v3v3(a1b0, b0, a1);
- len_a = len_squared_v3(a_dir);
- len_b = len_squared_v3(b_dir);
-
- if (len_a) {
- fac1 = dot_v3v3(a0b0, a_dir);
- fac2 = dot_v3v3(a0b1, a_dir);
- CLAMP(fac1, 0.0f, len_a);
- CLAMP(fac2, 0.0f, len_a);
- fac_a = (fac1 + fac2) / (2 * len_a);
- }
- else {
- fac_a = 0.0f;
- }
-
- if (len_b) {
- fac1 = -dot_v3v3(a0b0, b_dir);
- fac2 = -dot_v3v3(a1b0, b_dir);
- CLAMP(fac1, 0.0f, len_b);
- CLAMP(fac2, 0.0f, len_b);
- fac_b = (fac1 + fac2) / (2 * len_b);
- }
- else {
- fac_b = 0.0f;
- }
- }
- else {
- float c[3], cray[3];
- sub_v3_v3v3(c, crs_ab, a0b0);
-
- cross_v3_v3v3(cray, c, b_dir);
- fac_a = dot_v3v3(cray, crs_ab) / nlen;
-
- cross_v3_v3v3(cray, c, a_dir);
- fac_b = dot_v3v3(cray, crs_ab) / nlen;
-
- CLAMP(fac_a, 0.0f, 1.0f);
- CLAMP(fac_b, 0.0f, 1.0f);
- }
-
- madd_v3_v3v3fl(r_a, a0, a_dir, fac_a);
- madd_v3_v3v3fl(r_b, b0, b_dir, fac_b);
+void isect_seg_seg_v3(const float a0[3],
+ const float a1[3],
+ const float b0[3],
+ const float b1[3],
+ float r_a[3],
+ float r_b[3])
+{
+ float fac_a, fac_b;
+ float a_dir[3], b_dir[3], a0b0[3], crs_ab[3];
+ sub_v3_v3v3(a_dir, a1, a0);
+ sub_v3_v3v3(b_dir, b1, b0);
+ sub_v3_v3v3(a0b0, b0, a0);
+ cross_v3_v3v3(crs_ab, b_dir, a_dir);
+ const float nlen = len_squared_v3(crs_ab);
+
+ if (nlen == 0.0f) {
+ /* Parallel Lines */
+ /* In this case return any point that
+ * is between the closest segments. */
+ float a0b1[3], a1b0[3], len_a, len_b, fac1, fac2;
+ sub_v3_v3v3(a0b1, b1, a0);
+ sub_v3_v3v3(a1b0, b0, a1);
+ len_a = len_squared_v3(a_dir);
+ len_b = len_squared_v3(b_dir);
+
+ if (len_a) {
+ fac1 = dot_v3v3(a0b0, a_dir);
+ fac2 = dot_v3v3(a0b1, a_dir);
+ CLAMP(fac1, 0.0f, len_a);
+ CLAMP(fac2, 0.0f, len_a);
+ fac_a = (fac1 + fac2) / (2 * len_a);
+ }
+ else {
+ fac_a = 0.0f;
+ }
+
+ if (len_b) {
+ fac1 = -dot_v3v3(a0b0, b_dir);
+ fac2 = -dot_v3v3(a1b0, b_dir);
+ CLAMP(fac1, 0.0f, len_b);
+ CLAMP(fac2, 0.0f, len_b);
+ fac_b = (fac1 + fac2) / (2 * len_b);
+ }
+ else {
+ fac_b = 0.0f;
+ }
+ }
+ else {
+ float c[3], cray[3];
+ sub_v3_v3v3(c, crs_ab, a0b0);
+
+ cross_v3_v3v3(cray, c, b_dir);
+ fac_a = dot_v3v3(cray, crs_ab) / nlen;
+
+ cross_v3_v3v3(cray, c, a_dir);
+ fac_b = dot_v3v3(cray, crs_ab) / nlen;
+
+ CLAMP(fac_a, 0.0f, 1.0f);
+ CLAMP(fac_b, 0.0f, 1.0f);
+ }
+
+ madd_v3_v3v3fl(r_a, a0, a_dir, fac_a);
+ madd_v3_v3v3fl(r_b, b0, b_dir, fac_b);
}
/**
@@ -1217,127 +1238,123 @@ void isect_seg_seg_v3(
* - 1: intersection.
* - 0: no intersection.
*/
-int isect_seg_seg_v2_point_ex(
- const float v0[2], const float v1[2],
- const float v2[2], const float v3[2],
- const float endpoint_bias,
- float r_vi[2])
+int isect_seg_seg_v2_point_ex(const float v0[2],
+ const float v1[2],
+ const float v2[2],
+ const float v3[2],
+ const float endpoint_bias,
+ float r_vi[2])
{
- float s10[2], s32[2], s30[2], d;
- const float eps = 1e-6f;
- const float endpoint_min = -endpoint_bias;
- const float endpoint_max = endpoint_bias + 1.0f;
+ float s10[2], s32[2], s30[2], d;
+ const float eps = 1e-6f;
+ const float endpoint_min = -endpoint_bias;
+ const float endpoint_max = endpoint_bias + 1.0f;
- sub_v2_v2v2(s10, v1, v0);
- sub_v2_v2v2(s32, v3, v2);
- sub_v2_v2v2(s30, v3, v0);
+ sub_v2_v2v2(s10, v1, v0);
+ sub_v2_v2v2(s32, v3, v2);
+ sub_v2_v2v2(s30, v3, v0);
- d = cross_v2v2(s10, s32);
+ d = cross_v2v2(s10, s32);
- if (d != 0) {
- float u, v;
+ if (d != 0) {
+ float u, v;
- u = cross_v2v2(s30, s32) / d;
- v = cross_v2v2(s10, s30) / d;
+ u = cross_v2v2(s30, s32) / d;
+ v = cross_v2v2(s10, s30) / d;
- if ((u >= endpoint_min && u <= endpoint_max) &&
- (v >= endpoint_min && v <= endpoint_max))
- {
- /* intersection */
- float vi_test[2];
- float s_vi_v2[2];
+ if ((u >= endpoint_min && u <= endpoint_max) && (v >= endpoint_min && v <= endpoint_max)) {
+ /* intersection */
+ float vi_test[2];
+ float s_vi_v2[2];
- madd_v2_v2v2fl(vi_test, v0, s10, u);
+ madd_v2_v2v2fl(vi_test, v0, s10, u);
- /* When 'd' approaches zero, float precision lets non-overlapping co-linear segments
- * detect as an intersection. So re-calculate 'v' to ensure the point overlaps both.
- * see T45123 */
+ /* When 'd' approaches zero, float precision lets non-overlapping co-linear segments
+ * detect as an intersection. So re-calculate 'v' to ensure the point overlaps both.
+ * see T45123 */
- /* inline since we have most vars already */
+ /* inline since we have most vars already */
#if 0
- v = line_point_factor_v2(ix_test, v2, v3);
+ v = line_point_factor_v2(ix_test, v2, v3);
#else
- sub_v2_v2v2(s_vi_v2, vi_test, v2);
- v = (dot_v2v2(s32, s_vi_v2) / dot_v2v2(s32, s32));
+ sub_v2_v2v2(s_vi_v2, vi_test, v2);
+ v = (dot_v2v2(s32, s_vi_v2) / dot_v2v2(s32, s32));
#endif
- if (v >= endpoint_min && v <= endpoint_max) {
- copy_v2_v2(r_vi, vi_test);
- return 1;
- }
- }
-
- /* out of segment intersection */
- return -1;
- }
- else {
- if ((cross_v2v2(s10, s30) == 0.0f) &&
- (cross_v2v2(s32, s30) == 0.0f))
- {
- /* equal lines */
- float s20[2];
- float u_a, u_b;
-
- if (equals_v2v2(v0, v1)) {
- if (len_squared_v2v2(v2, v3) > SQUARE(eps)) {
- /* use non-point segment as basis */
- SWAP(const float *, v0, v2);
- SWAP(const float *, v1, v3);
-
- sub_v2_v2v2(s10, v1, v0);
- sub_v2_v2v2(s30, v3, v0);
- }
- else { /* both of segments are points */
- if (equals_v2v2(v0, v2)) { /* points are equal */
- copy_v2_v2(r_vi, v0);
- return 1;
- }
-
- /* two different points */
- return -1;
- }
- }
-
- sub_v2_v2v2(s20, v2, v0);
-
- u_a = dot_v2v2(s20, s10) / dot_v2v2(s10, s10);
- u_b = dot_v2v2(s30, s10) / dot_v2v2(s10, s10);
-
- if (u_a > u_b) {
- SWAP(float, u_a, u_b);
- }
-
- if (u_a > endpoint_max || u_b < endpoint_min) {
- /* non-overlapping segments */
- return -1;
- }
- else if (max_ff(0.0f, u_a) == min_ff(1.0f, u_b)) {
- /* one common point: can return result */
- madd_v2_v2v2fl(r_vi, v0, s10, max_ff(0, u_a));
- return 1;
- }
- }
-
- /* lines are collinear */
- return -1;
- }
+ if (v >= endpoint_min && v <= endpoint_max) {
+ copy_v2_v2(r_vi, vi_test);
+ return 1;
+ }
+ }
+
+ /* out of segment intersection */
+ return -1;
+ }
+ else {
+ if ((cross_v2v2(s10, s30) == 0.0f) && (cross_v2v2(s32, s30) == 0.0f)) {
+ /* equal lines */
+ float s20[2];
+ float u_a, u_b;
+
+ if (equals_v2v2(v0, v1)) {
+ if (len_squared_v2v2(v2, v3) > SQUARE(eps)) {
+ /* use non-point segment as basis */
+ SWAP(const float *, v0, v2);
+ SWAP(const float *, v1, v3);
+
+ sub_v2_v2v2(s10, v1, v0);
+ sub_v2_v2v2(s30, v3, v0);
+ }
+ else { /* both of segments are points */
+ if (equals_v2v2(v0, v2)) { /* points are equal */
+ copy_v2_v2(r_vi, v0);
+ return 1;
+ }
+
+ /* two different points */
+ return -1;
+ }
+ }
+
+ sub_v2_v2v2(s20, v2, v0);
+
+ u_a = dot_v2v2(s20, s10) / dot_v2v2(s10, s10);
+ u_b = dot_v2v2(s30, s10) / dot_v2v2(s10, s10);
+
+ if (u_a > u_b) {
+ SWAP(float, u_a, u_b);
+ }
+
+ if (u_a > endpoint_max || u_b < endpoint_min) {
+ /* non-overlapping segments */
+ return -1;
+ }
+ else if (max_ff(0.0f, u_a) == min_ff(1.0f, u_b)) {
+ /* one common point: can return result */
+ madd_v2_v2v2fl(r_vi, v0, s10, max_ff(0, u_a));
+ return 1;
+ }
+ }
+
+ /* lines are collinear */
+ return -1;
+ }
}
int isect_seg_seg_v2_point(
- const float v0[2], const float v1[2],
- const float v2[2], const float v3[2],
- float r_vi[2])
+ const float v0[2], const float v1[2], const float v2[2], const float v3[2], float r_vi[2])
{
- const float endpoint_bias = 1e-6f;
- return isect_seg_seg_v2_point_ex(v0, v1, v2, v3, endpoint_bias, r_vi);
+ const float endpoint_bias = 1e-6f;
+ return isect_seg_seg_v2_point_ex(v0, v1, v2, v3, endpoint_bias, r_vi);
}
-bool isect_seg_seg_v2_simple(const float v1[2], const float v2[2], const float v3[2], const float v4[2])
+bool isect_seg_seg_v2_simple(const float v1[2],
+ const float v2[2],
+ const float v3[2],
+ const float v4[2])
{
-#define CCW(A, B, C) \
- ((C[1] - A[1]) * (B[0] - A[0]) > \
- (B[1] - A[1]) * (C[0] - A[0]))
+#define CCW(A, B, C) ((C[1] - A[1]) * (B[0] - A[0]) > (B[1] - A[1]) * (C[0] - A[0]))
- return CCW(v1, v3, v4) != CCW(v2, v3, v4) && CCW(v1, v2, v3) != CCW(v1, v2, v4);
+ return CCW(v1, v3, v4) != CCW(v2, v3, v4) && CCW(v1, v2, v3) != CCW(v1, v2, v4);
#undef CCW
}
@@ -1355,364 +1372,377 @@ bool isect_seg_seg_v2_simple(const float v1[2], const float v2[2], const float v
* For example, when \a l1 is inside the sphere and \a l2 is outside,
* \a r_p1 will always be between \a l1 and \a l2.
*/
-int isect_line_sphere_v3(const float l1[3], const float l2[3],
- const float sp[3], const float r,
- float r_p1[3], float r_p2[3])
-{
- /* adapted for use in blender by Campbell Barton - 2011
- *
- * atelier iebele abel - 2001
- * atelier@iebele.nl
- * http://www.iebele.nl
- *
- * sphere_line_intersection function adapted from:
- * http://astronomy.swin.edu.au/pbourke/geometry/sphereline
- * Paul Bourke pbourke@swin.edu.au
- */
-
- const float ldir[3] = {
- l2[0] - l1[0],
- l2[1] - l1[1],
- l2[2] - l1[2],
- };
-
- const float a = len_squared_v3(ldir);
-
- const float b = 2.0f *
- (ldir[0] * (l1[0] - sp[0]) +
- ldir[1] * (l1[1] - sp[1]) +
- ldir[2] * (l1[2] - sp[2]));
-
- const float c =
- len_squared_v3(sp) +
- len_squared_v3(l1) -
- (2.0f * dot_v3v3(sp, l1)) -
- (r * r);
-
- const float i = b * b - 4.0f * a * c;
-
- float mu;
-
- if (i < 0.0f) {
- /* no intersections */
- return 0;
- }
- else if (i == 0.0f) {
- /* one intersection */
- mu = -b / (2.0f * a);
- madd_v3_v3v3fl(r_p1, l1, ldir, mu);
- return 1;
- }
- else if (i > 0.0f) {
- const float i_sqrt = sqrtf(i); /* avoid calc twice */
-
- /* first intersection */
- mu = (-b + i_sqrt) / (2.0f * a);
- madd_v3_v3v3fl(r_p1, l1, ldir, mu);
-
- /* second intersection */
- mu = (-b - i_sqrt) / (2.0f * a);
- madd_v3_v3v3fl(r_p2, l1, ldir, mu);
- return 2;
- }
- else {
- /* math domain error - nan */
- return -1;
- }
+int isect_line_sphere_v3(const float l1[3],
+ const float l2[3],
+ const float sp[3],
+ const float r,
+ float r_p1[3],
+ float r_p2[3])
+{
+ /* adapted for use in blender by Campbell Barton - 2011
+ *
+ * atelier iebele abel - 2001
+ * atelier@iebele.nl
+ * http://www.iebele.nl
+ *
+ * sphere_line_intersection function adapted from:
+ * http://astronomy.swin.edu.au/pbourke/geometry/sphereline
+ * Paul Bourke pbourke@swin.edu.au
+ */
+
+ const float ldir[3] = {
+ l2[0] - l1[0],
+ l2[1] - l1[1],
+ l2[2] - l1[2],
+ };
+
+ const float a = len_squared_v3(ldir);
+
+ const float b = 2.0f * (ldir[0] * (l1[0] - sp[0]) + ldir[1] * (l1[1] - sp[1]) +
+ ldir[2] * (l1[2] - sp[2]));
+
+ const float c = len_squared_v3(sp) + len_squared_v3(l1) - (2.0f * dot_v3v3(sp, l1)) - (r * r);
+
+ const float i = b * b - 4.0f * a * c;
+
+ float mu;
+
+ if (i < 0.0f) {
+ /* no intersections */
+ return 0;
+ }
+ else if (i == 0.0f) {
+ /* one intersection */
+ mu = -b / (2.0f * a);
+ madd_v3_v3v3fl(r_p1, l1, ldir, mu);
+ return 1;
+ }
+ else if (i > 0.0f) {
+ const float i_sqrt = sqrtf(i); /* avoid calc twice */
+
+ /* first intersection */
+ mu = (-b + i_sqrt) / (2.0f * a);
+ madd_v3_v3v3fl(r_p1, l1, ldir, mu);
+
+ /* second intersection */
+ mu = (-b - i_sqrt) / (2.0f * a);
+ madd_v3_v3v3fl(r_p2, l1, ldir, mu);
+ return 2;
+ }
+ else {
+ /* math domain error - nan */
+ return -1;
+ }
}
/* keep in sync with isect_line_sphere_v3 */
-int isect_line_sphere_v2(const float l1[2], const float l2[2],
- const float sp[2], const float r,
- float r_p1[2], float r_p2[2])
-{
- const float ldir[2] = {l2[0] - l1[0],
- l2[1] - l1[1]};
-
- const float a = dot_v2v2(ldir, ldir);
-
- const float b = 2.0f *
- (ldir[0] * (l1[0] - sp[0]) +
- ldir[1] * (l1[1] - sp[1]));
-
- const float c =
- dot_v2v2(sp, sp) +
- dot_v2v2(l1, l1) -
- (2.0f * dot_v2v2(sp, l1)) -
- (r * r);
-
- const float i = b * b - 4.0f * a * c;
-
- float mu;
-
- if (i < 0.0f) {
- /* no intersections */
- return 0;
- }
- else if (i == 0.0f) {
- /* one intersection */
- mu = -b / (2.0f * a);
- madd_v2_v2v2fl(r_p1, l1, ldir, mu);
- return 1;
- }
- else if (i > 0.0f) {
- const float i_sqrt = sqrtf(i); /* avoid calc twice */
-
- /* first intersection */
- mu = (-b + i_sqrt) / (2.0f * a);
- madd_v2_v2v2fl(r_p1, l1, ldir, mu);
-
- /* second intersection */
- mu = (-b - i_sqrt) / (2.0f * a);
- madd_v2_v2v2fl(r_p2, l1, ldir, mu);
- return 2;
- }
- else {
- /* math domain error - nan */
- return -1;
- }
+int isect_line_sphere_v2(const float l1[2],
+ const float l2[2],
+ const float sp[2],
+ const float r,
+ float r_p1[2],
+ float r_p2[2])
+{
+ const float ldir[2] = {l2[0] - l1[0], l2[1] - l1[1]};
+
+ const float a = dot_v2v2(ldir, ldir);
+
+ const float b = 2.0f * (ldir[0] * (l1[0] - sp[0]) + ldir[1] * (l1[1] - sp[1]));
+
+ const float c = dot_v2v2(sp, sp) + dot_v2v2(l1, l1) - (2.0f * dot_v2v2(sp, l1)) - (r * r);
+
+ const float i = b * b - 4.0f * a * c;
+
+ float mu;
+
+ if (i < 0.0f) {
+ /* no intersections */
+ return 0;
+ }
+ else if (i == 0.0f) {
+ /* one intersection */
+ mu = -b / (2.0f * a);
+ madd_v2_v2v2fl(r_p1, l1, ldir, mu);
+ return 1;
+ }
+ else if (i > 0.0f) {
+ const float i_sqrt = sqrtf(i); /* avoid calc twice */
+
+ /* first intersection */
+ mu = (-b + i_sqrt) / (2.0f * a);
+ madd_v2_v2v2fl(r_p1, l1, ldir, mu);
+
+ /* second intersection */
+ mu = (-b - i_sqrt) / (2.0f * a);
+ madd_v2_v2v2fl(r_p2, l1, ldir, mu);
+ return 2;
+ }
+ else {
+ /* math domain error - nan */
+ return -1;
+ }
}
/* point in polygon (keep float and int versions in sync) */
-bool isect_point_poly_v2(const float pt[2], const float verts[][2], const unsigned int nr,
+bool isect_point_poly_v2(const float pt[2],
+ const float verts[][2],
+ const unsigned int nr,
const bool UNUSED(use_holes))
{
- unsigned int i, j;
- bool isect = false;
- for (i = 0, j = nr - 1; i < nr; j = i++) {
- if (((verts[i][1] > pt[1]) != (verts[j][1] > pt[1])) &&
- (pt[0] < (verts[j][0] - verts[i][0]) * (pt[1] - verts[i][1]) / (verts[j][1] - verts[i][1]) + verts[i][0]))
- {
- isect = !isect;
- }
- }
- return isect;
-}
-bool isect_point_poly_v2_int(const int pt[2], const int verts[][2], const unsigned int nr,
+ unsigned int i, j;
+ bool isect = false;
+ for (i = 0, j = nr - 1; i < nr; j = i++) {
+ if (((verts[i][1] > pt[1]) != (verts[j][1] > pt[1])) &&
+ (pt[0] <
+ (verts[j][0] - verts[i][0]) * (pt[1] - verts[i][1]) / (verts[j][1] - verts[i][1]) +
+ verts[i][0])) {
+ isect = !isect;
+ }
+ }
+ return isect;
+}
+bool isect_point_poly_v2_int(const int pt[2],
+ const int verts[][2],
+ const unsigned int nr,
const bool UNUSED(use_holes))
{
- unsigned int i, j;
- bool isect = false;
- for (i = 0, j = nr - 1; i < nr; j = i++) {
- if (((verts[i][1] > pt[1]) != (verts[j][1] > pt[1])) &&
- (pt[0] < (verts[j][0] - verts[i][0]) * (pt[1] - verts[i][1]) / (verts[j][1] - verts[i][1]) + verts[i][0]))
- {
- isect = !isect;
- }
- }
- return isect;
+ unsigned int i, j;
+ bool isect = false;
+ for (i = 0, j = nr - 1; i < nr; j = i++) {
+ if (((verts[i][1] > pt[1]) != (verts[j][1] > pt[1])) &&
+ (pt[0] <
+ (verts[j][0] - verts[i][0]) * (pt[1] - verts[i][1]) / (verts[j][1] - verts[i][1]) +
+ verts[i][0])) {
+ isect = !isect;
+ }
+ }
+ return isect;
}
/* point in tri */
/* only single direction */
-bool isect_point_tri_v2_cw(const float pt[2], const float v1[2], const float v2[2], const float v3[2])
+bool isect_point_tri_v2_cw(const float pt[2],
+ const float v1[2],
+ const float v2[2],
+ const float v3[2])
{
- 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 true;
- }
- }
- }
+ 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 true;
+ }
+ }
+ }
- return false;
+ return false;
}
int isect_point_tri_v2(const float pt[2], const float v1[2], const float v2[2], const float v3[2])
{
- 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;
- }
- }
- }
- else {
- if (!(line_point_side_v2(v2, v3, pt) >= 0.0f)) {
- if (!(line_point_side_v2(v3, v1, pt) >= 0.0f)) {
- return -1;
- }
- }
- }
+ 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;
+ }
+ }
+ }
+ else {
+ if (!(line_point_side_v2(v2, v3, pt) >= 0.0f)) {
+ if (!(line_point_side_v2(v3, v1, pt) >= 0.0f)) {
+ return -1;
+ }
+ }
+ }
- return 0;
+ return 0;
}
/* point in quad - only convex quads */
-int isect_point_quad_v2(const float pt[2], const float v1[2], const float v2[2], const float v3[2], const float v4[2])
-{
- 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, v4, pt) >= 0.0f) {
- if (line_point_side_v2(v4, v1, pt) >= 0.0f) {
- return 1;
- }
- }
- }
- }
- else {
- if (!(line_point_side_v2(v2, v3, pt) >= 0.0f)) {
- if (!(line_point_side_v2(v3, v4, pt) >= 0.0f)) {
- if (!(line_point_side_v2(v4, v1, pt) >= 0.0f)) {
- return -1;
- }
- }
- }
- }
-
- return 0;
+int isect_point_quad_v2(
+ const float pt[2], const float v1[2], const float v2[2], const float v3[2], const float v4[2])
+{
+ 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, v4, pt) >= 0.0f) {
+ if (line_point_side_v2(v4, v1, pt) >= 0.0f) {
+ return 1;
+ }
+ }
+ }
+ }
+ else {
+ if (!(line_point_side_v2(v2, v3, pt) >= 0.0f)) {
+ if (!(line_point_side_v2(v3, v4, pt) >= 0.0f)) {
+ if (!(line_point_side_v2(v4, v1, pt) >= 0.0f)) {
+ return -1;
+ }
+ }
+ }
+ }
+
+ return 0;
}
/* moved from effect.c
* test if the line starting at p1 ending at p2 intersects the triangle v0..v2
* return non zero if it does
*/
-bool isect_line_segment_tri_v3(
- const float p1[3], const float p2[3],
- const float v0[3], const float v1[3], const float v2[3],
- float *r_lambda, float r_uv[2])
+bool isect_line_segment_tri_v3(const float p1[3],
+ const float p2[3],
+ const float v0[3],
+ const float v1[3],
+ const float v2[3],
+ float *r_lambda,
+ float r_uv[2])
{
- float p[3], s[3], d[3], e1[3], e2[3], q[3];
- float a, f, u, v;
+ float p[3], s[3], d[3], e1[3], e2[3], q[3];
+ float a, f, u, v;
- sub_v3_v3v3(e1, v1, v0);
- sub_v3_v3v3(e2, v2, v0);
- sub_v3_v3v3(d, p2, p1);
+ sub_v3_v3v3(e1, v1, v0);
+ sub_v3_v3v3(e2, v2, v0);
+ sub_v3_v3v3(d, p2, p1);
- cross_v3_v3v3(p, d, e2);
- a = dot_v3v3(e1, p);
- if (a == 0.0f) {
- return false;
- }
- f = 1.0f / a;
+ cross_v3_v3v3(p, d, e2);
+ a = dot_v3v3(e1, p);
+ if (a == 0.0f) {
+ return false;
+ }
+ f = 1.0f / a;
- sub_v3_v3v3(s, p1, v0);
+ sub_v3_v3v3(s, p1, v0);
- u = f * dot_v3v3(s, p);
- if ((u < 0.0f) || (u > 1.0f)) {
- return false;
- }
+ u = f * dot_v3v3(s, p);
+ if ((u < 0.0f) || (u > 1.0f)) {
+ return false;
+ }
- cross_v3_v3v3(q, s, e1);
+ cross_v3_v3v3(q, s, e1);
- v = f * dot_v3v3(d, q);
- if ((v < 0.0f) || ((u + v) > 1.0f)) {
- return false;
- }
+ v = f * dot_v3v3(d, q);
+ 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 false;
- }
+ *r_lambda = f * dot_v3v3(e2, q);
+ if ((*r_lambda < 0.0f) || (*r_lambda > 1.0f)) {
+ return false;
+ }
- if (r_uv) {
- r_uv[0] = u;
- r_uv[1] = v;
- }
+ if (r_uv) {
+ r_uv[0] = u;
+ r_uv[1] = v;
+ }
- return true;
+ return true;
}
/* like isect_line_segment_tri_v3, but allows epsilon tolerance around triangle */
-bool isect_line_segment_tri_epsilon_v3(
- const float p1[3], const float p2[3],
- const float v0[3], const float v1[3], const float v2[3],
- float *r_lambda, float r_uv[2], const float epsilon)
+bool isect_line_segment_tri_epsilon_v3(const float p1[3],
+ const float p2[3],
+ const float v0[3],
+ const float v1[3],
+ const float v2[3],
+ float *r_lambda,
+ float r_uv[2],
+ const float epsilon)
{
- float p[3], s[3], d[3], e1[3], e2[3], q[3];
- float a, f, u, v;
+ float p[3], s[3], d[3], e1[3], e2[3], q[3];
+ float a, f, u, v;
- sub_v3_v3v3(e1, v1, v0);
- sub_v3_v3v3(e2, v2, v0);
- sub_v3_v3v3(d, p2, p1);
+ sub_v3_v3v3(e1, v1, v0);
+ sub_v3_v3v3(e2, v2, v0);
+ sub_v3_v3v3(d, p2, p1);
- cross_v3_v3v3(p, d, e2);
- a = dot_v3v3(e1, p);
- if (a == 0.0f) {
- return false;
- }
- f = 1.0f / a;
+ cross_v3_v3v3(p, d, e2);
+ a = dot_v3v3(e1, p);
+ if (a == 0.0f) {
+ return false;
+ }
+ f = 1.0f / a;
- sub_v3_v3v3(s, p1, v0);
+ sub_v3_v3v3(s, p1, v0);
- u = f * dot_v3v3(s, p);
- if ((u < -epsilon) || (u > 1.0f + epsilon)) {
- return false;
- }
+ u = f * dot_v3v3(s, p);
+ if ((u < -epsilon) || (u > 1.0f + epsilon)) {
+ return false;
+ }
- cross_v3_v3v3(q, s, e1);
+ cross_v3_v3v3(q, s, e1);
- v = f * dot_v3v3(d, q);
- if ((v < -epsilon) || ((u + v) > 1.0f + epsilon)) {
- return false;
- }
+ v = f * dot_v3v3(d, q);
+ 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 false;
- }
+ *r_lambda = f * dot_v3v3(e2, q);
+ if ((*r_lambda < 0.0f) || (*r_lambda > 1.0f)) {
+ return false;
+ }
- if (r_uv) {
- r_uv[0] = u;
- r_uv[1] = v;
- }
+ if (r_uv) {
+ r_uv[0] = u;
+ r_uv[1] = v;
+ }
- return true;
+ return true;
}
/* moved from effect.c
* test if the ray starting at p1 going in d direction intersects the triangle v0..v2
* return non zero if it does
*/
-bool isect_ray_tri_v3(
- const float ray_origin[3], const float ray_direction[3],
- const float v0[3], const float v1[3], const float v2[3],
- float *r_lambda, float r_uv[2])
+bool isect_ray_tri_v3(const float ray_origin[3],
+ const float ray_direction[3],
+ const float v0[3],
+ const float v1[3],
+ const float v2[3],
+ float *r_lambda,
+ float r_uv[2])
{
- /* 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 */
- const float epsilon = 0.00000001f;
- float p[3], s[3], e1[3], e2[3], q[3];
- float a, f, u, v;
+ /* 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 */
+ const float epsilon = 0.00000001f;
+ float p[3], s[3], e1[3], e2[3], q[3];
+ float a, f, u, v;
- sub_v3_v3v3(e1, v1, v0);
- sub_v3_v3v3(e2, v2, v0);
+ sub_v3_v3v3(e1, v1, v0);
+ sub_v3_v3v3(e2, v2, v0);
- cross_v3_v3v3(p, ray_direction, e2);
- a = dot_v3v3(e1, p);
- if ((a > -epsilon) && (a < epsilon)) {
- return false;
- }
- f = 1.0f / a;
+ cross_v3_v3v3(p, ray_direction, e2);
+ a = dot_v3v3(e1, p);
+ if ((a > -epsilon) && (a < epsilon)) {
+ return false;
+ }
+ f = 1.0f / a;
- sub_v3_v3v3(s, ray_origin, v0);
+ sub_v3_v3v3(s, ray_origin, v0);
- u = f * dot_v3v3(s, p);
- if ((u < 0.0f) || (u > 1.0f)) {
- return false;
- }
+ u = f * dot_v3v3(s, p);
+ if ((u < 0.0f) || (u > 1.0f)) {
+ return false;
+ }
- cross_v3_v3v3(q, s, e1);
+ cross_v3_v3v3(q, s, e1);
- v = f * dot_v3v3(ray_direction, q);
- if ((v < 0.0f) || ((u + v) > 1.0f)) {
- return false;
- }
+ v = f * dot_v3v3(ray_direction, q);
+ if ((v < 0.0f) || ((u + v) > 1.0f)) {
+ return false;
+ }
- *r_lambda = f * dot_v3v3(e2, q);
- if ((*r_lambda < 0.0f)) {
- return false;
- }
+ *r_lambda = f * dot_v3v3(e2, q);
+ if ((*r_lambda < 0.0f)) {
+ return false;
+ }
- if (r_uv) {
- r_uv[0] = u;
- r_uv[1] = v;
- }
+ if (r_uv) {
+ r_uv[0] = u;
+ r_uv[1] = v;
+ }
- return true;
+ return true;
}
/**
@@ -1721,187 +1751,196 @@ bool isect_ray_tri_v3(
*
* \note #line_plane_factor_v3() shares logic.
*/
-bool isect_ray_plane_v3(
- const float ray_origin[3], const float ray_direction[3],
- const float plane[4],
- float *r_lambda, const bool clip)
-{
- float h[3], plane_co[3];
- float dot;
-
- dot = dot_v3v3(plane, ray_direction);
- if (dot == 0.0f) {
- return false;
- }
- mul_v3_v3fl(plane_co, plane, (-plane[3] / len_squared_v3(plane)));
- sub_v3_v3v3(h, ray_origin, plane_co);
- *r_lambda = -dot_v3v3(plane, h) / dot;
- if (clip && (*r_lambda < 0.0f)) {
- return false;
- }
- return true;
-}
-
-bool isect_ray_tri_epsilon_v3(
- const float ray_origin[3], const float ray_direction[3],
- const float v0[3], const float v1[3], const float v2[3],
- float *r_lambda, float r_uv[2], const float epsilon)
-{
- float p[3], s[3], e1[3], e2[3], q[3];
- float a, f, u, v;
-
- sub_v3_v3v3(e1, v1, v0);
- sub_v3_v3v3(e2, v2, v0);
-
- cross_v3_v3v3(p, ray_direction, e2);
- a = dot_v3v3(e1, p);
- if (a == 0.0f) {
- return false;
- }
- f = 1.0f / a;
-
- sub_v3_v3v3(s, ray_origin, v0);
-
- u = f * dot_v3v3(s, p);
- if ((u < -epsilon) || (u > 1.0f + epsilon)) {
- return false;
- }
-
- cross_v3_v3v3(q, s, e1);
-
- v = f * dot_v3v3(ray_direction, q);
- if ((v < -epsilon) || ((u + v) > 1.0f + epsilon)) {
- return false;
- }
-
- *r_lambda = f * dot_v3v3(e2, q);
- if ((*r_lambda < 0.0f)) {
- return false;
- }
-
- if (r_uv) {
- r_uv[0] = u;
- r_uv[1] = v;
- }
-
- return true;
-}
-
-void isect_ray_tri_watertight_v3_precalc(struct IsectRayPrecalc *isect_precalc, const float ray_direction[3])
-{
- float inv_dir_z;
-
- /* Calculate dimension where the ray direction is maximal. */
- int kz = axis_dominant_v3_single(ray_direction);
- int kx = (kz != 2) ? (kz + 1) : 0;
- int ky = (kx != 2) ? (kx + 1) : 0;
-
- /* Swap kx and ky dimensions to preserve winding direction of triangles. */
- if (ray_direction[kz] < 0.0f) {
- SWAP(int, kx, ky);
- }
-
- /* Calculate the shear constants. */
- inv_dir_z = 1.0f / ray_direction[kz];
- isect_precalc->sx = ray_direction[kx] * inv_dir_z;
- isect_precalc->sy = ray_direction[ky] * inv_dir_z;
- isect_precalc->sz = inv_dir_z;
-
- /* Store the dimensions. */
- isect_precalc->kx = kx;
- isect_precalc->ky = ky;
- isect_precalc->kz = kz;
-}
-
-bool isect_ray_tri_watertight_v3(
- const float ray_origin[3], const struct IsectRayPrecalc *isect_precalc,
- const float v0[3], const float v1[3], const float v2[3],
- float *r_lambda, float r_uv[2])
-{
- const int kx = isect_precalc->kx;
- const int ky = isect_precalc->ky;
- const int kz = isect_precalc->kz;
- const float sx = isect_precalc->sx;
- const float sy = isect_precalc->sy;
- const float sz = isect_precalc->sz;
-
- /* Calculate vertices relative to ray origin. */
- const float a[3] = {v0[0] - ray_origin[0], v0[1] - ray_origin[1], v0[2] - ray_origin[2]};
- const float b[3] = {v1[0] - ray_origin[0], v1[1] - ray_origin[1], v1[2] - ray_origin[2]};
- const float c[3] = {v2[0] - ray_origin[0], v2[1] - ray_origin[1], v2[2] - ray_origin[2]};
-
- const float a_kx = a[kx], a_ky = a[ky], a_kz = a[kz];
- const float b_kx = b[kx], b_ky = b[ky], b_kz = b[kz];
- const float c_kx = c[kx], c_ky = c[ky], c_kz = c[kz];
-
- /* Perform shear and scale of vertices. */
- const float ax = a_kx - sx * a_kz;
- const float ay = a_ky - sy * a_kz;
- const float bx = b_kx - sx * b_kz;
- const float by = b_ky - sy * b_kz;
- const float cx = c_kx - sx * c_kz;
- const float cy = c_ky - sy * c_kz;
-
- /* Calculate scaled barycentric coordinates. */
- const float u = cx * by - cy * bx;
- const float v = ax * cy - ay * cx;
- const float w = bx * ay - by * ax;
- float det;
-
- if ((u < 0.0f || v < 0.0f || w < 0.0f) &&
- (u > 0.0f || v > 0.0f || w > 0.0f))
- {
- return false;
- }
-
- /* Calculate determinant. */
- det = u + v + w;
- if (UNLIKELY(det == 0.0f || !isfinite(det))) {
- return false;
- }
- else {
- /* Calculate scaled z-coordinates of vertices and use them to calculate
- * the hit distance.
- */
- const int sign_det = (float_as_int(det) & (int)0x80000000);
- const float t = (u * a_kz + v * b_kz + w * c_kz) * sz;
- const float sign_t = xor_fl(t, sign_det);
- if ((sign_t < 0.0f)
- /* differ from Cycles, don't read r_lambda's original value
- * otherwise we won't match any of the other intersect functions here...
- * which would be confusing */
+bool isect_ray_plane_v3(const float ray_origin[3],
+ const float ray_direction[3],
+ const float plane[4],
+ float *r_lambda,
+ const bool clip)
+{
+ float h[3], plane_co[3];
+ float dot;
+
+ dot = dot_v3v3(plane, ray_direction);
+ if (dot == 0.0f) {
+ return false;
+ }
+ mul_v3_v3fl(plane_co, plane, (-plane[3] / len_squared_v3(plane)));
+ sub_v3_v3v3(h, ray_origin, plane_co);
+ *r_lambda = -dot_v3v3(plane, h) / dot;
+ if (clip && (*r_lambda < 0.0f)) {
+ return false;
+ }
+ return true;
+}
+
+bool isect_ray_tri_epsilon_v3(const float ray_origin[3],
+ const float ray_direction[3],
+ const float v0[3],
+ const float v1[3],
+ const float v2[3],
+ float *r_lambda,
+ float r_uv[2],
+ const float epsilon)
+{
+ float p[3], s[3], e1[3], e2[3], q[3];
+ float a, f, u, v;
+
+ sub_v3_v3v3(e1, v1, v0);
+ sub_v3_v3v3(e2, v2, v0);
+
+ cross_v3_v3v3(p, ray_direction, e2);
+ a = dot_v3v3(e1, p);
+ if (a == 0.0f) {
+ return false;
+ }
+ f = 1.0f / a;
+
+ sub_v3_v3v3(s, ray_origin, v0);
+
+ u = f * dot_v3v3(s, p);
+ if ((u < -epsilon) || (u > 1.0f + epsilon)) {
+ return false;
+ }
+
+ cross_v3_v3v3(q, s, e1);
+
+ v = f * dot_v3v3(ray_direction, q);
+ if ((v < -epsilon) || ((u + v) > 1.0f + epsilon)) {
+ return false;
+ }
+
+ *r_lambda = f * dot_v3v3(e2, q);
+ if ((*r_lambda < 0.0f)) {
+ return false;
+ }
+
+ if (r_uv) {
+ r_uv[0] = u;
+ r_uv[1] = v;
+ }
+
+ return true;
+}
+
+void isect_ray_tri_watertight_v3_precalc(struct IsectRayPrecalc *isect_precalc,
+ const float ray_direction[3])
+{
+ float inv_dir_z;
+
+ /* Calculate dimension where the ray direction is maximal. */
+ int kz = axis_dominant_v3_single(ray_direction);
+ int kx = (kz != 2) ? (kz + 1) : 0;
+ int ky = (kx != 2) ? (kx + 1) : 0;
+
+ /* Swap kx and ky dimensions to preserve winding direction of triangles. */
+ if (ray_direction[kz] < 0.0f) {
+ SWAP(int, kx, ky);
+ }
+
+ /* Calculate the shear constants. */
+ inv_dir_z = 1.0f / ray_direction[kz];
+ isect_precalc->sx = ray_direction[kx] * inv_dir_z;
+ isect_precalc->sy = ray_direction[ky] * inv_dir_z;
+ isect_precalc->sz = inv_dir_z;
+
+ /* Store the dimensions. */
+ isect_precalc->kx = kx;
+ isect_precalc->ky = ky;
+ isect_precalc->kz = kz;
+}
+
+bool isect_ray_tri_watertight_v3(const float ray_origin[3],
+ const struct IsectRayPrecalc *isect_precalc,
+ const float v0[3],
+ const float v1[3],
+ const float v2[3],
+ float *r_lambda,
+ float r_uv[2])
+{
+ const int kx = isect_precalc->kx;
+ const int ky = isect_precalc->ky;
+ const int kz = isect_precalc->kz;
+ const float sx = isect_precalc->sx;
+ const float sy = isect_precalc->sy;
+ const float sz = isect_precalc->sz;
+
+ /* Calculate vertices relative to ray origin. */
+ const float a[3] = {v0[0] - ray_origin[0], v0[1] - ray_origin[1], v0[2] - ray_origin[2]};
+ const float b[3] = {v1[0] - ray_origin[0], v1[1] - ray_origin[1], v1[2] - ray_origin[2]};
+ const float c[3] = {v2[0] - ray_origin[0], v2[1] - ray_origin[1], v2[2] - ray_origin[2]};
+
+ const float a_kx = a[kx], a_ky = a[ky], a_kz = a[kz];
+ const float b_kx = b[kx], b_ky = b[ky], b_kz = b[kz];
+ const float c_kx = c[kx], c_ky = c[ky], c_kz = c[kz];
+
+ /* Perform shear and scale of vertices. */
+ const float ax = a_kx - sx * a_kz;
+ const float ay = a_ky - sy * a_kz;
+ const float bx = b_kx - sx * b_kz;
+ const float by = b_ky - sy * b_kz;
+ const float cx = c_kx - sx * c_kz;
+ const float cy = c_ky - sy * c_kz;
+
+ /* Calculate scaled barycentric coordinates. */
+ const float u = cx * by - cy * bx;
+ const float v = ax * cy - ay * cx;
+ const float w = bx * ay - by * ax;
+ float det;
+
+ if ((u < 0.0f || v < 0.0f || w < 0.0f) && (u > 0.0f || v > 0.0f || w > 0.0f)) {
+ return false;
+ }
+
+ /* Calculate determinant. */
+ det = u + v + w;
+ if (UNLIKELY(det == 0.0f || !isfinite(det))) {
+ return false;
+ }
+ else {
+ /* Calculate scaled z-coordinates of vertices and use them to calculate
+ * the hit distance.
+ */
+ const int sign_det = (float_as_int(det) & (int)0x80000000);
+ const float t = (u * a_kz + v * b_kz + w * c_kz) * sz;
+ const float sign_t = xor_fl(t, sign_det);
+ if ((sign_t < 0.0f)
+ /* differ from Cycles, don't read r_lambda's original value
+ * otherwise we won't match any of the other intersect functions here...
+ * which would be confusing */
#if 0
- ||
- (sign_T > *r_lambda * xor_signmask(det, sign_mask))
+ ||
+ (sign_T > *r_lambda * xor_signmask(det, sign_mask))
#endif
- )
- {
- return false;
- }
- else {
- /* Normalize u, v and t. */
- const float inv_det = 1.0f / det;
- if (r_uv) {
- r_uv[0] = u * inv_det;
- r_uv[1] = v * inv_det;
- }
- *r_lambda = t * inv_det;
- return true;
- }
- }
-}
-
-bool isect_ray_tri_watertight_v3_simple(
- const float ray_origin[3], const float ray_direction[3],
- const float v0[3], const float v1[3], const float v2[3],
- float *r_lambda, float r_uv[2])
-{
- struct IsectRayPrecalc isect_precalc;
- isect_ray_tri_watertight_v3_precalc(&isect_precalc, ray_direction);
- return isect_ray_tri_watertight_v3(ray_origin, &isect_precalc, v0, v1, v2, r_lambda, r_uv);
-}
-
-#if 0 /* UNUSED */
+ ) {
+ return false;
+ }
+ else {
+ /* Normalize u, v and t. */
+ const float inv_det = 1.0f / det;
+ if (r_uv) {
+ r_uv[0] = u * inv_det;
+ r_uv[1] = v * inv_det;
+ }
+ *r_lambda = t * inv_det;
+ return true;
+ }
+ }
+}
+
+bool isect_ray_tri_watertight_v3_simple(const float ray_origin[3],
+ const float ray_direction[3],
+ const float v0[3],
+ const float v1[3],
+ const float v2[3],
+ float *r_lambda,
+ float r_uv[2])
+{
+ struct IsectRayPrecalc isect_precalc;
+ isect_ray_tri_watertight_v3_precalc(&isect_precalc, ray_direction);
+ return isect_ray_tri_watertight_v3(ray_origin, &isect_precalc, v0, v1, v2, r_lambda, r_uv);
+}
+
+#if 0 /* UNUSED */
/**
* A version of #isect_ray_tri_v3 which takes a threshold argument
* so rays slightly outside the triangle to be considered as intersecting.
@@ -1911,164 +1950,162 @@ bool isect_ray_tri_threshold_v3(
const float v0[3], const float v1[3], const float v2[3],
float *r_lambda, float r_uv[2], const float threshold)
{
- const float epsilon = 0.00000001f;
- float p[3], s[3], e1[3], e2[3], q[3];
- float a, f, u, v;
- float du, dv;
+ const float epsilon = 0.00000001f;
+ float p[3], s[3], e1[3], e2[3], q[3];
+ float a, f, u, v;
+ float du, dv;
- sub_v3_v3v3(e1, v1, v0);
- sub_v3_v3v3(e2, v2, v0);
+ sub_v3_v3v3(e1, v1, v0);
+ sub_v3_v3v3(e2, v2, v0);
- cross_v3_v3v3(p, ray_direction, e2);
- a = dot_v3v3(e1, p);
- if ((a > -epsilon) && (a < epsilon)) return false;
- f = 1.0f / a;
+ cross_v3_v3v3(p, ray_direction, e2);
+ a = dot_v3v3(e1, p);
+ if ((a > -epsilon) && (a < epsilon)) return false;
+ f = 1.0f / a;
- sub_v3_v3v3(s, ray_origin, v0);
+ sub_v3_v3v3(s, ray_origin, v0);
- cross_v3_v3v3(q, s, e1);
- *r_lambda = f * dot_v3v3(e2, q);
- if ((*r_lambda < 0.0f)) return false;
+ cross_v3_v3v3(q, s, e1);
+ *r_lambda = f * dot_v3v3(e2, q);
+ if ((*r_lambda < 0.0f)) return false;
- u = f * dot_v3v3(s, p);
- v = f * dot_v3v3(ray_direction, q);
+ u = f * dot_v3v3(s, p);
+ v = f * dot_v3v3(ray_direction, q);
- if (u > 0 && v > 0 && u + v > 1) {
- float t = (u + v - 1) / 2;
- du = u - t;
- dv = v - t;
- }
- else {
- if (u < 0) du = u;
- else if (u > 1) du = u - 1;
- else du = 0.0f;
+ if (u > 0 && v > 0 && u + v > 1) {
+ float t = (u + v - 1) / 2;
+ du = u - t;
+ dv = v - t;
+ }
+ else {
+ if (u < 0) du = u;
+ else if (u > 1) du = u - 1;
+ else du = 0.0f;
- if (v < 0) dv = v;
- else if (v > 1) dv = v - 1;
- else dv = 0.0f;
- }
+ if (v < 0) dv = v;
+ else if (v > 1) dv = v - 1;
+ else dv = 0.0f;
+ }
- mul_v3_fl(e1, du);
- mul_v3_fl(e2, dv);
+ mul_v3_fl(e1, du);
+ mul_v3_fl(e2, dv);
- if (len_squared_v3(e1) + len_squared_v3(e2) > threshold * threshold) {
- return false;
- }
+ if (len_squared_v3(e1) + len_squared_v3(e2) > threshold * threshold) {
+ return false;
+ }
- if (r_uv) {
- r_uv[0] = u;
- r_uv[1] = v;
- }
+ if (r_uv) {
+ r_uv[0] = u;
+ r_uv[1] = v;
+ }
- return true;
+ return true;
}
#endif
-
-bool isect_ray_seg_v2(
- const float ray_origin[2], const float ray_direction[2],
- const float v0[2], const float v1[2],
- float *r_lambda, float *r_u)
+bool isect_ray_seg_v2(const float ray_origin[2],
+ const float ray_direction[2],
+ const float v0[2],
+ const float v1[2],
+ float *r_lambda,
+ float *r_u)
{
- float v0_local[2], v1_local[2];
- sub_v2_v2v2(v0_local, v0, ray_origin);
- sub_v2_v2v2(v1_local, v1, ray_origin);
+ float v0_local[2], v1_local[2];
+ sub_v2_v2v2(v0_local, v0, ray_origin);
+ sub_v2_v2v2(v1_local, v1, ray_origin);
- float s10[2];
- float det;
+ float s10[2];
+ float det;
- sub_v2_v2v2(s10, v1_local, v0_local);
+ sub_v2_v2v2(s10, v1_local, v0_local);
- det = cross_v2v2(ray_direction, s10);
- if (det != 0.0f) {
- const float v = cross_v2v2(v0_local, v1_local);
- float p[2] = {(ray_direction[0] * v) / det, (ray_direction[1] * v) / det};
+ det = cross_v2v2(ray_direction, s10);
+ if (det != 0.0f) {
+ const float v = cross_v2v2(v0_local, v1_local);
+ float p[2] = {(ray_direction[0] * v) / det, (ray_direction[1] * v) / det};
- const float t = (dot_v2v2(p, ray_direction) / dot_v2v2(ray_direction, ray_direction));
- if ((t >= 0.0f) == 0) {
- return false;
- }
+ const float t = (dot_v2v2(p, ray_direction) / dot_v2v2(ray_direction, ray_direction));
+ if ((t >= 0.0f) == 0) {
+ return false;
+ }
- float h[2];
- sub_v2_v2v2(h, v1_local, p);
- const float u = (dot_v2v2(s10, h) / dot_v2v2(s10, s10));
- if ((u >= 0.0f && u <= 1.0f) == 0) {
- return false;
- }
+ float h[2];
+ sub_v2_v2v2(h, v1_local, p);
+ const float u = (dot_v2v2(s10, h) / dot_v2v2(s10, s10));
+ if ((u >= 0.0f && u <= 1.0f) == 0) {
+ return false;
+ }
- if (r_lambda) {
- *r_lambda = t;
- }
- if (r_u) {
- *r_u = u;
- }
+ if (r_lambda) {
+ *r_lambda = t;
+ }
+ if (r_u) {
+ *r_u = u;
+ }
- return true;
- }
+ return true;
+ }
- return false;
+ return false;
}
-
-bool isect_ray_seg_v3(
- const float ray_origin[3], const float ray_direction[3],
- const float v0[3], const float v1[3],
- float *r_lambda)
+bool isect_ray_seg_v3(const float ray_origin[3],
+ const float ray_direction[3],
+ const float v0[3],
+ const float v1[3],
+ float *r_lambda)
{
- float a[3], t[3], n[3];
- sub_v3_v3v3(a, v1, v0);
- sub_v3_v3v3(t, v0, ray_origin);
- cross_v3_v3v3(n, a, ray_direction);
- const float nlen = len_squared_v3(n);
+ float a[3], t[3], n[3];
+ sub_v3_v3v3(a, v1, v0);
+ sub_v3_v3v3(t, v0, ray_origin);
+ cross_v3_v3v3(n, a, ray_direction);
+ const float nlen = len_squared_v3(n);
- if (nlen == 0.0f) {
- /* the lines are parallel.*/
- return false;
- }
+ if (nlen == 0.0f) {
+ /* the lines are parallel.*/
+ return false;
+ }
- float c[3], cray[3];
- sub_v3_v3v3(c, n, t);
- cross_v3_v3v3(cray, c, ray_direction);
+ float c[3], cray[3];
+ sub_v3_v3v3(c, n, t);
+ cross_v3_v3v3(cray, c, ray_direction);
- *r_lambda = dot_v3v3(cray, n) / nlen;
+ *r_lambda = dot_v3v3(cray, n) / nlen;
- return true;
+ return true;
}
-
/**
* Check if a point is behind all planes.
*/
bool isect_point_planes_v3(float (*planes)[4], int totplane, const float p[3])
{
- int i;
+ int i;
- for (i = 0; i < totplane; i++) {
- if (plane_point_side_v3(planes[i], p) > 0.0f) {
- return false;
- }
- }
+ for (i = 0; i < totplane; i++) {
+ if (plane_point_side_v3(planes[i], p) > 0.0f) {
+ return false;
+ }
+ }
- return true;
+ return true;
}
/**
* Check if a point is in front all planes.
* Same as isect_point_planes_v3 but with planes facing the opposite direction.
*/
-bool isect_point_planes_v3_negated(
- const float(*planes)[4], const int totplane, const float p[3])
+bool isect_point_planes_v3_negated(const float (*planes)[4], const int totplane, const float p[3])
{
- for (int i = 0; i < totplane; i++) {
- if (plane_point_side_v3(planes[i], p) <= 0.0f) {
- return false;
- }
- }
+ for (int i = 0; i < totplane; i++) {
+ if (plane_point_side_v3(planes[i], p) <= 0.0f) {
+ return false;
+ }
+ }
- return true;
+ return true;
}
-
/**
* Intersect line/plane.
*
@@ -2080,27 +2117,28 @@ bool isect_point_planes_v3_negated(
*
* \note #line_plane_factor_v3() shares logic.
*/
-bool isect_line_plane_v3(
- float r_isect_co[3],
- const float l1[3], const float l2[3],
- const float plane_co[3], const float plane_no[3])
-{
- float u[3], h[3];
- float dot;
-
- sub_v3_v3v3(u, l2, l1);
- sub_v3_v3v3(h, l1, plane_co);
- dot = dot_v3v3(plane_no, u);
-
- if (fabsf(dot) > FLT_EPSILON) {
- float lambda = -dot_v3v3(plane_no, h) / dot;
- madd_v3_v3v3fl(r_isect_co, l1, u, lambda);
- return true;
- }
- else {
- /* The segment is parallel to plane */
- return false;
- }
+bool isect_line_plane_v3(float r_isect_co[3],
+ const float l1[3],
+ const float l2[3],
+ const float plane_co[3],
+ const float plane_no[3])
+{
+ float u[3], h[3];
+ float dot;
+
+ sub_v3_v3v3(u, l2, l1);
+ sub_v3_v3v3(h, l1, plane_co);
+ dot = dot_v3v3(plane_no, u);
+
+ if (fabsf(dot) > FLT_EPSILON) {
+ float lambda = -dot_v3v3(plane_no, h) / dot;
+ madd_v3_v3v3fl(r_isect_co, l1, u, lambda);
+ return true;
+ }
+ else {
+ /* The segment is parallel to plane */
+ return false;
+ }
}
/**
@@ -2110,37 +2148,38 @@ bool isect_line_plane_v3(
* \param plane_a, plane_b, plane_c: Planes.
* \param r_isect_co: The resulting intersection point.
*/
-bool isect_plane_plane_plane_v3(
- const float plane_a[4], const float plane_b[4], const float plane_c[4],
- float r_isect_co[3])
+bool isect_plane_plane_plane_v3(const float plane_a[4],
+ const float plane_b[4],
+ const float plane_c[4],
+ float r_isect_co[3])
{
- float det;
+ float det;
- det = determinant_m3(UNPACK3(plane_a), UNPACK3(plane_b), UNPACK3(plane_c));
+ det = determinant_m3(UNPACK3(plane_a), UNPACK3(plane_b), UNPACK3(plane_c));
- if (det != 0.0f) {
- float tmp[3];
+ if (det != 0.0f) {
+ float tmp[3];
- /* (plane_b.xyz.cross(plane_c.xyz) * -plane_a[3] +
- * plane_c.xyz.cross(plane_a.xyz) * -plane_b[3] +
- * plane_a.xyz.cross(plane_b.xyz) * -plane_c[3]) / det; */
+ /* (plane_b.xyz.cross(plane_c.xyz) * -plane_a[3] +
+ * plane_c.xyz.cross(plane_a.xyz) * -plane_b[3] +
+ * plane_a.xyz.cross(plane_b.xyz) * -plane_c[3]) / det; */
- cross_v3_v3v3(tmp, plane_c, plane_b);
- mul_v3_v3fl(r_isect_co, tmp, plane_a[3]);
+ cross_v3_v3v3(tmp, plane_c, plane_b);
+ mul_v3_v3fl(r_isect_co, tmp, plane_a[3]);
- cross_v3_v3v3(tmp, plane_a, plane_c);
- madd_v3_v3fl(r_isect_co, tmp, plane_b[3]);
+ cross_v3_v3v3(tmp, plane_a, plane_c);
+ madd_v3_v3fl(r_isect_co, tmp, plane_b[3]);
- cross_v3_v3v3(tmp, plane_b, plane_a);
- madd_v3_v3fl(r_isect_co, tmp, plane_c[3]);
+ cross_v3_v3v3(tmp, plane_b, plane_a);
+ madd_v3_v3fl(r_isect_co, tmp, plane_c[3]);
- mul_v3_fl(r_isect_co, 1.0f / det);
+ mul_v3_fl(r_isect_co, 1.0f / det);
- return true;
- }
- else {
- return false;
- }
+ return true;
+ }
+ else {
+ return false;
+ }
}
/**
@@ -2154,38 +2193,39 @@ bool isect_plane_plane_plane_v3(
*
* \note \a r_isect_no isn't unit length.
*/
-bool isect_plane_plane_v3(
- const float plane_a[4], const float plane_b[4],
- float r_isect_co[3], float r_isect_no[3])
+bool isect_plane_plane_v3(const float plane_a[4],
+ const float plane_b[4],
+ float r_isect_co[3],
+ float r_isect_no[3])
{
- float det, plane_c[3];
+ float det, plane_c[3];
- /* direction is simply the cross product */
- cross_v3_v3v3(plane_c, plane_a, plane_b);
+ /* direction is simply the cross product */
+ cross_v3_v3v3(plane_c, plane_a, plane_b);
- /* in this case we don't need to use 'determinant_m3' */
- det = len_squared_v3(plane_c);
+ /* in this case we don't need to use 'determinant_m3' */
+ det = len_squared_v3(plane_c);
- if (det != 0.0f) {
- float tmp[3];
+ if (det != 0.0f) {
+ float tmp[3];
- /* (plane_b.xyz.cross(plane_c.xyz) * -plane_a[3] +
- * plane_c.xyz.cross(plane_a.xyz) * -plane_b[3]) / det; */
- cross_v3_v3v3(tmp, plane_c, plane_b);
- mul_v3_v3fl(r_isect_co, tmp, plane_a[3]);
+ /* (plane_b.xyz.cross(plane_c.xyz) * -plane_a[3] +
+ * plane_c.xyz.cross(plane_a.xyz) * -plane_b[3]) / det; */
+ cross_v3_v3v3(tmp, plane_c, plane_b);
+ mul_v3_v3fl(r_isect_co, tmp, plane_a[3]);
- cross_v3_v3v3(tmp, plane_a, plane_c);
- madd_v3_v3fl(r_isect_co, tmp, plane_b[3]);
+ cross_v3_v3v3(tmp, plane_a, plane_c);
+ madd_v3_v3fl(r_isect_co, tmp, plane_b[3]);
- mul_v3_fl(r_isect_co, 1.0f / det);
+ mul_v3_fl(r_isect_co, 1.0f / det);
- copy_v3_v3(r_isect_no, plane_c);
+ copy_v3_v3(r_isect_no, plane_c);
- return true;
- }
- else {
- return false;
- }
+ return true;
+ }
+ else {
+ return false;
+ }
}
/**
@@ -2196,138 +2236,140 @@ bool isect_plane_plane_v3(
*
* \note intersections between coplanar triangles are currently undetected.
*/
-bool isect_tri_tri_epsilon_v3(
- const float t_a0[3], const float t_a1[3], const float t_a2[3],
- const float t_b0[3], const float t_b1[3], const float t_b2[3],
- float r_i1[3], float r_i2[3],
- const float epsilon)
-{
- const float *tri_pair[2][3] = {{t_a0, t_a1, t_a2}, {t_b0, t_b1, t_b2}};
- float plane_a[4], plane_b[4];
- float plane_co[3], plane_no[3];
-
- BLI_assert((r_i1 != NULL) == (r_i2 != NULL));
-
- /* normalizing is needed for small triangles T46007 */
- normal_tri_v3(plane_a, UNPACK3(tri_pair[0]));
- normal_tri_v3(plane_b, UNPACK3(tri_pair[1]));
-
- plane_a[3] = -dot_v3v3(plane_a, t_a0);
- plane_b[3] = -dot_v3v3(plane_b, t_b0);
-
- if (isect_plane_plane_v3(plane_a, plane_b, plane_co, plane_no) &&
- (normalize_v3(plane_no) > epsilon))
- {
- /**
- * Implementation note: its simpler to project the triangles onto the intersection plane
- * before intersecting their edges with the ray, defined by 'isect_plane_plane_v3'.
- * This way we can use 'line_point_factor_v3_ex' to see if an edge crosses 'co_proj',
- * then use the factor to calculate the world-space point.
- */
- struct {
- float min, max;
- } range[2] = {{FLT_MAX, -FLT_MAX}, {FLT_MAX, -FLT_MAX}};
- int t;
- float co_proj[3];
-
- closest_to_plane3_normalized_v3(co_proj, plane_no, plane_co);
-
- /* For both triangles, find the overlap with the line defined by the ray [co_proj, plane_no].
- * When the ranges overlap we know the triangles do too. */
- for (t = 0; t < 2; t++) {
- int j, j_prev;
- float tri_proj[3][3];
-
- closest_to_plane3_normalized_v3(tri_proj[0], plane_no, tri_pair[t][0]);
- closest_to_plane3_normalized_v3(tri_proj[1], plane_no, tri_pair[t][1]);
- closest_to_plane3_normalized_v3(tri_proj[2], plane_no, tri_pair[t][2]);
-
- for (j = 0, j_prev = 2; j < 3; j_prev = j++) {
- /* note that its important to have a very small nonzero epsilon here
- * otherwise this fails for very small faces.
- * However if its too small, large adjacent faces will count as intersecting */
- const float edge_fac = line_point_factor_v3_ex(co_proj, tri_proj[j_prev], tri_proj[j], 1e-10f, -1.0f);
- /* ignore collinear lines, they are either an edge shared between 2 tri's
- * (which runs along [co_proj, plane_no], but can be safely ignored).
- *
- * or a collinear edge placed away from the ray -
- * which we don't intersect with & can ignore. */
- if (UNLIKELY(edge_fac == -1.0f)) {
- /* pass */
- }
- else if (edge_fac > 0.0f && edge_fac < 1.0f) {
- float ix_tri[3];
- float span_fac;
-
- interp_v3_v3v3(ix_tri, tri_pair[t][j_prev], tri_pair[t][j], edge_fac);
- /* the actual distance, since 'plane_no' is normalized */
- span_fac = dot_v3v3(plane_no, ix_tri);
-
- range[t].min = min_ff(range[t].min, span_fac);
- range[t].max = max_ff(range[t].max, span_fac);
- }
- }
-
- if (range[t].min == FLT_MAX) {
- return false;
- }
- }
-
- if (((range[0].min > range[1].max) ||
- (range[0].max < range[1].min)) == 0)
- {
- if (r_i1 && r_i2) {
- project_plane_normalized_v3_v3v3(plane_co, plane_co, plane_no);
- madd_v3_v3v3fl(r_i1, plane_co, plane_no, max_ff(range[0].min, range[1].min));
- madd_v3_v3v3fl(r_i2, plane_co, plane_no, min_ff(range[0].max, range[1].max));
- }
-
- return true;
- }
- }
-
- return false;
+bool isect_tri_tri_epsilon_v3(const float t_a0[3],
+ const float t_a1[3],
+ const float t_a2[3],
+ const float t_b0[3],
+ const float t_b1[3],
+ const float t_b2[3],
+ float r_i1[3],
+ float r_i2[3],
+ const float epsilon)
+{
+ const float *tri_pair[2][3] = {{t_a0, t_a1, t_a2}, {t_b0, t_b1, t_b2}};
+ float plane_a[4], plane_b[4];
+ float plane_co[3], plane_no[3];
+
+ BLI_assert((r_i1 != NULL) == (r_i2 != NULL));
+
+ /* normalizing is needed for small triangles T46007 */
+ normal_tri_v3(plane_a, UNPACK3(tri_pair[0]));
+ normal_tri_v3(plane_b, UNPACK3(tri_pair[1]));
+
+ plane_a[3] = -dot_v3v3(plane_a, t_a0);
+ plane_b[3] = -dot_v3v3(plane_b, t_b0);
+
+ if (isect_plane_plane_v3(plane_a, plane_b, plane_co, plane_no) &&
+ (normalize_v3(plane_no) > epsilon)) {
+ /**
+ * Implementation note: its simpler to project the triangles onto the intersection plane
+ * before intersecting their edges with the ray, defined by 'isect_plane_plane_v3'.
+ * This way we can use 'line_point_factor_v3_ex' to see if an edge crosses 'co_proj',
+ * then use the factor to calculate the world-space point.
+ */
+ struct {
+ float min, max;
+ } range[2] = {{FLT_MAX, -FLT_MAX}, {FLT_MAX, -FLT_MAX}};
+ int t;
+ float co_proj[3];
+
+ closest_to_plane3_normalized_v3(co_proj, plane_no, plane_co);
+
+ /* For both triangles, find the overlap with the line defined by the ray [co_proj, plane_no].
+ * When the ranges overlap we know the triangles do too. */
+ for (t = 0; t < 2; t++) {
+ int j, j_prev;
+ float tri_proj[3][3];
+
+ closest_to_plane3_normalized_v3(tri_proj[0], plane_no, tri_pair[t][0]);
+ closest_to_plane3_normalized_v3(tri_proj[1], plane_no, tri_pair[t][1]);
+ closest_to_plane3_normalized_v3(tri_proj[2], plane_no, tri_pair[t][2]);
+
+ for (j = 0, j_prev = 2; j < 3; j_prev = j++) {
+ /* note that its important to have a very small nonzero epsilon here
+ * otherwise this fails for very small faces.
+ * However if its too small, large adjacent faces will count as intersecting */
+ const float edge_fac = line_point_factor_v3_ex(
+ co_proj, tri_proj[j_prev], tri_proj[j], 1e-10f, -1.0f);
+ /* ignore collinear lines, they are either an edge shared between 2 tri's
+ * (which runs along [co_proj, plane_no], but can be safely ignored).
+ *
+ * or a collinear edge placed away from the ray -
+ * which we don't intersect with & can ignore. */
+ if (UNLIKELY(edge_fac == -1.0f)) {
+ /* pass */
+ }
+ else if (edge_fac > 0.0f && edge_fac < 1.0f) {
+ float ix_tri[3];
+ float span_fac;
+
+ interp_v3_v3v3(ix_tri, tri_pair[t][j_prev], tri_pair[t][j], edge_fac);
+ /* the actual distance, since 'plane_no' is normalized */
+ span_fac = dot_v3v3(plane_no, ix_tri);
+
+ range[t].min = min_ff(range[t].min, span_fac);
+ range[t].max = max_ff(range[t].max, span_fac);
+ }
+ }
+
+ if (range[t].min == FLT_MAX) {
+ return false;
+ }
+ }
+
+ if (((range[0].min > range[1].max) || (range[0].max < range[1].min)) == 0) {
+ if (r_i1 && r_i2) {
+ project_plane_normalized_v3_v3v3(plane_co, plane_co, plane_no);
+ madd_v3_v3v3fl(r_i1, plane_co, plane_no, max_ff(range[0].min, range[1].min));
+ madd_v3_v3v3fl(r_i2, plane_co, plane_no, min_ff(range[0].max, range[1].max));
+ }
+
+ return true;
+ }
+ }
+
+ return false;
}
/* Adapted from the paper by Kasper Fauerby */
/* "Improved Collision detection and Response" */
-static bool getLowestRoot(const float a, const float b, const float c, const float maxR, float *root)
-{
- /* Check if a solution exists */
- const float determinant = b * b - 4.0f * a * c;
-
- /* If determinant is negative it means no solutions. */
- if (determinant >= 0.0f) {
- /* calculate the two roots: (if determinant == 0 then
- * x1==x2 but lets disregard that slight optimization) */
- const float sqrtD = sqrtf(determinant);
- float r1 = (-b - sqrtD) / (2.0f * a);
- float r2 = (-b + sqrtD) / (2.0f * a);
-
- /* Sort so x1 <= x2 */
- if (r1 > r2) {
- SWAP(float, r1, r2);
- }
-
- /* Get lowest root: */
- if (r1 > 0.0f && r1 < maxR) {
- *root = r1;
- return true;
- }
-
- /* It is possible that we want x2 - this can happen */
- /* if x1 < 0 */
- if (r2 > 0.0f && r2 < maxR) {
- *root = r2;
- return true;
- }
- }
- /* No (valid) solutions */
- return false;
+static bool getLowestRoot(
+ const float a, const float b, const float c, const float maxR, float *root)
+{
+ /* Check if a solution exists */
+ const float determinant = b * b - 4.0f * a * c;
+
+ /* If determinant is negative it means no solutions. */
+ if (determinant >= 0.0f) {
+ /* calculate the two roots: (if determinant == 0 then
+ * x1==x2 but lets disregard that slight optimization) */
+ const float sqrtD = sqrtf(determinant);
+ float r1 = (-b - sqrtD) / (2.0f * a);
+ float r2 = (-b + sqrtD) / (2.0f * a);
+
+ /* Sort so x1 <= x2 */
+ if (r1 > r2) {
+ SWAP(float, r1, r2);
+ }
+
+ /* Get lowest root: */
+ if (r1 > 0.0f && r1 < maxR) {
+ *root = r1;
+ return true;
+ }
+
+ /* It is possible that we want x2 - this can happen */
+ /* if x1 < 0 */
+ if (r2 > 0.0f && r2 < maxR) {
+ *root = r2;
+ return true;
+ }
+ }
+ /* No (valid) solutions */
+ return false;
}
-
/**
* Checks status of an AABB in relation to a list of planes.
*
@@ -2336,268 +2378,272 @@ static bool getLowestRoot(const float a, const float b, const float c, const flo
* - ISECT_AABB_PLANE_CROSS_ANY (1): AABB intersects at least 1 plane;
* - ISECT_AABB_PLANE_IN_FRONT_ALL (2): AABB is completely in front of all planes;
*/
-int isect_aabb_planes_v3(
- const float (*planes)[4], const int totplane,
- const float bbmin[3], const float bbmax[3])
-{
- int ret = ISECT_AABB_PLANE_IN_FRONT_ALL;
-
- float bb_near[3], bb_far[3];
- for (int i = 0; i < totplane; i++) {
- aabb_get_near_far_from_plane(planes[i], bbmin, bbmax, bb_near, bb_far);
-
- if (plane_point_side_v3(planes[i], bb_far) < 0.0f) {
- return ISECT_AABB_PLANE_BEHIND_ANY;
- }
- else if ((ret != ISECT_AABB_PLANE_CROSS_ANY) &&
- (plane_point_side_v3(planes[i], bb_near) < 0.0f))
- {
- ret = ISECT_AABB_PLANE_CROSS_ANY;
- }
- }
-
- return ret;
-}
-
-bool isect_sweeping_sphere_tri_v3(const float p1[3], const float p2[3], const float radius,
- const float v0[3], const float v1[3], const float v2[3],
- float *r_lambda, float ipoint[3])
-{
- float e1[3], e2[3], e3[3], point[3], vel[3], /*dist[3],*/ nor[3], temp[3], bv[3];
- float a, b, c, d, e, x, y, z, radius2 = radius * radius;
- float elen2, edotv, edotbv, nordotv;
- float newLambda;
- bool found_by_sweep = false;
-
- sub_v3_v3v3(e1, v1, v0);
- sub_v3_v3v3(e2, v2, v0);
- sub_v3_v3v3(vel, p2, p1);
-
- /*---test plane of tri---*/
- cross_v3_v3v3(nor, e1, e2);
- normalize_v3(nor);
-
- /* flip normal */
- if (dot_v3v3(nor, vel) > 0.0f) {
- negate_v3(nor);
- }
-
- a = dot_v3v3(p1, nor) - dot_v3v3(v0, nor);
- nordotv = dot_v3v3(nor, vel);
-
- if (fabsf(nordotv) < 0.000001f) {
- if (fabsf(a) >= radius) {
- return false;
- }
- }
- else {
- float t0 = (-a + radius) / nordotv;
- float t1 = (-a - radius) / nordotv;
-
- if (t0 > t1) {
- SWAP(float, t0, t1);
- }
-
- if (t0 > 1.0f || t1 < 0.0f) {
- return false;
- }
-
- /* clamp to [0, 1] */
- CLAMP(t0, 0.0f, 1.0f);
- CLAMP(t1, 0.0f, 1.0f);
-
- /*---test inside of tri---*/
- /* plane intersection point */
-
- point[0] = p1[0] + vel[0] * t0 - nor[0] * radius;
- point[1] = p1[1] + vel[1] * t0 - nor[1] * radius;
- point[2] = p1[2] + vel[2] * t0 - nor[2] * radius;
-
-
- /* is the point in the tri? */
- a = dot_v3v3(e1, e1);
- b = dot_v3v3(e1, e2);
- c = dot_v3v3(e2, e2);
-
- sub_v3_v3v3(temp, point, v0);
- d = dot_v3v3(temp, e1);
- e = dot_v3v3(temp, e2);
-
- x = d * c - e * b;
- y = e * a - d * b;
- z = x + y - (a * c - b * b);
-
-
- if (z <= 0.0f && (x >= 0.0f && y >= 0.0f)) {
- //(((unsigned int)z)& ~(((unsigned int)x)|((unsigned int)y))) & 0x80000000) {
- *r_lambda = t0;
- copy_v3_v3(ipoint, point);
- return true;
- }
- }
-
-
- *r_lambda = 1.0f;
-
- /*---test points---*/
- a = dot_v3v3(vel, vel);
-
- /*v0*/
- sub_v3_v3v3(temp, p1, v0);
- b = 2.0f * dot_v3v3(vel, temp);
- c = dot_v3v3(temp, temp) - radius2;
-
- if (getLowestRoot(a, b, c, *r_lambda, r_lambda)) {
- copy_v3_v3(ipoint, v0);
- found_by_sweep = true;
- }
-
- /*v1*/
- sub_v3_v3v3(temp, p1, v1);
- b = 2.0f * dot_v3v3(vel, temp);
- c = dot_v3v3(temp, temp) - radius2;
-
- if (getLowestRoot(a, b, c, *r_lambda, r_lambda)) {
- copy_v3_v3(ipoint, v1);
- found_by_sweep = true;
- }
-
- /*v2*/
- sub_v3_v3v3(temp, p1, v2);
- b = 2.0f * dot_v3v3(vel, temp);
- c = dot_v3v3(temp, temp) - radius2;
-
- if (getLowestRoot(a, b, c, *r_lambda, r_lambda)) {
- copy_v3_v3(ipoint, v2);
- found_by_sweep = true;
- }
-
- /*---test edges---*/
- sub_v3_v3v3(e3, v2, v1); /* wasnt yet calculated */
-
-
- /*e1*/
- sub_v3_v3v3(bv, v0, p1);
-
- elen2 = dot_v3v3(e1, e1);
- edotv = dot_v3v3(e1, vel);
- edotbv = dot_v3v3(e1, bv);
-
- a = elen2 * (-dot_v3v3(vel, vel)) + edotv * edotv;
- b = 2.0f * (elen2 * dot_v3v3(vel, bv) - edotv * edotbv);
- c = elen2 * (radius2 - dot_v3v3(bv, bv)) + edotbv * edotbv;
-
- if (getLowestRoot(a, b, c, *r_lambda, &newLambda)) {
- e = (edotv * newLambda - edotbv) / elen2;
-
- if (e >= 0.0f && e <= 1.0f) {
- *r_lambda = newLambda;
- copy_v3_v3(ipoint, e1);
- mul_v3_fl(ipoint, e);
- add_v3_v3(ipoint, v0);
- found_by_sweep = true;
- }
- }
-
- /*e2*/
- /*bv is same*/
- elen2 = dot_v3v3(e2, e2);
- edotv = dot_v3v3(e2, vel);
- edotbv = dot_v3v3(e2, bv);
-
- a = elen2 * (-dot_v3v3(vel, vel)) + edotv * edotv;
- b = 2.0f * (elen2 * dot_v3v3(vel, bv) - edotv * edotbv);
- c = elen2 * (radius2 - dot_v3v3(bv, bv)) + edotbv * edotbv;
-
- if (getLowestRoot(a, b, c, *r_lambda, &newLambda)) {
- e = (edotv * newLambda - edotbv) / elen2;
-
- if (e >= 0.0f && e <= 1.0f) {
- *r_lambda = newLambda;
- copy_v3_v3(ipoint, e2);
- mul_v3_fl(ipoint, e);
- add_v3_v3(ipoint, v0);
- found_by_sweep = true;
- }
- }
-
- /*e3*/
- /* sub_v3_v3v3(bv, v0, p1); */ /* UNUSED */
- /* elen2 = dot_v3v3(e1, e1); */ /* UNUSED */
- /* edotv = dot_v3v3(e1, vel); */ /* UNUSED */
- /* edotbv = dot_v3v3(e1, bv); */ /* UNUSED */
-
- sub_v3_v3v3(bv, v1, p1);
- elen2 = dot_v3v3(e3, e3);
- edotv = dot_v3v3(e3, vel);
- edotbv = dot_v3v3(e3, bv);
-
- a = elen2 * (-dot_v3v3(vel, vel)) + edotv * edotv;
- b = 2.0f * (elen2 * dot_v3v3(vel, bv) - edotv * edotbv);
- c = elen2 * (radius2 - dot_v3v3(bv, bv)) + edotbv * edotbv;
-
- if (getLowestRoot(a, b, c, *r_lambda, &newLambda)) {
- e = (edotv * newLambda - edotbv) / elen2;
-
- if (e >= 0.0f && e <= 1.0f) {
- *r_lambda = newLambda;
- copy_v3_v3(ipoint, e3);
- mul_v3_fl(ipoint, e);
- add_v3_v3(ipoint, v1);
- found_by_sweep = true;
- }
- }
-
-
- return found_by_sweep;
-}
-
-bool isect_axial_line_segment_tri_v3(
- const int axis, const float p1[3], const float p2[3],
- const float v0[3], const float v1[3], const float v2[3], float *r_lambda)
-{
- const float epsilon = 0.000001f;
- float p[3], e1[3], e2[3];
- float u, v, f;
- int a0 = axis, a1 = (axis + 1) % 3, a2 = (axis + 2) % 3;
-
- sub_v3_v3v3(e1, v1, v0);
- sub_v3_v3v3(e2, v2, v0);
- sub_v3_v3v3(p, v0, p1);
-
- f = (e2[a1] * e1[a2] - e2[a2] * e1[a1]);
- if ((f > -epsilon) && (f < epsilon)) {
- return false;
- }
-
- v = (p[a2] * e1[a1] - p[a1] * e1[a2]) / f;
- if ((v < 0.0f) || (v > 1.0f)) {
- return false;
- }
-
- f = e1[a1];
- if ((f > -epsilon) && (f < epsilon)) {
- f = e1[a2];
- if ((f > -epsilon) && (f < epsilon)) {
- return false;
- }
- u = (-p[a2] - v * e2[a2]) / f;
- }
- else {
- u = (-p[a1] - v * e2[a1]) / f;
- }
-
- if ((u < 0.0f) || ((u + v) > 1.0f)) {
- return false;
- }
-
- *r_lambda = (p[a0] + u * e1[a0] + v * e2[a0]) / (p2[a0] - p1[a0]);
-
- if ((*r_lambda < 0.0f) || (*r_lambda > 1.0f)) {
- return false;
- }
-
- return true;
+int isect_aabb_planes_v3(const float (*planes)[4],
+ const int totplane,
+ const float bbmin[3],
+ const float bbmax[3])
+{
+ int ret = ISECT_AABB_PLANE_IN_FRONT_ALL;
+
+ float bb_near[3], bb_far[3];
+ for (int i = 0; i < totplane; i++) {
+ aabb_get_near_far_from_plane(planes[i], bbmin, bbmax, bb_near, bb_far);
+
+ if (plane_point_side_v3(planes[i], bb_far) < 0.0f) {
+ return ISECT_AABB_PLANE_BEHIND_ANY;
+ }
+ else if ((ret != ISECT_AABB_PLANE_CROSS_ANY) &&
+ (plane_point_side_v3(planes[i], bb_near) < 0.0f)) {
+ ret = ISECT_AABB_PLANE_CROSS_ANY;
+ }
+ }
+
+ return ret;
+}
+
+bool isect_sweeping_sphere_tri_v3(const float p1[3],
+ const float p2[3],
+ const float radius,
+ const float v0[3],
+ const float v1[3],
+ const float v2[3],
+ float *r_lambda,
+ float ipoint[3])
+{
+ float e1[3], e2[3], e3[3], point[3], vel[3], /*dist[3],*/ nor[3], temp[3], bv[3];
+ float a, b, c, d, e, x, y, z, radius2 = radius * radius;
+ float elen2, edotv, edotbv, nordotv;
+ float newLambda;
+ bool found_by_sweep = false;
+
+ sub_v3_v3v3(e1, v1, v0);
+ sub_v3_v3v3(e2, v2, v0);
+ sub_v3_v3v3(vel, p2, p1);
+
+ /*---test plane of tri---*/
+ cross_v3_v3v3(nor, e1, e2);
+ normalize_v3(nor);
+
+ /* flip normal */
+ if (dot_v3v3(nor, vel) > 0.0f) {
+ negate_v3(nor);
+ }
+
+ a = dot_v3v3(p1, nor) - dot_v3v3(v0, nor);
+ nordotv = dot_v3v3(nor, vel);
+
+ if (fabsf(nordotv) < 0.000001f) {
+ if (fabsf(a) >= radius) {
+ return false;
+ }
+ }
+ else {
+ float t0 = (-a + radius) / nordotv;
+ float t1 = (-a - radius) / nordotv;
+
+ if (t0 > t1) {
+ SWAP(float, t0, t1);
+ }
+
+ if (t0 > 1.0f || t1 < 0.0f) {
+ return false;
+ }
+
+ /* clamp to [0, 1] */
+ CLAMP(t0, 0.0f, 1.0f);
+ CLAMP(t1, 0.0f, 1.0f);
+
+ /*---test inside of tri---*/
+ /* plane intersection point */
+
+ point[0] = p1[0] + vel[0] * t0 - nor[0] * radius;
+ point[1] = p1[1] + vel[1] * t0 - nor[1] * radius;
+ point[2] = p1[2] + vel[2] * t0 - nor[2] * radius;
+
+ /* is the point in the tri? */
+ a = dot_v3v3(e1, e1);
+ b = dot_v3v3(e1, e2);
+ c = dot_v3v3(e2, e2);
+
+ sub_v3_v3v3(temp, point, v0);
+ d = dot_v3v3(temp, e1);
+ e = dot_v3v3(temp, e2);
+
+ x = d * c - e * b;
+ y = e * a - d * b;
+ z = x + y - (a * c - b * b);
+
+ if (z <= 0.0f && (x >= 0.0f && y >= 0.0f)) {
+ //(((unsigned int)z)& ~(((unsigned int)x)|((unsigned int)y))) & 0x80000000) {
+ *r_lambda = t0;
+ copy_v3_v3(ipoint, point);
+ return true;
+ }
+ }
+
+ *r_lambda = 1.0f;
+
+ /*---test points---*/
+ a = dot_v3v3(vel, vel);
+
+ /*v0*/
+ sub_v3_v3v3(temp, p1, v0);
+ b = 2.0f * dot_v3v3(vel, temp);
+ c = dot_v3v3(temp, temp) - radius2;
+
+ if (getLowestRoot(a, b, c, *r_lambda, r_lambda)) {
+ copy_v3_v3(ipoint, v0);
+ found_by_sweep = true;
+ }
+
+ /*v1*/
+ sub_v3_v3v3(temp, p1, v1);
+ b = 2.0f * dot_v3v3(vel, temp);
+ c = dot_v3v3(temp, temp) - radius2;
+
+ if (getLowestRoot(a, b, c, *r_lambda, r_lambda)) {
+ copy_v3_v3(ipoint, v1);
+ found_by_sweep = true;
+ }
+
+ /*v2*/
+ sub_v3_v3v3(temp, p1, v2);
+ b = 2.0f * dot_v3v3(vel, temp);
+ c = dot_v3v3(temp, temp) - radius2;
+
+ if (getLowestRoot(a, b, c, *r_lambda, r_lambda)) {
+ copy_v3_v3(ipoint, v2);
+ found_by_sweep = true;
+ }
+
+ /*---test edges---*/
+ sub_v3_v3v3(e3, v2, v1); /* wasnt yet calculated */
+
+ /*e1*/
+ sub_v3_v3v3(bv, v0, p1);
+
+ elen2 = dot_v3v3(e1, e1);
+ edotv = dot_v3v3(e1, vel);
+ edotbv = dot_v3v3(e1, bv);
+
+ a = elen2 * (-dot_v3v3(vel, vel)) + edotv * edotv;
+ b = 2.0f * (elen2 * dot_v3v3(vel, bv) - edotv * edotbv);
+ c = elen2 * (radius2 - dot_v3v3(bv, bv)) + edotbv * edotbv;
+
+ if (getLowestRoot(a, b, c, *r_lambda, &newLambda)) {
+ e = (edotv * newLambda - edotbv) / elen2;
+
+ if (e >= 0.0f && e <= 1.0f) {
+ *r_lambda = newLambda;
+ copy_v3_v3(ipoint, e1);
+ mul_v3_fl(ipoint, e);
+ add_v3_v3(ipoint, v0);
+ found_by_sweep = true;
+ }
+ }
+
+ /*e2*/
+ /*bv is same*/
+ elen2 = dot_v3v3(e2, e2);
+ edotv = dot_v3v3(e2, vel);
+ edotbv = dot_v3v3(e2, bv);
+
+ a = elen2 * (-dot_v3v3(vel, vel)) + edotv * edotv;
+ b = 2.0f * (elen2 * dot_v3v3(vel, bv) - edotv * edotbv);
+ c = elen2 * (radius2 - dot_v3v3(bv, bv)) + edotbv * edotbv;
+
+ if (getLowestRoot(a, b, c, *r_lambda, &newLambda)) {
+ e = (edotv * newLambda - edotbv) / elen2;
+
+ if (e >= 0.0f && e <= 1.0f) {
+ *r_lambda = newLambda;
+ copy_v3_v3(ipoint, e2);
+ mul_v3_fl(ipoint, e);
+ add_v3_v3(ipoint, v0);
+ found_by_sweep = true;
+ }
+ }
+
+ /*e3*/
+ /* sub_v3_v3v3(bv, v0, p1); */ /* UNUSED */
+ /* elen2 = dot_v3v3(e1, e1); */ /* UNUSED */
+ /* edotv = dot_v3v3(e1, vel); */ /* UNUSED */
+ /* edotbv = dot_v3v3(e1, bv); */ /* UNUSED */
+
+ sub_v3_v3v3(bv, v1, p1);
+ elen2 = dot_v3v3(e3, e3);
+ edotv = dot_v3v3(e3, vel);
+ edotbv = dot_v3v3(e3, bv);
+
+ a = elen2 * (-dot_v3v3(vel, vel)) + edotv * edotv;
+ b = 2.0f * (elen2 * dot_v3v3(vel, bv) - edotv * edotbv);
+ c = elen2 * (radius2 - dot_v3v3(bv, bv)) + edotbv * edotbv;
+
+ if (getLowestRoot(a, b, c, *r_lambda, &newLambda)) {
+ e = (edotv * newLambda - edotbv) / elen2;
+
+ if (e >= 0.0f && e <= 1.0f) {
+ *r_lambda = newLambda;
+ copy_v3_v3(ipoint, e3);
+ mul_v3_fl(ipoint, e);
+ add_v3_v3(ipoint, v1);
+ found_by_sweep = true;
+ }
+ }
+
+ return found_by_sweep;
+}
+
+bool isect_axial_line_segment_tri_v3(const int axis,
+ const float p1[3],
+ const float p2[3],
+ const float v0[3],
+ const float v1[3],
+ const float v2[3],
+ float *r_lambda)
+{
+ const float epsilon = 0.000001f;
+ float p[3], e1[3], e2[3];
+ float u, v, f;
+ int a0 = axis, a1 = (axis + 1) % 3, a2 = (axis + 2) % 3;
+
+ sub_v3_v3v3(e1, v1, v0);
+ sub_v3_v3v3(e2, v2, v0);
+ sub_v3_v3v3(p, v0, p1);
+
+ f = (e2[a1] * e1[a2] - e2[a2] * e1[a1]);
+ if ((f > -epsilon) && (f < epsilon)) {
+ return false;
+ }
+
+ v = (p[a2] * e1[a1] - p[a1] * e1[a2]) / f;
+ if ((v < 0.0f) || (v > 1.0f)) {
+ return false;
+ }
+
+ f = e1[a1];
+ if ((f > -epsilon) && (f < epsilon)) {
+ f = e1[a2];
+ if ((f > -epsilon) && (f < epsilon)) {
+ return false;
+ }
+ u = (-p[a2] - v * e2[a2]) / f;
+ }
+ else {
+ u = (-p[a1] - v * e2[a1]) / f;
+ }
+
+ if ((u < 0.0f) || ((u + v) > 1.0f)) {
+ return false;
+ }
+
+ *r_lambda = (p[a0] + u * e1[a0] + v * e2[a0]) / (p2[a0] - p1[a0]);
+
+ if ((*r_lambda < 0.0f) || (*r_lambda > 1.0f)) {
+ return false;
+ }
+
+ return true;
}
/**
@@ -2606,201 +2652,210 @@ bool isect_axial_line_segment_tri_v3(
* 1 - lines are coplanar, i1 is set to intersection
* 2 - i1 and i2 are the nearest points on line 1 (v1, v2) and line 2 (v3, v4) respectively
*/
-int isect_line_line_epsilon_v3(
- const float v1[3], const float v2[3],
- const float v3[3], const float v4[3],
- float r_i1[3], float r_i2[3],
- const float epsilon)
-{
- float a[3], b[3], c[3], ab[3], cb[3];
- float d, div;
-
- sub_v3_v3v3(c, v3, v1);
- sub_v3_v3v3(a, v2, v1);
- sub_v3_v3v3(b, v4, v3);
-
- cross_v3_v3v3(ab, a, b);
- d = dot_v3v3(c, ab);
- div = dot_v3v3(ab, ab);
-
- /* important not to use an epsilon here, see: T45919 */
- /* test zero length line */
- if (UNLIKELY(div == 0.0f)) {
- return 0;
- }
- /* test if the two lines are coplanar */
- else if (UNLIKELY(fabsf(d) <= epsilon)) {
- cross_v3_v3v3(cb, c, b);
-
- mul_v3_fl(a, dot_v3v3(cb, ab) / div);
- add_v3_v3v3(r_i1, v1, a);
- copy_v3_v3(r_i2, r_i1);
-
- return 1; /* one intersection only */
- }
- /* if not */
- else {
- float n[3], t[3];
- float v3t[3], v4t[3];
- sub_v3_v3v3(t, v1, v3);
-
- /* offset between both plane where the lines lies */
- cross_v3_v3v3(n, a, b);
- project_v3_v3v3(t, t, n);
-
- /* for the first line, offset the second line until it is coplanar */
- add_v3_v3v3(v3t, v3, t);
- add_v3_v3v3(v4t, v4, t);
-
- sub_v3_v3v3(c, v3t, v1);
- sub_v3_v3v3(a, v2, v1);
- sub_v3_v3v3(b, v4t, v3t);
-
- cross_v3_v3v3(ab, a, b);
- cross_v3_v3v3(cb, c, b);
-
- mul_v3_fl(a, dot_v3v3(cb, ab) / dot_v3v3(ab, ab));
- add_v3_v3v3(r_i1, v1, a);
-
- /* for the second line, just substract the offset from the first intersection point */
- sub_v3_v3v3(r_i2, r_i1, t);
-
- return 2; /* two nearest points */
- }
-}
-
-int isect_line_line_v3(
- const float v1[3], const float v2[3],
- const float v3[3], const float v4[3],
- float r_i1[3], float r_i2[3])
-{
- const float epsilon = 0.000001f;
- return isect_line_line_epsilon_v3(v1, v2, v3, v4, r_i1, r_i2, epsilon);
+int isect_line_line_epsilon_v3(const float v1[3],
+ const float v2[3],
+ const float v3[3],
+ const float v4[3],
+ float r_i1[3],
+ float r_i2[3],
+ const float epsilon)
+{
+ float a[3], b[3], c[3], ab[3], cb[3];
+ float d, div;
+
+ sub_v3_v3v3(c, v3, v1);
+ sub_v3_v3v3(a, v2, v1);
+ sub_v3_v3v3(b, v4, v3);
+
+ cross_v3_v3v3(ab, a, b);
+ d = dot_v3v3(c, ab);
+ div = dot_v3v3(ab, ab);
+
+ /* important not to use an epsilon here, see: T45919 */
+ /* test zero length line */
+ if (UNLIKELY(div == 0.0f)) {
+ return 0;
+ }
+ /* test if the two lines are coplanar */
+ else if (UNLIKELY(fabsf(d) <= epsilon)) {
+ cross_v3_v3v3(cb, c, b);
+
+ mul_v3_fl(a, dot_v3v3(cb, ab) / div);
+ add_v3_v3v3(r_i1, v1, a);
+ copy_v3_v3(r_i2, r_i1);
+
+ return 1; /* one intersection only */
+ }
+ /* if not */
+ else {
+ float n[3], t[3];
+ float v3t[3], v4t[3];
+ sub_v3_v3v3(t, v1, v3);
+
+ /* offset between both plane where the lines lies */
+ cross_v3_v3v3(n, a, b);
+ project_v3_v3v3(t, t, n);
+
+ /* for the first line, offset the second line until it is coplanar */
+ add_v3_v3v3(v3t, v3, t);
+ add_v3_v3v3(v4t, v4, t);
+
+ sub_v3_v3v3(c, v3t, v1);
+ sub_v3_v3v3(a, v2, v1);
+ sub_v3_v3v3(b, v4t, v3t);
+
+ cross_v3_v3v3(ab, a, b);
+ cross_v3_v3v3(cb, c, b);
+
+ mul_v3_fl(a, dot_v3v3(cb, ab) / dot_v3v3(ab, ab));
+ add_v3_v3v3(r_i1, v1, a);
+
+ /* for the second line, just substract the offset from the first intersection point */
+ sub_v3_v3v3(r_i2, r_i1, t);
+
+ return 2; /* two nearest points */
+ }
+}
+
+int isect_line_line_v3(const float v1[3],
+ const float v2[3],
+ const float v3[3],
+ const float v4[3],
+ float r_i1[3],
+ float r_i2[3])
+{
+ const float epsilon = 0.000001f;
+ return isect_line_line_epsilon_v3(v1, v2, v3, v4, r_i1, r_i2, epsilon);
}
/** Intersection point strictly between the two lines
* \return false when no intersection is found
*/
-bool isect_line_line_strict_v3(const float v1[3], const float v2[3],
- const float v3[3], const float v4[3],
- float vi[3], float *r_lambda)
-{
- const float epsilon = 0.000001f;
- float a[3], b[3], c[3], ab[3], cb[3], ca[3];
- float d, div;
-
- sub_v3_v3v3(c, v3, v1);
- sub_v3_v3v3(a, v2, v1);
- sub_v3_v3v3(b, v4, v3);
-
- cross_v3_v3v3(ab, a, b);
- d = dot_v3v3(c, ab);
- div = dot_v3v3(ab, ab);
-
- /* important not to use an epsilon here, see: T45919 */
- /* test zero length line */
- if (UNLIKELY(div == 0.0f)) {
- return false;
- }
- /* test if the two lines are coplanar */
- else if (UNLIKELY(fabsf(d) < epsilon)) {
- return false;
- }
- else {
- float f1, f2;
- cross_v3_v3v3(cb, c, b);
- cross_v3_v3v3(ca, c, a);
-
- f1 = dot_v3v3(cb, ab) / div;
- f2 = dot_v3v3(ca, ab) / div;
-
- if (f1 >= 0 && f1 <= 1 &&
- f2 >= 0 && f2 <= 1)
- {
- mul_v3_fl(a, f1);
- add_v3_v3v3(vi, v1, a);
-
- if (r_lambda) {
- *r_lambda = f1;
- }
-
- return true; /* intersection found */
- }
- else {
- return false;
- }
- }
-}
-
-bool isect_aabb_aabb_v3(const float min1[3], const float max1[3], const float min2[3], const float max2[3])
-{
- return (min1[0] < max2[0] && min1[1] < max2[1] && min1[2] < max2[2] &&
- min2[0] < max1[0] && min2[1] < max1[1] && min2[2] < max1[2]);
-}
-
-void isect_ray_aabb_v3_precalc(
- struct IsectRayAABB_Precalc *data,
- const float ray_origin[3], const float ray_direction[3])
-{
- copy_v3_v3(data->ray_origin, ray_origin);
-
- data->ray_inv_dir[0] = 1.0f / ray_direction[0];
- data->ray_inv_dir[1] = 1.0f / ray_direction[1];
- data->ray_inv_dir[2] = 1.0f / ray_direction[2];
-
- data->sign[0] = data->ray_inv_dir[0] < 0.0f;
- data->sign[1] = data->ray_inv_dir[1] < 0.0f;
- data->sign[2] = data->ray_inv_dir[2] < 0.0f;
+bool isect_line_line_strict_v3(const float v1[3],
+ const float v2[3],
+ const float v3[3],
+ const float v4[3],
+ float vi[3],
+ float *r_lambda)
+{
+ const float epsilon = 0.000001f;
+ float a[3], b[3], c[3], ab[3], cb[3], ca[3];
+ float d, div;
+
+ sub_v3_v3v3(c, v3, v1);
+ sub_v3_v3v3(a, v2, v1);
+ sub_v3_v3v3(b, v4, v3);
+
+ cross_v3_v3v3(ab, a, b);
+ d = dot_v3v3(c, ab);
+ div = dot_v3v3(ab, ab);
+
+ /* important not to use an epsilon here, see: T45919 */
+ /* test zero length line */
+ if (UNLIKELY(div == 0.0f)) {
+ return false;
+ }
+ /* test if the two lines are coplanar */
+ else if (UNLIKELY(fabsf(d) < epsilon)) {
+ return false;
+ }
+ else {
+ float f1, f2;
+ cross_v3_v3v3(cb, c, b);
+ cross_v3_v3v3(ca, c, a);
+
+ f1 = dot_v3v3(cb, ab) / div;
+ f2 = dot_v3v3(ca, ab) / div;
+
+ if (f1 >= 0 && f1 <= 1 && f2 >= 0 && f2 <= 1) {
+ mul_v3_fl(a, f1);
+ add_v3_v3v3(vi, v1, a);
+
+ if (r_lambda) {
+ *r_lambda = f1;
+ }
+
+ return true; /* intersection found */
+ }
+ else {
+ return false;
+ }
+ }
+}
+
+bool isect_aabb_aabb_v3(const float min1[3],
+ const float max1[3],
+ const float min2[3],
+ const float max2[3])
+{
+ return (min1[0] < max2[0] && min1[1] < max2[1] && min1[2] < max2[2] && min2[0] < max1[0] &&
+ min2[1] < max1[1] && min2[2] < max1[2]);
+}
+
+void isect_ray_aabb_v3_precalc(struct IsectRayAABB_Precalc *data,
+ const float ray_origin[3],
+ const float ray_direction[3])
+{
+ copy_v3_v3(data->ray_origin, ray_origin);
+
+ data->ray_inv_dir[0] = 1.0f / ray_direction[0];
+ data->ray_inv_dir[1] = 1.0f / ray_direction[1];
+ data->ray_inv_dir[2] = 1.0f / ray_direction[2];
+
+ data->sign[0] = data->ray_inv_dir[0] < 0.0f;
+ data->sign[1] = data->ray_inv_dir[1] < 0.0f;
+ data->sign[2] = data->ray_inv_dir[2] < 0.0f;
}
/* Adapted from http://www.gamedev.net/community/forums/topic.asp?topic_id=459973 */
-bool isect_ray_aabb_v3(
- const struct IsectRayAABB_Precalc *data, const float bb_min[3],
- const float bb_max[3], float *tmin_out)
+bool isect_ray_aabb_v3(const struct IsectRayAABB_Precalc *data,
+ const float bb_min[3],
+ const float bb_max[3],
+ float *tmin_out)
{
- float bbox[2][3];
+ float bbox[2][3];
- copy_v3_v3(bbox[0], bb_min);
- copy_v3_v3(bbox[1], bb_max);
+ copy_v3_v3(bbox[0], bb_min);
+ copy_v3_v3(bbox[1], bb_max);
- float tmin = (bbox[data->sign[0]][0] - data->ray_origin[0]) * data->ray_inv_dir[0];
- float tmax = (bbox[1 - data->sign[0]][0] - data->ray_origin[0]) * data->ray_inv_dir[0];
+ float tmin = (bbox[data->sign[0]][0] - data->ray_origin[0]) * data->ray_inv_dir[0];
+ float tmax = (bbox[1 - data->sign[0]][0] - data->ray_origin[0]) * data->ray_inv_dir[0];
- const float tymin = (bbox[data->sign[1]][1] - data->ray_origin[1]) * data->ray_inv_dir[1];
- const float tymax = (bbox[1 - data->sign[1]][1] - data->ray_origin[1]) * data->ray_inv_dir[1];
+ const float tymin = (bbox[data->sign[1]][1] - data->ray_origin[1]) * data->ray_inv_dir[1];
+ const float tymax = (bbox[1 - data->sign[1]][1] - data->ray_origin[1]) * data->ray_inv_dir[1];
- if ((tmin > tymax) || (tymin > tmax)) {
- return false;
- }
+ if ((tmin > tymax) || (tymin > tmax)) {
+ return false;
+ }
- if (tymin > tmin) {
- tmin = tymin;
- }
+ if (tymin > tmin) {
+ tmin = tymin;
+ }
- if (tymax < tmax) {
- tmax = tymax;
- }
+ if (tymax < tmax) {
+ tmax = tymax;
+ }
- const float tzmin = (bbox[data->sign[2]][2] - data->ray_origin[2]) * data->ray_inv_dir[2];
- const float tzmax = (bbox[1 - data->sign[2]][2] - data->ray_origin[2]) * data->ray_inv_dir[2];
+ const float tzmin = (bbox[data->sign[2]][2] - data->ray_origin[2]) * data->ray_inv_dir[2];
+ const float tzmax = (bbox[1 - data->sign[2]][2] - data->ray_origin[2]) * data->ray_inv_dir[2];
- if ((tmin > tzmax) || (tzmin > tmax)) {
- return false;
- }
+ if ((tmin > tzmax) || (tzmin > tmax)) {
+ return false;
+ }
- if (tzmin > tmin) {
- tmin = tzmin;
- }
+ if (tzmin > tmin) {
+ tmin = tzmin;
+ }
- /* 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;
+ /* 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) {
- (*tmin_out) = tmin;
- }
+ if (tmin_out) {
+ (*tmin_out) = tmin;
+ }
- return true;
+ return true;
}
/**
@@ -2809,36 +2864,38 @@ bool isect_ray_aabb_v3(
*
* \note: \a direction should be normalized if you intend to use the \a tmin or \a tmax distance results!
*/
-bool isect_ray_aabb_v3_simple(
- const float orig[3], const float dir[3],
- const float bb_min[3], const float bb_max[3],
- float *tmin, float *tmax)
-{
- double t[6];
- float hit_dist[2];
- const double invdirx = (dir[0] > 1e-35f || dir[0] < -1e-35f) ? 1.0 / (double)dir[0] : DBL_MAX;
- const double invdiry = (dir[1] > 1e-35f || dir[1] < -1e-35f) ? 1.0 / (double)dir[1] : DBL_MAX;
- const double invdirz = (dir[2] > 1e-35f || dir[2] < -1e-35f) ? 1.0 / (double)dir[2] : DBL_MAX;
- t[0] = (double)(bb_min[0] - orig[0]) * invdirx;
- t[1] = (double)(bb_max[0] - orig[0]) * invdirx;
- t[2] = (double)(bb_min[1] - orig[1]) * invdiry;
- t[3] = (double)(bb_max[1] - orig[1]) * invdiry;
- t[4] = (double)(bb_min[2] - orig[2]) * invdirz;
- t[5] = (double)(bb_max[2] - orig[2]) * invdirz;
- hit_dist[0] = (float)fmax(fmax(fmin(t[0], t[1]), fmin(t[2], t[3])), fmin(t[4], t[5]));
- hit_dist[1] = (float)fmin(fmin(fmax(t[0], t[1]), fmax(t[2], t[3])), fmax(t[4], t[5]));
- if ((hit_dist[1] < 0.0f || hit_dist[0] > hit_dist[1])) {
- return false;
- }
- else {
- if (tmin) {
- *tmin = hit_dist[0];
- }
- if (tmax) {
- *tmax = hit_dist[1];
- }
- return true;
- }
+bool isect_ray_aabb_v3_simple(const float orig[3],
+ const float dir[3],
+ const float bb_min[3],
+ const float bb_max[3],
+ float *tmin,
+ float *tmax)
+{
+ double t[6];
+ float hit_dist[2];
+ const double invdirx = (dir[0] > 1e-35f || dir[0] < -1e-35f) ? 1.0 / (double)dir[0] : DBL_MAX;
+ const double invdiry = (dir[1] > 1e-35f || dir[1] < -1e-35f) ? 1.0 / (double)dir[1] : DBL_MAX;
+ const double invdirz = (dir[2] > 1e-35f || dir[2] < -1e-35f) ? 1.0 / (double)dir[2] : DBL_MAX;
+ t[0] = (double)(bb_min[0] - orig[0]) * invdirx;
+ t[1] = (double)(bb_max[0] - orig[0]) * invdirx;
+ t[2] = (double)(bb_min[1] - orig[1]) * invdiry;
+ t[3] = (double)(bb_max[1] - orig[1]) * invdiry;
+ t[4] = (double)(bb_min[2] - orig[2]) * invdirz;
+ t[5] = (double)(bb_max[2] - orig[2]) * invdirz;
+ hit_dist[0] = (float)fmax(fmax(fmin(t[0], t[1]), fmin(t[2], t[3])), fmin(t[4], t[5]));
+ hit_dist[1] = (float)fmin(fmin(fmax(t[0], t[1]), fmax(t[2], t[3])), fmax(t[4], t[5]));
+ if ((hit_dist[1] < 0.0f || hit_dist[0] > hit_dist[1])) {
+ return false;
+ }
+ else {
+ if (tmin) {
+ *tmin = hit_dist[0];
+ }
+ if (tmax) {
+ *tmax = hit_dist[1];
+ }
+ return true;
+ }
}
/* find closest point to p on line through (l1, l2) and return lambda,
@@ -2846,41 +2903,44 @@ bool isect_ray_aabb_v3_simple(
*/
float closest_to_line_v3(float r_close[3], const float p[3], const float l1[3], const float l2[3])
{
- float h[3], u[3], lambda;
- sub_v3_v3v3(u, l2, l1);
- sub_v3_v3v3(h, p, l1);
- lambda = dot_v3v3(u, h) / dot_v3v3(u, u);
- r_close[0] = l1[0] + u[0] * lambda;
- r_close[1] = l1[1] + u[1] * lambda;
- r_close[2] = l1[2] + u[2] * lambda;
- return lambda;
+ float h[3], u[3], lambda;
+ sub_v3_v3v3(u, l2, l1);
+ sub_v3_v3v3(h, p, l1);
+ lambda = dot_v3v3(u, h) / dot_v3v3(u, u);
+ r_close[0] = l1[0] + u[0] * lambda;
+ r_close[1] = l1[1] + u[1] * lambda;
+ r_close[2] = l1[2] + u[2] * lambda;
+ return lambda;
}
float closest_to_line_v2(float r_close[2], const float p[2], const float l1[2], const float l2[2])
{
- float h[2], u[2], lambda;
- sub_v2_v2v2(u, l2, l1);
- sub_v2_v2v2(h, p, l1);
- lambda = dot_v2v2(u, h) / dot_v2v2(u, u);
- r_close[0] = l1[0] + u[0] * lambda;
- r_close[1] = l1[1] + u[1] * lambda;
- return lambda;
+ float h[2], u[2], lambda;
+ sub_v2_v2v2(u, l2, l1);
+ sub_v2_v2v2(h, p, l1);
+ lambda = dot_v2v2(u, h) / dot_v2v2(u, u);
+ r_close[0] = l1[0] + u[0] * lambda;
+ r_close[1] = l1[1] + u[1] * lambda;
+ return lambda;
}
-float ray_point_factor_v3_ex(
- const float p[3], const float ray_origin[3], const float ray_direction[3],
- const float epsilon, const float fallback)
+float ray_point_factor_v3_ex(const float p[3],
+ const float ray_origin[3],
+ const float ray_direction[3],
+ const float epsilon,
+ const float fallback)
{
- float p_relative[3];
- sub_v3_v3v3(p_relative, p, ray_origin);
- const float dot = len_squared_v3(ray_direction);
- return (dot > epsilon) ? (dot_v3v3(ray_direction, p_relative) / dot) : fallback;
+ float p_relative[3];
+ sub_v3_v3v3(p_relative, p, ray_origin);
+ const float dot = len_squared_v3(ray_direction);
+ return (dot > epsilon) ? (dot_v3v3(ray_direction, p_relative) / dot) : fallback;
}
-float ray_point_factor_v3(
- const float p[3], const float ray_origin[3], const float ray_direction[3])
+float ray_point_factor_v3(const float p[3],
+ const float ray_origin[3],
+ const float ray_direction[3])
{
- return ray_point_factor_v3_ex(p, ray_origin, ray_direction, 0.0f, 0.0f);
+ return ray_point_factor_v3_ex(p, ray_origin, ray_direction, 0.0f, 0.0f);
}
/**
@@ -2890,55 +2950,60 @@ float ray_point_factor_v3(
* \param epsilon: avoid approaching divide-by-zero.
* Passing a zero will just check for nonzero division.
*/
-float line_point_factor_v3_ex(
- const float p[3], const float l1[3], const float l2[3],
- const float epsilon, const float fallback)
+float line_point_factor_v3_ex(const float p[3],
+ const float l1[3],
+ const float l2[3],
+ const float epsilon,
+ const float fallback)
{
- float h[3], u[3];
- float dot;
- sub_v3_v3v3(u, l2, l1);
- sub_v3_v3v3(h, p, l1);
+ float h[3], u[3];
+ float dot;
+ sub_v3_v3v3(u, l2, l1);
+ sub_v3_v3v3(h, p, l1);
- /* better check for zero */
- dot = len_squared_v3(u);
- return (dot > epsilon) ? (dot_v3v3(u, h) / dot) : fallback;
+ /* better check for zero */
+ dot = len_squared_v3(u);
+ return (dot > epsilon) ? (dot_v3v3(u, h) / dot) : fallback;
}
-float line_point_factor_v3(
- const float p[3], const float l1[3], const float l2[3])
+float line_point_factor_v3(const float p[3], const float l1[3], const float l2[3])
{
- return line_point_factor_v3_ex(p, l1, l2, 0.0f, 0.0f);
+ return line_point_factor_v3_ex(p, l1, l2, 0.0f, 0.0f);
}
-float line_point_factor_v2_ex(
- const float p[2], const float l1[2], const float l2[2],
- const float epsilon, const float fallback)
+float line_point_factor_v2_ex(const float p[2],
+ const float l1[2],
+ const float l2[2],
+ const float epsilon,
+ const float fallback)
{
- float h[2], u[2];
- float dot;
- sub_v2_v2v2(u, l2, l1);
- sub_v2_v2v2(h, p, l1);
- /* better check for zero */
- dot = len_squared_v2(u);
- return (dot > epsilon) ? (dot_v2v2(u, h) / dot) : fallback;
+ float h[2], u[2];
+ float dot;
+ sub_v2_v2v2(u, l2, l1);
+ sub_v2_v2v2(h, p, l1);
+ /* better check for zero */
+ dot = len_squared_v2(u);
+ return (dot > epsilon) ? (dot_v2v2(u, h) / dot) : fallback;
}
float line_point_factor_v2(const float p[2], const float l1[2], const float l2[2])
{
- return line_point_factor_v2_ex(p, l1, l2, 0.0f, 0.0f);
+ return line_point_factor_v2_ex(p, l1, l2, 0.0f, 0.0f);
}
/**
* \note #isect_line_plane_v3() shares logic
*/
-float line_plane_factor_v3(const float plane_co[3], const float plane_no[3],
- const float l1[3], const float l2[3])
+float line_plane_factor_v3(const float plane_co[3],
+ const float plane_no[3],
+ const float l1[3],
+ const float l2[3])
{
- float u[3], h[3];
- float dot;
- sub_v3_v3v3(u, l2, l1);
- sub_v3_v3v3(h, l1, plane_co);
- dot = dot_v3v3(plane_no, u);
- return (dot != 0.0f) ? -dot_v3v3(plane_no, h) / dot : 0.0f;
+ float u[3], h[3];
+ float dot;
+ sub_v3_v3v3(u, l2, l1);
+ sub_v3_v3v3(h, l1, plane_co);
+ dot = dot_v3v3(plane_no, u);
+ return (dot != 0.0f) ? -dot_v3v3(plane_no, h) / dot : 0.0f;
}
/**
@@ -2947,19 +3012,19 @@ float line_plane_factor_v3(const float plane_co[3], const float plane_no[3],
*/
void limit_dist_v3(float v1[3], float v2[3], const float dist)
{
- const float dist_old = len_v3v3(v1, v2);
+ const float dist_old = len_v3v3(v1, v2);
- if (dist_old > dist) {
- float v1_old[3];
- float v2_old[3];
- float fac = (dist / dist_old) * 0.5f;
+ if (dist_old > dist) {
+ float v1_old[3];
+ float v2_old[3];
+ float fac = (dist / dist_old) * 0.5f;
- copy_v3_v3(v1_old, v1);
- copy_v3_v3(v2_old, v2);
+ copy_v3_v3(v1_old, v1);
+ copy_v3_v3(v2_old, v2);
- interp_v3_v3v3(v1, v1_old, v2_old, 0.5f - fac);
- interp_v3_v3v3(v2, v1_old, v2_old, 0.5f + fac);
- }
+ interp_v3_v3v3(v1, v1_old, v2_old, 0.5f - fac);
+ interp_v3_v3v3(v2, v1_old, v2_old, 0.5f + fac);
+ }
}
/*
@@ -2969,79 +3034,92 @@ void limit_dist_v3(float v1[3], float v2[3], const float dist)
* | \
* x1,y1-- x2,y1
*/
-int isect_point_tri_v2_int(const int x1, const int y1, const int x2, const int y2, const int a, const int b)
+int isect_point_tri_v2_int(
+ const int x1, const int y1, const int x2, const int y2, const int a, const int b)
{
- float v1[2], v2[2], v3[2], p[2];
+ float v1[2], v2[2], v3[2], p[2];
- v1[0] = (float)x1;
- v1[1] = (float)y1;
+ v1[0] = (float)x1;
+ v1[1] = (float)y1;
- v2[0] = (float)x1;
- v2[1] = (float)y2;
+ v2[0] = (float)x1;
+ v2[1] = (float)y2;
- v3[0] = (float)x2;
- v3[1] = (float)y1;
+ v3[0] = (float)x2;
+ v3[1] = (float)y1;
- p[0] = (float)a;
- p[1] = (float)b;
+ p[0] = (float)a;
+ p[1] = (float)b;
- return isect_point_tri_v2(p, v1, v2, v3);
+ return isect_point_tri_v2(p, v1, v2, v3);
}
-static bool point_in_slice(const float p[3], const float v1[3], const float l1[3], const float l2[3])
+static bool point_in_slice(const float p[3],
+ const float v1[3],
+ const float l1[3],
+ const float l2[3])
{
- /*
- * what is a slice ?
- * some maths:
- * a line including (l1, l2) and a point not on the line
- * define a subset of R3 delimited by planes parallel to the line and orthogonal
- * to the (point --> line) distance vector, one plane on the line one on the point,
- * the room inside usually is rather small compared to R3 though still infinite
- * useful for restricting (speeding up) searches
- * e.g. all points of triangular prism are within the intersection of 3 'slices'
- * another trivial case : cube
- * but see a 'spat' which is a deformed cube with paired parallel planes needs only 3 slices too
- */
- float h, rp[3], cp[3], q[3];
+ /*
+ * what is a slice ?
+ * some maths:
+ * a line including (l1, l2) and a point not on the line
+ * define a subset of R3 delimited by planes parallel to the line and orthogonal
+ * to the (point --> line) distance vector, one plane on the line one on the point,
+ * the room inside usually is rather small compared to R3 though still infinite
+ * useful for restricting (speeding up) searches
+ * e.g. all points of triangular prism are within the intersection of 3 'slices'
+ * another trivial case : cube
+ * but see a 'spat' which is a deformed cube with paired parallel planes needs only 3 slices too
+ */
+ float h, rp[3], cp[3], q[3];
- closest_to_line_v3(cp, v1, l1, l2);
- sub_v3_v3v3(q, cp, v1);
+ closest_to_line_v3(cp, v1, l1, l2);
+ sub_v3_v3v3(q, cp, v1);
- sub_v3_v3v3(rp, p, v1);
- h = dot_v3v3(q, rp) / dot_v3v3(q, q);
- /* note: when 'h' is nan/-nan, this check returns false
- * without explicit check - covering the degenerate case */
- return (h >= 0.0f && h <= 1.0f);
+ sub_v3_v3v3(rp, p, v1);
+ h = dot_v3v3(q, rp) / dot_v3v3(q, q);
+ /* note: when 'h' is nan/-nan, this check returns false
+ * without explicit check - covering the degenerate case */
+ return (h >= 0.0f && h <= 1.0f);
}
/* adult sister defining the slice planes by the origin and the normal
* NOTE |normal| may not be 1 but defining the thickness of the slice */
static bool point_in_slice_as(float p[3], float origin[3], float normal[3])
{
- float h, rp[3];
- sub_v3_v3v3(rp, p, origin);
- h = dot_v3v3(normal, rp) / dot_v3v3(normal, normal);
- if (h < 0.0f || h > 1.0f) {
- return false;
- }
- return true;
+ float h, rp[3];
+ sub_v3_v3v3(rp, p, origin);
+ h = dot_v3v3(normal, rp) / dot_v3v3(normal, normal);
+ if (h < 0.0f || h > 1.0f) {
+ return false;
+ }
+ return true;
}
bool point_in_slice_seg(float p[3], float l1[3], float l2[3])
{
- float normal[3];
+ float normal[3];
- sub_v3_v3v3(normal, l2, l1);
+ sub_v3_v3v3(normal, l2, l1);
- return point_in_slice_as(p, l1, normal);
+ return point_in_slice_as(p, l1, normal);
}
-bool isect_point_tri_prism_v3(const float p[3], const float v1[3], const float v2[3], const float v3[3])
+bool isect_point_tri_prism_v3(const float p[3],
+ const float v1[3],
+ const float v2[3],
+ const float v3[3])
{
- if (!point_in_slice(p, v1, v2, v3)) { return false; }
- if (!point_in_slice(p, v2, v3, v1)) { return false; }
- if (!point_in_slice(p, v3, v1, v2)) { return false; }
- return true;
+ if (!point_in_slice(p, v1, v2, v3)) {
+ return false;
+ }
+ if (!point_in_slice(p, v2, v3, v1)) {
+ return false;
+ }
+ if (!point_in_slice(p, v3, v1, v2)) {
+ return false;
+ }
+ return true;
}
/**
@@ -3050,133 +3128,132 @@ bool isect_point_tri_prism_v3(const float p[3], const float v1[3], const float v
* \note Its up to the caller to check the distance between \a p and \a r_vi against an error margin.
*/
bool isect_point_tri_v3(
- const float p[3], const float v1[3], const float v2[3], const float v3[3],
- float r_isect_co[3])
+ const float p[3], const float v1[3], const float v2[3], const float v3[3], float r_isect_co[3])
{
- if (isect_point_tri_prism_v3(p, v1, v2, v3)) {
- float plane[4];
- float no[3];
+ if (isect_point_tri_prism_v3(p, v1, v2, v3)) {
+ float plane[4];
+ float no[3];
- /* Could use normal_tri_v3, but doesn't have to be unit-length */
- cross_tri_v3(no, v1, v2, v3);
- BLI_assert(len_squared_v3(no) != 0.0f);
+ /* Could use normal_tri_v3, but doesn't have to be unit-length */
+ cross_tri_v3(no, v1, v2, v3);
+ BLI_assert(len_squared_v3(no) != 0.0f);
- plane_from_point_normal_v3(plane, v1, no);
- closest_to_plane_v3(r_isect_co, plane, p);
+ plane_from_point_normal_v3(plane, v1, no);
+ closest_to_plane_v3(r_isect_co, plane, p);
- return true;
- }
- else {
- return false;
- }
+ return true;
+ }
+ else {
+ return false;
+ }
}
bool clip_segment_v3_plane(
- const float p1[3], const float p2[3],
- const float plane[4],
- float r_p1[3], float r_p2[3])
-{
- float dp[3], div;
-
- sub_v3_v3v3(dp, p2, p1);
- div = dot_v3v3(dp, plane);
-
- if (div == 0.0f) {
- /* parallel */
- return true;
- }
-
- float t = -plane_point_side_v3(plane, p1);
-
- if (div > 0.0f) {
- /* behind plane, completely clipped */
- if (t >= div) {
- return false;
- }
- else if (t > 0.0f) {
- const float p1_copy[3] = {UNPACK3(p1)};
- copy_v3_v3(r_p2, p2);
- madd_v3_v3v3fl(r_p1, p1_copy, dp, t / div);
- return true;
- }
- }
- else {
- /* behind plane, completely clipped */
- if (t >= 0.0f) {
- return false;
- }
- else if (t > div) {
- const float p1_copy[3] = {UNPACK3(p1)};
- copy_v3_v3(r_p1, p1);
- madd_v3_v3v3fl(r_p2, p1_copy, dp, t / div);
- return true;
- }
- }
-
- /* incase input/output values match (above also) */
- const float p1_copy[3] = {UNPACK3(p1)};
- copy_v3_v3(r_p2, p2);
- copy_v3_v3(r_p1, p1_copy);
- return true;
-}
-
-bool clip_segment_v3_plane_n(
- const float p1[3], const float p2[3],
- const float plane_array[][4], const int plane_tot,
- float r_p1[3], float r_p2[3])
-{
- /* intersect from both directions */
- float p1_fac = 0.0f, p2_fac = 1.0f;
-
- float dp[3];
- sub_v3_v3v3(dp, p2, p1);
-
- for (int i = 0; i < plane_tot; i++) {
- const float *plane = plane_array[i];
- const float div = dot_v3v3(dp, plane);
-
- if (div != 0.0f) {
- float t = -plane_point_side_v3(plane, p1);
- if (div > 0.0f) {
- /* clip p1 lower bounds */
- if (t >= div) {
- return false;
- }
- else if (t > 0.0f) {
- t /= div;
- if (t > p1_fac) {
- p1_fac = t;
- if (p1_fac > p2_fac) {
- return false;
- }
- }
- }
- }
- else if (div < 0.0f) {
- /* clip p2 upper bounds */
- if (t >= 0.0f) {
- return false;
- }
- else if (t > div) {
- t /= div;
- if (t < p2_fac) {
- p2_fac = t;
- if (p1_fac > p2_fac) {
- return false;
- }
- }
- }
- }
- }
- }
-
- /* incase input/output values match */
- const float p1_copy[3] = {UNPACK3(p1)};
-
- madd_v3_v3v3fl(r_p1, p1_copy, dp, p1_fac);
- madd_v3_v3v3fl(r_p2, p1_copy, dp, p2_fac);
-
- return true;
+ const float p1[3], const float p2[3], const float plane[4], float r_p1[3], float r_p2[3])
+{
+ float dp[3], div;
+
+ sub_v3_v3v3(dp, p2, p1);
+ div = dot_v3v3(dp, plane);
+
+ if (div == 0.0f) {
+ /* parallel */
+ return true;
+ }
+
+ float t = -plane_point_side_v3(plane, p1);
+
+ if (div > 0.0f) {
+ /* behind plane, completely clipped */
+ if (t >= div) {
+ return false;
+ }
+ else if (t > 0.0f) {
+ const float p1_copy[3] = {UNPACK3(p1)};
+ copy_v3_v3(r_p2, p2);
+ madd_v3_v3v3fl(r_p1, p1_copy, dp, t / div);
+ return true;
+ }
+ }
+ else {
+ /* behind plane, completely clipped */
+ if (t >= 0.0f) {
+ return false;
+ }
+ else if (t > div) {
+ const float p1_copy[3] = {UNPACK3(p1)};
+ copy_v3_v3(r_p1, p1);
+ madd_v3_v3v3fl(r_p2, p1_copy, dp, t / div);
+ return true;
+ }
+ }
+
+ /* incase input/output values match (above also) */
+ const float p1_copy[3] = {UNPACK3(p1)};
+ copy_v3_v3(r_p2, p2);
+ copy_v3_v3(r_p1, p1_copy);
+ return true;
+}
+
+bool clip_segment_v3_plane_n(const float p1[3],
+ const float p2[3],
+ const float plane_array[][4],
+ const int plane_tot,
+ float r_p1[3],
+ float r_p2[3])
+{
+ /* intersect from both directions */
+ float p1_fac = 0.0f, p2_fac = 1.0f;
+
+ float dp[3];
+ sub_v3_v3v3(dp, p2, p1);
+
+ for (int i = 0; i < plane_tot; i++) {
+ const float *plane = plane_array[i];
+ const float div = dot_v3v3(dp, plane);
+
+ if (div != 0.0f) {
+ float t = -plane_point_side_v3(plane, p1);
+ if (div > 0.0f) {
+ /* clip p1 lower bounds */
+ if (t >= div) {
+ return false;
+ }
+ else if (t > 0.0f) {
+ t /= div;
+ if (t > p1_fac) {
+ p1_fac = t;
+ if (p1_fac > p2_fac) {
+ return false;
+ }
+ }
+ }
+ }
+ else if (div < 0.0f) {
+ /* clip p2 upper bounds */
+ if (t >= 0.0f) {
+ return false;
+ }
+ else if (t > div) {
+ t /= div;
+ if (t < p2_fac) {
+ p2_fac = t;
+ if (p1_fac > p2_fac) {
+ return false;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /* incase input/output values match */
+ const float p1_copy[3] = {UNPACK3(p1)};
+
+ madd_v3_v3v3fl(r_p1, p1_copy, dp, p1_fac);
+ madd_v3_v3v3fl(r_p2, p1_copy, dp, p2_fac);
+
+ return true;
}
/****************************** Axis Utils ********************************/
@@ -3193,18 +3270,19 @@ bool clip_segment_v3_plane_n(
*/
void axis_dominant_v3_to_m3(float r_mat[3][3], const float normal[3])
{
- BLI_ASSERT_UNIT_V3(normal);
+ BLI_ASSERT_UNIT_V3(normal);
- copy_v3_v3(r_mat[2], normal);
- ortho_basis_v3v3_v3(r_mat[0], r_mat[1], r_mat[2]);
+ copy_v3_v3(r_mat[2], normal);
+ ortho_basis_v3v3_v3(r_mat[0], r_mat[1], r_mat[2]);
- BLI_ASSERT_UNIT_V3(r_mat[0]);
- BLI_ASSERT_UNIT_V3(r_mat[1]);
+ BLI_ASSERT_UNIT_V3(r_mat[0]);
+ BLI_ASSERT_UNIT_V3(r_mat[1]);
- transpose_m3(r_mat);
+ transpose_m3(r_mat);
- BLI_assert(!is_negative_m3(r_mat));
- BLI_assert((fabsf(dot_m3_v3_row_z(r_mat, normal) - 1.0f) < BLI_ASSERT_UNIT_EPSILON) || is_zero_v3(normal));
+ BLI_assert(!is_negative_m3(r_mat));
+ BLI_assert((fabsf(dot_m3_v3_row_z(r_mat, normal) - 1.0f) < BLI_ASSERT_UNIT_EPSILON) ||
+ is_zero_v3(normal));
}
/**
@@ -3212,143 +3290,151 @@ void axis_dominant_v3_to_m3(float r_mat[3][3], const float normal[3])
*/
void axis_dominant_v3_to_m3_negate(float r_mat[3][3], const float normal[3])
{
- BLI_ASSERT_UNIT_V3(normal);
+ BLI_ASSERT_UNIT_V3(normal);
- negate_v3_v3(r_mat[2], normal);
- ortho_basis_v3v3_v3(r_mat[0], r_mat[1], r_mat[2]);
+ negate_v3_v3(r_mat[2], normal);
+ ortho_basis_v3v3_v3(r_mat[0], r_mat[1], r_mat[2]);
- BLI_ASSERT_UNIT_V3(r_mat[0]);
- BLI_ASSERT_UNIT_V3(r_mat[1]);
+ BLI_ASSERT_UNIT_V3(r_mat[0]);
+ BLI_ASSERT_UNIT_V3(r_mat[1]);
- transpose_m3(r_mat);
+ transpose_m3(r_mat);
- BLI_assert(!is_negative_m3(r_mat));
- BLI_assert((dot_m3_v3_row_z(r_mat, normal) < BLI_ASSERT_UNIT_EPSILON) || is_zero_v3(normal));
+ BLI_assert(!is_negative_m3(r_mat));
+ BLI_assert((dot_m3_v3_row_z(r_mat, normal) < BLI_ASSERT_UNIT_EPSILON) || is_zero_v3(normal));
}
/****************************** Interpolation ********************************/
-static float tri_signed_area(const float v1[3], const float v2[3], const float v3[3], const int i, const int j)
+static float tri_signed_area(
+ const float v1[3], const float v2[3], const float v3[3], const int i, const int j)
{
- return 0.5f * ((v1[i] - v2[i]) * (v2[j] - v3[j]) + (v1[j] - v2[j]) * (v3[i] - v2[i]));
+ return 0.5f * ((v1[i] - v2[i]) * (v2[j] - v3[j]) + (v1[j] - v2[j]) * (v3[i] - v2[i]));
}
/* return 1 when degenerate */
-static bool barycentric_weights(const float v1[3], const float v2[3], const float v3[3], const float co[3], const float n[3], float w[3])
-{
- float wtot;
- int i, j;
-
- axis_dominant_v3(&i, &j, n);
-
- w[0] = tri_signed_area(v2, v3, co, i, j);
- w[1] = tri_signed_area(v3, v1, co, i, j);
- w[2] = tri_signed_area(v1, v2, co, i, j);
-
- wtot = w[0] + w[1] + w[2];
-
- if (fabsf(wtot) > FLT_EPSILON) {
- mul_v3_fl(w, 1.0f / wtot);
- return false;
- }
- else {
- /* zero area triangle */
- copy_v3_fl(w, 1.0f / 3.0f);
- return true;
- }
-}
-
-void interp_weights_tri_v3(float w[3], const float v1[3], const float v2[3], const float v3[3], const float co[3])
-{
- float n[3];
-
- normal_tri_v3(n, v1, v2, v3);
- barycentric_weights(v1, v2, v3, co, n, w);
-}
-
-void interp_weights_quad_v3(float w[4], const float v1[3], const float v2[3], const float v3[3], const float v4[3], const float co[3])
-{
- float w2[3];
-
- w[0] = w[1] = w[2] = w[3] = 0.0f;
-
- /* first check for exact match */
- if (equals_v3v3(co, v1)) {
- w[0] = 1.0f;
- }
- else if (equals_v3v3(co, v2)) {
- w[1] = 1.0f;
- }
- else if (equals_v3v3(co, v3)) {
- w[2] = 1.0f;
- }
- else if (equals_v3v3(co, v4)) {
- w[3] = 1.0f;
- }
- else {
- /* otherwise compute barycentric interpolation weights */
- float n1[3], n2[3], n[3];
- bool degenerate;
-
- sub_v3_v3v3(n1, v1, v3);
- sub_v3_v3v3(n2, v2, v4);
- cross_v3_v3v3(n, n1, n2);
-
- degenerate = barycentric_weights(v1, v2, v4, co, n, w);
- SWAP(float, w[2], w[3]);
-
- if (degenerate || (w[0] < 0.0f)) {
- /* if w[1] is negative, co is on the other side of the v1-v3 edge,
- * so we interpolate using the other triangle */
- degenerate = barycentric_weights(v2, v3, v4, co, n, w2);
-
- if (!degenerate) {
- w[0] = 0.0f;
- w[1] = w2[0];
- w[2] = w2[1];
- w[3] = w2[2];
- }
- }
- }
+static bool barycentric_weights(const float v1[3],
+ const float v2[3],
+ const float v3[3],
+ const float co[3],
+ const float n[3],
+ float w[3])
+{
+ float wtot;
+ int i, j;
+
+ axis_dominant_v3(&i, &j, n);
+
+ w[0] = tri_signed_area(v2, v3, co, i, j);
+ w[1] = tri_signed_area(v3, v1, co, i, j);
+ w[2] = tri_signed_area(v1, v2, co, i, j);
+
+ wtot = w[0] + w[1] + w[2];
+
+ if (fabsf(wtot) > FLT_EPSILON) {
+ mul_v3_fl(w, 1.0f / wtot);
+ return false;
+ }
+ else {
+ /* zero area triangle */
+ copy_v3_fl(w, 1.0f / 3.0f);
+ return true;
+ }
+}
+
+void interp_weights_tri_v3(
+ float w[3], const float v1[3], const float v2[3], const float v3[3], const float co[3])
+{
+ float n[3];
+
+ normal_tri_v3(n, v1, v2, v3);
+ barycentric_weights(v1, v2, v3, co, n, w);
+}
+
+void interp_weights_quad_v3(float w[4],
+ const float v1[3],
+ const float v2[3],
+ const float v3[3],
+ const float v4[3],
+ const float co[3])
+{
+ float w2[3];
+
+ w[0] = w[1] = w[2] = w[3] = 0.0f;
+
+ /* first check for exact match */
+ if (equals_v3v3(co, v1)) {
+ w[0] = 1.0f;
+ }
+ else if (equals_v3v3(co, v2)) {
+ w[1] = 1.0f;
+ }
+ else if (equals_v3v3(co, v3)) {
+ w[2] = 1.0f;
+ }
+ else if (equals_v3v3(co, v4)) {
+ w[3] = 1.0f;
+ }
+ else {
+ /* otherwise compute barycentric interpolation weights */
+ float n1[3], n2[3], n[3];
+ bool degenerate;
+
+ sub_v3_v3v3(n1, v1, v3);
+ sub_v3_v3v3(n2, v2, v4);
+ cross_v3_v3v3(n, n1, n2);
+
+ degenerate = barycentric_weights(v1, v2, v4, co, n, w);
+ SWAP(float, w[2], w[3]);
+
+ if (degenerate || (w[0] < 0.0f)) {
+ /* if w[1] is negative, co is on the other side of the v1-v3 edge,
+ * so we interpolate using the other triangle */
+ degenerate = barycentric_weights(v2, v3, v4, co, n, w2);
+
+ if (!degenerate) {
+ w[0] = 0.0f;
+ w[1] = w2[0];
+ w[2] = w2[1];
+ w[3] = w2[2];
+ }
+ }
+ }
}
/* return 1 of point is inside triangle, 2 if it's on the edge, 0 if point is outside of triangle */
int barycentric_inside_triangle_v2(const float w[3])
{
- if (IN_RANGE(w[0], 0.0f, 1.0f) &&
- IN_RANGE(w[1], 0.0f, 1.0f) &&
- IN_RANGE(w[2], 0.0f, 1.0f))
- {
- return 1;
- }
- else if (IN_RANGE_INCL(w[0], 0.0f, 1.0f) &&
- IN_RANGE_INCL(w[1], 0.0f, 1.0f) &&
- IN_RANGE_INCL(w[2], 0.0f, 1.0f))
- {
- return 2;
- }
+ if (IN_RANGE(w[0], 0.0f, 1.0f) && IN_RANGE(w[1], 0.0f, 1.0f) && IN_RANGE(w[2], 0.0f, 1.0f)) {
+ return 1;
+ }
+ else if (IN_RANGE_INCL(w[0], 0.0f, 1.0f) && IN_RANGE_INCL(w[1], 0.0f, 1.0f) &&
+ IN_RANGE_INCL(w[2], 0.0f, 1.0f)) {
+ return 2;
+ }
- return 0;
+ return 0;
}
/* returns 0 for degenerated triangles */
-bool barycentric_coords_v2(const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3])
+bool barycentric_coords_v2(
+ const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3])
{
- const float x = co[0], y = co[1];
- const float x1 = v1[0], y1 = v1[1];
- const float x2 = v2[0], y2 = v2[1];
- const float x3 = v3[0], y3 = v3[1];
- const float det = (y2 - y3) * (x1 - x3) + (x3 - x2) * (y1 - y3);
+ const float x = co[0], y = co[1];
+ const float x1 = v1[0], y1 = v1[1];
+ const float x2 = v2[0], y2 = v2[1];
+ const float x3 = v3[0], y3 = v3[1];
+ const float det = (y2 - y3) * (x1 - x3) + (x3 - x2) * (y1 - y3);
- if (fabsf(det) > FLT_EPSILON) {
- w[0] = ((y2 - y3) * (x - x3) + (x3 - x2) * (y - y3)) / det;
- w[1] = ((y3 - y1) * (x - x3) + (x1 - x3) * (y - y3)) / det;
- w[2] = 1.0f - w[0] - w[1];
+ if (fabsf(det) > FLT_EPSILON) {
+ w[0] = ((y2 - y3) * (x - x3) + (x3 - x2) * (y - y3)) / det;
+ w[1] = ((y3 - y1) * (x - x3) + (x1 - x3) * (y - y3)) / det;
+ w[2] = 1.0f - w[0] - w[1];
- return true;
- }
+ return true;
+ }
- return false;
+ return false;
}
/**
@@ -3358,22 +3444,21 @@ bool barycentric_coords_v2(const float v1[2], const float v2[2], const float v3[
* although it has double precision and is used for texture baking, so keep both.
*/
void barycentric_weights_v2(
- const float v1[2], const float v2[2], const float v3[2],
- const float co[2], float w[3])
+ const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3])
{
- float wtot;
+ float wtot;
- w[0] = cross_tri_v2(v2, v3, co);
- w[1] = cross_tri_v2(v3, v1, co);
- w[2] = cross_tri_v2(v1, v2, co);
- wtot = w[0] + w[1] + w[2];
+ w[0] = cross_tri_v2(v2, v3, co);
+ w[1] = cross_tri_v2(v3, v1, co);
+ w[2] = cross_tri_v2(v1, v2, co);
+ wtot = w[0] + w[1] + w[2];
- if (wtot != 0.0f) {
- mul_v3_fl(w, 1.0f / wtot);
- }
- else { /* dummy values for zero area face */
- copy_v3_fl(w, 1.0f / 3.0f);
- }
+ if (wtot != 0.0f) {
+ mul_v3_fl(w, 1.0f / wtot);
+ }
+ else { /* dummy values for zero area face */
+ copy_v3_fl(w, 1.0f / 3.0f);
+ }
}
/**
@@ -3381,22 +3466,21 @@ void barycentric_weights_v2(
* Useful when negative values cause problems and points are only ever slightly outside of the triangle.
*/
void barycentric_weights_v2_clamped(
- const float v1[2], const float v2[2], const float v3[2],
- const float co[2], float w[3])
+ const float v1[2], const float v2[2], const float v3[2], const float co[2], float w[3])
{
- float wtot;
+ float wtot;
- w[0] = max_ff(cross_tri_v2(v2, v3, co), 0.0f);
- w[1] = max_ff(cross_tri_v2(v3, v1, co), 0.0f);
- w[2] = max_ff(cross_tri_v2(v1, v2, co), 0.0f);
- wtot = w[0] + w[1] + w[2];
+ w[0] = max_ff(cross_tri_v2(v2, v3, co), 0.0f);
+ w[1] = max_ff(cross_tri_v2(v3, v1, co), 0.0f);
+ w[2] = max_ff(cross_tri_v2(v1, v2, co), 0.0f);
+ wtot = w[0] + w[1] + w[2];
- if (wtot != 0.0f) {
- mul_v3_fl(w, 1.0f / wtot);
- }
- else { /* dummy values for zero area face */
- copy_v3_fl(w, 1.0f / 3.0f);
- }
+ if (wtot != 0.0f) {
+ mul_v3_fl(w, 1.0f / wtot);
+ }
+ else { /* dummy values for zero area face */
+ copy_v3_fl(w, 1.0f / 3.0f);
+ }
}
/**
@@ -3404,22 +3488,21 @@ void barycentric_weights_v2_clamped(
* using their 4th component as a weight
*/
void barycentric_weights_v2_persp(
- const float v1[4], const float v2[4], const float v3[4],
- const float co[2], float w[3])
+ const float v1[4], const float v2[4], const float v3[4], const float co[2], float w[3])
{
- float wtot;
+ float wtot;
- w[0] = cross_tri_v2(v2, v3, co) / v1[3];
- w[1] = cross_tri_v2(v3, v1, co) / v2[3];
- w[2] = cross_tri_v2(v1, v2, co) / v3[3];
- wtot = w[0] + w[1] + w[2];
+ w[0] = cross_tri_v2(v2, v3, co) / v1[3];
+ w[1] = cross_tri_v2(v3, v1, co) / v2[3];
+ w[2] = cross_tri_v2(v1, v2, co) / v3[3];
+ wtot = w[0] + w[1] + w[2];
- if (wtot != 0.0f) {
- mul_v3_fl(w, 1.0f / wtot);
- }
- else { /* dummy values for zero area face */
- w[0] = w[1] = w[2] = 1.0f / 3.0f;
- }
+ if (wtot != 0.0f) {
+ mul_v3_fl(w, 1.0f / wtot);
+ }
+ else { /* dummy values for zero area face */
+ w[0] = w[1] = w[2] = 1.0f / 3.0f;
+ }
}
/**
@@ -3427,54 +3510,70 @@ void barycentric_weights_v2_persp(
* note: untested for values outside the quad's bounds
* this is #interp_weights_poly_v2 expanded for quads only
*/
-void barycentric_weights_v2_quad(
- const float v1[2], const float v2[2], const float v3[2], const float v4[2],
- const float co[2], float w[4])
-{
- /* note: fabsf() here is not needed for convex quads (and not used in interp_weights_poly_v2).
- * but in the case of concave/bow-tie quads for the mask rasterizer it gives unreliable results
- * without adding absf(). If this becomes an issue for more general usage we could have
- * this optional or use a different function - Campbell */
+void barycentric_weights_v2_quad(const float v1[2],
+ const float v2[2],
+ const float v3[2],
+ const float v4[2],
+ const float co[2],
+ float w[4])
+{
+ /* note: fabsf() here is not needed for convex quads (and not used in interp_weights_poly_v2).
+ * but in the case of concave/bow-tie quads for the mask rasterizer it gives unreliable results
+ * without adding absf(). If this becomes an issue for more general usage we could have
+ * this optional or use a different function - Campbell */
#define MEAN_VALUE_HALF_TAN_V2(_area, i1, i2) \
- ((_area = cross_v2v2(dirs[i1], dirs[i2])) != 0.0f ? \
- fabsf(((lens[i1] * lens[i2]) - dot_v2v2(dirs[i1], dirs[i2])) / _area) : 0.0f)
-
- const float dirs[4][2] = {
- {v1[0] - co[0], v1[1] - co[1]},
- {v2[0] - co[0], v2[1] - co[1]},
- {v3[0] - co[0], v3[1] - co[1]},
- {v4[0] - co[0], v4[1] - co[1]},
- };
-
- const float lens[4] = {
- len_v2(dirs[0]),
- len_v2(dirs[1]),
- len_v2(dirs[2]),
- len_v2(dirs[3]),
- };
-
- /* avoid divide by zero */
- if (UNLIKELY(lens[0] < FLT_EPSILON)) { w[0] = 1.0f; w[1] = w[2] = w[3] = 0.0f; }
- else if (UNLIKELY(lens[1] < FLT_EPSILON)) { w[1] = 1.0f; w[0] = w[2] = w[3] = 0.0f; }
- else if (UNLIKELY(lens[2] < FLT_EPSILON)) { w[2] = 1.0f; w[0] = w[1] = w[3] = 0.0f; }
- else if (UNLIKELY(lens[3] < FLT_EPSILON)) { w[3] = 1.0f; w[0] = w[1] = w[2] = 0.0f; }
- else {
- float wtot, area;
-
- /* variable 'area' is just for storage,
- * the order its initialized doesn't matter */
+ ((_area = cross_v2v2(dirs[i1], dirs[i2])) != 0.0f ? \
+ fabsf(((lens[i1] * lens[i2]) - dot_v2v2(dirs[i1], dirs[i2])) / _area) : \
+ 0.0f)
+
+ const float dirs[4][2] = {
+ {v1[0] - co[0], v1[1] - co[1]},
+ {v2[0] - co[0], v2[1] - co[1]},
+ {v3[0] - co[0], v3[1] - co[1]},
+ {v4[0] - co[0], v4[1] - co[1]},
+ };
+
+ const float lens[4] = {
+ len_v2(dirs[0]),
+ len_v2(dirs[1]),
+ len_v2(dirs[2]),
+ len_v2(dirs[3]),
+ };
+
+ /* avoid divide by zero */
+ if (UNLIKELY(lens[0] < FLT_EPSILON)) {
+ w[0] = 1.0f;
+ w[1] = w[2] = w[3] = 0.0f;
+ }
+ else if (UNLIKELY(lens[1] < FLT_EPSILON)) {
+ w[1] = 1.0f;
+ w[0] = w[2] = w[3] = 0.0f;
+ }
+ else if (UNLIKELY(lens[2] < FLT_EPSILON)) {
+ w[2] = 1.0f;
+ w[0] = w[1] = w[3] = 0.0f;
+ }
+ else if (UNLIKELY(lens[3] < FLT_EPSILON)) {
+ w[3] = 1.0f;
+ w[0] = w[1] = w[2] = 0.0f;
+ }
+ else {
+ float wtot, area;
+
+ /* variable 'area' is just for storage,
+ * the order its initialized doesn't matter */
#ifdef __clang__
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wunsequenced"
#endif
- /* inline mean_value_half_tan four times here */
- const float t[4] = {
- MEAN_VALUE_HALF_TAN_V2(area, 0, 1),
- MEAN_VALUE_HALF_TAN_V2(area, 1, 2),
- MEAN_VALUE_HALF_TAN_V2(area, 2, 3),
- MEAN_VALUE_HALF_TAN_V2(area, 3, 0),
- };
+ /* inline mean_value_half_tan four times here */
+ const float t[4] = {
+ MEAN_VALUE_HALF_TAN_V2(area, 0, 1),
+ MEAN_VALUE_HALF_TAN_V2(area, 1, 2),
+ MEAN_VALUE_HALF_TAN_V2(area, 2, 3),
+ MEAN_VALUE_HALF_TAN_V2(area, 3, 0),
+ };
#ifdef __clang__
# pragma clang diagnostic pop
@@ -3482,365 +3581,376 @@ void barycentric_weights_v2_quad(
#undef MEAN_VALUE_HALF_TAN_V2
- w[0] = (t[3] + t[0]) / lens[0];
- w[1] = (t[0] + t[1]) / lens[1];
- w[2] = (t[1] + t[2]) / lens[2];
- w[3] = (t[2] + t[3]) / lens[3];
+ w[0] = (t[3] + t[0]) / lens[0];
+ w[1] = (t[0] + t[1]) / lens[1];
+ w[2] = (t[1] + t[2]) / lens[2];
+ w[3] = (t[2] + t[3]) / lens[3];
- wtot = w[0] + w[1] + w[2] + w[3];
+ wtot = w[0] + w[1] + w[2] + w[3];
- if (wtot != 0.0f) {
- mul_v4_fl(w, 1.0f / wtot);
- }
- else { /* dummy values for zero area face */
- copy_v4_fl(w, 1.0f / 4.0f);
- }
- }
+ if (wtot != 0.0f) {
+ mul_v4_fl(w, 1.0f / wtot);
+ }
+ else { /* dummy values for zero area face */
+ copy_v4_fl(w, 1.0f / 4.0f);
+ }
+ }
}
/* given 2 triangles in 3D space, and a point in relation to the first triangle.
* calculate the location of a point in relation to the second triangle.
* Useful for finding relative positions with geometry */
-void transform_point_by_tri_v3(
- float pt_tar[3], float const pt_src[3],
- const float tri_tar_p1[3], const float tri_tar_p2[3], const float tri_tar_p3[3],
- const float tri_src_p1[3], const float tri_src_p2[3], const float tri_src_p3[3])
-{
- /* this works by moving the source triangle so its normal is pointing on the Z
- * axis where its barycentric weights can be calculated in 2D and its Z offset can
- * be re-applied. The weights are applied directly to the targets 3D points and the
- * z-depth is used to scale the targets normal as an offset.
- * This saves transforming the target into its Z-Up orientation and back
- * (which could also work) */
- float no_tar[3], no_src[3];
- float mat_src[3][3];
- float pt_src_xy[3];
- float tri_xy_src[3][3];
- float w_src[3];
- float area_tar, area_src;
- float z_ofs_src;
-
- normal_tri_v3(no_tar, tri_tar_p1, tri_tar_p2, tri_tar_p3);
- normal_tri_v3(no_src, tri_src_p1, tri_src_p2, tri_src_p3);
-
- axis_dominant_v3_to_m3(mat_src, no_src);
-
- /* make the source tri xy space */
- mul_v3_m3v3(pt_src_xy, mat_src, pt_src);
- mul_v3_m3v3(tri_xy_src[0], mat_src, tri_src_p1);
- mul_v3_m3v3(tri_xy_src[1], mat_src, tri_src_p2);
- mul_v3_m3v3(tri_xy_src[2], mat_src, tri_src_p3);
-
-
- barycentric_weights_v2(tri_xy_src[0], tri_xy_src[1], tri_xy_src[2], pt_src_xy, w_src);
- interp_v3_v3v3v3(pt_tar, tri_tar_p1, tri_tar_p2, tri_tar_p3, w_src);
-
- area_tar = sqrtf(area_tri_v3(tri_tar_p1, tri_tar_p2, tri_tar_p3));
- area_src = sqrtf(area_tri_v2(tri_xy_src[0], tri_xy_src[1], tri_xy_src[2]));
-
- z_ofs_src = pt_src_xy[2] - tri_xy_src[0][2];
- madd_v3_v3v3fl(pt_tar, pt_tar, no_tar, (z_ofs_src / area_src) * area_tar);
+void transform_point_by_tri_v3(float pt_tar[3],
+ float const pt_src[3],
+ const float tri_tar_p1[3],
+ const float tri_tar_p2[3],
+ const float tri_tar_p3[3],
+ const float tri_src_p1[3],
+ const float tri_src_p2[3],
+ const float tri_src_p3[3])
+{
+ /* this works by moving the source triangle so its normal is pointing on the Z
+ * axis where its barycentric weights can be calculated in 2D and its Z offset can
+ * be re-applied. The weights are applied directly to the targets 3D points and the
+ * z-depth is used to scale the targets normal as an offset.
+ * This saves transforming the target into its Z-Up orientation and back
+ * (which could also work) */
+ float no_tar[3], no_src[3];
+ float mat_src[3][3];
+ float pt_src_xy[3];
+ float tri_xy_src[3][3];
+ float w_src[3];
+ float area_tar, area_src;
+ float z_ofs_src;
+
+ normal_tri_v3(no_tar, tri_tar_p1, tri_tar_p2, tri_tar_p3);
+ normal_tri_v3(no_src, tri_src_p1, tri_src_p2, tri_src_p3);
+
+ axis_dominant_v3_to_m3(mat_src, no_src);
+
+ /* make the source tri xy space */
+ mul_v3_m3v3(pt_src_xy, mat_src, pt_src);
+ mul_v3_m3v3(tri_xy_src[0], mat_src, tri_src_p1);
+ mul_v3_m3v3(tri_xy_src[1], mat_src, tri_src_p2);
+ mul_v3_m3v3(tri_xy_src[2], mat_src, tri_src_p3);
+
+ barycentric_weights_v2(tri_xy_src[0], tri_xy_src[1], tri_xy_src[2], pt_src_xy, w_src);
+ interp_v3_v3v3v3(pt_tar, tri_tar_p1, tri_tar_p2, tri_tar_p3, w_src);
+
+ area_tar = sqrtf(area_tri_v3(tri_tar_p1, tri_tar_p2, tri_tar_p3));
+ area_src = sqrtf(area_tri_v2(tri_xy_src[0], tri_xy_src[1], tri_xy_src[2]));
+
+ z_ofs_src = pt_src_xy[2] - tri_xy_src[0][2];
+ madd_v3_v3v3fl(pt_tar, pt_tar, no_tar, (z_ofs_src / area_src) * area_tar);
}
/**
* Simply re-interpolates,
* assumes p_src is between \a l_src_p1-l_src_p2
*/
-void transform_point_by_seg_v3(
- float p_dst[3], const float p_src[3],
- const float l_dst_p1[3], const float l_dst_p2[3],
- const float l_src_p1[3], const float l_src_p2[3])
+void transform_point_by_seg_v3(float p_dst[3],
+ const float p_src[3],
+ const float l_dst_p1[3],
+ const float l_dst_p2[3],
+ const float l_src_p1[3],
+ const float l_src_p2[3])
{
- float t = line_point_factor_v3(p_src, l_src_p1, l_src_p2);
- interp_v3_v3v3(p_dst, l_dst_p1, l_dst_p2, t);
+ float t = line_point_factor_v3(p_src, l_src_p1, l_src_p2);
+ interp_v3_v3v3(p_dst, l_dst_p1, l_dst_p2, t);
}
/* given an array with some invalid values this function interpolates valid values
* replacing the invalid ones */
int interp_sparse_array(float *array, const int list_size, const float skipval)
{
- int found_invalid = 0;
- int found_valid = 0;
- int i;
-
- for (i = 0; i < list_size; i++) {
- if (array[i] == skipval) {
- found_invalid = 1;
- }
- else {
- found_valid = 1;
- }
- }
-
- if (found_valid == 0) {
- return -1;
- }
- else if (found_invalid == 0) {
- return 0;
- }
- else {
- /* found invalid depths, interpolate */
- float valid_last = skipval;
- int valid_ofs = 0;
-
- float *array_up = MEM_callocN(sizeof(float) * (size_t)list_size, "interp_sparse_array up");
- float *array_down = MEM_callocN(sizeof(float) * (size_t)list_size, "interp_sparse_array up");
-
- int *ofs_tot_up = MEM_callocN(sizeof(int) * (size_t)list_size, "interp_sparse_array tup");
- int *ofs_tot_down = MEM_callocN(sizeof(int) * (size_t)list_size, "interp_sparse_array tdown");
-
- for (i = 0; i < list_size; i++) {
- if (array[i] == skipval) {
- array_up[i] = valid_last;
- ofs_tot_up[i] = ++valid_ofs;
- }
- else {
- valid_last = array[i];
- valid_ofs = 0;
- }
- }
-
- valid_last = skipval;
- valid_ofs = 0;
-
- for (i = list_size - 1; i >= 0; i--) {
- if (array[i] == skipval) {
- array_down[i] = valid_last;
- ofs_tot_down[i] = ++valid_ofs;
- }
- else {
- valid_last = array[i];
- valid_ofs = 0;
- }
- }
-
- /* now blend */
- for (i = 0; i < list_size; i++) {
- if (array[i] == skipval) {
- if (array_up[i] != skipval && array_down[i] != skipval) {
- array[i] = ((array_up[i] * (float)ofs_tot_down[i]) +
- (array_down[i] * (float)ofs_tot_up[i])) / (float)(ofs_tot_down[i] + ofs_tot_up[i]);
- }
- else if (array_up[i] != skipval) {
- array[i] = array_up[i];
- }
- else if (array_down[i] != skipval) {
- array[i] = array_down[i];
- }
- }
- }
-
- MEM_freeN(array_up);
- MEM_freeN(array_down);
-
- MEM_freeN(ofs_tot_up);
- MEM_freeN(ofs_tot_down);
- }
-
- return 1;
+ int found_invalid = 0;
+ int found_valid = 0;
+ int i;
+
+ for (i = 0; i < list_size; i++) {
+ if (array[i] == skipval) {
+ found_invalid = 1;
+ }
+ else {
+ found_valid = 1;
+ }
+ }
+
+ if (found_valid == 0) {
+ return -1;
+ }
+ else if (found_invalid == 0) {
+ return 0;
+ }
+ else {
+ /* found invalid depths, interpolate */
+ float valid_last = skipval;
+ int valid_ofs = 0;
+
+ float *array_up = MEM_callocN(sizeof(float) * (size_t)list_size, "interp_sparse_array up");
+ float *array_down = MEM_callocN(sizeof(float) * (size_t)list_size, "interp_sparse_array up");
+
+ int *ofs_tot_up = MEM_callocN(sizeof(int) * (size_t)list_size, "interp_sparse_array tup");
+ int *ofs_tot_down = MEM_callocN(sizeof(int) * (size_t)list_size, "interp_sparse_array tdown");
+
+ for (i = 0; i < list_size; i++) {
+ if (array[i] == skipval) {
+ array_up[i] = valid_last;
+ ofs_tot_up[i] = ++valid_ofs;
+ }
+ else {
+ valid_last = array[i];
+ valid_ofs = 0;
+ }
+ }
+
+ valid_last = skipval;
+ valid_ofs = 0;
+
+ for (i = list_size - 1; i >= 0; i--) {
+ if (array[i] == skipval) {
+ array_down[i] = valid_last;
+ ofs_tot_down[i] = ++valid_ofs;
+ }
+ else {
+ valid_last = array[i];
+ valid_ofs = 0;
+ }
+ }
+
+ /* now blend */
+ for (i = 0; i < list_size; i++) {
+ if (array[i] == skipval) {
+ if (array_up[i] != skipval && array_down[i] != skipval) {
+ array[i] = ((array_up[i] * (float)ofs_tot_down[i]) +
+ (array_down[i] * (float)ofs_tot_up[i])) /
+ (float)(ofs_tot_down[i] + ofs_tot_up[i]);
+ }
+ else if (array_up[i] != skipval) {
+ array[i] = array_up[i];
+ }
+ else if (array_down[i] != skipval) {
+ array[i] = array_down[i];
+ }
+ }
+ }
+
+ MEM_freeN(array_up);
+ MEM_freeN(array_down);
+
+ MEM_freeN(ofs_tot_up);
+ MEM_freeN(ofs_tot_down);
+ }
+
+ return 1;
}
/** \name interp_weights_poly_v2, v3
* \{ */
-#define IS_POINT_IX (1 << 0)
-#define IS_SEGMENT_IX (1 << 1)
+#define IS_POINT_IX (1 << 0)
+#define IS_SEGMENT_IX (1 << 1)
-#define DIR_V3_SET(d_len, va, vb) { \
- sub_v3_v3v3((d_len)->dir, va, vb); \
- (d_len)->len = len_v3((d_len)->dir); \
-} (void)0
+#define DIR_V3_SET(d_len, va, vb) \
+ { \
+ sub_v3_v3v3((d_len)->dir, va, vb); \
+ (d_len)->len = len_v3((d_len)->dir); \
+ } \
+ (void)0
-#define DIR_V2_SET(d_len, va, vb) { \
- sub_v2_v2v2((d_len)->dir, va, vb); \
- (d_len)->len = len_v2((d_len)->dir); \
-} (void)0
+#define DIR_V2_SET(d_len, va, vb) \
+ { \
+ sub_v2_v2v2((d_len)->dir, va, vb); \
+ (d_len)->len = len_v2((d_len)->dir); \
+ } \
+ (void)0
struct Float3_Len {
- float dir[3], len;
+ float dir[3], len;
};
struct Float2_Len {
- float dir[2], len;
+ float dir[2], len;
};
/* Mean value weights - smooth interpolation weights for polygons with
* more than 3 vertices */
-static float mean_value_half_tan_v3(const struct Float3_Len *d_curr, const struct Float3_Len *d_next)
-{
- float cross[3], area;
- cross_v3_v3v3(cross, d_curr->dir, d_next->dir);
- area = len_v3(cross);
- if (LIKELY(fabsf(area) > FLT_EPSILON)) {
- const float dot = dot_v3v3(d_curr->dir, d_next->dir);
- const float len = d_curr->len * d_next->len;
- return (len - dot) / area;
- }
- else {
- return 0.0f;
- }
-}
-
-static float mean_value_half_tan_v2(const struct Float2_Len *d_curr, const struct Float2_Len *d_next)
-{
- float area;
- /* different from the 3d version but still correct */
- area = cross_v2v2(d_curr->dir, d_next->dir);
- if (LIKELY(fabsf(area) > FLT_EPSILON)) {
- const float dot = dot_v2v2(d_curr->dir, d_next->dir);
- const float len = d_curr->len * d_next->len;
- return (len - dot) / area;
- }
- else {
- return 0.0f;
- }
+static float mean_value_half_tan_v3(const struct Float3_Len *d_curr,
+ const struct Float3_Len *d_next)
+{
+ float cross[3], area;
+ cross_v3_v3v3(cross, d_curr->dir, d_next->dir);
+ area = len_v3(cross);
+ if (LIKELY(fabsf(area) > FLT_EPSILON)) {
+ const float dot = dot_v3v3(d_curr->dir, d_next->dir);
+ const float len = d_curr->len * d_next->len;
+ return (len - dot) / area;
+ }
+ else {
+ return 0.0f;
+ }
+}
+
+static float mean_value_half_tan_v2(const struct Float2_Len *d_curr,
+ const struct Float2_Len *d_next)
+{
+ float area;
+ /* different from the 3d version but still correct */
+ area = cross_v2v2(d_curr->dir, d_next->dir);
+ if (LIKELY(fabsf(area) > FLT_EPSILON)) {
+ const float dot = dot_v2v2(d_curr->dir, d_next->dir);
+ const float len = d_curr->len * d_next->len;
+ return (len - dot) / area;
+ }
+ else {
+ return 0.0f;
+ }
}
void interp_weights_poly_v3(float *w, float v[][3], const int n, const float co[3])
{
- const float eps = 1e-5f; /* take care, low values cause [#36105] */
- const float eps_sq = eps * eps;
- const float *v_curr, *v_next;
- float ht_prev, ht; /* half tangents */
- float totweight = 0.0f;
- int i_curr, i_next;
- char ix_flag = 0;
- struct Float3_Len d_curr, d_next;
-
- /* loop over 'i_next' */
- i_curr = n - 1;
- i_next = 0;
-
- v_curr = v[i_curr];
- v_next = v[i_next];
-
- DIR_V3_SET(&d_curr, v_curr - 3 /* v[n - 2] */, co);
- DIR_V3_SET(&d_next, v_curr /* v[n - 1] */, co);
- ht_prev = mean_value_half_tan_v3(&d_curr, &d_next);
-
- while (i_next < n) {
- /* Mark Mayer et al algorithm that is used here does not operate well if vertex is close
- * to borders of face.
- * In that case, do simple linear interpolation between the two edge vertices */
-
- /* 'd_next.len' is infact 'd_curr.len', just avoid copy to begin with */
- if (UNLIKELY(d_next.len < eps)) {
- ix_flag = IS_POINT_IX;
- break;
- }
- else if (UNLIKELY(dist_squared_to_line_segment_v3(co, v_curr, v_next) < eps_sq)) {
- ix_flag = IS_SEGMENT_IX;
- break;
- }
-
- d_curr = d_next;
- DIR_V3_SET(&d_next, v_next, co);
- ht = mean_value_half_tan_v3(&d_curr, &d_next);
- w[i_curr] = (ht_prev + ht) / d_curr.len;
- totweight += w[i_curr];
-
- /* step */
- i_curr = i_next++;
- v_curr = v_next;
- v_next = v[i_next];
-
- ht_prev = ht;
- }
-
- if (ix_flag) {
- memset(w, 0, sizeof(*w) * (size_t)n);
-
- if (ix_flag & IS_POINT_IX) {
- w[i_curr] = 1.0f;
- }
- else {
- float fac = line_point_factor_v3(co, v_curr, v_next);
- CLAMP(fac, 0.0f, 1.0f);
- w[i_curr] = 1.0f - fac;
- w[i_next] = fac;
- }
- }
- else {
- if (totweight != 0.0f) {
- for (i_curr = 0; i_curr < n; i_curr++) {
- w[i_curr] /= totweight;
- }
- }
- }
+ const float eps = 1e-5f; /* take care, low values cause [#36105] */
+ const float eps_sq = eps * eps;
+ const float *v_curr, *v_next;
+ float ht_prev, ht; /* half tangents */
+ float totweight = 0.0f;
+ int i_curr, i_next;
+ char ix_flag = 0;
+ struct Float3_Len d_curr, d_next;
+
+ /* loop over 'i_next' */
+ i_curr = n - 1;
+ i_next = 0;
+
+ v_curr = v[i_curr];
+ v_next = v[i_next];
+
+ DIR_V3_SET(&d_curr, v_curr - 3 /* v[n - 2] */, co);
+ DIR_V3_SET(&d_next, v_curr /* v[n - 1] */, co);
+ ht_prev = mean_value_half_tan_v3(&d_curr, &d_next);
+
+ while (i_next < n) {
+ /* Mark Mayer et al algorithm that is used here does not operate well if vertex is close
+ * to borders of face.
+ * In that case, do simple linear interpolation between the two edge vertices */
+
+ /* 'd_next.len' is infact 'd_curr.len', just avoid copy to begin with */
+ if (UNLIKELY(d_next.len < eps)) {
+ ix_flag = IS_POINT_IX;
+ break;
+ }
+ else if (UNLIKELY(dist_squared_to_line_segment_v3(co, v_curr, v_next) < eps_sq)) {
+ ix_flag = IS_SEGMENT_IX;
+ break;
+ }
+
+ d_curr = d_next;
+ DIR_V3_SET(&d_next, v_next, co);
+ ht = mean_value_half_tan_v3(&d_curr, &d_next);
+ w[i_curr] = (ht_prev + ht) / d_curr.len;
+ totweight += w[i_curr];
+
+ /* step */
+ i_curr = i_next++;
+ v_curr = v_next;
+ v_next = v[i_next];
+
+ ht_prev = ht;
+ }
+
+ if (ix_flag) {
+ memset(w, 0, sizeof(*w) * (size_t)n);
+
+ if (ix_flag & IS_POINT_IX) {
+ w[i_curr] = 1.0f;
+ }
+ else {
+ float fac = line_point_factor_v3(co, v_curr, v_next);
+ CLAMP(fac, 0.0f, 1.0f);
+ w[i_curr] = 1.0f - fac;
+ w[i_next] = fac;
+ }
+ }
+ else {
+ if (totweight != 0.0f) {
+ for (i_curr = 0; i_curr < n; i_curr++) {
+ w[i_curr] /= totweight;
+ }
+ }
+ }
}
-
void interp_weights_poly_v2(float *w, float v[][2], const int n, const float co[2])
{
- const float eps = 1e-5f; /* take care, low values cause [#36105] */
- const float eps_sq = eps * eps;
- const float *v_curr, *v_next;
- float ht_prev, ht; /* half tangents */
- float totweight = 0.0f;
- int i_curr, i_next;
- char ix_flag = 0;
- struct Float2_Len d_curr, d_next;
-
- /* loop over 'i_next' */
- i_curr = n - 1;
- i_next = 0;
-
- v_curr = v[i_curr];
- v_next = v[i_next];
-
- DIR_V2_SET(&d_curr, v_curr - 2 /* v[n - 2] */, co);
- DIR_V2_SET(&d_next, v_curr /* v[n - 1] */, co);
- ht_prev = mean_value_half_tan_v2(&d_curr, &d_next);
-
- while (i_next < n) {
- /* Mark Mayer et al algorithm that is used here does not operate well if vertex is close
- * to borders of face. In that case,
- * do simple linear interpolation between the two edge vertices */
-
- /* 'd_next.len' is infact 'd_curr.len', just avoid copy to begin with */
- if (UNLIKELY(d_next.len < eps)) {
- ix_flag = IS_POINT_IX;
- break;
- }
- else if (UNLIKELY(dist_squared_to_line_segment_v2(co, v_curr, v_next) < eps_sq)) {
- ix_flag = IS_SEGMENT_IX;
- break;
- }
-
- d_curr = d_next;
- DIR_V2_SET(&d_next, v_next, co);
- ht = mean_value_half_tan_v2(&d_curr, &d_next);
- w[i_curr] = (ht_prev + ht) / d_curr.len;
- totweight += w[i_curr];
-
- /* step */
- i_curr = i_next++;
- v_curr = v_next;
- v_next = v[i_next];
-
- ht_prev = ht;
- }
-
- if (ix_flag) {
- memset(w, 0, sizeof(*w) * (size_t)n);
-
- if (ix_flag & IS_POINT_IX) {
- w[i_curr] = 1.0f;
- }
- else {
- float fac = line_point_factor_v2(co, v_curr, v_next);
- CLAMP(fac, 0.0f, 1.0f);
- w[i_curr] = 1.0f - fac;
- w[i_next] = fac;
- }
- }
- else {
- if (totweight != 0.0f) {
- for (i_curr = 0; i_curr < n; i_curr++) {
- w[i_curr] /= totweight;
- }
- }
- }
+ const float eps = 1e-5f; /* take care, low values cause [#36105] */
+ const float eps_sq = eps * eps;
+ const float *v_curr, *v_next;
+ float ht_prev, ht; /* half tangents */
+ float totweight = 0.0f;
+ int i_curr, i_next;
+ char ix_flag = 0;
+ struct Float2_Len d_curr, d_next;
+
+ /* loop over 'i_next' */
+ i_curr = n - 1;
+ i_next = 0;
+
+ v_curr = v[i_curr];
+ v_next = v[i_next];
+
+ DIR_V2_SET(&d_curr, v_curr - 2 /* v[n - 2] */, co);
+ DIR_V2_SET(&d_next, v_curr /* v[n - 1] */, co);
+ ht_prev = mean_value_half_tan_v2(&d_curr, &d_next);
+
+ while (i_next < n) {
+ /* Mark Mayer et al algorithm that is used here does not operate well if vertex is close
+ * to borders of face. In that case,
+ * do simple linear interpolation between the two edge vertices */
+
+ /* 'd_next.len' is infact 'd_curr.len', just avoid copy to begin with */
+ if (UNLIKELY(d_next.len < eps)) {
+ ix_flag = IS_POINT_IX;
+ break;
+ }
+ else if (UNLIKELY(dist_squared_to_line_segment_v2(co, v_curr, v_next) < eps_sq)) {
+ ix_flag = IS_SEGMENT_IX;
+ break;
+ }
+
+ d_curr = d_next;
+ DIR_V2_SET(&d_next, v_next, co);
+ ht = mean_value_half_tan_v2(&d_curr, &d_next);
+ w[i_curr] = (ht_prev + ht) / d_curr.len;
+ totweight += w[i_curr];
+
+ /* step */
+ i_curr = i_next++;
+ v_curr = v_next;
+ v_next = v[i_next];
+
+ ht_prev = ht;
+ }
+
+ if (ix_flag) {
+ memset(w, 0, sizeof(*w) * (size_t)n);
+
+ if (ix_flag & IS_POINT_IX) {
+ w[i_curr] = 1.0f;
+ }
+ else {
+ float fac = line_point_factor_v2(co, v_curr, v_next);
+ CLAMP(fac, 0.0f, 1.0f);
+ w[i_curr] = 1.0f - fac;
+ w[i_next] = fac;
+ }
+ }
+ else {
+ if (totweight != 0.0f) {
+ for (i_curr = 0; i_curr < n; i_curr++) {
+ w[i_curr] /= totweight;
+ }
+ }
+ }
}
#undef IS_POINT_IX
@@ -3851,30 +3961,35 @@ void interp_weights_poly_v2(float *w, float v[][2], const int n, const float co[
/** \} */
-
/* (x1, v1)(t1=0)------(x2, v2)(t2=1), 0<t<1 --> (x, v)(t) */
-void interp_cubic_v3(float x[3], float v[3], const float x1[3], const float v1[3], const float x2[3], const float v2[3], const float t)
+void interp_cubic_v3(float x[3],
+ float v[3],
+ const float x1[3],
+ const float v1[3],
+ const float x2[3],
+ const float v2[3],
+ const float t)
{
- float a[3], b[3];
- const float t2 = t * t;
- const float t3 = t2 * t;
+ float a[3], b[3];
+ const float t2 = t * t;
+ const float t3 = t2 * t;
- /* cubic interpolation */
- a[0] = v1[0] + v2[0] + 2 * (x1[0] - x2[0]);
- a[1] = v1[1] + v2[1] + 2 * (x1[1] - x2[1]);
- a[2] = v1[2] + v2[2] + 2 * (x1[2] - x2[2]);
+ /* cubic interpolation */
+ a[0] = v1[0] + v2[0] + 2 * (x1[0] - x2[0]);
+ a[1] = v1[1] + v2[1] + 2 * (x1[1] - x2[1]);
+ a[2] = v1[2] + v2[2] + 2 * (x1[2] - x2[2]);
- b[0] = -2 * v1[0] - v2[0] - 3 * (x1[0] - x2[0]);
- b[1] = -2 * v1[1] - v2[1] - 3 * (x1[1] - x2[1]);
- b[2] = -2 * v1[2] - v2[2] - 3 * (x1[2] - x2[2]);
+ b[0] = -2 * v1[0] - v2[0] - 3 * (x1[0] - x2[0]);
+ b[1] = -2 * v1[1] - v2[1] - 3 * (x1[1] - x2[1]);
+ b[2] = -2 * v1[2] - v2[2] - 3 * (x1[2] - x2[2]);
- x[0] = a[0] * t3 + b[0] * t2 + v1[0] * t + x1[0];
- x[1] = a[1] * t3 + b[1] * t2 + v1[1] * t + x1[1];
- x[2] = a[2] * t3 + b[2] * t2 + v1[2] * t + x1[2];
+ x[0] = a[0] * t3 + b[0] * t2 + v1[0] * t + x1[0];
+ x[1] = a[1] * t3 + b[1] * t2 + v1[1] * t + x1[1];
+ x[2] = a[2] * t3 + b[2] * t2 + v1[2] * t + x1[2];
- v[0] = 3 * a[0] * t2 + 2 * b[0] * t + v1[0];
- v[1] = 3 * a[1] * t2 + 2 * b[1] * t + v1[1];
- v[2] = 3 * a[2] * t2 + 2 * b[2] * t + v1[2];
+ v[0] = 3 * a[0] * t2 + 2 * b[0] * t + v1[0];
+ v[1] = 3 * a[1] * t2 + 2 * b[1] * t + v1[1];
+ v[2] = 3 * a[2] * t2 + 2 * b[2] * t + v1[2];
}
/* unfortunately internal calculations have to be done at double precision
@@ -3889,26 +4004,26 @@ void interp_cubic_v3(float x[3], float v[3], const float x1[3], const float v1[3
*
* \note same basic result as #barycentric_weights_v2, see it's comment for details.
*/
-void resolve_tri_uv_v2(float r_uv[2], const float st[2],
- const float st0[2], const float st1[2], const float st2[2])
+void resolve_tri_uv_v2(
+ float r_uv[2], const float st[2], const float st0[2], const float st1[2], const float st2[2])
{
- /* find UV such that
- * t = u * t0 + v * t1 + (1 - u - v) * t2
- * u * (t0 - t2) + v * (t1 - t2) = t - t2 */
- const double a = st0[0] - st2[0], b = st1[0] - st2[0];
- const double c = st0[1] - st2[1], d = st1[1] - st2[1];
- const double det = a * d - c * b;
+ /* find UV such that
+ * t = u * t0 + v * t1 + (1 - u - v) * t2
+ * u * (t0 - t2) + v * (t1 - t2) = t - t2 */
+ const double a = st0[0] - st2[0], b = st1[0] - st2[0];
+ const double c = st0[1] - st2[1], d = st1[1] - st2[1];
+ const double det = a * d - c * b;
- /* det should never be zero since the determinant is the signed ST area of the triangle. */
- if (IS_ZERO(det) == 0) {
- const double x[2] = {st[0] - st2[0], st[1] - st2[1]};
+ /* det should never be zero since the determinant is the signed ST area of the triangle. */
+ if (IS_ZERO(det) == 0) {
+ const double x[2] = {st[0] - st2[0], st[1] - st2[1]};
- r_uv[0] = (float)((d * x[0] - b * x[1]) / det);
- r_uv[1] = (float)(((-c) * x[0] + a * x[1]) / det);
- }
- else {
- zero_v2(r_uv);
- }
+ r_uv[0] = (float)((d * x[0] - b * x[1]) / det);
+ r_uv[1] = (float)(((-c) * x[0] + a * x[1]) / det);
+ }
+ else {
+ zero_v2(r_uv);
+ }
}
/**
@@ -3916,189 +4031,215 @@ void resolve_tri_uv_v2(float r_uv[2], const float st[2],
*
* Compute coordinates (u, v) for point \a st with respect to triangle (\a st0, \a st1, \a st2)
*/
-void resolve_tri_uv_v3(float r_uv[2], const float st[3], const float st0[3], const float st1[3], const float st2[3])
+void resolve_tri_uv_v3(
+ float r_uv[2], const float st[3], const float st0[3], const float st1[3], const float st2[3])
{
- float v0[3], v1[3], v2[3];
- double d00, d01, d11, d20, d21, det;
+ float v0[3], v1[3], v2[3];
+ double d00, d01, d11, d20, d21, det;
- sub_v3_v3v3(v0, st1, st0);
- sub_v3_v3v3(v1, st2, st0);
- sub_v3_v3v3(v2, st, st0);
+ sub_v3_v3v3(v0, st1, st0);
+ sub_v3_v3v3(v1, st2, st0);
+ sub_v3_v3v3(v2, st, st0);
- d00 = dot_v3v3(v0, v0);
- d01 = dot_v3v3(v0, v1);
- d11 = dot_v3v3(v1, v1);
- d20 = dot_v3v3(v2, v0);
- d21 = dot_v3v3(v2, v1);
+ d00 = dot_v3v3(v0, v0);
+ d01 = dot_v3v3(v0, v1);
+ d11 = dot_v3v3(v1, v1);
+ d20 = dot_v3v3(v2, v0);
+ d21 = dot_v3v3(v2, v1);
- det = d00 * d11 - d01 * d01;
+ det = d00 * d11 - d01 * d01;
- /* det should never be zero since the determinant is the signed ST area of the triangle. */
- if (IS_ZERO(det) == 0) {
- float w;
+ /* det should never be zero since the determinant is the signed ST area of the triangle. */
+ if (IS_ZERO(det) == 0) {
+ float w;
- w = (float)((d00 * d21 - d01 * d20) / det);
- r_uv[1] = (float)((d11 * d20 - d01 * d21) / det);
- r_uv[0] = 1.0f - r_uv[1] - w;
- }
- else {
- zero_v2(r_uv);
- }
+ w = (float)((d00 * d21 - d01 * d20) / det);
+ r_uv[1] = (float)((d11 * d20 - d01 * d21) / det);
+ r_uv[0] = 1.0f - r_uv[1] - w;
+ }
+ else {
+ zero_v2(r_uv);
+ }
}
/* bilinear reverse */
-void resolve_quad_uv_v2(float r_uv[2], const float st[2],
- const float st0[2], const float st1[2], const float st2[2], const float st3[2])
+void resolve_quad_uv_v2(float r_uv[2],
+ const float st[2],
+ const float st0[2],
+ const float st1[2],
+ const float st2[2],
+ const float st3[2])
{
- resolve_quad_uv_v2_deriv(r_uv, NULL, st, st0, st1, st2, st3);
+ resolve_quad_uv_v2_deriv(r_uv, NULL, st, st0, st1, st2, st3);
}
/* bilinear reverse with derivatives */
-void resolve_quad_uv_v2_deriv(float r_uv[2], float r_deriv[2][2],
- const float st[2], const float st0[2], const float st1[2], const float st2[2], const float st3[2])
-{
- const double signed_area = (st0[0] * st1[1] - st0[1] * st1[0]) + (st1[0] * st2[1] - st1[1] * st2[0]) +
- (st2[0] * st3[1] - st2[1] * st3[0]) + (st3[0] * st0[1] - st3[1] * st0[0]);
-
- /* X is 2D cross product (determinant)
- * A = (p0 - p) X (p0 - p3)*/
- const double a = (st0[0] - st[0]) * (st0[1] - st3[1]) - (st0[1] - st[1]) * (st0[0] - st3[0]);
-
- /* B = ( (p0 - p) X (p1 - p2) + (p1 - p) X (p0 - p3) ) / 2 */
- const double b = 0.5 * (double)(((st0[0] - st[0]) * (st1[1] - st2[1]) - (st0[1] - st[1]) * (st1[0] - st2[0])) +
- ((st1[0] - st[0]) * (st0[1] - st3[1]) - (st1[1] - st[1]) * (st0[0] - st3[0])));
-
- /* C = (p1-p) X (p1-p2) */
- const double fC = (st1[0] - st[0]) * (st1[1] - st2[1]) - (st1[1] - st[1]) * (st1[0] - st2[0]);
- double denom = a - 2 * b + fC;
-
- /* clear outputs */
- zero_v2(r_uv);
-
- if (IS_ZERO(denom) != 0) {
- const double fDen = a - fC;
- if (IS_ZERO(fDen) == 0) {
- r_uv[0] = (float)(a / fDen);
- }
- }
- else {
- const double desc_sq = b * b - a * fC;
- const double desc = sqrt(desc_sq < 0.0 ? 0.0 : desc_sq);
- const double s = signed_area > 0 ? (-1.0) : 1.0;
-
- r_uv[0] = (float)(((a - b) + s * desc) / denom);
- }
-
- /* find UV such that
- * fST = (1-u)(1-v) * ST0 + u * (1-v) * ST1 + u * v * ST2 + (1-u) * v * ST3 */
- {
- const double denom_s = (1 - r_uv[0]) * (st0[0] - st3[0]) + r_uv[0] * (st1[0] - st2[0]);
- const double denom_t = (1 - r_uv[0]) * (st0[1] - st3[1]) + r_uv[0] * (st1[1] - st2[1]);
- int i = 0;
- denom = denom_s;
-
- if (fabs(denom_s) < fabs(denom_t)) {
- i = 1;
- denom = denom_t;
- }
-
- if (IS_ZERO(denom) == 0) {
- r_uv[1] = (float)((double)((1.0f - r_uv[0]) * (st0[i] - st[i]) + r_uv[0] * (st1[i] - st[i])) / denom);
- }
- }
-
- if (r_deriv) {
- float tmp1[2], tmp2[2], s[2], t[2];
-
- /* clear outputs */
- zero_v2(r_deriv[0]);
- zero_v2(r_deriv[1]);
-
- sub_v2_v2v2(tmp1, st1, st0);
- sub_v2_v2v2(tmp2, st2, st3);
- interp_v2_v2v2(s, tmp1, tmp2, r_uv[1]);
- sub_v2_v2v2(tmp1, st3, st0);
- sub_v2_v2v2(tmp2, st2, st1);
- interp_v2_v2v2(t, tmp1, tmp2, r_uv[0]);
-
- denom = t[0] * s[1] - t[1] * s[0];
-
- if (!IS_ZERO(denom)) {
- double inv_denom = 1.0 / denom;
- r_deriv[0][0] = (float)((double)-t[1] * inv_denom);
- r_deriv[0][1] = (float)((double) t[0] * inv_denom);
- r_deriv[1][0] = (float)((double) s[1] * inv_denom);
- r_deriv[1][1] = (float)((double)-s[0] * inv_denom);
- }
- }
+void resolve_quad_uv_v2_deriv(float r_uv[2],
+ float r_deriv[2][2],
+ const float st[2],
+ const float st0[2],
+ const float st1[2],
+ const float st2[2],
+ const float st3[2])
+{
+ const double signed_area = (st0[0] * st1[1] - st0[1] * st1[0]) +
+ (st1[0] * st2[1] - st1[1] * st2[0]) +
+ (st2[0] * st3[1] - st2[1] * st3[0]) +
+ (st3[0] * st0[1] - st3[1] * st0[0]);
+
+ /* X is 2D cross product (determinant)
+ * A = (p0 - p) X (p0 - p3)*/
+ const double a = (st0[0] - st[0]) * (st0[1] - st3[1]) - (st0[1] - st[1]) * (st0[0] - st3[0]);
+
+ /* B = ( (p0 - p) X (p1 - p2) + (p1 - p) X (p0 - p3) ) / 2 */
+ const double b = 0.5 * (double)(((st0[0] - st[0]) * (st1[1] - st2[1]) -
+ (st0[1] - st[1]) * (st1[0] - st2[0])) +
+ ((st1[0] - st[0]) * (st0[1] - st3[1]) -
+ (st1[1] - st[1]) * (st0[0] - st3[0])));
+
+ /* C = (p1-p) X (p1-p2) */
+ const double fC = (st1[0] - st[0]) * (st1[1] - st2[1]) - (st1[1] - st[1]) * (st1[0] - st2[0]);
+ double denom = a - 2 * b + fC;
+
+ /* clear outputs */
+ zero_v2(r_uv);
+
+ if (IS_ZERO(denom) != 0) {
+ const double fDen = a - fC;
+ if (IS_ZERO(fDen) == 0) {
+ r_uv[0] = (float)(a / fDen);
+ }
+ }
+ else {
+ const double desc_sq = b * b - a * fC;
+ const double desc = sqrt(desc_sq < 0.0 ? 0.0 : desc_sq);
+ const double s = signed_area > 0 ? (-1.0) : 1.0;
+
+ r_uv[0] = (float)(((a - b) + s * desc) / denom);
+ }
+
+ /* find UV such that
+ * fST = (1-u)(1-v) * ST0 + u * (1-v) * ST1 + u * v * ST2 + (1-u) * v * ST3 */
+ {
+ const double denom_s = (1 - r_uv[0]) * (st0[0] - st3[0]) + r_uv[0] * (st1[0] - st2[0]);
+ const double denom_t = (1 - r_uv[0]) * (st0[1] - st3[1]) + r_uv[0] * (st1[1] - st2[1]);
+ int i = 0;
+ denom = denom_s;
+
+ if (fabs(denom_s) < fabs(denom_t)) {
+ i = 1;
+ denom = denom_t;
+ }
+
+ if (IS_ZERO(denom) == 0) {
+ r_uv[1] = (float)((double)((1.0f - r_uv[0]) * (st0[i] - st[i]) +
+ r_uv[0] * (st1[i] - st[i])) /
+ denom);
+ }
+ }
+
+ if (r_deriv) {
+ float tmp1[2], tmp2[2], s[2], t[2];
+
+ /* clear outputs */
+ zero_v2(r_deriv[0]);
+ zero_v2(r_deriv[1]);
+
+ sub_v2_v2v2(tmp1, st1, st0);
+ sub_v2_v2v2(tmp2, st2, st3);
+ interp_v2_v2v2(s, tmp1, tmp2, r_uv[1]);
+ sub_v2_v2v2(tmp1, st3, st0);
+ sub_v2_v2v2(tmp2, st2, st1);
+ interp_v2_v2v2(t, tmp1, tmp2, r_uv[0]);
+
+ denom = t[0] * s[1] - t[1] * s[0];
+
+ if (!IS_ZERO(denom)) {
+ double inv_denom = 1.0 / denom;
+ r_deriv[0][0] = (float)((double)-t[1] * inv_denom);
+ r_deriv[0][1] = (float)((double)t[0] * inv_denom);
+ r_deriv[1][0] = (float)((double)s[1] * inv_denom);
+ r_deriv[1][1] = (float)((double)-s[0] * inv_denom);
+ }
+ }
}
/* a version of resolve_quad_uv_v2 that only calculates the 'u' */
-float resolve_quad_u_v2(
- const float st[2],
- const float st0[2], const float st1[2], const float st2[2], const float st3[2])
-{
- const double signed_area = (st0[0] * st1[1] - st0[1] * st1[0]) + (st1[0] * st2[1] - st1[1] * st2[0]) +
- (st2[0] * st3[1] - st2[1] * st3[0]) + (st3[0] * st0[1] - st3[1] * st0[0]);
-
- /* X is 2D cross product (determinant)
- * A = (p0 - p) X (p0 - p3)*/
- const double a = (st0[0] - st[0]) * (st0[1] - st3[1]) - (st0[1] - st[1]) * (st0[0] - st3[0]);
-
- /* B = ( (p0 - p) X (p1 - p2) + (p1 - p) X (p0 - p3) ) / 2 */
- const double b = 0.5 * (double)(((st0[0] - st[0]) * (st1[1] - st2[1]) - (st0[1] - st[1]) * (st1[0] - st2[0])) +
- ((st1[0] - st[0]) * (st0[1] - st3[1]) - (st1[1] - st[1]) * (st0[0] - st3[0])));
-
- /* C = (p1-p) X (p1-p2) */
- const double fC = (st1[0] - st[0]) * (st1[1] - st2[1]) - (st1[1] - st[1]) * (st1[0] - st2[0]);
- double denom = a - 2 * b + fC;
-
- if (IS_ZERO(denom) != 0) {
- const double fDen = a - fC;
- if (IS_ZERO(fDen) == 0) {
- return (float)(a / fDen);
- }
- else {
- return 0.0f;
- }
- }
- else {
- const double desc_sq = b * b - a * fC;
- const double desc = sqrt(desc_sq < 0.0 ? 0.0 : desc_sq);
- const double s = signed_area > 0 ? (-1.0) : 1.0;
-
- return (float)(((a - b) + s * desc) / denom);
- }
+float resolve_quad_u_v2(const float st[2],
+ const float st0[2],
+ const float st1[2],
+ const float st2[2],
+ const float st3[2])
+{
+ const double signed_area = (st0[0] * st1[1] - st0[1] * st1[0]) +
+ (st1[0] * st2[1] - st1[1] * st2[0]) +
+ (st2[0] * st3[1] - st2[1] * st3[0]) +
+ (st3[0] * st0[1] - st3[1] * st0[0]);
+
+ /* X is 2D cross product (determinant)
+ * A = (p0 - p) X (p0 - p3)*/
+ const double a = (st0[0] - st[0]) * (st0[1] - st3[1]) - (st0[1] - st[1]) * (st0[0] - st3[0]);
+
+ /* B = ( (p0 - p) X (p1 - p2) + (p1 - p) X (p0 - p3) ) / 2 */
+ const double b = 0.5 * (double)(((st0[0] - st[0]) * (st1[1] - st2[1]) -
+ (st0[1] - st[1]) * (st1[0] - st2[0])) +
+ ((st1[0] - st[0]) * (st0[1] - st3[1]) -
+ (st1[1] - st[1]) * (st0[0] - st3[0])));
+
+ /* C = (p1-p) X (p1-p2) */
+ const double fC = (st1[0] - st[0]) * (st1[1] - st2[1]) - (st1[1] - st[1]) * (st1[0] - st2[0]);
+ double denom = a - 2 * b + fC;
+
+ if (IS_ZERO(denom) != 0) {
+ const double fDen = a - fC;
+ if (IS_ZERO(fDen) == 0) {
+ return (float)(a / fDen);
+ }
+ else {
+ return 0.0f;
+ }
+ }
+ else {
+ const double desc_sq = b * b - a * fC;
+ const double desc = sqrt(desc_sq < 0.0 ? 0.0 : desc_sq);
+ const double s = signed_area > 0 ? (-1.0) : 1.0;
+
+ return (float)(((a - b) + s * desc) / denom);
+ }
}
-
#undef IS_ZERO
/* reverse of the functions above */
void interp_bilinear_quad_v3(float data[4][3], float u, float v, float res[3])
{
- float vec[3];
+ float vec[3];
- copy_v3_v3(res, data[0]);
- mul_v3_fl(res, (1 - u) * (1 - v));
- copy_v3_v3(vec, data[1]);
- mul_v3_fl(vec, u * (1 - v)); add_v3_v3(res, vec);
- copy_v3_v3(vec, data[2]);
- mul_v3_fl(vec, u * v); add_v3_v3(res, vec);
- copy_v3_v3(vec, data[3]);
- mul_v3_fl(vec, (1 - u) * v); add_v3_v3(res, vec);
+ copy_v3_v3(res, data[0]);
+ mul_v3_fl(res, (1 - u) * (1 - v));
+ copy_v3_v3(vec, data[1]);
+ mul_v3_fl(vec, u * (1 - v));
+ add_v3_v3(res, vec);
+ copy_v3_v3(vec, data[2]);
+ mul_v3_fl(vec, u * v);
+ add_v3_v3(res, vec);
+ copy_v3_v3(vec, data[3]);
+ mul_v3_fl(vec, (1 - u) * v);
+ add_v3_v3(res, vec);
}
void interp_barycentric_tri_v3(float data[3][3], float u, float v, float res[3])
{
- float vec[3];
+ float vec[3];
- copy_v3_v3(res, data[0]);
- mul_v3_fl(res, u);
- copy_v3_v3(vec, data[1]);
- mul_v3_fl(vec, v); add_v3_v3(res, vec);
- copy_v3_v3(vec, data[2]);
- mul_v3_fl(vec, 1.0f - u - v); add_v3_v3(res, vec);
+ copy_v3_v3(res, data[0]);
+ mul_v3_fl(res, u);
+ copy_v3_v3(vec, data[1]);
+ mul_v3_fl(vec, v);
+ add_v3_v3(res, vec);
+ copy_v3_v3(vec, data[2]);
+ mul_v3_fl(vec, 1.0f - u - v);
+ add_v3_v3(res, vec);
}
/***************************** View & Projection *****************************/
@@ -4106,80 +4247,88 @@ void interp_barycentric_tri_v3(float data[3][3], float u, float v, float res[3])
/**
* Matches `glOrtho` result.
*/
-void orthographic_m4(float matrix[4][4], const float left, const float right, const float bottom, const float top,
- const float nearClip, const float farClip)
-{
- float Xdelta, Ydelta, Zdelta;
-
- Xdelta = right - left;
- Ydelta = top - bottom;
- Zdelta = farClip - nearClip;
- if (Xdelta == 0.0f || Ydelta == 0.0f || Zdelta == 0.0f) {
- return;
- }
- unit_m4(matrix);
- matrix[0][0] = 2.0f / Xdelta;
- matrix[3][0] = -(right + left) / Xdelta;
- matrix[1][1] = 2.0f / Ydelta;
- matrix[3][1] = -(top + bottom) / Ydelta;
- matrix[2][2] = -2.0f / Zdelta; /* note: negate Z */
- matrix[3][2] = -(farClip + nearClip) / Zdelta;
+void orthographic_m4(float matrix[4][4],
+ const float left,
+ const float right,
+ const float bottom,
+ const float top,
+ const float nearClip,
+ const float farClip)
+{
+ float Xdelta, Ydelta, Zdelta;
+
+ Xdelta = right - left;
+ Ydelta = top - bottom;
+ Zdelta = farClip - nearClip;
+ if (Xdelta == 0.0f || Ydelta == 0.0f || Zdelta == 0.0f) {
+ return;
+ }
+ unit_m4(matrix);
+ matrix[0][0] = 2.0f / Xdelta;
+ matrix[3][0] = -(right + left) / Xdelta;
+ matrix[1][1] = 2.0f / Ydelta;
+ matrix[3][1] = -(top + bottom) / Ydelta;
+ matrix[2][2] = -2.0f / Zdelta; /* note: negate Z */
+ matrix[3][2] = -(farClip + nearClip) / Zdelta;
}
/**
* Matches `glFrustum` result.
*/
-void perspective_m4(float mat[4][4], const float left, const float right, const float bottom, const float top,
- const float nearClip, const float farClip)
-{
- const float Xdelta = right - left;
- const float Ydelta = top - bottom;
- const float Zdelta = farClip - nearClip;
-
- if (Xdelta == 0.0f || Ydelta == 0.0f || Zdelta == 0.0f) {
- return;
- }
- mat[0][0] = nearClip * 2.0f / Xdelta;
- mat[1][1] = nearClip * 2.0f / Ydelta;
- mat[2][0] = (right + left) / Xdelta; /* note: negate Z */
- mat[2][1] = (top + bottom) / Ydelta;
- mat[2][2] = -(farClip + nearClip) / Zdelta;
- mat[2][3] = -1.0f;
- mat[3][2] = (-2.0f * nearClip * farClip) / Zdelta;
- mat[0][1] = mat[0][2] = mat[0][3] =
- mat[1][0] = mat[1][2] = mat[1][3] =
- mat[3][0] = mat[3][1] = mat[3][3] = 0.0f;
-
+void perspective_m4(float mat[4][4],
+ const float left,
+ const float right,
+ const float bottom,
+ const float top,
+ const float nearClip,
+ const float farClip)
+{
+ const float Xdelta = right - left;
+ const float Ydelta = top - bottom;
+ const float Zdelta = farClip - nearClip;
+
+ if (Xdelta == 0.0f || Ydelta == 0.0f || Zdelta == 0.0f) {
+ return;
+ }
+ mat[0][0] = nearClip * 2.0f / Xdelta;
+ mat[1][1] = nearClip * 2.0f / Ydelta;
+ mat[2][0] = (right + left) / Xdelta; /* note: negate Z */
+ mat[2][1] = (top + bottom) / Ydelta;
+ mat[2][2] = -(farClip + nearClip) / Zdelta;
+ mat[2][3] = -1.0f;
+ mat[3][2] = (-2.0f * nearClip * farClip) / Zdelta;
+ mat[0][1] = mat[0][2] = mat[0][3] = mat[1][0] = mat[1][2] = mat[1][3] = mat[3][0] = mat[3][1] =
+ mat[3][3] = 0.0f;
}
/* translate a matrix created by orthographic_m4 or perspective_m4 in XY coords
* (used to jitter the view) */
void window_translate_m4(float winmat[4][4], float perspmat[4][4], const float x, const float y)
{
- if (winmat[2][3] == -1.0f) {
- /* in the case of a win-matrix, this means perspective always */
- float v1[3];
- float v2[3];
- float len1, len2;
+ if (winmat[2][3] == -1.0f) {
+ /* in the case of a win-matrix, this means perspective always */
+ float v1[3];
+ float v2[3];
+ float len1, len2;
- v1[0] = perspmat[0][0];
- v1[1] = perspmat[1][0];
- v1[2] = perspmat[2][0];
+ v1[0] = perspmat[0][0];
+ v1[1] = perspmat[1][0];
+ v1[2] = perspmat[2][0];
- v2[0] = perspmat[0][1];
- v2[1] = perspmat[1][1];
- v2[2] = perspmat[2][1];
+ v2[0] = perspmat[0][1];
+ v2[1] = perspmat[1][1];
+ v2[2] = perspmat[2][1];
- len1 = (1.0f / len_v3(v1));
- len2 = (1.0f / len_v3(v2));
+ len1 = (1.0f / len_v3(v1));
+ len2 = (1.0f / len_v3(v2));
- winmat[2][0] += len1 * winmat[0][0] * x;
- winmat[2][1] += len2 * winmat[1][1] * y;
- }
- else {
- winmat[3][0] += x;
- winmat[3][1] += y;
- }
+ winmat[2][0] += len1 * winmat[0][0] * x;
+ winmat[2][1] += len2 * winmat[1][1] * y;
+ }
+ else {
+ winmat[3][0] += x;
+ winmat[3][1] += y;
+ }
}
/**
@@ -4187,423 +4336,466 @@ void window_translate_m4(float winmat[4][4], float perspmat[4][4], const float x
*
* plane parameters can be NULL if you do not need them.
*/
-void planes_from_projmat(float mat[4][4], float left[4], float right[4], float top[4], float bottom[4],
- float near[4], float far[4])
-{
- /* References:
- *
- * https://fgiesen.wordpress.com/2012/08/31/frustum-planes-from-the-projection-matrix/
- * http://www8.cs.umu.se/kurser/5DV051/HT12/lab/plane_extraction.pdf
- */
-
- int i;
-
- if (left) {
- for (i = 4; i--; ) {
- left[i] = mat[i][3] + mat[i][0];
- }
- }
-
- if (right) {
- for (i = 4; i--; ) {
- right[i] = mat[i][3] - mat[i][0];
- }
- }
-
- if (bottom) {
- for (i = 4; i--; ) {
- bottom[i] = mat[i][3] + mat[i][1];
- }
- }
-
- if (top) {
- for (i = 4; i--; ) {
- top[i] = mat[i][3] - mat[i][1];
- }
- }
-
- if (near) {
- for (i = 4; i--; ) {
- near[i] = mat[i][3] + mat[i][2];
- }
- }
-
- if (far) {
- for (i = 4; i--; ) {
- far[i] = mat[i][3] - mat[i][2];
- }
- }
+void planes_from_projmat(float mat[4][4],
+ float left[4],
+ float right[4],
+ float top[4],
+ float bottom[4],
+ float near[4],
+ float far[4])
+{
+ /* References:
+ *
+ * https://fgiesen.wordpress.com/2012/08/31/frustum-planes-from-the-projection-matrix/
+ * http://www8.cs.umu.se/kurser/5DV051/HT12/lab/plane_extraction.pdf
+ */
+
+ int i;
+
+ if (left) {
+ for (i = 4; i--;) {
+ left[i] = mat[i][3] + mat[i][0];
+ }
+ }
+
+ if (right) {
+ for (i = 4; i--;) {
+ right[i] = mat[i][3] - mat[i][0];
+ }
+ }
+
+ if (bottom) {
+ for (i = 4; i--;) {
+ bottom[i] = mat[i][3] + mat[i][1];
+ }
+ }
+
+ if (top) {
+ for (i = 4; i--;) {
+ top[i] = mat[i][3] - mat[i][1];
+ }
+ }
+
+ if (near) {
+ for (i = 4; i--;) {
+ near[i] = mat[i][3] + mat[i][2];
+ }
+ }
+
+ if (far) {
+ for (i = 4; i--;) {
+ far[i] = mat[i][3] - mat[i][2];
+ }
+ }
}
void projmat_dimensions(const float projmat[4][4],
- float *r_left, float *r_right,
- float *r_bottom, float *r_top,
- float *r_near, float *r_far)
-{
- bool is_persp = projmat[3][3] == 0.0f;
-
- if (is_persp) {
- *r_left = (projmat[2][0] - 1.0f) / projmat[0][0];
- *r_right = (projmat[2][0] + 1.0f) / projmat[0][0];
- *r_bottom = (projmat[2][1] - 1.0f) / projmat[1][1];
- *r_top = (projmat[2][1] + 1.0f) / projmat[1][1];
- *r_near = projmat[3][2] / (projmat[2][2] - 1.0f);
- *r_far = projmat[3][2] / (projmat[2][2] + 1.0f);
- }
- else {
- *r_left = (-projmat[3][0] - 1.0f) / projmat[0][0];
- *r_right = (-projmat[3][0] + 1.0f) / projmat[0][0];
- *r_bottom = (-projmat[3][1] - 1.0f) / projmat[1][1];
- *r_top = (-projmat[3][1] + 1.0f) / projmat[1][1];
- *r_near = ( projmat[3][2] + 1.0f) / projmat[2][2];
- *r_far = ( projmat[3][2] - 1.0f) / projmat[2][2];
- }
-
+ float *r_left,
+ float *r_right,
+ float *r_bottom,
+ float *r_top,
+ float *r_near,
+ float *r_far)
+{
+ bool is_persp = projmat[3][3] == 0.0f;
+
+ if (is_persp) {
+ *r_left = (projmat[2][0] - 1.0f) / projmat[0][0];
+ *r_right = (projmat[2][0] + 1.0f) / projmat[0][0];
+ *r_bottom = (projmat[2][1] - 1.0f) / projmat[1][1];
+ *r_top = (projmat[2][1] + 1.0f) / projmat[1][1];
+ *r_near = projmat[3][2] / (projmat[2][2] - 1.0f);
+ *r_far = projmat[3][2] / (projmat[2][2] + 1.0f);
+ }
+ else {
+ *r_left = (-projmat[3][0] - 1.0f) / projmat[0][0];
+ *r_right = (-projmat[3][0] + 1.0f) / projmat[0][0];
+ *r_bottom = (-projmat[3][1] - 1.0f) / projmat[1][1];
+ *r_top = (-projmat[3][1] + 1.0f) / projmat[1][1];
+ *r_near = (projmat[3][2] + 1.0f) / projmat[2][2];
+ *r_far = (projmat[3][2] - 1.0f) / projmat[2][2];
+ }
}
static void i_multmatrix(float icand[4][4], float Vm[4][4])
{
- int row, col;
- float temp[4][4];
+ int row, col;
+ float temp[4][4];
- for (row = 0; row < 4; row++) {
- for (col = 0; col < 4; col++) {
- temp[row][col] = (icand[row][0] * Vm[0][col] +
- icand[row][1] * Vm[1][col] +
- icand[row][2] * Vm[2][col] +
- icand[row][3] * Vm[3][col]);
- }
- }
- copy_m4_m4(Vm, temp);
+ for (row = 0; row < 4; row++) {
+ for (col = 0; col < 4; col++) {
+ temp[row][col] = (icand[row][0] * Vm[0][col] + icand[row][1] * Vm[1][col] +
+ icand[row][2] * Vm[2][col] + icand[row][3] * Vm[3][col]);
+ }
+ }
+ copy_m4_m4(Vm, temp);
}
void polarview_m4(float Vm[4][4], float dist, float azimuth, float incidence, float twist)
{
- unit_m4(Vm);
+ unit_m4(Vm);
- translate_m4(Vm, 0.0, 0.0, -dist);
- rotate_m4(Vm, 'Z', -twist);
- rotate_m4(Vm, 'X', -incidence);
- rotate_m4(Vm, 'Z', -azimuth);
+ translate_m4(Vm, 0.0, 0.0, -dist);
+ rotate_m4(Vm, 'Z', -twist);
+ rotate_m4(Vm, 'X', -incidence);
+ rotate_m4(Vm, 'Z', -azimuth);
}
-void lookat_m4(float mat[4][4], float vx, float vy, float vz, float px, float py, float pz, float twist)
+void lookat_m4(
+ float mat[4][4], float vx, float vy, float vz, float px, float py, float pz, float twist)
{
- float sine, cosine, hyp, hyp1, dx, dy, dz;
- float mat1[4][4];
+ float sine, cosine, hyp, hyp1, dx, dy, dz;
+ float mat1[4][4];
- unit_m4(mat1);
+ unit_m4(mat1);
- axis_angle_to_mat4_single(mat, 'Z', -twist);
+ axis_angle_to_mat4_single(mat, 'Z', -twist);
- dx = px - vx;
- dy = py - vy;
- dz = pz - vz;
- hyp = dx * dx + dz * dz; /* hyp squared */
- hyp1 = sqrtf(dy * dy + hyp);
- hyp = sqrtf(hyp); /* the real hyp */
+ dx = px - vx;
+ dy = py - vy;
+ dz = pz - vz;
+ hyp = dx * dx + dz * dz; /* hyp squared */
+ hyp1 = sqrtf(dy * dy + hyp);
+ hyp = sqrtf(hyp); /* the real hyp */
- if (hyp1 != 0.0f) { /* rotate X */
- sine = -dy / hyp1;
- cosine = hyp / hyp1;
- }
- else {
- sine = 0.0f;
- cosine = 1.0f;
- }
- mat1[1][1] = cosine;
- mat1[1][2] = sine;
- mat1[2][1] = -sine;
- mat1[2][2] = cosine;
+ if (hyp1 != 0.0f) { /* rotate X */
+ sine = -dy / hyp1;
+ cosine = hyp / hyp1;
+ }
+ else {
+ sine = 0.0f;
+ cosine = 1.0f;
+ }
+ mat1[1][1] = cosine;
+ mat1[1][2] = sine;
+ mat1[2][1] = -sine;
+ mat1[2][2] = cosine;
- i_multmatrix(mat1, mat);
+ i_multmatrix(mat1, mat);
- mat1[1][1] = mat1[2][2] = 1.0f; /* be careful here to reinit */
- mat1[1][2] = mat1[2][1] = 0.0f; /* those modified by the last */
+ mat1[1][1] = mat1[2][2] = 1.0f; /* be careful here to reinit */
+ mat1[1][2] = mat1[2][1] = 0.0f; /* those modified by the last */
- /* paragraph */
- if (hyp != 0.0f) { /* rotate Y */
- sine = dx / hyp;
- cosine = -dz / hyp;
- }
- else {
- sine = 0.0f;
- cosine = 1.0f;
- }
- mat1[0][0] = cosine;
- mat1[0][2] = -sine;
- mat1[2][0] = sine;
- mat1[2][2] = cosine;
+ /* paragraph */
+ if (hyp != 0.0f) { /* rotate Y */
+ sine = dx / hyp;
+ cosine = -dz / hyp;
+ }
+ else {
+ sine = 0.0f;
+ cosine = 1.0f;
+ }
+ mat1[0][0] = cosine;
+ mat1[0][2] = -sine;
+ mat1[2][0] = sine;
+ mat1[2][2] = cosine;
- i_multmatrix(mat1, mat);
- translate_m4(mat, -vx, -vy, -vz); /* translate viewpoint to origin */
+ i_multmatrix(mat1, mat);
+ translate_m4(mat, -vx, -vy, -vz); /* translate viewpoint to origin */
}
int box_clip_bounds_m4(float boundbox[2][3], const float bounds[4], float winmat[4][4])
{
- float mat[4][4], vec[4];
- int a, fl, flag = -1;
-
- copy_m4_m4(mat, winmat);
-
- for (a = 0; a < 8; a++) {
- vec[0] = (a & 1) ? boundbox[0][0] : boundbox[1][0];
- vec[1] = (a & 2) ? boundbox[0][1] : boundbox[1][1];
- vec[2] = (a & 4) ? boundbox[0][2] : boundbox[1][2];
- vec[3] = 1.0;
- mul_m4_v4(mat, vec);
-
- fl = 0;
- if (bounds) {
- if (vec[0] > bounds[1] * vec[3]) { fl |= 1; }
- if (vec[0] < bounds[0] * vec[3]) { fl |= 2; }
- if (vec[1] > bounds[3] * vec[3]) { fl |= 4; }
- if (vec[1] < bounds[2] * vec[3]) { fl |= 8; }
- }
- else {
- if (vec[0] < -vec[3]) { fl |= 1; }
- if (vec[0] > vec[3]) { fl |= 2; }
- if (vec[1] < -vec[3]) { fl |= 4; }
- if (vec[1] > vec[3]) { fl |= 8; }
- }
- if (vec[2] < -vec[3]) { fl |= 16; }
- if (vec[2] > vec[3]) { fl |= 32; }
-
- flag &= fl;
- if (flag == 0) {
- return 0;
- }
- }
-
- return flag;
+ float mat[4][4], vec[4];
+ int a, fl, flag = -1;
+
+ copy_m4_m4(mat, winmat);
+
+ for (a = 0; a < 8; a++) {
+ vec[0] = (a & 1) ? boundbox[0][0] : boundbox[1][0];
+ vec[1] = (a & 2) ? boundbox[0][1] : boundbox[1][1];
+ vec[2] = (a & 4) ? boundbox[0][2] : boundbox[1][2];
+ vec[3] = 1.0;
+ mul_m4_v4(mat, vec);
+
+ fl = 0;
+ if (bounds) {
+ if (vec[0] > bounds[1] * vec[3]) {
+ fl |= 1;
+ }
+ if (vec[0] < bounds[0] * vec[3]) {
+ fl |= 2;
+ }
+ if (vec[1] > bounds[3] * vec[3]) {
+ fl |= 4;
+ }
+ if (vec[1] < bounds[2] * vec[3]) {
+ fl |= 8;
+ }
+ }
+ else {
+ if (vec[0] < -vec[3]) {
+ fl |= 1;
+ }
+ if (vec[0] > vec[3]) {
+ fl |= 2;
+ }
+ if (vec[1] < -vec[3]) {
+ fl |= 4;
+ }
+ if (vec[1] > vec[3]) {
+ fl |= 8;
+ }
+ }
+ if (vec[2] < -vec[3]) {
+ fl |= 16;
+ }
+ if (vec[2] > vec[3]) {
+ fl |= 32;
+ }
+
+ flag &= fl;
+ if (flag == 0) {
+ return 0;
+ }
+ }
+
+ return flag;
}
void box_minmax_bounds_m4(float min[3], float max[3], float boundbox[2][3], float mat[4][4])
{
- float mn[3], mx[3], vec[3];
- int a;
+ float mn[3], mx[3], vec[3];
+ int a;
- copy_v3_v3(mn, min);
- copy_v3_v3(mx, max);
+ copy_v3_v3(mn, min);
+ copy_v3_v3(mx, max);
- for (a = 0; a < 8; a++) {
- vec[0] = (a & 1) ? boundbox[0][0] : boundbox[1][0];
- vec[1] = (a & 2) ? boundbox[0][1] : boundbox[1][1];
- vec[2] = (a & 4) ? boundbox[0][2] : boundbox[1][2];
+ for (a = 0; a < 8; a++) {
+ vec[0] = (a & 1) ? boundbox[0][0] : boundbox[1][0];
+ vec[1] = (a & 2) ? boundbox[0][1] : boundbox[1][1];
+ vec[2] = (a & 4) ? boundbox[0][2] : boundbox[1][2];
- mul_m4_v3(mat, vec);
- minmax_v3v3_v3(mn, mx, vec);
- }
+ mul_m4_v3(mat, vec);
+ minmax_v3v3_v3(mn, mx, vec);
+ }
- copy_v3_v3(min, mn);
- copy_v3_v3(max, mx);
+ copy_v3_v3(min, mn);
+ copy_v3_v3(max, mx);
}
/********************************** Mapping **********************************/
void map_to_tube(float *r_u, float *r_v, const float x, const float y, const float z)
{
- float len;
+ float len;
- *r_v = (z + 1.0f) / 2.0f;
+ *r_v = (z + 1.0f) / 2.0f;
- len = sqrtf(x * x + y * y);
- if (len > 0.0f) {
- *r_u = (1.0f - (atan2f(x / len, y / len) / (float)M_PI)) / 2.0f;
- }
- else {
- *r_v = *r_u = 0.0f; /* to avoid un-initialized variables */
- }
+ len = sqrtf(x * x + y * y);
+ if (len > 0.0f) {
+ *r_u = (1.0f - (atan2f(x / len, y / len) / (float)M_PI)) / 2.0f;
+ }
+ else {
+ *r_v = *r_u = 0.0f; /* to avoid un-initialized variables */
+ }
}
void map_to_sphere(float *r_u, float *r_v, const float x, const float y, const float z)
{
- float len;
+ float len;
- len = sqrtf(x * x + y * y + z * z);
- if (len > 0.0f) {
- if (UNLIKELY(x == 0.0f && y == 0.0f)) {
- *r_u = 0.0f; /* othwise domain error */
- }
- else {
- *r_u = (1.0f - atan2f(x, y) / (float)M_PI) / 2.0f;
- }
+ len = sqrtf(x * x + y * y + z * z);
+ if (len > 0.0f) {
+ if (UNLIKELY(x == 0.0f && y == 0.0f)) {
+ *r_u = 0.0f; /* othwise domain error */
+ }
+ else {
+ *r_u = (1.0f - atan2f(x, y) / (float)M_PI) / 2.0f;
+ }
- *r_v = 1.0f - saacos(z / len) / (float)M_PI;
- }
- else {
- *r_v = *r_u = 0.0f; /* to avoid un-initialized variables */
- }
+ *r_v = 1.0f - saacos(z / len) / (float)M_PI;
+ }
+ else {
+ *r_v = *r_u = 0.0f; /* to avoid un-initialized variables */
+ }
}
void map_to_plane_v2_v3v3(float r_co[2], const float co[3], const float no[3])
{
- float target[3] = {0.0f, 0.0f, 1.0f};
- float axis[3];
+ float target[3] = {0.0f, 0.0f, 1.0f};
+ float axis[3];
- cross_v3_v3v3(axis, no, target);
- normalize_v3(axis);
+ cross_v3_v3v3(axis, no, target);
+ normalize_v3(axis);
- map_to_plane_axis_angle_v2_v3v3fl(r_co, co, axis, angle_normalized_v3v3(no, target));
+ map_to_plane_axis_angle_v2_v3v3fl(r_co, co, axis, angle_normalized_v3v3(no, target));
}
-void map_to_plane_axis_angle_v2_v3v3fl(float r_co[2], const float co[3], const float axis[3], const float angle)
+void map_to_plane_axis_angle_v2_v3v3fl(float r_co[2],
+ const float co[3],
+ const float axis[3],
+ const float angle)
{
- float tmp[3];
+ float tmp[3];
- rotate_normalized_v3_v3v3fl(tmp, co, axis, angle);
+ rotate_normalized_v3_v3v3fl(tmp, co, axis, angle);
- copy_v2_v2(r_co, tmp);
+ copy_v2_v2(r_co, tmp);
}
/********************************* Normals **********************************/
-void accumulate_vertex_normals_tri_v3(
- float n1[3], float n2[3], float n3[3],
- const float f_no[3],
- const float co1[3], const float co2[3], const float co3[3])
-{
- float vdiffs[3][3];
- const int nverts = 3;
-
- /* compute normalized edge vectors */
- sub_v3_v3v3(vdiffs[0], co2, co1);
- sub_v3_v3v3(vdiffs[1], co3, co2);
- sub_v3_v3v3(vdiffs[2], co1, co3);
-
- normalize_v3(vdiffs[0]);
- normalize_v3(vdiffs[1]);
- normalize_v3(vdiffs[2]);
-
- /* accumulate angle weighted face normal */
- {
- float *vn[] = {n1, n2, n3};
- const float *prev_edge = vdiffs[nverts - 1];
- int i;
-
- for (i = 0; i < nverts; i++) {
- const float *cur_edge = vdiffs[i];
- const float fac = saacos(-dot_v3v3(cur_edge, prev_edge));
-
- /* accumulate */
- madd_v3_v3fl(vn[i], f_no, fac);
- prev_edge = cur_edge;
- }
- }
-}
-
-void accumulate_vertex_normals_v3(
- float n1[3], float n2[3], float n3[3], float n4[3],
- const float f_no[3],
- const float co1[3], const float co2[3], const float co3[3], const float co4[3])
-{
- float vdiffs[4][3];
- const int nverts = (n4 != NULL && co4 != NULL) ? 4 : 3;
-
- /* compute normalized edge vectors */
- sub_v3_v3v3(vdiffs[0], co2, co1);
- sub_v3_v3v3(vdiffs[1], co3, co2);
-
- if (nverts == 3) {
- sub_v3_v3v3(vdiffs[2], co1, co3);
- }
- else {
- sub_v3_v3v3(vdiffs[2], co4, co3);
- sub_v3_v3v3(vdiffs[3], co1, co4);
- normalize_v3(vdiffs[3]);
- }
-
- normalize_v3(vdiffs[0]);
- normalize_v3(vdiffs[1]);
- normalize_v3(vdiffs[2]);
-
- /* accumulate angle weighted face normal */
- {
- float *vn[] = {n1, n2, n3, n4};
- const float *prev_edge = vdiffs[nverts - 1];
- int i;
-
- for (i = 0; i < nverts; i++) {
- const float *cur_edge = vdiffs[i];
- const float fac = saacos(-dot_v3v3(cur_edge, prev_edge));
-
- /* accumulate */
- madd_v3_v3fl(vn[i], f_no, fac);
- prev_edge = cur_edge;
- }
- }
+void accumulate_vertex_normals_tri_v3(float n1[3],
+ float n2[3],
+ float n3[3],
+ const float f_no[3],
+ const float co1[3],
+ const float co2[3],
+ const float co3[3])
+{
+ float vdiffs[3][3];
+ const int nverts = 3;
+
+ /* compute normalized edge vectors */
+ sub_v3_v3v3(vdiffs[0], co2, co1);
+ sub_v3_v3v3(vdiffs[1], co3, co2);
+ sub_v3_v3v3(vdiffs[2], co1, co3);
+
+ normalize_v3(vdiffs[0]);
+ normalize_v3(vdiffs[1]);
+ normalize_v3(vdiffs[2]);
+
+ /* accumulate angle weighted face normal */
+ {
+ float *vn[] = {n1, n2, n3};
+ const float *prev_edge = vdiffs[nverts - 1];
+ int i;
+
+ for (i = 0; i < nverts; i++) {
+ const float *cur_edge = vdiffs[i];
+ const float fac = saacos(-dot_v3v3(cur_edge, prev_edge));
+
+ /* accumulate */
+ madd_v3_v3fl(vn[i], f_no, fac);
+ prev_edge = cur_edge;
+ }
+ }
+}
+
+void accumulate_vertex_normals_v3(float n1[3],
+ float n2[3],
+ float n3[3],
+ float n4[3],
+ const float f_no[3],
+ const float co1[3],
+ const float co2[3],
+ const float co3[3],
+ const float co4[3])
+{
+ float vdiffs[4][3];
+ const int nverts = (n4 != NULL && co4 != NULL) ? 4 : 3;
+
+ /* compute normalized edge vectors */
+ sub_v3_v3v3(vdiffs[0], co2, co1);
+ sub_v3_v3v3(vdiffs[1], co3, co2);
+
+ if (nverts == 3) {
+ sub_v3_v3v3(vdiffs[2], co1, co3);
+ }
+ else {
+ sub_v3_v3v3(vdiffs[2], co4, co3);
+ sub_v3_v3v3(vdiffs[3], co1, co4);
+ normalize_v3(vdiffs[3]);
+ }
+
+ normalize_v3(vdiffs[0]);
+ normalize_v3(vdiffs[1]);
+ normalize_v3(vdiffs[2]);
+
+ /* accumulate angle weighted face normal */
+ {
+ float *vn[] = {n1, n2, n3, n4};
+ const float *prev_edge = vdiffs[nverts - 1];
+ int i;
+
+ for (i = 0; i < nverts; i++) {
+ const float *cur_edge = vdiffs[i];
+ const float fac = saacos(-dot_v3v3(cur_edge, prev_edge));
+
+ /* accumulate */
+ madd_v3_v3fl(vn[i], f_no, fac);
+ prev_edge = cur_edge;
+ }
+ }
}
/* Add weighted face normal component into normals of the face vertices.
* Caller must pass pre-allocated vdiffs of nverts length. */
-void accumulate_vertex_normals_poly_v3(float **vertnos, const float polyno[3],
- const float **vertcos, float vdiffs[][3], const int nverts)
+void accumulate_vertex_normals_poly_v3(float **vertnos,
+ const float polyno[3],
+ const float **vertcos,
+ float vdiffs[][3],
+ const int nverts)
{
- int i;
+ int i;
- /* calculate normalized edge directions for each edge in the poly */
- for (i = 0; i < nverts; i++) {
- sub_v3_v3v3(vdiffs[i], vertcos[(i + 1) % nverts], vertcos[i]);
- normalize_v3(vdiffs[i]);
- }
+ /* calculate normalized edge directions for each edge in the poly */
+ for (i = 0; i < nverts; i++) {
+ sub_v3_v3v3(vdiffs[i], vertcos[(i + 1) % nverts], vertcos[i]);
+ normalize_v3(vdiffs[i]);
+ }
- /* accumulate angle weighted face normal */
- {
- const float *prev_edge = vdiffs[nverts - 1];
+ /* accumulate angle weighted face normal */
+ {
+ const float *prev_edge = vdiffs[nverts - 1];
- for (i = 0; i < nverts; i++) {
- const float *cur_edge = vdiffs[i];
+ for (i = 0; i < nverts; i++) {
+ const float *cur_edge = vdiffs[i];
- /* calculate angle between the two poly edges incident on
- * this vertex */
- const float fac = saacos(-dot_v3v3(cur_edge, prev_edge));
+ /* calculate angle between the two poly edges incident on
+ * this vertex */
+ const float fac = saacos(-dot_v3v3(cur_edge, prev_edge));
- /* accumulate */
- madd_v3_v3fl(vertnos[i], polyno, fac);
- prev_edge = cur_edge;
- }
- }
+ /* accumulate */
+ madd_v3_v3fl(vertnos[i], polyno, fac);
+ prev_edge = cur_edge;
+ }
+ }
}
/********************************* Tangents **********************************/
-void tangent_from_uv_v3(
- const float uv1[2], const float uv2[2], const float uv3[3],
- const float co1[3], const float co2[3], const float co3[3],
- const float n[3],
- float r_tang[3])
-{
- const float s1 = uv2[0] - uv1[0];
- const float s2 = uv3[0] - uv1[0];
- const float t1 = uv2[1] - uv1[1];
- const float t2 = uv3[1] - uv1[1];
- float det = (s1 * t2 - s2 * t1);
-
- /* otherwise 'r_tang' becomes nan */
- if (det != 0.0f) {
- float tangv[3], ct[3], e1[3], e2[3];
-
- det = 1.0f / det;
-
- /* normals in render are inversed... */
- sub_v3_v3v3(e1, co1, co2);
- sub_v3_v3v3(e2, co1, co3);
- r_tang[0] = (t2 * e1[0] - t1 * e2[0]) * det;
- r_tang[1] = (t2 * e1[1] - t1 * e2[1]) * det;
- r_tang[2] = (t2 * e1[2] - t1 * e2[2]) * det;
- tangv[0] = (s1 * e2[0] - s2 * e1[0]) * det;
- tangv[1] = (s1 * e2[1] - s2 * e1[1]) * det;
- tangv[2] = (s1 * e2[2] - s2 * e1[2]) * det;
- cross_v3_v3v3(ct, r_tang, tangv);
-
- /* check flip */
- if (dot_v3v3(ct, n) < 0.0f) {
- negate_v3(r_tang);
- }
- }
- else {
- zero_v3(r_tang);
- }
+void tangent_from_uv_v3(const float uv1[2],
+ const float uv2[2],
+ const float uv3[3],
+ const float co1[3],
+ const float co2[3],
+ const float co3[3],
+ const float n[3],
+ float r_tang[3])
+{
+ const float s1 = uv2[0] - uv1[0];
+ const float s2 = uv3[0] - uv1[0];
+ const float t1 = uv2[1] - uv1[1];
+ const float t2 = uv3[1] - uv1[1];
+ float det = (s1 * t2 - s2 * t1);
+
+ /* otherwise 'r_tang' becomes nan */
+ if (det != 0.0f) {
+ float tangv[3], ct[3], e1[3], e2[3];
+
+ det = 1.0f / det;
+
+ /* normals in render are inversed... */
+ sub_v3_v3v3(e1, co1, co2);
+ sub_v3_v3v3(e2, co1, co3);
+ r_tang[0] = (t2 * e1[0] - t1 * e2[0]) * det;
+ r_tang[1] = (t2 * e1[1] - t1 * e2[1]) * det;
+ r_tang[2] = (t2 * e1[2] - t1 * e2[2]) * det;
+ tangv[0] = (s1 * e2[0] - s2 * e1[0]) * det;
+ tangv[1] = (s1 * e2[1] - s2 * e1[1]) * det;
+ tangv[2] = (s1 * e2[2] - s2 * e1[2]) * det;
+ cross_v3_v3v3(ct, r_tang, tangv);
+
+ /* check flip */
+ if (dot_v3v3(ct, n) < 0.0f) {
+ negate_v3(r_tang);
+ }
+ }
+ else {
+ zero_v3(r_tang);
+ }
}
/****************************** Vector Clouds ********************************/
@@ -4628,424 +4820,449 @@ void tangent_from_uv_v3(
* pointers may be NULL if not needed
*/
-void vcloud_estimate_transform_v3(
- const int list_size, const float (*pos)[3], const float *weight, const float (*rpos)[3], const float *rweight,
- float lloc[3], float rloc[3], float lrot[3][3], float lscale[3][3])
-{
- float accu_com[3] = {0.0f, 0.0f, 0.0f}, accu_rcom[3] = {0.0f, 0.0f, 0.0f};
- float accu_weight = 0.0f, accu_rweight = 0.0f;
- const float eps = 1e-6f;
-
- int a;
- /* first set up a nice default response */
- if (lloc) { zero_v3(lloc); }
- if (rloc) { zero_v3(rloc); }
- if (lrot) { unit_m3(lrot); }
- if (lscale) { unit_m3(lscale); }
- /* do com for both clouds */
- if (pos && rpos && (list_size > 0)) { /* paranoya check */
- /* do com for both clouds */
- for (a = 0; a < list_size; a++) {
- if (weight) {
- float v[3];
- copy_v3_v3(v, pos[a]);
- mul_v3_fl(v, weight[a]);
- add_v3_v3(accu_com, v);
- accu_weight += weight[a];
- }
- else {
- add_v3_v3(accu_com, pos[a]);
- }
-
- if (rweight) {
- float v[3];
- copy_v3_v3(v, rpos[a]);
- mul_v3_fl(v, rweight[a]);
- add_v3_v3(accu_rcom, v);
- accu_rweight += rweight[a];
- }
- else {
- add_v3_v3(accu_rcom, rpos[a]);
- }
- }
- if (!weight || !rweight) {
- accu_weight = accu_rweight = (float)list_size;
- }
-
- mul_v3_fl(accu_com, 1.0f / accu_weight);
- mul_v3_fl(accu_rcom, 1.0f / accu_rweight);
- if (lloc) {
- copy_v3_v3(lloc, accu_com);
- }
- if (rloc) {
- copy_v3_v3(rloc, accu_rcom);
- }
- if (lrot || lscale) { /* caller does not want rot nor scale, strange but legal */
- /* so now do some reverse engineering and see if we can
- * split rotation from scale -> Polardecompose */
- /* build 'projection' matrix */
- float m[3][3], mr[3][3], q[3][3], qi[3][3];
- float va[3], vb[3], stunt[3];
- float odet, ndet;
- int i = 0, imax = 15;
- zero_m3(m);
- zero_m3(mr);
-
- /* build 'projection' matrix */
- for (a = 0; a < list_size; a++) {
- sub_v3_v3v3(va, rpos[a], accu_rcom);
- /* mul_v3_fl(va, bp->mass); mass needs renormalzation here ?? */
- sub_v3_v3v3(vb, pos[a], accu_com);
- /* mul_v3_fl(va, rp->mass); */
- m[0][0] += va[0] * vb[0];
- m[0][1] += va[0] * vb[1];
- m[0][2] += va[0] * vb[2];
-
- m[1][0] += va[1] * vb[0];
- m[1][1] += va[1] * vb[1];
- m[1][2] += va[1] * vb[2];
-
- m[2][0] += va[2] * vb[0];
- m[2][1] += va[2] * vb[1];
- m[2][2] += va[2] * vb[2];
-
- /* building the reference matrix on the fly
- * needed to scale properly later */
-
- mr[0][0] += va[0] * va[0];
- mr[0][1] += va[0] * va[1];
- mr[0][2] += va[0] * va[2];
-
- mr[1][0] += va[1] * va[0];
- mr[1][1] += va[1] * va[1];
- mr[1][2] += va[1] * va[2];
-
- mr[2][0] += va[2] * va[0];
- mr[2][1] += va[2] * va[1];
- mr[2][2] += va[2] * va[2];
- }
- copy_m3_m3(q, m);
- stunt[0] = q[0][0];
- stunt[1] = q[1][1];
- stunt[2] = q[2][2];
- /* renormalizing for numeric stability */
- mul_m3_fl(q, 1.f / len_v3(stunt));
-
- /* this is pretty much Polardecompose 'inline' the algo based on Higham's thesis */
- /* without the far case ... but seems to work here pretty neat */
- odet = 0.0f;
- ndet = determinant_m3_array(q);
- while ((odet - ndet) * (odet - ndet) > eps && i < imax) {
- invert_m3_m3(qi, q);
- transpose_m3(qi);
- add_m3_m3m3(q, q, qi);
- mul_m3_fl(q, 0.5f);
- odet = ndet;
- ndet = determinant_m3_array(q);
- i++;
- }
-
- if (i) {
- float scale[3][3];
- float irot[3][3];
- if (lrot) {
- copy_m3_m3(lrot, q);
- }
- invert_m3_m3(irot, q);
- invert_m3_m3(qi, mr);
- mul_m3_m3m3(q, m, qi);
- mul_m3_m3m3(scale, irot, q);
- if (lscale) {
- copy_m3_m3(lscale, scale);
- }
-
- }
- }
- }
+void vcloud_estimate_transform_v3(const int list_size,
+ const float (*pos)[3],
+ const float *weight,
+ const float (*rpos)[3],
+ const float *rweight,
+ float lloc[3],
+ float rloc[3],
+ float lrot[3][3],
+ float lscale[3][3])
+{
+ float accu_com[3] = {0.0f, 0.0f, 0.0f}, accu_rcom[3] = {0.0f, 0.0f, 0.0f};
+ float accu_weight = 0.0f, accu_rweight = 0.0f;
+ const float eps = 1e-6f;
+
+ int a;
+ /* first set up a nice default response */
+ if (lloc) {
+ zero_v3(lloc);
+ }
+ if (rloc) {
+ zero_v3(rloc);
+ }
+ if (lrot) {
+ unit_m3(lrot);
+ }
+ if (lscale) {
+ unit_m3(lscale);
+ }
+ /* do com for both clouds */
+ if (pos && rpos && (list_size > 0)) { /* paranoya check */
+ /* do com for both clouds */
+ for (a = 0; a < list_size; a++) {
+ if (weight) {
+ float v[3];
+ copy_v3_v3(v, pos[a]);
+ mul_v3_fl(v, weight[a]);
+ add_v3_v3(accu_com, v);
+ accu_weight += weight[a];
+ }
+ else {
+ add_v3_v3(accu_com, pos[a]);
+ }
+
+ if (rweight) {
+ float v[3];
+ copy_v3_v3(v, rpos[a]);
+ mul_v3_fl(v, rweight[a]);
+ add_v3_v3(accu_rcom, v);
+ accu_rweight += rweight[a];
+ }
+ else {
+ add_v3_v3(accu_rcom, rpos[a]);
+ }
+ }
+ if (!weight || !rweight) {
+ accu_weight = accu_rweight = (float)list_size;
+ }
+
+ mul_v3_fl(accu_com, 1.0f / accu_weight);
+ mul_v3_fl(accu_rcom, 1.0f / accu_rweight);
+ if (lloc) {
+ copy_v3_v3(lloc, accu_com);
+ }
+ if (rloc) {
+ copy_v3_v3(rloc, accu_rcom);
+ }
+ if (lrot || lscale) { /* caller does not want rot nor scale, strange but legal */
+ /* so now do some reverse engineering and see if we can
+ * split rotation from scale -> Polardecompose */
+ /* build 'projection' matrix */
+ float m[3][3], mr[3][3], q[3][3], qi[3][3];
+ float va[3], vb[3], stunt[3];
+ float odet, ndet;
+ int i = 0, imax = 15;
+ zero_m3(m);
+ zero_m3(mr);
+
+ /* build 'projection' matrix */
+ for (a = 0; a < list_size; a++) {
+ sub_v3_v3v3(va, rpos[a], accu_rcom);
+ /* mul_v3_fl(va, bp->mass); mass needs renormalzation here ?? */
+ sub_v3_v3v3(vb, pos[a], accu_com);
+ /* mul_v3_fl(va, rp->mass); */
+ m[0][0] += va[0] * vb[0];
+ m[0][1] += va[0] * vb[1];
+ m[0][2] += va[0] * vb[2];
+
+ m[1][0] += va[1] * vb[0];
+ m[1][1] += va[1] * vb[1];
+ m[1][2] += va[1] * vb[2];
+
+ m[2][0] += va[2] * vb[0];
+ m[2][1] += va[2] * vb[1];
+ m[2][2] += va[2] * vb[2];
+
+ /* building the reference matrix on the fly
+ * needed to scale properly later */
+
+ mr[0][0] += va[0] * va[0];
+ mr[0][1] += va[0] * va[1];
+ mr[0][2] += va[0] * va[2];
+
+ mr[1][0] += va[1] * va[0];
+ mr[1][1] += va[1] * va[1];
+ mr[1][2] += va[1] * va[2];
+
+ mr[2][0] += va[2] * va[0];
+ mr[2][1] += va[2] * va[1];
+ mr[2][2] += va[2] * va[2];
+ }
+ copy_m3_m3(q, m);
+ stunt[0] = q[0][0];
+ stunt[1] = q[1][1];
+ stunt[2] = q[2][2];
+ /* renormalizing for numeric stability */
+ mul_m3_fl(q, 1.f / len_v3(stunt));
+
+ /* this is pretty much Polardecompose 'inline' the algo based on Higham's thesis */
+ /* without the far case ... but seems to work here pretty neat */
+ odet = 0.0f;
+ ndet = determinant_m3_array(q);
+ while ((odet - ndet) * (odet - ndet) > eps && i < imax) {
+ invert_m3_m3(qi, q);
+ transpose_m3(qi);
+ add_m3_m3m3(q, q, qi);
+ mul_m3_fl(q, 0.5f);
+ odet = ndet;
+ ndet = determinant_m3_array(q);
+ i++;
+ }
+
+ if (i) {
+ float scale[3][3];
+ float irot[3][3];
+ if (lrot) {
+ copy_m3_m3(lrot, q);
+ }
+ invert_m3_m3(irot, q);
+ invert_m3_m3(qi, mr);
+ mul_m3_m3m3(q, m, qi);
+ mul_m3_m3m3(scale, irot, q);
+ if (lscale) {
+ copy_m3_m3(lscale, scale);
+ }
+ }
+ }
+ }
}
/******************************* Form Factor *********************************/
static void vec_add_dir(float r[3], const float v1[3], const float v2[3], const float fac)
{
- r[0] = v1[0] + fac * (v2[0] - v1[0]);
- r[1] = v1[1] + fac * (v2[1] - v1[1]);
- r[2] = v1[2] + fac * (v2[2] - v1[2]);
-}
-
-bool form_factor_visible_quad(const float p[3], const float n[3],
- const float v0[3], const float v1[3], const float v2[3],
- float q0[3], float q1[3], float q2[3], float q3[3])
-{
- static const float epsilon = 1e-6f;
- float sd[3];
- const float c = dot_v3v3(n, p);
-
- /* signed distances from the vertices to the plane. */
- sd[0] = dot_v3v3(n, v0) - c;
- sd[1] = dot_v3v3(n, v1) - c;
- sd[2] = dot_v3v3(n, v2) - c;
-
- if (fabsf(sd[0]) < epsilon) { sd[0] = 0.0f; }
- if (fabsf(sd[1]) < epsilon) { sd[1] = 0.0f; }
- if (fabsf(sd[2]) < epsilon) { sd[2] = 0.0f; }
-
- if (sd[0] > 0.0f) {
- if (sd[1] > 0.0f) {
- if (sd[2] > 0.0f) {
- /* +++ */
- copy_v3_v3(q0, v0);
- copy_v3_v3(q1, v1);
- copy_v3_v3(q2, v2);
- copy_v3_v3(q3, q2);
- }
- else if (sd[2] < 0.0f) {
- /* ++- */
- copy_v3_v3(q0, v0);
- copy_v3_v3(q1, v1);
- vec_add_dir(q2, v1, v2, (sd[1] / (sd[1] - sd[2])));
- vec_add_dir(q3, v0, v2, (sd[0] / (sd[0] - sd[2])));
- }
- else {
- /* ++0 */
- copy_v3_v3(q0, v0);
- copy_v3_v3(q1, v1);
- copy_v3_v3(q2, v2);
- copy_v3_v3(q3, q2);
- }
- }
- else if (sd[1] < 0.0f) {
- if (sd[2] > 0.0f) {
- /* +-+ */
- copy_v3_v3(q0, v0);
- vec_add_dir(q1, v0, v1, (sd[0] / (sd[0] - sd[1])));
- vec_add_dir(q2, v1, v2, (sd[1] / (sd[1] - sd[2])));
- copy_v3_v3(q3, v2);
- }
- else if (sd[2] < 0.0f) {
- /* +-- */
- copy_v3_v3(q0, v0);
- vec_add_dir(q1, v0, v1, (sd[0] / (sd[0] - sd[1])));
- vec_add_dir(q2, v0, v2, (sd[0] / (sd[0] - sd[2])));
- copy_v3_v3(q3, q2);
- }
- else {
- /* +-0 */
- copy_v3_v3(q0, v0);
- vec_add_dir(q1, v0, v1, (sd[0] / (sd[0] - sd[1])));
- copy_v3_v3(q2, v2);
- copy_v3_v3(q3, q2);
- }
- }
- else {
- if (sd[2] > 0.0f) {
- /* +0+ */
- copy_v3_v3(q0, v0);
- copy_v3_v3(q1, v1);
- copy_v3_v3(q2, v2);
- copy_v3_v3(q3, q2);
- }
- else if (sd[2] < 0.0f) {
- /* +0- */
- copy_v3_v3(q0, v0);
- copy_v3_v3(q1, v1);
- vec_add_dir(q2, v0, v2, (sd[0] / (sd[0] - sd[2])));
- copy_v3_v3(q3, q2);
- }
- else {
- /* +00 */
- copy_v3_v3(q0, v0);
- copy_v3_v3(q1, v1);
- copy_v3_v3(q2, v2);
- copy_v3_v3(q3, q2);
- }
- }
- }
- else if (sd[0] < 0.0f) {
- if (sd[1] > 0.0f) {
- if (sd[2] > 0.0f) {
- /* -++ */
- vec_add_dir(q0, v0, v1, (sd[0] / (sd[0] - sd[1])));
- copy_v3_v3(q1, v1);
- copy_v3_v3(q2, v2);
- vec_add_dir(q3, v0, v2, (sd[0] / (sd[0] - sd[2])));
- }
- else if (sd[2] < 0.0f) {
- /* -+- */
- vec_add_dir(q0, v0, v1, (sd[0] / (sd[0] - sd[1])));
- copy_v3_v3(q1, v1);
- vec_add_dir(q2, v1, v2, (sd[1] / (sd[1] - sd[2])));
- copy_v3_v3(q3, q2);
- }
- else {
- /* -+0 */
- vec_add_dir(q0, v0, v1, (sd[0] / (sd[0] - sd[1])));
- copy_v3_v3(q1, v1);
- copy_v3_v3(q2, v2);
- copy_v3_v3(q3, q2);
- }
- }
- else if (sd[1] < 0.0f) {
- if (sd[2] > 0.0f) {
- /* --+ */
- vec_add_dir(q0, v0, v2, (sd[0] / (sd[0] - sd[2])));
- vec_add_dir(q1, v1, v2, (sd[1] / (sd[1] - sd[2])));
- copy_v3_v3(q2, v2);
- copy_v3_v3(q3, q2);
- }
- else if (sd[2] < 0.0f) {
- /* --- */
- return false;
- }
- else {
- /* --0 */
- return false;
- }
- }
- else {
- if (sd[2] > 0.0f) {
- /* -0+ */
- vec_add_dir(q0, v0, v2, (sd[0] / (sd[0] - sd[2])));
- copy_v3_v3(q1, v1);
- copy_v3_v3(q2, v2);
- copy_v3_v3(q3, q2);
- }
- else if (sd[2] < 0.0f) {
- /* -0- */
- return false;
- }
- else {
- /* -00 */
- return false;
- }
- }
- }
- else {
- if (sd[1] > 0.0f) {
- if (sd[2] > 0.0f) {
- /* 0++ */
- copy_v3_v3(q0, v0);
- copy_v3_v3(q1, v1);
- copy_v3_v3(q2, v2);
- copy_v3_v3(q3, q2);
- }
- else if (sd[2] < 0.0f) {
- /* 0+- */
- copy_v3_v3(q0, v0);
- copy_v3_v3(q1, v1);
- vec_add_dir(q2, v1, v2, (sd[1] / (sd[1] - sd[2])));
- copy_v3_v3(q3, q2);
- }
- else {
- /* 0+0 */
- copy_v3_v3(q0, v0);
- copy_v3_v3(q1, v1);
- copy_v3_v3(q2, v2);
- copy_v3_v3(q3, q2);
- }
- }
- else if (sd[1] < 0.0f) {
- if (sd[2] > 0.0f) {
- /* 0-+ */
- copy_v3_v3(q0, v0);
- vec_add_dir(q1, v1, v2, (sd[1] / (sd[1] - sd[2])));
- copy_v3_v3(q2, v2);
- copy_v3_v3(q3, q2);
- }
- else if (sd[2] < 0.0f) {
- /* 0-- */
- return false;
- }
- else {
- /* 0-0 */
- return false;
- }
- }
- else {
- if (sd[2] > 0.0f) {
- /* 00+ */
- copy_v3_v3(q0, v0);
- copy_v3_v3(q1, v1);
- copy_v3_v3(q2, v2);
- copy_v3_v3(q3, q2);
- }
- else if (sd[2] < 0.0f) {
- /* 00- */
- return false;
- }
- else {
- /* 000 */
- return false;
- }
- }
- }
-
- return true;
+ r[0] = v1[0] + fac * (v2[0] - v1[0]);
+ r[1] = v1[1] + fac * (v2[1] - v1[1]);
+ r[2] = v1[2] + fac * (v2[2] - v1[2]);
+}
+
+bool form_factor_visible_quad(const float p[3],
+ const float n[3],
+ const float v0[3],
+ const float v1[3],
+ const float v2[3],
+ float q0[3],
+ float q1[3],
+ float q2[3],
+ float q3[3])
+{
+ static const float epsilon = 1e-6f;
+ float sd[3];
+ const float c = dot_v3v3(n, p);
+
+ /* signed distances from the vertices to the plane. */
+ sd[0] = dot_v3v3(n, v0) - c;
+ sd[1] = dot_v3v3(n, v1) - c;
+ sd[2] = dot_v3v3(n, v2) - c;
+
+ if (fabsf(sd[0]) < epsilon) {
+ sd[0] = 0.0f;
+ }
+ if (fabsf(sd[1]) < epsilon) {
+ sd[1] = 0.0f;
+ }
+ if (fabsf(sd[2]) < epsilon) {
+ sd[2] = 0.0f;
+ }
+
+ if (sd[0] > 0.0f) {
+ if (sd[1] > 0.0f) {
+ if (sd[2] > 0.0f) {
+ /* +++ */
+ copy_v3_v3(q0, v0);
+ copy_v3_v3(q1, v1);
+ copy_v3_v3(q2, v2);
+ copy_v3_v3(q3, q2);
+ }
+ else if (sd[2] < 0.0f) {
+ /* ++- */
+ copy_v3_v3(q0, v0);
+ copy_v3_v3(q1, v1);
+ vec_add_dir(q2, v1, v2, (sd[1] / (sd[1] - sd[2])));
+ vec_add_dir(q3, v0, v2, (sd[0] / (sd[0] - sd[2])));
+ }
+ else {
+ /* ++0 */
+ copy_v3_v3(q0, v0);
+ copy_v3_v3(q1, v1);
+ copy_v3_v3(q2, v2);
+ copy_v3_v3(q3, q2);
+ }
+ }
+ else if (sd[1] < 0.0f) {
+ if (sd[2] > 0.0f) {
+ /* +-+ */
+ copy_v3_v3(q0, v0);
+ vec_add_dir(q1, v0, v1, (sd[0] / (sd[0] - sd[1])));
+ vec_add_dir(q2, v1, v2, (sd[1] / (sd[1] - sd[2])));
+ copy_v3_v3(q3, v2);
+ }
+ else if (sd[2] < 0.0f) {
+ /* +-- */
+ copy_v3_v3(q0, v0);
+ vec_add_dir(q1, v0, v1, (sd[0] / (sd[0] - sd[1])));
+ vec_add_dir(q2, v0, v2, (sd[0] / (sd[0] - sd[2])));
+ copy_v3_v3(q3, q2);
+ }
+ else {
+ /* +-0 */
+ copy_v3_v3(q0, v0);
+ vec_add_dir(q1, v0, v1, (sd[0] / (sd[0] - sd[1])));
+ copy_v3_v3(q2, v2);
+ copy_v3_v3(q3, q2);
+ }
+ }
+ else {
+ if (sd[2] > 0.0f) {
+ /* +0+ */
+ copy_v3_v3(q0, v0);
+ copy_v3_v3(q1, v1);
+ copy_v3_v3(q2, v2);
+ copy_v3_v3(q3, q2);
+ }
+ else if (sd[2] < 0.0f) {
+ /* +0- */
+ copy_v3_v3(q0, v0);
+ copy_v3_v3(q1, v1);
+ vec_add_dir(q2, v0, v2, (sd[0] / (sd[0] - sd[2])));
+ copy_v3_v3(q3, q2);
+ }
+ else {
+ /* +00 */
+ copy_v3_v3(q0, v0);
+ copy_v3_v3(q1, v1);
+ copy_v3_v3(q2, v2);
+ copy_v3_v3(q3, q2);
+ }
+ }
+ }
+ else if (sd[0] < 0.0f) {
+ if (sd[1] > 0.0f) {
+ if (sd[2] > 0.0f) {
+ /* -++ */
+ vec_add_dir(q0, v0, v1, (sd[0] / (sd[0] - sd[1])));
+ copy_v3_v3(q1, v1);
+ copy_v3_v3(q2, v2);
+ vec_add_dir(q3, v0, v2, (sd[0] / (sd[0] - sd[2])));
+ }
+ else if (sd[2] < 0.0f) {
+ /* -+- */
+ vec_add_dir(q0, v0, v1, (sd[0] / (sd[0] - sd[1])));
+ copy_v3_v3(q1, v1);
+ vec_add_dir(q2, v1, v2, (sd[1] / (sd[1] - sd[2])));
+ copy_v3_v3(q3, q2);
+ }
+ else {
+ /* -+0 */
+ vec_add_dir(q0, v0, v1, (sd[0] / (sd[0] - sd[1])));
+ copy_v3_v3(q1, v1);
+ copy_v3_v3(q2, v2);
+ copy_v3_v3(q3, q2);
+ }
+ }
+ else if (sd[1] < 0.0f) {
+ if (sd[2] > 0.0f) {
+ /* --+ */
+ vec_add_dir(q0, v0, v2, (sd[0] / (sd[0] - sd[2])));
+ vec_add_dir(q1, v1, v2, (sd[1] / (sd[1] - sd[2])));
+ copy_v3_v3(q2, v2);
+ copy_v3_v3(q3, q2);
+ }
+ else if (sd[2] < 0.0f) {
+ /* --- */
+ return false;
+ }
+ else {
+ /* --0 */
+ return false;
+ }
+ }
+ else {
+ if (sd[2] > 0.0f) {
+ /* -0+ */
+ vec_add_dir(q0, v0, v2, (sd[0] / (sd[0] - sd[2])));
+ copy_v3_v3(q1, v1);
+ copy_v3_v3(q2, v2);
+ copy_v3_v3(q3, q2);
+ }
+ else if (sd[2] < 0.0f) {
+ /* -0- */
+ return false;
+ }
+ else {
+ /* -00 */
+ return false;
+ }
+ }
+ }
+ else {
+ if (sd[1] > 0.0f) {
+ if (sd[2] > 0.0f) {
+ /* 0++ */
+ copy_v3_v3(q0, v0);
+ copy_v3_v3(q1, v1);
+ copy_v3_v3(q2, v2);
+ copy_v3_v3(q3, q2);
+ }
+ else if (sd[2] < 0.0f) {
+ /* 0+- */
+ copy_v3_v3(q0, v0);
+ copy_v3_v3(q1, v1);
+ vec_add_dir(q2, v1, v2, (sd[1] / (sd[1] - sd[2])));
+ copy_v3_v3(q3, q2);
+ }
+ else {
+ /* 0+0 */
+ copy_v3_v3(q0, v0);
+ copy_v3_v3(q1, v1);
+ copy_v3_v3(q2, v2);
+ copy_v3_v3(q3, q2);
+ }
+ }
+ else if (sd[1] < 0.0f) {
+ if (sd[2] > 0.0f) {
+ /* 0-+ */
+ copy_v3_v3(q0, v0);
+ vec_add_dir(q1, v1, v2, (sd[1] / (sd[1] - sd[2])));
+ copy_v3_v3(q2, v2);
+ copy_v3_v3(q3, q2);
+ }
+ else if (sd[2] < 0.0f) {
+ /* 0-- */
+ return false;
+ }
+ else {
+ /* 0-0 */
+ return false;
+ }
+ }
+ else {
+ if (sd[2] > 0.0f) {
+ /* 00+ */
+ copy_v3_v3(q0, v0);
+ copy_v3_v3(q1, v1);
+ copy_v3_v3(q2, v2);
+ copy_v3_v3(q3, q2);
+ }
+ else if (sd[2] < 0.0f) {
+ /* 00- */
+ return false;
+ }
+ else {
+ /* 000 */
+ return false;
+ }
+ }
+ }
+
+ return true;
}
/* altivec optimization, this works, but is unused */
#if 0
-#include <Accelerate/Accelerate.h>
+# include <Accelerate/Accelerate.h>
typedef union {
- vFloat v;
- float f[4];
+ vFloat v;
+ float f[4];
} vFloatResult;
static vFloat vec_splat_float(float val)
{
- return (vFloat) {val, val, val, val};
+ return (vFloat) {val, val, val, val};
}
static float ff_quad_form_factor(float *p, float *n, float *q0, float *q1, float *q2, float *q3)
{
- vFloat vcos, rlen, vrx, vry, vrz, vsrx, vsry, vsrz, gx, gy, gz, vangle;
- vUInt8 rotate = (vUInt8) {4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3};
- vFloatResult vresult;
- float result;
+ vFloat vcos, rlen, vrx, vry, vrz, vsrx, vsry, vsrz, gx, gy, gz, vangle;
+ vUInt8 rotate = (vUInt8) {4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0, 1, 2, 3};
+ vFloatResult vresult;
+ float result;
- /* compute r* */
- vrx = (vFloat) {q0[0], q1[0], q2[0], q3[0]} -vec_splat_float(p[0]);
- vry = (vFloat) {q0[1], q1[1], q2[1], q3[1]} -vec_splat_float(p[1]);
- vrz = (vFloat) {q0[2], q1[2], q2[2], q3[2]} -vec_splat_float(p[2]);
+ /* compute r* */
+ vrx = (vFloat) {q0[0], q1[0], q2[0], q3[0]} -vec_splat_float(p[0]);
+ vry = (vFloat) {q0[1], q1[1], q2[1], q3[1]} -vec_splat_float(p[1]);
+ vrz = (vFloat) {q0[2], q1[2], q2[2], q3[2]} -vec_splat_float(p[2]);
- /* normalize r* */
- rlen = vec_rsqrte(vrx * vrx + vry * vry + vrz * vrz + vec_splat_float(1e-16f));
- vrx = vrx * rlen;
- vry = vry * rlen;
- vrz = vrz * rlen;
+ /* normalize r* */
+ rlen = vec_rsqrte(vrx * vrx + vry * vry + vrz * vrz + vec_splat_float(1e-16f));
+ vrx = vrx * rlen;
+ vry = vry * rlen;
+ vrz = vrz * rlen;
- /* rotate r* for cross and dot */
- vsrx = vec_perm(vrx, vrx, rotate);
- vsry = vec_perm(vry, vry, rotate);
- vsrz = vec_perm(vrz, vrz, rotate);
+ /* rotate r* for cross and dot */
+ vsrx = vec_perm(vrx, vrx, rotate);
+ vsry = vec_perm(vry, vry, rotate);
+ vsrz = vec_perm(vrz, vrz, rotate);
- /* cross product */
- gx = vsry * vrz - vsrz * vry;
- gy = vsrz * vrx - vsrx * vrz;
- gz = vsrx * vry - vsry * vrx;
+ /* cross product */
+ gx = vsry * vrz - vsrz * vry;
+ gy = vsrz * vrx - vsrx * vrz;
+ gz = vsrx * vry - vsry * vrx;
- /* normalize */
- rlen = vec_rsqrte(gx * gx + gy * gy + gz * gz + vec_splat_float(1e-16f));
- gx = gx * rlen;
- gy = gy * rlen;
- gz = gz * rlen;
+ /* normalize */
+ rlen = vec_rsqrte(gx * gx + gy * gy + gz * gz + vec_splat_float(1e-16f));
+ gx = gx * rlen;
+ gy = gy * rlen;
+ gz = gz * rlen;
- /* angle */
- vcos = vrx * vsrx + vry * vsry + vrz * vsrz;
- vcos = vec_max(vec_min(vcos, vec_splat_float(1.0f)), vec_splat_float(-1.0f));
- vangle = vacosf(vcos);
+ /* angle */
+ vcos = vrx * vsrx + vry * vsry + vrz * vsrz;
+ vcos = vec_max(vec_min(vcos, vec_splat_float(1.0f)), vec_splat_float(-1.0f));
+ vangle = vacosf(vcos);
- /* dot */
- vresult.v = (vec_splat_float(n[0]) * gx +
- vec_splat_float(n[1]) * gy +
- vec_splat_float(n[2]) * gz) * vangle;
+ /* dot */
+ vresult.v = (vec_splat_float(n[0]) * gx +
+ vec_splat_float(n[1]) * gy +
+ vec_splat_float(n[2]) * gz) * vangle;
- result = (vresult.f[0] + vresult.f[1] + vresult.f[2] + vresult.f[3]) * (0.5f / (float)M_PI);
- result = MAX2(result, 0.0f);
+ result = (vresult.f[0] + vresult.f[1] + vresult.f[2] + vresult.f[3]) * (0.5f / (float)M_PI);
+ result = MAX2(result, 0.0f);
- return result;
+ return result;
}
#endif
@@ -5054,141 +5271,146 @@ static float ff_quad_form_factor(float *p, float *n, float *q0, float *q1, float
#if 0
-#include <xmmintrin.h>
+# include <xmmintrin.h>
static __m128 sse_approx_acos(__m128 x)
{
- /* needs a better approximation than taylor expansion of acos, since that
- * gives big errors for near 1.0 values, sqrt(2 * x) * acos(1 - x) should work
- * better, see http://www.tom.womack.net/projects/sse-fast-arctrig.html */
+ /* needs a better approximation than taylor expansion of acos, since that
+ * gives big errors for near 1.0 values, sqrt(2 * x) * acos(1 - x) should work
+ * better, see http://www.tom.womack.net/projects/sse-fast-arctrig.html */
- return _mm_set_ps1(1.0f);
+ return _mm_set_ps1(1.0f);
}
static float ff_quad_form_factor(float *p, float *n, float *q0, float *q1, float *q2, float *q3)
{
- float r0[3], r1[3], r2[3], r3[3], g0[3], g1[3], g2[3], g3[3];
- float a1, a2, a3, a4, dot1, dot2, dot3, dot4, result;
- float fresult[4] __attribute__((aligned(16)));
- __m128 qx, qy, qz, rx, ry, rz, rlen, srx, sry, srz, gx, gy, gz, glen, rcos, angle, aresult;
+ float r0[3], r1[3], r2[3], r3[3], g0[3], g1[3], g2[3], g3[3];
+ float a1, a2, a3, a4, dot1, dot2, dot3, dot4, result;
+ float fresult[4] __attribute__((aligned(16)));
+ __m128 qx, qy, qz, rx, ry, rz, rlen, srx, sry, srz, gx, gy, gz, glen, rcos, angle, aresult;
- /* compute r */
- qx = _mm_set_ps(q3[0], q2[0], q1[0], q0[0]);
- qy = _mm_set_ps(q3[1], q2[1], q1[1], q0[1]);
- qz = _mm_set_ps(q3[2], q2[2], q1[2], q0[2]);
+ /* compute r */
+ qx = _mm_set_ps(q3[0], q2[0], q1[0], q0[0]);
+ qy = _mm_set_ps(q3[1], q2[1], q1[1], q0[1]);
+ qz = _mm_set_ps(q3[2], q2[2], q1[2], q0[2]);
- rx = qx - _mm_set_ps1(p[0]);
- ry = qy - _mm_set_ps1(p[1]);
- rz = qz - _mm_set_ps1(p[2]);
+ rx = qx - _mm_set_ps1(p[0]);
+ ry = qy - _mm_set_ps1(p[1]);
+ rz = qz - _mm_set_ps1(p[2]);
- /* normalize r */
- rlen = _mm_rsqrt_ps(rx * rx + ry * ry + rz * rz + _mm_set_ps1(1e-16f));
- rx = rx * rlen;
- ry = ry * rlen;
- rz = rz * rlen;
+ /* normalize r */
+ rlen = _mm_rsqrt_ps(rx * rx + ry * ry + rz * rz + _mm_set_ps1(1e-16f));
+ rx = rx * rlen;
+ ry = ry * rlen;
+ rz = rz * rlen;
- /* cross product */
- srx = _mm_shuffle_ps(rx, rx, _MM_SHUFFLE(0, 3, 2, 1));
- sry = _mm_shuffle_ps(ry, ry, _MM_SHUFFLE(0, 3, 2, 1));
- srz = _mm_shuffle_ps(rz, rz, _MM_SHUFFLE(0, 3, 2, 1));
+ /* cross product */
+ srx = _mm_shuffle_ps(rx, rx, _MM_SHUFFLE(0, 3, 2, 1));
+ sry = _mm_shuffle_ps(ry, ry, _MM_SHUFFLE(0, 3, 2, 1));
+ srz = _mm_shuffle_ps(rz, rz, _MM_SHUFFLE(0, 3, 2, 1));
- gx = sry * rz - srz * ry;
- gy = srz * rx - srx * rz;
- gz = srx * ry - sry * rx;
+ gx = sry * rz - srz * ry;
+ gy = srz * rx - srx * rz;
+ gz = srx * ry - sry * rx;
- /* normalize g */
- glen = _mm_rsqrt_ps(gx * gx + gy * gy + gz * gz + _mm_set_ps1(1e-16f));
- gx = gx * glen;
- gy = gy * glen;
- gz = gz * glen;
+ /* normalize g */
+ glen = _mm_rsqrt_ps(gx * gx + gy * gy + gz * gz + _mm_set_ps1(1e-16f));
+ gx = gx * glen;
+ gy = gy * glen;
+ gz = gz * glen;
- /* compute angle */
- rcos = rx * srx + ry * sry + rz * srz;
- rcos = _mm_max_ps(_mm_min_ps(rcos, _mm_set_ps1(1.0f)), _mm_set_ps1(-1.0f));
+ /* compute angle */
+ rcos = rx * srx + ry * sry + rz * srz;
+ rcos = _mm_max_ps(_mm_min_ps(rcos, _mm_set_ps1(1.0f)), _mm_set_ps1(-1.0f));
- angle = sse_approx_cos(rcos);
- aresult = (_mm_set_ps1(n[0]) * gx + _mm_set_ps1(n[1]) * gy + _mm_set_ps1(n[2]) * gz) * angle;
+ angle = sse_approx_cos(rcos);
+ aresult = (_mm_set_ps1(n[0]) * gx + _mm_set_ps1(n[1]) * gy + _mm_set_ps1(n[2]) * gz) * angle;
- /* sum together */
- result = (fresult[0] + fresult[1] + fresult[2] + fresult[3]) * (0.5f / (float)M_PI);
- result = MAX2(result, 0.0f);
+ /* sum together */
+ result = (fresult[0] + fresult[1] + fresult[2] + fresult[3]) * (0.5f / (float)M_PI);
+ result = MAX2(result, 0.0f);
- return result;
+ return result;
}
#endif
static void ff_normalize(float n[3])
{
- float d;
+ float d;
- d = dot_v3v3(n, n);
+ d = dot_v3v3(n, n);
- if (d > 1.0e-35f) {
- d = 1.0f / sqrtf(d);
+ if (d > 1.0e-35f) {
+ d = 1.0f / sqrtf(d);
- n[0] *= d;
- n[1] *= d;
- n[2] *= d;
- }
+ n[0] *= d;
+ n[1] *= d;
+ n[2] *= d;
+ }
}
-float form_factor_quad(const float p[3], const float n[3],
- const float q0[3], const float q1[3], const float q2[3], const float q3[3])
+float form_factor_quad(const float p[3],
+ const float n[3],
+ const float q0[3],
+ const float q1[3],
+ const float q2[3],
+ const float q3[3])
{
- float r0[3], r1[3], r2[3], r3[3], g0[3], g1[3], g2[3], g3[3];
- float a1, a2, a3, a4, dot1, dot2, dot3, dot4, result;
+ float r0[3], r1[3], r2[3], r3[3], g0[3], g1[3], g2[3], g3[3];
+ float a1, a2, a3, a4, dot1, dot2, dot3, dot4, result;
- sub_v3_v3v3(r0, q0, p);
- sub_v3_v3v3(r1, q1, p);
- sub_v3_v3v3(r2, q2, p);
- sub_v3_v3v3(r3, q3, p);
+ sub_v3_v3v3(r0, q0, p);
+ sub_v3_v3v3(r1, q1, p);
+ sub_v3_v3v3(r2, q2, p);
+ sub_v3_v3v3(r3, q3, p);
- ff_normalize(r0);
- ff_normalize(r1);
- ff_normalize(r2);
- ff_normalize(r3);
+ ff_normalize(r0);
+ ff_normalize(r1);
+ ff_normalize(r2);
+ ff_normalize(r3);
- cross_v3_v3v3(g0, r1, r0);
- ff_normalize(g0);
- cross_v3_v3v3(g1, r2, r1);
- ff_normalize(g1);
- cross_v3_v3v3(g2, r3, r2);
- ff_normalize(g2);
- cross_v3_v3v3(g3, r0, r3);
- ff_normalize(g3);
+ cross_v3_v3v3(g0, r1, r0);
+ ff_normalize(g0);
+ cross_v3_v3v3(g1, r2, r1);
+ ff_normalize(g1);
+ cross_v3_v3v3(g2, r3, r2);
+ ff_normalize(g2);
+ cross_v3_v3v3(g3, r0, r3);
+ ff_normalize(g3);
- a1 = saacosf(dot_v3v3(r0, r1));
- a2 = saacosf(dot_v3v3(r1, r2));
- a3 = saacosf(dot_v3v3(r2, r3));
- a4 = saacosf(dot_v3v3(r3, r0));
+ a1 = saacosf(dot_v3v3(r0, r1));
+ a2 = saacosf(dot_v3v3(r1, r2));
+ a3 = saacosf(dot_v3v3(r2, r3));
+ a4 = saacosf(dot_v3v3(r3, r0));
- dot1 = dot_v3v3(n, g0);
- dot2 = dot_v3v3(n, g1);
- dot3 = dot_v3v3(n, g2);
- dot4 = dot_v3v3(n, g3);
+ dot1 = dot_v3v3(n, g0);
+ dot2 = dot_v3v3(n, g1);
+ dot3 = dot_v3v3(n, g2);
+ dot4 = dot_v3v3(n, g3);
- result = (a1 * dot1 + a2 * dot2 + a3 * dot3 + a4 * dot4) * 0.5f / (float)M_PI;
- result = MAX2(result, 0.0f);
+ result = (a1 * dot1 + a2 * dot2 + a3 * dot3 + a4 * dot4) * 0.5f / (float)M_PI;
+ result = MAX2(result, 0.0f);
- return result;
+ return result;
}
-float form_factor_hemi_poly(float p[3], float n[3], float v1[3], float v2[3], float v3[3], float v4[3])
+float form_factor_hemi_poly(
+ float p[3], float n[3], float v1[3], float v2[3], float v3[3], float v4[3])
{
- /* computes how much hemisphere defined by point and normal is
- * covered by a quad or triangle, cosine weighted */
- float q0[3], q1[3], q2[3], q3[3], contrib = 0.0f;
+ /* computes how much hemisphere defined by point and normal is
+ * covered by a quad or triangle, cosine weighted */
+ float q0[3], q1[3], q2[3], q3[3], contrib = 0.0f;
- if (form_factor_visible_quad(p, n, v1, v2, v3, q0, q1, q2, q3)) {
- contrib += form_factor_quad(p, n, q0, q1, q2, q3);
- }
+ if (form_factor_visible_quad(p, n, v1, v2, v3, q0, q1, q2, q3)) {
+ contrib += form_factor_quad(p, n, q0, q1, q2, q3);
+ }
- if (v4 && form_factor_visible_quad(p, n, v1, v3, v4, q0, q1, q2, q3)) {
- contrib += form_factor_quad(p, n, q0, q1, q2, q3);
- }
+ if (v4 && form_factor_visible_quad(p, n, v1, v3, v4, q0, q1, q2, q3)) {
+ contrib += form_factor_quad(p, n, q0, q1, q2, q3);
+ }
- return contrib;
+ return contrib;
}
/**
@@ -5196,99 +5418,97 @@ float form_factor_hemi_poly(float p[3], float n[3], float v1[3], float v2[3], fl
*/
bool is_quad_convex_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3])
{
- /**
- * Method projects points onto a plane and checks its convex using following method:
- *
- * - Create a plane from the cross-product of both diagonal vectors.
- * - Project all points onto the plane.
- * - Subtract for direction vectors.
- * - Return true if all corners cross-products point the direction of the plane.
- */
+ /**
+ * Method projects points onto a plane and checks its convex using following method:
+ *
+ * - Create a plane from the cross-product of both diagonal vectors.
+ * - Project all points onto the plane.
+ * - Subtract for direction vectors.
+ * - Return true if all corners cross-products point the direction of the plane.
+ */
- /* non-unit length normal, used as a projection plane */
- float plane[3];
+ /* non-unit length normal, used as a projection plane */
+ float plane[3];
- {
- float v13[3], v24[3];
+ {
+ float v13[3], v24[3];
- sub_v3_v3v3(v13, v1, v3);
- sub_v3_v3v3(v24, v2, v4);
+ sub_v3_v3v3(v13, v1, v3);
+ sub_v3_v3v3(v24, v2, v4);
- cross_v3_v3v3(plane, v13, v24);
+ cross_v3_v3v3(plane, v13, v24);
- if (len_squared_v3(plane) < FLT_EPSILON) {
- return false;
- }
- }
+ if (len_squared_v3(plane) < FLT_EPSILON) {
+ return false;
+ }
+ }
- const float *quad_coords[4] = {v1, v2, v3, v4};
- float quad_proj[4][3];
+ const float *quad_coords[4] = {v1, v2, v3, v4};
+ float quad_proj[4][3];
- for (int i = 0; i < 4; i++) {
- project_plane_v3_v3v3(quad_proj[i], quad_coords[i], plane);
- }
+ for (int i = 0; i < 4; i++) {
+ project_plane_v3_v3v3(quad_proj[i], quad_coords[i], plane);
+ }
- float quad_dirs[4][3];
- for (int i = 0, j = 3; i < 4; j = i++) {
- sub_v3_v3v3(quad_dirs[i], quad_proj[i], quad_proj[j]);
- }
+ float quad_dirs[4][3];
+ for (int i = 0, j = 3; i < 4; j = i++) {
+ sub_v3_v3v3(quad_dirs[i], quad_proj[i], quad_proj[j]);
+ }
- float test_dir[3];
+ float test_dir[3];
#define CROSS_SIGN(dir_a, dir_b) \
- ((void)cross_v3_v3v3(test_dir, dir_a, dir_b), (dot_v3v3(plane, test_dir) > 0.0f))
+ ((void)cross_v3_v3v3(test_dir, dir_a, dir_b), (dot_v3v3(plane, test_dir) > 0.0f))
- return (CROSS_SIGN(quad_dirs[0], quad_dirs[1]) &&
- CROSS_SIGN(quad_dirs[1], quad_dirs[2]) &&
- CROSS_SIGN(quad_dirs[2], quad_dirs[3]) &&
- CROSS_SIGN(quad_dirs[3], quad_dirs[0]));
+ return (CROSS_SIGN(quad_dirs[0], quad_dirs[1]) && CROSS_SIGN(quad_dirs[1], quad_dirs[2]) &&
+ CROSS_SIGN(quad_dirs[2], quad_dirs[3]) && CROSS_SIGN(quad_dirs[3], quad_dirs[0]));
#undef CROSS_SIGN
}
bool is_quad_convex_v2(const float v1[2], const float v2[2], const float v3[2], const float v4[2])
{
- /* linetests, the 2 diagonals have to instersect to be convex */
- return (isect_seg_seg_v2(v1, v3, v2, v4) > 0);
+ /* linetests, the 2 diagonals have to instersect to be convex */
+ return (isect_seg_seg_v2(v1, v3, v2, v4) > 0);
}
bool is_poly_convex_v2(const float verts[][2], unsigned int nr)
{
- unsigned int sign_flag = 0;
- unsigned int a;
- const float *co_curr, *co_prev;
- float dir_curr[2], dir_prev[2];
+ unsigned int sign_flag = 0;
+ unsigned int a;
+ const float *co_curr, *co_prev;
+ float dir_curr[2], dir_prev[2];
- co_prev = verts[nr - 1];
- co_curr = verts[0];
+ co_prev = verts[nr - 1];
+ co_curr = verts[0];
- sub_v2_v2v2(dir_prev, verts[nr - 2], co_prev);
+ sub_v2_v2v2(dir_prev, verts[nr - 2], co_prev);
- for (a = 0; a < nr; a++) {
- float cross;
+ for (a = 0; a < nr; a++) {
+ float cross;
- sub_v2_v2v2(dir_curr, co_prev, co_curr);
+ sub_v2_v2v2(dir_curr, co_prev, co_curr);
- cross = cross_v2v2(dir_prev, dir_curr);
+ cross = cross_v2v2(dir_prev, dir_curr);
- if (cross < 0.0f) {
- sign_flag |= 1;
- }
- else if (cross > 0.0f) {
- sign_flag |= 2;
- }
+ if (cross < 0.0f) {
+ sign_flag |= 1;
+ }
+ else if (cross > 0.0f) {
+ sign_flag |= 2;
+ }
- if (sign_flag == (1 | 2)) {
- return false;
- }
+ if (sign_flag == (1 | 2)) {
+ return false;
+ }
- copy_v2_v2(dir_prev, dir_curr);
+ copy_v2_v2(dir_prev, dir_curr);
- co_prev = co_curr;
- co_curr += 2;
- }
+ co_prev = co_curr;
+ co_curr += 2;
+ }
- return true;
+ return true;
}
/**
@@ -5299,36 +5519,39 @@ 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])
{
- float d_12[3], d_23[3], d_34[3], d_41[3];
- float cross_a[3], cross_b[3];
- int ret = 0;
+ 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);
+ 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_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);
+ 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;
+ return ret;
}
-bool is_quad_flip_v3_first_third_fast(const float v1[3], const float v2[3], const float v3[3], const float v4[3])
+bool is_quad_flip_v3_first_third_fast(const float v1[3],
+ const float v2[3],
+ const float v3[3],
+ const float v4[3])
{
- float d_12[3], d_13[3], d_14[3];
- float cross_a[3], cross_b[3];
- sub_v3_v3v3(d_12, v2, v1);
- sub_v3_v3v3(d_13, v3, v1);
- sub_v3_v3v3(d_14, v4, v1);
- cross_v3_v3v3(cross_a, d_12, d_13);
- cross_v3_v3v3(cross_b, d_14, d_13);
- return dot_v3v3(cross_a, cross_b) > 0.0f;
+ float d_12[3], d_13[3], d_14[3];
+ float cross_a[3], cross_b[3];
+ sub_v3_v3v3(d_12, v2, v1);
+ sub_v3_v3v3(d_13, v3, v1);
+ sub_v3_v3v3(d_14, v4, v1);
+ cross_v3_v3v3(cross_a, d_12, d_13);
+ cross_v3_v3v3(cross_b, d_14, d_13);
+ return dot_v3v3(cross_a, cross_b) > 0.0f;
}
/**
@@ -5341,28 +5564,28 @@ bool is_quad_flip_v3_first_third_fast(const float v1[3], const float v2[3], cons
*/
float cubic_tangent_factor_circle_v3(const float tan_l[3], const float tan_r[3])
{
- BLI_ASSERT_UNIT_V3(tan_l);
- BLI_ASSERT_UNIT_V3(tan_r);
-
- /* -7f causes instability/glitches with Bendy Bones + Custom Refs */
- const float eps = 1e-5f;
-
- const float tan_dot = dot_v3v3(tan_l, tan_r);
- if (tan_dot > 1.0f - eps) {
- /* no angle difference (use fallback, length wont make any difference) */
- return (1.0f / 3.0f) * 0.75f;
- }
- else if (tan_dot < -1.0f + eps) {
- /* parallele tangents (half-circle) */
- return (1.0f / 2.0f);
- }
- else {
- /* non-aligned tangents, calculate handle length */
- const float angle = acosf(tan_dot) / 2.0f;
-
- /* could also use 'angle_sin = len_vnvn(tan_l, tan_r, dims) / 2.0' */
- const float angle_sin = sinf(angle);
- const float angle_cos = cosf(angle);
- return ((1.0f - angle_cos) / (angle_sin * 2.0f)) / angle_sin;
- }
+ BLI_ASSERT_UNIT_V3(tan_l);
+ BLI_ASSERT_UNIT_V3(tan_r);
+
+ /* -7f causes instability/glitches with Bendy Bones + Custom Refs */
+ const float eps = 1e-5f;
+
+ const float tan_dot = dot_v3v3(tan_l, tan_r);
+ if (tan_dot > 1.0f - eps) {
+ /* no angle difference (use fallback, length wont make any difference) */
+ return (1.0f / 3.0f) * 0.75f;
+ }
+ else if (tan_dot < -1.0f + eps) {
+ /* parallele tangents (half-circle) */
+ return (1.0f / 2.0f);
+ }
+ else {
+ /* non-aligned tangents, calculate handle length */
+ const float angle = acosf(tan_dot) / 2.0f;
+
+ /* could also use 'angle_sin = len_vnvn(tan_l, tan_r, dims) / 2.0' */
+ const float angle_sin = sinf(angle);
+ const float angle_cos = cosf(angle);
+ return ((1.0f - angle_cos) / (angle_sin * 2.0f)) / angle_sin;
+ }
}
diff --git a/source/blender/blenlib/intern/math_geom_inline.c b/source/blender/blenlib/intern/math_geom_inline.c
index 0922c47f553..d275ea0862e 100644
--- a/source/blender/blenlib/intern/math_geom_inline.c
+++ b/source/blender/blenlib/intern/math_geom_inline.c
@@ -32,202 +32,215 @@
#include <string.h>
/* A few small defines. Keep'em local! */
-#define SMALL_NUMBER 1.e-8f
+#define SMALL_NUMBER 1.e-8f
/********************************** Polygons *********************************/
MINLINE float cross_tri_v2(const float v1[2], const float v2[2], const float v3[2])
{
- return (v1[0] - v2[0]) * (v2[1] - v3[1]) + (v1[1] - v2[1]) * (v3[0] - v2[0]);
+ return (v1[0] - v2[0]) * (v2[1] - v3[1]) + (v1[1] - v2[1]) * (v3[0] - v2[0]);
}
MINLINE float area_tri_signed_v2(const float v1[2], const float v2[2], const float v3[2])
{
- return 0.5f * ((v1[0] - v2[0]) * (v2[1] - v3[1]) + (v1[1] - v2[1]) * (v3[0] - v2[0]));
+ return 0.5f * ((v1[0] - v2[0]) * (v2[1] - v3[1]) + (v1[1] - v2[1]) * (v3[0] - v2[0]));
}
MINLINE float area_tri_v2(const float v1[2], const float v2[2], const float v3[2])
{
- return fabsf(area_tri_signed_v2(v1, v2, v3));
+ return fabsf(area_tri_signed_v2(v1, v2, v3));
}
MINLINE float area_squared_tri_v2(const float v1[2], const float v2[2], const float v3[2])
{
- float area = area_tri_signed_v2(v1, v2, v3);
- return area * area;
+ float area = area_tri_signed_v2(v1, v2, v3);
+ return area * area;
}
/****************************** Spherical Harmonics **************************/
MINLINE void zero_sh(float r[9])
{
- memset(r, 0, sizeof(float) * 9);
+ memset(r, 0, sizeof(float) * 9);
}
MINLINE void copy_sh_sh(float r[9], const float a[9])
{
- memcpy(r, a, sizeof(float) * 9);
+ memcpy(r, a, sizeof(float) * 9);
}
MINLINE void mul_sh_fl(float r[9], const float f)
{
- int i;
+ int i;
- for (i = 0; i < 9; i++) {
- r[i] *= f;
- }
+ for (i = 0; i < 9; i++) {
+ r[i] *= f;
+ }
}
MINLINE void add_sh_shsh(float r[9], const float a[9], const float b[9])
{
- int i;
+ int i;
- for (i = 0; i < 9; i++) {
- r[i] = a[i] + b[i];
- }
+ for (i = 0; i < 9; i++) {
+ r[i] = a[i] + b[i];
+ }
}
MINLINE float dot_shsh(const float a[9], const float b[9])
{
- float r = 0.0f;
- int i;
+ float r = 0.0f;
+ int i;
- for (i = 0; i < 9; i++) {
- r += a[i] * b[i];
- }
+ for (i = 0; i < 9; i++) {
+ r += a[i] * b[i];
+ }
- return r;
+ return r;
}
MINLINE float diffuse_shv3(float sh[9], const float v[3])
{
- /* See formula (13) in:
- * "An Efficient Representation for Irradiance Environment Maps" */
- static const float c1 = 0.429043f, c2 = 0.511664f, c3 = 0.743125f;
- static const float c4 = 0.886227f, c5 = 0.247708f;
- float x, y, z, sum;
-
- x = v[0];
- y = v[1];
- z = v[2];
-
- sum = c1 * sh[8] * (x * x - y * y);
- sum += c3 * sh[6] * z * z;
- sum += c4 * sh[0];
- sum += -c5 * sh[6];
- sum += 2.0f * c1 * (sh[4] * x * y + sh[7] * x * z + sh[5] * y * z);
- sum += 2.0f * c2 * (sh[3] * x + sh[1] * y + sh[2] * z);
-
- return sum;
+ /* See formula (13) in:
+ * "An Efficient Representation for Irradiance Environment Maps" */
+ static const float c1 = 0.429043f, c2 = 0.511664f, c3 = 0.743125f;
+ static const float c4 = 0.886227f, c5 = 0.247708f;
+ float x, y, z, sum;
+
+ x = v[0];
+ y = v[1];
+ z = v[2];
+
+ sum = c1 * sh[8] * (x * x - y * y);
+ sum += c3 * sh[6] * z * z;
+ sum += c4 * sh[0];
+ sum += -c5 * sh[6];
+ sum += 2.0f * c1 * (sh[4] * x * y + sh[7] * x * z + sh[5] * y * z);
+ sum += 2.0f * c2 * (sh[3] * x + sh[1] * y + sh[2] * z);
+
+ return sum;
}
MINLINE void vec_fac_to_sh(float r[9], const float v[3], const float f)
{
- /* See formula (3) in:
- * "An Efficient Representation for Irradiance Environment Maps" */
- float sh[9], x, y, z;
+ /* See formula (3) in:
+ * "An Efficient Representation for Irradiance Environment Maps" */
+ float sh[9], x, y, z;
- x = v[0];
- y = v[1];
- z = v[2];
+ x = v[0];
+ y = v[1];
+ z = v[2];
- sh[0] = 0.282095f;
+ sh[0] = 0.282095f;
- sh[1] = 0.488603f * y;
- sh[2] = 0.488603f * z;
- sh[3] = 0.488603f * x;
+ sh[1] = 0.488603f * y;
+ sh[2] = 0.488603f * z;
+ sh[3] = 0.488603f * x;
- sh[4] = 1.092548f * x * y;
- sh[5] = 1.092548f * y * z;
- sh[6] = 0.315392f * (3.0f * z * z - 1.0f);
- sh[7] = 1.092548f * x * z;
- sh[8] = 0.546274f * (x * x - y * y);
+ sh[4] = 1.092548f * x * y;
+ sh[5] = 1.092548f * y * z;
+ sh[6] = 0.315392f * (3.0f * z * z - 1.0f);
+ sh[7] = 1.092548f * x * z;
+ sh[8] = 0.546274f * (x * x - y * y);
- mul_sh_fl(sh, f);
- copy_sh_sh(r, sh);
+ mul_sh_fl(sh, f);
+ copy_sh_sh(r, sh);
}
MINLINE float eval_shv3(float sh[9], const float v[3])
{
- float tmp[9];
+ float tmp[9];
- vec_fac_to_sh(tmp, v, 1.0f);
- return dot_shsh(tmp, sh);
+ vec_fac_to_sh(tmp, v, 1.0f);
+ return dot_shsh(tmp, sh);
}
MINLINE void madd_sh_shfl(float r[9], const float sh[9], const float f)
{
- float tmp[9];
+ float tmp[9];
- copy_sh_sh(tmp, sh);
- mul_sh_fl(tmp, f);
- add_sh_shsh(r, r, tmp);
+ copy_sh_sh(tmp, sh);
+ mul_sh_fl(tmp, f);
+ add_sh_shsh(r, r, tmp);
}
/* get the 2 dominant axis values, 0==X, 1==Y, 2==Z */
MINLINE void axis_dominant_v3(int *r_axis_a, int *r_axis_b, const float axis[3])
{
- const float xn = fabsf(axis[0]);
- const float yn = fabsf(axis[1]);
- const float zn = fabsf(axis[2]);
-
- if (zn >= xn && zn >= yn) { *r_axis_a = 0; *r_axis_b = 1; }
- else if (yn >= xn && yn >= zn) { *r_axis_a = 0; *r_axis_b = 2; }
- else { *r_axis_a = 1; *r_axis_b = 2; }
+ const float xn = fabsf(axis[0]);
+ const float yn = fabsf(axis[1]);
+ const float zn = fabsf(axis[2]);
+
+ if (zn >= xn && zn >= yn) {
+ *r_axis_a = 0;
+ *r_axis_b = 1;
+ }
+ else if (yn >= xn && yn >= zn) {
+ *r_axis_a = 0;
+ *r_axis_b = 2;
+ }
+ else {
+ *r_axis_a = 1;
+ *r_axis_b = 2;
+ }
}
/* same as axis_dominant_v3 but return the max value */
MINLINE float axis_dominant_v3_max(int *r_axis_a, int *r_axis_b, const float axis[3])
{
- const float xn = fabsf(axis[0]);
- const float yn = fabsf(axis[1]);
- const float zn = fabsf(axis[2]);
-
- if (zn >= xn && zn >= yn) { *r_axis_a = 0; *r_axis_b = 1; return zn; }
- else if (yn >= xn && yn >= zn) { *r_axis_a = 0; *r_axis_b = 2; return yn; }
- else { *r_axis_a = 1; *r_axis_b = 2; return xn; }
+ const float xn = fabsf(axis[0]);
+ const float yn = fabsf(axis[1]);
+ const float zn = fabsf(axis[2]);
+
+ if (zn >= xn && zn >= yn) {
+ *r_axis_a = 0;
+ *r_axis_b = 1;
+ return zn;
+ }
+ else if (yn >= xn && yn >= zn) {
+ *r_axis_a = 0;
+ *r_axis_b = 2;
+ return yn;
+ }
+ else {
+ *r_axis_a = 1;
+ *r_axis_b = 2;
+ return xn;
+ }
}
/* get the single dominant axis value, 0==X, 1==Y, 2==Z */
MINLINE int axis_dominant_v3_single(const float vec[3])
{
- const float x = fabsf(vec[0]);
- const float y = fabsf(vec[1]);
- const float z = fabsf(vec[2]);
- return ((x > y) ?
- ((x > z) ? 0 : 2) :
- ((y > z) ? 1 : 2));
+ const float x = fabsf(vec[0]);
+ const float y = fabsf(vec[1]);
+ const float z = fabsf(vec[2]);
+ return ((x > y) ? ((x > z) ? 0 : 2) : ((y > z) ? 1 : 2));
}
/* the dominant axis of an orthogonal vector */
MINLINE int axis_dominant_v3_ortho_single(const float vec[3])
{
- const float x = fabsf(vec[0]);
- const float y = fabsf(vec[1]);
- const float z = fabsf(vec[2]);
- return ((x < y) ?
- ((x < z) ? 0 : 2) :
- ((y < z) ? 1 : 2));
+ const float x = fabsf(vec[0]);
+ const float y = fabsf(vec[1]);
+ const float z = fabsf(vec[2]);
+ return ((x < y) ? ((x < z) ? 0 : 2) : ((y < z) ? 1 : 2));
}
MINLINE int max_axis_v3(const float vec[3])
{
- const float x = vec[0];
- const float y = vec[1];
- const float z = vec[2];
- return ((x > y) ?
- ((x > z) ? 0 : 2) :
- ((y > z) ? 1 : 2));
+ const float x = vec[0];
+ const float y = vec[1];
+ const float z = vec[2];
+ return ((x > y) ? ((x > z) ? 0 : 2) : ((y > z) ? 1 : 2));
}
MINLINE int min_axis_v3(const float vec[3])
{
- const float x = vec[0];
- const float y = vec[1];
- const float z = vec[2];
- return ((x < y) ?
- ((x < z) ? 0 : 2) :
- ((y < z) ? 1 : 2));
+ const float x = vec[0];
+ const float y = vec[1];
+ const float z = vec[2];
+ return ((x < y) ? ((x < z) ? 0 : 2) : ((y < z) ? 1 : 2));
}
/**
@@ -238,13 +251,13 @@ MINLINE int min_axis_v3(const float vec[3])
*/
MINLINE int poly_to_tri_count(const int poly_count, const int corner_count)
{
- BLI_assert(!poly_count || corner_count > poly_count * 2);
- return corner_count - (poly_count * 2);
+ BLI_assert(!poly_count || corner_count > poly_count * 2);
+ return corner_count - (poly_count * 2);
}
MINLINE float plane_point_side_v3(const float plane[4], const float co[3])
{
- return dot_v3v3(co, plane) + plane[3];
+ return dot_v3v3(co, plane) + plane[3];
}
/* useful to calculate an even width shell, by taking the angle between 2 planes.
@@ -253,27 +266,27 @@ MINLINE float plane_point_side_v3(const float plane[4], const float co[3])
* the distance gets very high, 180d would be inf, but this case isn't valid */
MINLINE float shell_angle_to_dist(const float angle)
{
- return (UNLIKELY(angle < SMALL_NUMBER)) ? 1.0f : fabsf(1.0f / cosf(angle));
+ return (UNLIKELY(angle < SMALL_NUMBER)) ? 1.0f : fabsf(1.0f / cosf(angle));
}
/**
* equivalent to ``shell_angle_to_dist(angle_normalized_v3v3(a, b))``
*/
MINLINE float shell_v3v3_normalized_to_dist(const float a[3], const float b[3])
{
- const float angle_cos = fabsf(dot_v3v3(a, b));
- BLI_ASSERT_UNIT_V3(a);
- BLI_ASSERT_UNIT_V3(b);
- return (UNLIKELY(angle_cos < SMALL_NUMBER)) ? 1.0f : (1.0f / angle_cos);
+ const float angle_cos = fabsf(dot_v3v3(a, b));
+ BLI_ASSERT_UNIT_V3(a);
+ BLI_ASSERT_UNIT_V3(b);
+ return (UNLIKELY(angle_cos < SMALL_NUMBER)) ? 1.0f : (1.0f / angle_cos);
}
/**
* equivalent to ``shell_angle_to_dist(angle_normalized_v2v2(a, b))``
*/
MINLINE float shell_v2v2_normalized_to_dist(const float a[2], const float b[2])
{
- const float angle_cos = fabsf(dot_v2v2(a, b));
- BLI_ASSERT_UNIT_V2(a);
- BLI_ASSERT_UNIT_V2(b);
- return (UNLIKELY(angle_cos < SMALL_NUMBER)) ? 1.0f : (1.0f / angle_cos);
+ const float angle_cos = fabsf(dot_v2v2(a, b));
+ BLI_ASSERT_UNIT_V2(a);
+ BLI_ASSERT_UNIT_V2(b);
+ return (UNLIKELY(angle_cos < SMALL_NUMBER)) ? 1.0f : (1.0f / angle_cos);
}
/**
@@ -281,13 +294,13 @@ MINLINE float shell_v2v2_normalized_to_dist(const float a[2], const float b[2])
*/
MINLINE float shell_v3v3_mid_normalized_to_dist(const float a[3], const float b[3])
{
- float angle_cos;
- float ab[3];
- BLI_ASSERT_UNIT_V3(a);
- BLI_ASSERT_UNIT_V3(b);
- add_v3_v3v3(ab, a, b);
- angle_cos = (normalize_v3(ab) != 0.0f) ? fabsf(dot_v3v3(a, ab)) : 0.0f;
- return (UNLIKELY(angle_cos < SMALL_NUMBER)) ? 1.0f : (1.0f / angle_cos);
+ float angle_cos;
+ float ab[3];
+ BLI_ASSERT_UNIT_V3(a);
+ BLI_ASSERT_UNIT_V3(b);
+ add_v3_v3v3(ab, a, b);
+ angle_cos = (normalize_v3(ab) != 0.0f) ? fabsf(dot_v3v3(a, ab)) : 0.0f;
+ return (UNLIKELY(angle_cos < SMALL_NUMBER)) ? 1.0f : (1.0f / angle_cos);
}
/**
@@ -295,13 +308,13 @@ MINLINE float shell_v3v3_mid_normalized_to_dist(const float a[3], const float b[
*/
MINLINE float shell_v2v2_mid_normalized_to_dist(const float a[2], const float b[2])
{
- float angle_cos;
- float ab[2];
- BLI_ASSERT_UNIT_V2(a);
- BLI_ASSERT_UNIT_V2(b);
- add_v2_v2v2(ab, a, b);
- angle_cos = (normalize_v2(ab) != 0.0f) ? fabsf(dot_v2v2(a, ab)) : 0.0f;
- return (UNLIKELY(angle_cos < SMALL_NUMBER)) ? 1.0f : (1.0f / angle_cos);
+ float angle_cos;
+ float ab[2];
+ BLI_ASSERT_UNIT_V2(a);
+ BLI_ASSERT_UNIT_V2(b);
+ add_v2_v2v2(ab, a, b);
+ angle_cos = (normalize_v2(ab) != 0.0f) ? fabsf(dot_v2v2(a, ab)) : 0.0f;
+ return (UNLIKELY(angle_cos < SMALL_NUMBER)) ? 1.0f : (1.0f / angle_cos);
}
#undef SMALL_NUMBER
diff --git a/source/blender/blenlib/intern/math_interp.c b/source/blender/blenlib/intern/math_interp.c
index ed2b48f6e62..6acfb538036 100644
--- a/source/blender/blenlib/intern/math_interp.c
+++ b/source/blender/blenlib/intern/math_interp.c
@@ -40,418 +40,473 @@
static float P(float k)
{
- float p1, p2, p3, p4;
- p1 = max_ff(k + 2.0f, 0.0f);
- p2 = max_ff(k + 1.0f, 0.0f);
- p3 = max_ff(k, 0.0f);
- p4 = max_ff(k - 1.0f, 0.0f);
- return (float)(1.0f / 6.0f) * (p1 * p1 * p1 - 4.0f * p2 * p2 * p2 + 6.0f * p3 * p3 * p3 - 4.0f * p4 * p4 * p4);
+ float p1, p2, p3, p4;
+ p1 = max_ff(k + 2.0f, 0.0f);
+ p2 = max_ff(k + 1.0f, 0.0f);
+ p3 = max_ff(k, 0.0f);
+ p4 = max_ff(k - 1.0f, 0.0f);
+ return (float)(1.0f / 6.0f) *
+ (p1 * p1 * p1 - 4.0f * p2 * p2 * p2 + 6.0f * p3 * p3 * p3 - 4.0f * p4 * p4 * p4);
}
-
#if 0
/* older, slower function, works the same as above */
static float P(float k)
{
- return (float)(1.0f / 6.0f) *
- (pow(MAX2(k + 2.0f, 0), 3.0f) - 4.0f *
- pow(MAX2(k + 1.0f, 0), 3.0f) + 6.0f *
- pow(MAX2(k, 0), 3.0f) - 4.0f *
- pow(MAX2(k - 1.0f, 0), 3.0f));
+ return (float)(1.0f / 6.0f) *
+ (pow(MAX2(k + 2.0f, 0), 3.0f) - 4.0f *
+ pow(MAX2(k + 1.0f, 0), 3.0f) + 6.0f *
+ pow(MAX2(k, 0), 3.0f) - 4.0f *
+ pow(MAX2(k - 1.0f, 0), 3.0f));
}
#endif
static void vector_from_float(const float *data, float vector[4], int components)
{
- if (components == 1) {
- vector[0] = data[0];
- }
- else if (components == 3) {
- copy_v3_v3(vector, data);
- }
- else {
- copy_v4_v4(vector, data);
- }
+ if (components == 1) {
+ vector[0] = data[0];
+ }
+ else if (components == 3) {
+ copy_v3_v3(vector, data);
+ }
+ else {
+ copy_v4_v4(vector, data);
+ }
}
static void vector_from_byte(const unsigned char *data, float vector[4], int components)
{
- if (components == 1) {
- vector[0] = data[0];
- }
- else if (components == 3) {
- vector[0] = data[0];
- vector[1] = data[1];
- vector[2] = data[2];
- }
- else {
- vector[0] = data[0];
- vector[1] = data[1];
- vector[2] = data[2];
- vector[3] = data[3];
- }
+ if (components == 1) {
+ vector[0] = data[0];
+ }
+ else if (components == 3) {
+ vector[0] = data[0];
+ vector[1] = data[1];
+ vector[2] = data[2];
+ }
+ else {
+ vector[0] = data[0];
+ vector[1] = data[1];
+ vector[2] = data[2];
+ vector[3] = data[3];
+ }
}
/* BICUBIC INTERPOLATION */
-BLI_INLINE void bicubic_interpolation(const unsigned char *byte_buffer, const float *float_buffer,
- unsigned char *byte_output, float *float_output, int width, int height,
- int components, float u, float v)
+BLI_INLINE void bicubic_interpolation(const unsigned char *byte_buffer,
+ const float *float_buffer,
+ unsigned char *byte_output,
+ float *float_output,
+ int width,
+ int height,
+ int components,
+ float u,
+ float v)
{
- int i, j, n, m, x1, y1;
- float a, b, w, wx, wy[4], out[4];
-
- /* sample area entirely outside image? */
- if (ceil(u) < 0 || floor(u) > width - 1 || ceil(v) < 0 || floor(v) > height - 1) {
- if (float_output) {
- copy_vn_fl(float_output, components, 0.0f);
- }
- if (byte_output) {
- copy_vn_uchar(byte_output, components, 0);
- }
- return;
- }
-
- i = (int)floor(u);
- j = (int)floor(v);
- a = u - (float)i;
- b = v - (float)j;
-
- zero_v4(out);
-
-/* Optimized and not so easy to read */
-
- /* avoid calling multiple times */
- wy[0] = P(b - (-1));
- wy[1] = P(b - 0);
- wy[2] = P(b - 1);
- wy[3] = P(b - 2);
-
- for (n = -1; n <= 2; n++) {
- x1 = i + n;
- CLAMP(x1, 0, width - 1);
- wx = P((float)n - a);
- for (m = -1; m <= 2; m++) {
- float data[4];
-
- y1 = j + m;
- CLAMP(y1, 0, height - 1);
- /* normally we could do this */
- /* w = P(n-a) * P(b-m); */
- /* except that would call P() 16 times per pixel therefor pow() 64 times,
- * better precalc these */
- w = wx * wy[m + 1];
-
- if (float_output) {
- const float *float_data = float_buffer + width * y1 * components + components * x1;
-
- vector_from_float(float_data, data, components);
- }
- else {
- const unsigned char *byte_data = byte_buffer + width * y1 * components + components * x1;
-
- vector_from_byte(byte_data, data, components);
- }
-
- if (components == 1) {
- out[0] += data[0] * w;
- }
- else if (components == 3) {
- out[0] += data[0] * w;
- out[1] += data[1] * w;
- out[2] += data[2] * w;
- }
- else {
- out[0] += data[0] * w;
- out[1] += data[1] * w;
- out[2] += data[2] * w;
- out[3] += data[3] * w;
- }
- }
- }
-
-/* Done with optimized part */
+ int i, j, n, m, x1, y1;
+ float a, b, w, wx, wy[4], out[4];
+
+ /* sample area entirely outside image? */
+ if (ceil(u) < 0 || floor(u) > width - 1 || ceil(v) < 0 || floor(v) > height - 1) {
+ if (float_output) {
+ copy_vn_fl(float_output, components, 0.0f);
+ }
+ if (byte_output) {
+ copy_vn_uchar(byte_output, components, 0);
+ }
+ return;
+ }
+
+ i = (int)floor(u);
+ j = (int)floor(v);
+ a = u - (float)i;
+ b = v - (float)j;
+
+ zero_v4(out);
+
+ /* Optimized and not so easy to read */
+
+ /* avoid calling multiple times */
+ wy[0] = P(b - (-1));
+ wy[1] = P(b - 0);
+ wy[2] = P(b - 1);
+ wy[3] = P(b - 2);
+
+ for (n = -1; n <= 2; n++) {
+ x1 = i + n;
+ CLAMP(x1, 0, width - 1);
+ wx = P((float)n - a);
+ for (m = -1; m <= 2; m++) {
+ float data[4];
+
+ y1 = j + m;
+ CLAMP(y1, 0, height - 1);
+ /* normally we could do this */
+ /* w = P(n-a) * P(b-m); */
+ /* except that would call P() 16 times per pixel therefor pow() 64 times,
+ * better precalc these */
+ w = wx * wy[m + 1];
+
+ if (float_output) {
+ const float *float_data = float_buffer + width * y1 * components + components * x1;
+
+ vector_from_float(float_data, data, components);
+ }
+ else {
+ const unsigned char *byte_data = byte_buffer + width * y1 * components + components * x1;
+
+ vector_from_byte(byte_data, data, components);
+ }
+
+ if (components == 1) {
+ out[0] += data[0] * w;
+ }
+ else if (components == 3) {
+ out[0] += data[0] * w;
+ out[1] += data[1] * w;
+ out[2] += data[2] * w;
+ }
+ else {
+ out[0] += data[0] * w;
+ out[1] += data[1] * w;
+ out[2] += data[2] * w;
+ out[3] += data[3] * w;
+ }
+ }
+ }
+
+ /* Done with optimized part */
#if 0
- /* older, slower function, works the same as above */
- for (n = -1; n <= 2; n++) {
- for (m = -1; m <= 2; m++) {
- x1 = i + n;
- y1 = j + m;
- if (x1 > 0 && x1 < width && y1 > 0 && y1 < height) {
- float data[4];
-
- if (float_output) {
- const float *float_data = float_buffer + width * y1 * components + components * x1;
-
- vector_from_float(float_data, data, components);
- }
- else {
- const unsigned char *byte_data = byte_buffer + width * y1 * components + components * x1;
-
- vector_from_byte(byte_data, data, components);
- }
-
- if (components == 1) {
- out[0] += data[0] * P(n - a) * P(b - m);
- }
- else if (components == 3) {
- out[0] += data[0] * P(n - a) * P(b - m);
- out[1] += data[1] * P(n - a) * P(b - m);
- out[2] += data[2] * P(n - a) * P(b - m);
- }
- else {
- out[0] += data[0] * P(n - a) * P(b - m);
- out[1] += data[1] * P(n - a) * P(b - m);
- out[2] += data[2] * P(n - a) * P(b - m);
- out[3] += data[3] * P(n - a) * P(b - m);
- }
- }
- }
- }
+ /* older, slower function, works the same as above */
+ for (n = -1; n <= 2; n++) {
+ for (m = -1; m <= 2; m++) {
+ x1 = i + n;
+ y1 = j + m;
+ if (x1 > 0 && x1 < width && y1 > 0 && y1 < height) {
+ float data[4];
+
+ if (float_output) {
+ const float *float_data = float_buffer + width * y1 * components + components * x1;
+
+ vector_from_float(float_data, data, components);
+ }
+ else {
+ const unsigned char *byte_data = byte_buffer + width * y1 * components + components * x1;
+
+ vector_from_byte(byte_data, data, components);
+ }
+
+ if (components == 1) {
+ out[0] += data[0] * P(n - a) * P(b - m);
+ }
+ else if (components == 3) {
+ out[0] += data[0] * P(n - a) * P(b - m);
+ out[1] += data[1] * P(n - a) * P(b - m);
+ out[2] += data[2] * P(n - a) * P(b - m);
+ }
+ else {
+ out[0] += data[0] * P(n - a) * P(b - m);
+ out[1] += data[1] * P(n - a) * P(b - m);
+ out[2] += data[2] * P(n - a) * P(b - m);
+ out[3] += data[3] * P(n - a) * P(b - m);
+ }
+ }
+ }
+ }
#endif
- if (float_output) {
- if (components == 1) {
- float_output[0] = out[0];
- }
- else if (components == 3) {
- copy_v3_v3(float_output, out);
- }
- else {
- copy_v4_v4(float_output, out);
- }
- }
- else {
- if (components == 1) {
- byte_output[0] = (unsigned char)(out[0] + 0.5f);
- }
- else if (components == 3) {
- byte_output[0] = (unsigned char)(out[0] + 0.5f);
- byte_output[1] = (unsigned char)(out[1] + 0.5f);
- byte_output[2] = (unsigned char)(out[2] + 0.5f);
- }
- else {
- byte_output[0] = (unsigned char)(out[0] + 0.5f);
- byte_output[1] = (unsigned char)(out[1] + 0.5f);
- byte_output[2] = (unsigned char)(out[2] + 0.5f);
- byte_output[3] = (unsigned char)(out[3] + 0.5f);
- }
- }
+ if (float_output) {
+ if (components == 1) {
+ float_output[0] = out[0];
+ }
+ else if (components == 3) {
+ copy_v3_v3(float_output, out);
+ }
+ else {
+ copy_v4_v4(float_output, out);
+ }
+ }
+ else {
+ if (components == 1) {
+ byte_output[0] = (unsigned char)(out[0] + 0.5f);
+ }
+ else if (components == 3) {
+ byte_output[0] = (unsigned char)(out[0] + 0.5f);
+ byte_output[1] = (unsigned char)(out[1] + 0.5f);
+ byte_output[2] = (unsigned char)(out[2] + 0.5f);
+ }
+ else {
+ byte_output[0] = (unsigned char)(out[0] + 0.5f);
+ byte_output[1] = (unsigned char)(out[1] + 0.5f);
+ byte_output[2] = (unsigned char)(out[2] + 0.5f);
+ byte_output[3] = (unsigned char)(out[3] + 0.5f);
+ }
+ }
}
-void BLI_bicubic_interpolation_fl(const float *buffer, float *output, int width, int height,
- int components, float u, float v)
+void BLI_bicubic_interpolation_fl(
+ const float *buffer, float *output, int width, int height, int components, float u, float v)
{
- bicubic_interpolation(NULL, buffer, NULL, output, width, height, components, u, v);
+ bicubic_interpolation(NULL, buffer, NULL, output, width, height, components, u, v);
}
-void BLI_bicubic_interpolation_char(const unsigned char *buffer, unsigned char *output, int width, int height,
- int components, float u, float v)
+void BLI_bicubic_interpolation_char(const unsigned char *buffer,
+ unsigned char *output,
+ int width,
+ int height,
+ int components,
+ float u,
+ float v)
{
- bicubic_interpolation(buffer, NULL, output, NULL, width, height, components, u, v);
+ bicubic_interpolation(buffer, NULL, output, NULL, width, height, components, u, v);
}
/* BILINEAR INTERPOLATION */
-BLI_INLINE void bilinear_interpolation(const unsigned char *byte_buffer, const float *float_buffer,
- unsigned char *byte_output, float *float_output, int width, int height,
- int components, float u, float v, bool wrap_x, bool wrap_y)
+BLI_INLINE void bilinear_interpolation(const unsigned char *byte_buffer,
+ const float *float_buffer,
+ unsigned char *byte_output,
+ float *float_output,
+ int width,
+ int height,
+ int components,
+ float u,
+ float v,
+ bool wrap_x,
+ bool wrap_y)
{
- float a, b;
- float a_b, ma_b, a_mb, ma_mb;
- int y1, y2, x1, x2;
-
- /* ImBuf in must have a valid rect or rect_float, assume this is already checked */
-
- x1 = (int)floor(u);
- x2 = (int)ceil(u);
- y1 = (int)floor(v);
- y2 = (int)ceil(v);
-
- if (float_output) {
- const float *row1, *row2, *row3, *row4;
- float empty[4] = {0.0f, 0.0f, 0.0f, 0.0f};
-
- /* pixel value must be already wrapped, however values at boundaries may flip */
- if (wrap_x) {
- if (x1 < 0) {
- x1 = width - 1;
- }
- if (x2 >= width) {
- x2 = 0;
- }
- }
- else if (x2 < 0 || x1 >= width) {
- copy_vn_fl(float_output, components, 0.0f);
- return;
- }
-
- if (wrap_y) {
- if (y1 < 0) {
- y1 = height - 1;
- }
- if (y2 >= height) {
- y2 = 0;
- }
- }
- else if (y2 < 0 || y1 >= height) {
- copy_vn_fl(float_output, components, 0.0f);
- return;
- }
-
- /* sample including outside of edges of image */
- if (x1 < 0 || y1 < 0) {
- row1 = empty;
- }
- else {
- row1 = float_buffer + width * y1 * components + components * x1;
- }
-
- if (x1 < 0 || y2 > height - 1) {
- row2 = empty;
- }
- else {
- row2 = float_buffer + width * y2 * components + components * x1;
- }
-
- if (x2 > width - 1 || y1 < 0) {
- row3 = empty;
- }
- else {
- row3 = float_buffer + width * y1 * components + components * x2;
- }
-
- if (x2 > width - 1 || y2 > height - 1) {
- row4 = empty;
- }
- else {
- row4 = float_buffer + width * y2 * components + components * x2;
- }
-
- a = u - floorf(u);
- b = v - floorf(v);
- a_b = a * b; ma_b = (1.0f - a) * b; a_mb = a * (1.0f - b); ma_mb = (1.0f - a) * (1.0f - b);
-
- if (components == 1) {
- float_output[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0];
- }
- else if (components == 3) {
- float_output[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0];
- float_output[1] = ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] + a_b * row4[1];
- float_output[2] = ma_mb * row1[2] + a_mb * row3[2] + ma_b * row2[2] + a_b * row4[2];
- }
- else {
- float_output[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0];
- float_output[1] = ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] + a_b * row4[1];
- float_output[2] = ma_mb * row1[2] + a_mb * row3[2] + ma_b * row2[2] + a_b * row4[2];
- float_output[3] = ma_mb * row1[3] + a_mb * row3[3] + ma_b * row2[3] + a_b * row4[3];
- }
- }
- else {
- const unsigned char *row1, *row2, *row3, *row4;
- unsigned char empty[4] = {0, 0, 0, 0};
-
- /* pixel value must be already wrapped, however values at boundaries may flip */
- if (wrap_x) {
- if (x1 < 0) {
- x1 = width - 1;
- }
- if (x2 >= width) {
- x2 = 0;
- }
- }
- else if (x2 < 0 || x1 >= width) {
- copy_vn_uchar(byte_output, components, 0);
- return;
- }
-
- if (wrap_y) {
- if (y1 < 0) {
- y1 = height - 1;
- }
- if (y2 >= height) {
- y2 = 0;
- }
- }
- else if (y2 < 0 || y1 >= height) {
- copy_vn_uchar(byte_output, components, 0);
- return;
- }
-
- /* sample including outside of edges of image */
- if (x1 < 0 || y1 < 0) {
- row1 = empty;
- }
- else {
- row1 = byte_buffer + width * y1 * components + components * x1;
- }
-
- if (x1 < 0 || y2 > height - 1) {
- row2 = empty;
- }
- else {
- row2 = byte_buffer + width * y2 * components + components * x1;
- }
-
- if (x2 > width - 1 || y1 < 0) {
- row3 = empty;
- }
- else {
- row3 = byte_buffer + width * y1 * components + components * x2;
- }
-
- if (x2 > width - 1 || y2 > height - 1) {
- row4 = empty;
- }
- else {
- row4 = byte_buffer + width * y2 * components + components * x2;
- }
-
- a = u - floorf(u);
- b = v - floorf(v);
- a_b = a * b; ma_b = (1.0f - a) * b; a_mb = a * (1.0f - b); ma_mb = (1.0f - a) * (1.0f - b);
-
- if (components == 1) {
- byte_output[0] = (unsigned char)(ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0] + 0.5f);
- }
- else if (components == 3) {
- byte_output[0] = (unsigned char)(ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0] + 0.5f);
- byte_output[1] = (unsigned char)(ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] + a_b * row4[1] + 0.5f);
- byte_output[2] = (unsigned char)(ma_mb * row1[2] + a_mb * row3[2] + ma_b * row2[2] + a_b * row4[2] + 0.5f);
- }
- else {
- byte_output[0] = (unsigned char)(ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0] + 0.5f);
- byte_output[1] = (unsigned char)(ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] + a_b * row4[1] + 0.5f);
- byte_output[2] = (unsigned char)(ma_mb * row1[2] + a_mb * row3[2] + ma_b * row2[2] + a_b * row4[2] + 0.5f);
- byte_output[3] = (unsigned char)(ma_mb * row1[3] + a_mb * row3[3] + ma_b * row2[3] + a_b * row4[3] + 0.5f);
- }
- }
+ float a, b;
+ float a_b, ma_b, a_mb, ma_mb;
+ int y1, y2, x1, x2;
+
+ /* ImBuf in must have a valid rect or rect_float, assume this is already checked */
+
+ x1 = (int)floor(u);
+ x2 = (int)ceil(u);
+ y1 = (int)floor(v);
+ y2 = (int)ceil(v);
+
+ if (float_output) {
+ const float *row1, *row2, *row3, *row4;
+ float empty[4] = {0.0f, 0.0f, 0.0f, 0.0f};
+
+ /* pixel value must be already wrapped, however values at boundaries may flip */
+ if (wrap_x) {
+ if (x1 < 0) {
+ x1 = width - 1;
+ }
+ if (x2 >= width) {
+ x2 = 0;
+ }
+ }
+ else if (x2 < 0 || x1 >= width) {
+ copy_vn_fl(float_output, components, 0.0f);
+ return;
+ }
+
+ if (wrap_y) {
+ if (y1 < 0) {
+ y1 = height - 1;
+ }
+ if (y2 >= height) {
+ y2 = 0;
+ }
+ }
+ else if (y2 < 0 || y1 >= height) {
+ copy_vn_fl(float_output, components, 0.0f);
+ return;
+ }
+
+ /* sample including outside of edges of image */
+ if (x1 < 0 || y1 < 0) {
+ row1 = empty;
+ }
+ else {
+ row1 = float_buffer + width * y1 * components + components * x1;
+ }
+
+ if (x1 < 0 || y2 > height - 1) {
+ row2 = empty;
+ }
+ else {
+ row2 = float_buffer + width * y2 * components + components * x1;
+ }
+
+ if (x2 > width - 1 || y1 < 0) {
+ row3 = empty;
+ }
+ else {
+ row3 = float_buffer + width * y1 * components + components * x2;
+ }
+
+ if (x2 > width - 1 || y2 > height - 1) {
+ row4 = empty;
+ }
+ else {
+ row4 = float_buffer + width * y2 * components + components * x2;
+ }
+
+ a = u - floorf(u);
+ b = v - floorf(v);
+ a_b = a * b;
+ ma_b = (1.0f - a) * b;
+ a_mb = a * (1.0f - b);
+ ma_mb = (1.0f - a) * (1.0f - b);
+
+ if (components == 1) {
+ float_output[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0];
+ }
+ else if (components == 3) {
+ float_output[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0];
+ float_output[1] = ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] + a_b * row4[1];
+ float_output[2] = ma_mb * row1[2] + a_mb * row3[2] + ma_b * row2[2] + a_b * row4[2];
+ }
+ else {
+ float_output[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0];
+ float_output[1] = ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] + a_b * row4[1];
+ float_output[2] = ma_mb * row1[2] + a_mb * row3[2] + ma_b * row2[2] + a_b * row4[2];
+ float_output[3] = ma_mb * row1[3] + a_mb * row3[3] + ma_b * row2[3] + a_b * row4[3];
+ }
+ }
+ else {
+ const unsigned char *row1, *row2, *row3, *row4;
+ unsigned char empty[4] = {0, 0, 0, 0};
+
+ /* pixel value must be already wrapped, however values at boundaries may flip */
+ if (wrap_x) {
+ if (x1 < 0) {
+ x1 = width - 1;
+ }
+ if (x2 >= width) {
+ x2 = 0;
+ }
+ }
+ else if (x2 < 0 || x1 >= width) {
+ copy_vn_uchar(byte_output, components, 0);
+ return;
+ }
+
+ if (wrap_y) {
+ if (y1 < 0) {
+ y1 = height - 1;
+ }
+ if (y2 >= height) {
+ y2 = 0;
+ }
+ }
+ else if (y2 < 0 || y1 >= height) {
+ copy_vn_uchar(byte_output, components, 0);
+ return;
+ }
+
+ /* sample including outside of edges of image */
+ if (x1 < 0 || y1 < 0) {
+ row1 = empty;
+ }
+ else {
+ row1 = byte_buffer + width * y1 * components + components * x1;
+ }
+
+ if (x1 < 0 || y2 > height - 1) {
+ row2 = empty;
+ }
+ else {
+ row2 = byte_buffer + width * y2 * components + components * x1;
+ }
+
+ if (x2 > width - 1 || y1 < 0) {
+ row3 = empty;
+ }
+ else {
+ row3 = byte_buffer + width * y1 * components + components * x2;
+ }
+
+ if (x2 > width - 1 || y2 > height - 1) {
+ row4 = empty;
+ }
+ else {
+ row4 = byte_buffer + width * y2 * components + components * x2;
+ }
+
+ a = u - floorf(u);
+ b = v - floorf(v);
+ a_b = a * b;
+ ma_b = (1.0f - a) * b;
+ a_mb = a * (1.0f - b);
+ ma_mb = (1.0f - a) * (1.0f - b);
+
+ if (components == 1) {
+ byte_output[0] = (unsigned char)(ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] +
+ a_b * row4[0] + 0.5f);
+ }
+ else if (components == 3) {
+ byte_output[0] = (unsigned char)(ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] +
+ a_b * row4[0] + 0.5f);
+ byte_output[1] = (unsigned char)(ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] +
+ a_b * row4[1] + 0.5f);
+ byte_output[2] = (unsigned char)(ma_mb * row1[2] + a_mb * row3[2] + ma_b * row2[2] +
+ a_b * row4[2] + 0.5f);
+ }
+ else {
+ byte_output[0] = (unsigned char)(ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] +
+ a_b * row4[0] + 0.5f);
+ byte_output[1] = (unsigned char)(ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] +
+ a_b * row4[1] + 0.5f);
+ byte_output[2] = (unsigned char)(ma_mb * row1[2] + a_mb * row3[2] + ma_b * row2[2] +
+ a_b * row4[2] + 0.5f);
+ byte_output[3] = (unsigned char)(ma_mb * row1[3] + a_mb * row3[3] + ma_b * row2[3] +
+ a_b * row4[3] + 0.5f);
+ }
+ }
}
-void BLI_bilinear_interpolation_fl(const float *buffer, float *output, int width, int height,
- int components, float u, float v)
+void BLI_bilinear_interpolation_fl(
+ const float *buffer, float *output, int width, int height, int components, float u, float v)
{
- bilinear_interpolation(NULL, buffer, NULL, output, width, height, components, u, v, false, false);
+ bilinear_interpolation(
+ NULL, buffer, NULL, output, width, height, components, u, v, false, false);
}
-void BLI_bilinear_interpolation_char(const unsigned char *buffer, unsigned char *output, int width, int height,
- int components, float u, float v)
+void BLI_bilinear_interpolation_char(const unsigned char *buffer,
+ unsigned char *output,
+ int width,
+ int height,
+ int components,
+ float u,
+ float v)
{
- bilinear_interpolation(buffer, NULL, output, NULL, width, height, components, u, v, false, false);
+ bilinear_interpolation(
+ buffer, NULL, output, NULL, width, height, components, u, v, false, false);
}
-void BLI_bilinear_interpolation_wrap_fl(const float *buffer, float *output, int width, int height,
- int components, float u, float v, bool wrap_x, bool wrap_y)
+void BLI_bilinear_interpolation_wrap_fl(const float *buffer,
+ float *output,
+ int width,
+ int height,
+ int components,
+ float u,
+ float v,
+ bool wrap_x,
+ bool wrap_y)
{
- bilinear_interpolation(NULL, buffer, NULL, output, width, height, components, u, v, wrap_x, wrap_y);
+ bilinear_interpolation(
+ NULL, buffer, NULL, output, width, height, components, u, v, wrap_x, wrap_y);
}
-void BLI_bilinear_interpolation_wrap_char(const unsigned char *buffer, unsigned char *output, int width, int height,
- int components, float u, float v, bool wrap_x, bool wrap_y)
+void BLI_bilinear_interpolation_wrap_char(const unsigned char *buffer,
+ unsigned char *output,
+ int width,
+ int height,
+ int components,
+ float u,
+ float v,
+ bool wrap_x,
+ bool wrap_y)
{
- bilinear_interpolation(buffer, NULL, output, NULL, width, height, components, u, v, wrap_x, wrap_y);
+ bilinear_interpolation(
+ buffer, NULL, output, NULL, width, height, components, u, v, wrap_x, wrap_y);
}
-
/**************************************************************************
* Filtering method based on
* "Creating raster omnimax images from multiple perspective views
@@ -463,80 +518,87 @@ void BLI_bilinear_interpolation_wrap_char(const unsigned char *buffer, unsigned
* used instead of actual gaussian, otherwise at high texture magnifications circular artifacts are visible */
#define EWA_MAXIDX 255
const float EWA_WTS[EWA_MAXIDX + 1] = {
- 1.f, 0.990965f, 0.982f, 0.973105f, 0.96428f, 0.955524f, 0.946836f, 0.938216f, 0.929664f,
- 0.921178f, 0.912759f, 0.904405f, 0.896117f, 0.887893f, 0.879734f, 0.871638f, 0.863605f,
- 0.855636f, 0.847728f, 0.839883f, 0.832098f, 0.824375f, 0.816712f, 0.809108f, 0.801564f,
- 0.794079f, 0.786653f, 0.779284f, 0.771974f, 0.76472f, 0.757523f, 0.750382f, 0.743297f,
- 0.736267f, 0.729292f, 0.722372f, 0.715505f, 0.708693f, 0.701933f, 0.695227f, 0.688572f,
- 0.68197f, 0.67542f, 0.66892f, 0.662471f, 0.656073f, 0.649725f, 0.643426f, 0.637176f,
- 0.630976f, 0.624824f, 0.618719f, 0.612663f, 0.606654f, 0.600691f, 0.594776f, 0.588906f,
- 0.583083f, 0.577305f, 0.571572f, 0.565883f, 0.56024f, 0.55464f, 0.549084f, 0.543572f,
- 0.538102f, 0.532676f, 0.527291f, 0.521949f, 0.516649f, 0.511389f, 0.506171f, 0.500994f,
- 0.495857f, 0.490761f, 0.485704f, 0.480687f, 0.475709f, 0.470769f, 0.465869f, 0.461006f,
- 0.456182f, 0.451395f, 0.446646f, 0.441934f, 0.437258f, 0.432619f, 0.428017f, 0.42345f,
- 0.418919f, 0.414424f, 0.409963f, 0.405538f, 0.401147f, 0.39679f, 0.392467f, 0.388178f,
- 0.383923f, 0.379701f, 0.375511f, 0.371355f, 0.367231f, 0.363139f, 0.359079f, 0.355051f,
- 0.351055f, 0.347089f, 0.343155f, 0.339251f, 0.335378f, 0.331535f, 0.327722f, 0.323939f,
- 0.320186f, 0.316461f, 0.312766f, 0.3091f, 0.305462f, 0.301853f, 0.298272f, 0.294719f,
- 0.291194f, 0.287696f, 0.284226f, 0.280782f, 0.277366f, 0.273976f, 0.270613f, 0.267276f,
- 0.263965f, 0.26068f, 0.257421f, 0.254187f, 0.250979f, 0.247795f, 0.244636f, 0.241502f,
- 0.238393f, 0.235308f, 0.232246f, 0.229209f, 0.226196f, 0.223206f, 0.220239f, 0.217296f,
- 0.214375f, 0.211478f, 0.208603f, 0.20575f, 0.20292f, 0.200112f, 0.197326f, 0.194562f,
- 0.191819f, 0.189097f, 0.186397f, 0.183718f, 0.18106f, 0.178423f, 0.175806f, 0.17321f,
- 0.170634f, 0.168078f, 0.165542f, 0.163026f, 0.16053f, 0.158053f, 0.155595f, 0.153157f,
- 0.150738f, 0.148337f, 0.145955f, 0.143592f, 0.141248f, 0.138921f, 0.136613f, 0.134323f,
- 0.132051f, 0.129797f, 0.12756f, 0.125341f, 0.123139f, 0.120954f, 0.118786f, 0.116635f,
- 0.114501f, 0.112384f, 0.110283f, 0.108199f, 0.106131f, 0.104079f, 0.102043f, 0.100023f,
- 0.0980186f, 0.09603f, 0.094057f, 0.0920994f, 0.0901571f, 0.08823f, 0.0863179f, 0.0844208f,
- 0.0825384f, 0.0806708f, 0.0788178f, 0.0769792f, 0.0751551f, 0.0733451f, 0.0715493f, 0.0697676f,
- 0.0679997f, 0.0662457f, 0.0645054f, 0.0627786f, 0.0610654f, 0.0593655f, 0.0576789f, 0.0560055f,
- 0.0543452f, 0.0526979f, 0.0510634f, 0.0494416f, 0.0478326f, 0.0462361f, 0.0446521f, 0.0430805f,
- 0.0415211f, 0.039974f, 0.0384389f, 0.0369158f, 0.0354046f, 0.0339052f, 0.0324175f, 0.0309415f,
- 0.029477f, 0.0280239f, 0.0265822f, 0.0251517f, 0.0237324f, 0.0223242f, 0.020927f, 0.0195408f,
- 0.0181653f, 0.0168006f, 0.0154466f, 0.0141031f, 0.0127701f, 0.0114476f, 0.0101354f, 0.00883339f,
- 0.00754159f, 0.00625989f, 0.00498819f, 0.00372644f, 0.00247454f, 0.00123242f, 0.f,
+ 1.f, 0.990965f, 0.982f, 0.973105f, 0.96428f, 0.955524f, 0.946836f,
+ 0.938216f, 0.929664f, 0.921178f, 0.912759f, 0.904405f, 0.896117f, 0.887893f,
+ 0.879734f, 0.871638f, 0.863605f, 0.855636f, 0.847728f, 0.839883f, 0.832098f,
+ 0.824375f, 0.816712f, 0.809108f, 0.801564f, 0.794079f, 0.786653f, 0.779284f,
+ 0.771974f, 0.76472f, 0.757523f, 0.750382f, 0.743297f, 0.736267f, 0.729292f,
+ 0.722372f, 0.715505f, 0.708693f, 0.701933f, 0.695227f, 0.688572f, 0.68197f,
+ 0.67542f, 0.66892f, 0.662471f, 0.656073f, 0.649725f, 0.643426f, 0.637176f,
+ 0.630976f, 0.624824f, 0.618719f, 0.612663f, 0.606654f, 0.600691f, 0.594776f,
+ 0.588906f, 0.583083f, 0.577305f, 0.571572f, 0.565883f, 0.56024f, 0.55464f,
+ 0.549084f, 0.543572f, 0.538102f, 0.532676f, 0.527291f, 0.521949f, 0.516649f,
+ 0.511389f, 0.506171f, 0.500994f, 0.495857f, 0.490761f, 0.485704f, 0.480687f,
+ 0.475709f, 0.470769f, 0.465869f, 0.461006f, 0.456182f, 0.451395f, 0.446646f,
+ 0.441934f, 0.437258f, 0.432619f, 0.428017f, 0.42345f, 0.418919f, 0.414424f,
+ 0.409963f, 0.405538f, 0.401147f, 0.39679f, 0.392467f, 0.388178f, 0.383923f,
+ 0.379701f, 0.375511f, 0.371355f, 0.367231f, 0.363139f, 0.359079f, 0.355051f,
+ 0.351055f, 0.347089f, 0.343155f, 0.339251f, 0.335378f, 0.331535f, 0.327722f,
+ 0.323939f, 0.320186f, 0.316461f, 0.312766f, 0.3091f, 0.305462f, 0.301853f,
+ 0.298272f, 0.294719f, 0.291194f, 0.287696f, 0.284226f, 0.280782f, 0.277366f,
+ 0.273976f, 0.270613f, 0.267276f, 0.263965f, 0.26068f, 0.257421f, 0.254187f,
+ 0.250979f, 0.247795f, 0.244636f, 0.241502f, 0.238393f, 0.235308f, 0.232246f,
+ 0.229209f, 0.226196f, 0.223206f, 0.220239f, 0.217296f, 0.214375f, 0.211478f,
+ 0.208603f, 0.20575f, 0.20292f, 0.200112f, 0.197326f, 0.194562f, 0.191819f,
+ 0.189097f, 0.186397f, 0.183718f, 0.18106f, 0.178423f, 0.175806f, 0.17321f,
+ 0.170634f, 0.168078f, 0.165542f, 0.163026f, 0.16053f, 0.158053f, 0.155595f,
+ 0.153157f, 0.150738f, 0.148337f, 0.145955f, 0.143592f, 0.141248f, 0.138921f,
+ 0.136613f, 0.134323f, 0.132051f, 0.129797f, 0.12756f, 0.125341f, 0.123139f,
+ 0.120954f, 0.118786f, 0.116635f, 0.114501f, 0.112384f, 0.110283f, 0.108199f,
+ 0.106131f, 0.104079f, 0.102043f, 0.100023f, 0.0980186f, 0.09603f, 0.094057f,
+ 0.0920994f, 0.0901571f, 0.08823f, 0.0863179f, 0.0844208f, 0.0825384f, 0.0806708f,
+ 0.0788178f, 0.0769792f, 0.0751551f, 0.0733451f, 0.0715493f, 0.0697676f, 0.0679997f,
+ 0.0662457f, 0.0645054f, 0.0627786f, 0.0610654f, 0.0593655f, 0.0576789f, 0.0560055f,
+ 0.0543452f, 0.0526979f, 0.0510634f, 0.0494416f, 0.0478326f, 0.0462361f, 0.0446521f,
+ 0.0430805f, 0.0415211f, 0.039974f, 0.0384389f, 0.0369158f, 0.0354046f, 0.0339052f,
+ 0.0324175f, 0.0309415f, 0.029477f, 0.0280239f, 0.0265822f, 0.0251517f, 0.0237324f,
+ 0.0223242f, 0.020927f, 0.0195408f, 0.0181653f, 0.0168006f, 0.0154466f, 0.0141031f,
+ 0.0127701f, 0.0114476f, 0.0101354f, 0.00883339f, 0.00754159f, 0.00625989f, 0.00498819f,
+ 0.00372644f, 0.00247454f, 0.00123242f, 0.f,
};
static void radangle2imp(float a2, float b2, float th, float *A, float *B, float *C, float *F)
{
- float ct2 = cosf(th);
- const float st2 = 1.0f - ct2 * ct2; /* <- sin(th)^2 */
- ct2 *= ct2;
- *A = a2 * st2 + b2 * ct2;
- *B = (b2 - a2) * sinf(2.0f * th);
- *C = a2 * ct2 + b2 * st2;
- *F = a2 * b2;
+ float ct2 = cosf(th);
+ const float st2 = 1.0f - ct2 * ct2; /* <- sin(th)^2 */
+ ct2 *= ct2;
+ *A = a2 * st2 + b2 * ct2;
+ *B = (b2 - a2) * sinf(2.0f * th);
+ *C = a2 * ct2 + b2 * st2;
+ *F = a2 * b2;
}
/* all tests here are done to make sure possible overflows are hopefully minimized */
-void BLI_ewa_imp2radangle(float A, float B, float C, float F, float *a, float *b, float *th, float *ecc)
+void BLI_ewa_imp2radangle(
+ float A, float B, float C, float F, float *a, float *b, float *th, float *ecc)
{
- if (F <= 1e-5f) { /* use arbitrary major radius, zero minor, infinite eccentricity */
- *a = sqrtf(A > C ? A : C);
- *b = 0.0f;
- *ecc = 1e10f;
- *th = 0.5f * (atan2f(B, A - C) + (float)M_PI);
- }
- else {
- const float AmC = A - C, ApC = A + C, F2 = F * 2.0f;
- const float r = sqrtf(AmC * AmC + B * B);
- float d = ApC - r;
- *a = (d <= 0.0f) ? sqrtf(A > C ? A : C) : sqrtf(F2 / d);
- d = ApC + r;
- if (d <= 0.0f) {
- *b = 0.0f;
- *ecc = 1e10f;
- }
- else {
- *b = sqrtf(F2 / d);
- *ecc = *a / *b;
- }
- /* incr theta by 0.5*pi (angle of major axis) */
- *th = 0.5f * (atan2f(B, AmC) + (float)M_PI);
- }
+ if (F <= 1e-5f) { /* use arbitrary major radius, zero minor, infinite eccentricity */
+ *a = sqrtf(A > C ? A : C);
+ *b = 0.0f;
+ *ecc = 1e10f;
+ *th = 0.5f * (atan2f(B, A - C) + (float)M_PI);
+ }
+ else {
+ const float AmC = A - C, ApC = A + C, F2 = F * 2.0f;
+ const float r = sqrtf(AmC * AmC + B * B);
+ float d = ApC - r;
+ *a = (d <= 0.0f) ? sqrtf(A > C ? A : C) : sqrtf(F2 / d);
+ d = ApC + r;
+ if (d <= 0.0f) {
+ *b = 0.0f;
+ *ecc = 1e10f;
+ }
+ else {
+ *b = sqrtf(F2 / d);
+ *ecc = *a / *b;
+ }
+ /* incr theta by 0.5*pi (angle of major axis) */
+ *th = 0.5f * (atan2f(B, AmC) + (float)M_PI);
+ }
}
-void BLI_ewa_filter(const int width, const int height,
+void BLI_ewa_filter(const int width,
+ const int height,
const bool intpol,
const bool use_alpha,
const float uv[2],
@@ -546,98 +608,106 @@ void BLI_ewa_filter(const int width, const int height,
void *userdata,
float result[4])
{
- /* 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 = 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;
- float F = A * C - B * B * 0.25f;
- float a, b, th, ecc, a2, b2, ue, ve, U0, V0, DDQ, U, ac1, ac2, BU, d;
- int u, v, u1, u2, v1, v2;
-
- /* The so-called 'high' quality ewa method simply adds a constant of 1 to both A & C,
- * so the ellipse always covers at least some texels. But since the filter is now always larger,
- * it also means that everywhere else it's also more blurry then ideally should be the case.
- * So instead here the ellipse radii are modified instead whenever either is too low.
- * Use a different radius based on interpolation switch, just enough to anti-alias when interpolation is off,
- * and slightly larger to make result a bit smoother than bilinear interpolation when interpolation is on
- * (minimum values: const float rmin = intpol ? 1.f : 0.5f;) */
- const float rmin = (intpol ? 1.5625f : 0.765625f) / ff2;
- BLI_ewa_imp2radangle(A, B, C, F, &a, &b, &th, &ecc);
- if ((b2 = b * b) < rmin) {
- if ((a2 = a * a) < rmin) {
- B = 0.0f;
- A = C = rmin;
- F = A * C;
- }
- else {
- b2 = rmin;
- radangle2imp(a2, b2, th, &A, &B, &C, &F);
- }
- }
-
- ue = ff * sqrtf(C);
- ve = ff * sqrtf(A);
- d = (float)(EWA_MAXIDX + 1) / (F * ff2);
- A *= d;
- B *= d;
- C *= d;
-
- U0 = uv[0] * (float)width;
- V0 = uv[1] * (float)height;
- u1 = (int)(floorf(U0 - ue));
- u2 = (int)(ceilf(U0 + ue));
- v1 = (int)(floorf(V0 - ve));
- v2 = (int)(ceilf(V0 + ve));
-
- /* sane clamping to avoid unnecessarily huge loops */
- /* note: if eccentricity gets clamped (see above),
- * the ue/ve limits can also be lowered accordingly
- */
- if (U0 - (float)u1 > EWA_MAXIDX) { u1 = (int)U0 - EWA_MAXIDX; }
- if ((float)u2 - U0 > EWA_MAXIDX) { u2 = (int)U0 + EWA_MAXIDX; }
- if (V0 - (float)v1 > EWA_MAXIDX) { v1 = (int)V0 - EWA_MAXIDX; }
- if ((float)v2 - V0 > EWA_MAXIDX) { v2 = (int)V0 + EWA_MAXIDX; }
-
- /* Early output check for cases the whole region is outside of the buffer. */
- if ((u2 < 0 || u1 >= width) || (v2 < 0 || v1 >= height)) {
- zero_v4(result);
- return;
- }
-
- U0 -= 0.5f;
- V0 -= 0.5f;
- DDQ = 2.0f * A;
- U = (float)u1 - U0;
- ac1 = A * (2.0f * U + 1.0f);
- ac2 = A * U * U;
- BU = B * U;
-
- d = 0.0f;
- zero_v4(result);
- for (v = v1; v <= v2; ++v) {
- const float V = (float)v - V0;
- float DQ = ac1 + B * V;
- float Q = (C * V + BU) * V + ac2;
- for (u = u1; u <= u2; ++u) {
- if (Q < (float)(EWA_MAXIDX + 1)) {
- float tc[4];
- const float wt = EWA_WTS[(Q < 0.0f) ? 0 : (unsigned int)Q];
- read_pixel_cb(userdata, u, v, tc);
- madd_v3_v3fl(result, tc, wt);
- result[3] += use_alpha ? tc[3] * wt : 0.0f;
- d += wt;
- }
- Q += DQ;
- DQ += DDQ;
- }
- }
-
- /* d should hopefully never be zero anymore */
- d = 1.0f / d;
- mul_v3_fl(result, d);
- /* clipping can be ignored if alpha used, texr->ta already includes filtered edge */
- result[3] = use_alpha ? result[3] * d : 1.0f;
+ /* 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 = 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;
+ float F = A * C - B * B * 0.25f;
+ float a, b, th, ecc, a2, b2, ue, ve, U0, V0, DDQ, U, ac1, ac2, BU, d;
+ int u, v, u1, u2, v1, v2;
+
+ /* The so-called 'high' quality ewa method simply adds a constant of 1 to both A & C,
+ * so the ellipse always covers at least some texels. But since the filter is now always larger,
+ * it also means that everywhere else it's also more blurry then ideally should be the case.
+ * So instead here the ellipse radii are modified instead whenever either is too low.
+ * Use a different radius based on interpolation switch, just enough to anti-alias when interpolation is off,
+ * and slightly larger to make result a bit smoother than bilinear interpolation when interpolation is on
+ * (minimum values: const float rmin = intpol ? 1.f : 0.5f;) */
+ const float rmin = (intpol ? 1.5625f : 0.765625f) / ff2;
+ BLI_ewa_imp2radangle(A, B, C, F, &a, &b, &th, &ecc);
+ if ((b2 = b * b) < rmin) {
+ if ((a2 = a * a) < rmin) {
+ B = 0.0f;
+ A = C = rmin;
+ F = A * C;
+ }
+ else {
+ b2 = rmin;
+ radangle2imp(a2, b2, th, &A, &B, &C, &F);
+ }
+ }
+
+ ue = ff * sqrtf(C);
+ ve = ff * sqrtf(A);
+ d = (float)(EWA_MAXIDX + 1) / (F * ff2);
+ A *= d;
+ B *= d;
+ C *= d;
+
+ U0 = uv[0] * (float)width;
+ V0 = uv[1] * (float)height;
+ u1 = (int)(floorf(U0 - ue));
+ u2 = (int)(ceilf(U0 + ue));
+ v1 = (int)(floorf(V0 - ve));
+ v2 = (int)(ceilf(V0 + ve));
+
+ /* sane clamping to avoid unnecessarily huge loops */
+ /* note: if eccentricity gets clamped (see above),
+ * the ue/ve limits can also be lowered accordingly
+ */
+ if (U0 - (float)u1 > EWA_MAXIDX) {
+ u1 = (int)U0 - EWA_MAXIDX;
+ }
+ if ((float)u2 - U0 > EWA_MAXIDX) {
+ u2 = (int)U0 + EWA_MAXIDX;
+ }
+ if (V0 - (float)v1 > EWA_MAXIDX) {
+ v1 = (int)V0 - EWA_MAXIDX;
+ }
+ if ((float)v2 - V0 > EWA_MAXIDX) {
+ v2 = (int)V0 + EWA_MAXIDX;
+ }
+
+ /* Early output check for cases the whole region is outside of the buffer. */
+ if ((u2 < 0 || u1 >= width) || (v2 < 0 || v1 >= height)) {
+ zero_v4(result);
+ return;
+ }
+
+ U0 -= 0.5f;
+ V0 -= 0.5f;
+ DDQ = 2.0f * A;
+ U = (float)u1 - U0;
+ ac1 = A * (2.0f * U + 1.0f);
+ ac2 = A * U * U;
+ BU = B * U;
+
+ d = 0.0f;
+ zero_v4(result);
+ for (v = v1; v <= v2; ++v) {
+ const float V = (float)v - V0;
+ float DQ = ac1 + B * V;
+ float Q = (C * V + BU) * V + ac2;
+ for (u = u1; u <= u2; ++u) {
+ if (Q < (float)(EWA_MAXIDX + 1)) {
+ float tc[4];
+ const float wt = EWA_WTS[(Q < 0.0f) ? 0 : (unsigned int)Q];
+ read_pixel_cb(userdata, u, v, tc);
+ madd_v3_v3fl(result, tc, wt);
+ result[3] += use_alpha ? tc[3] * wt : 0.0f;
+ d += wt;
+ }
+ Q += DQ;
+ DQ += DDQ;
+ }
+ }
+
+ /* d should hopefully never be zero anymore */
+ d = 1.0f / d;
+ mul_v3_fl(result, d);
+ /* clipping can be ignored if alpha used, texr->ta already includes filtered edge */
+ result[3] = use_alpha ? result[3] * d : 1.0f;
}
diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c
index 3da69e92227..71ea1ce1bc9 100644
--- a/source/blender/blenlib/intern/math_matrix.c
+++ b/source/blender/blenlib/intern/math_matrix.c
@@ -23,7 +23,6 @@
* \ingroup bli
*/
-
#include <assert.h>
#include "BLI_math.h"
@@ -35,1067 +34,1099 @@
void zero_m2(float m[2][2])
{
- memset(m, 0, sizeof(float[2][2]));
+ memset(m, 0, sizeof(float[2][2]));
}
void zero_m3(float m[3][3])
{
- memset(m, 0, sizeof(float[3][3]));
+ memset(m, 0, sizeof(float[3][3]));
}
void zero_m4(float m[4][4])
{
- memset(m, 0, sizeof(float[4][4]));
+ memset(m, 0, sizeof(float[4][4]));
}
void unit_m2(float m[2][2])
{
- m[0][0] = m[1][1] = 1.0f;
- m[0][1] = 0.0f;
- m[1][0] = 0.0f;
+ m[0][0] = m[1][1] = 1.0f;
+ m[0][1] = 0.0f;
+ m[1][0] = 0.0f;
}
void unit_m3(float m[3][3])
{
- m[0][0] = m[1][1] = m[2][2] = 1.0f;
- m[0][1] = m[0][2] = 0.0f;
- m[1][0] = m[1][2] = 0.0f;
- m[2][0] = m[2][1] = 0.0f;
+ m[0][0] = m[1][1] = m[2][2] = 1.0f;
+ m[0][1] = m[0][2] = 0.0f;
+ m[1][0] = m[1][2] = 0.0f;
+ m[2][0] = m[2][1] = 0.0f;
}
void unit_m4(float m[4][4])
{
- m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1.0f;
- m[0][1] = m[0][2] = m[0][3] = 0.0f;
- m[1][0] = m[1][2] = m[1][3] = 0.0f;
- m[2][0] = m[2][1] = m[2][3] = 0.0f;
- m[3][0] = m[3][1] = m[3][2] = 0.0f;
+ m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1.0f;
+ m[0][1] = m[0][2] = m[0][3] = 0.0f;
+ m[1][0] = m[1][2] = m[1][3] = 0.0f;
+ m[2][0] = m[2][1] = m[2][3] = 0.0f;
+ m[3][0] = m[3][1] = m[3][2] = 0.0f;
}
void copy_m2_m2(float m1[2][2], const float m2[2][2])
{
- memcpy(m1, m2, sizeof(float[2][2]));
+ memcpy(m1, m2, sizeof(float[2][2]));
}
void copy_m3_m3(float m1[3][3], const float m2[3][3])
{
- /* destination comes first: */
- memcpy(m1, m2, sizeof(float[3][3]));
+ /* destination comes first: */
+ memcpy(m1, m2, sizeof(float[3][3]));
}
void copy_m4_m4(float m1[4][4], const float m2[4][4])
{
- memcpy(m1, m2, sizeof(float[4][4]));
+ memcpy(m1, m2, sizeof(float[4][4]));
}
void copy_m3_m4(float m1[3][3], const float m2[4][4])
{
- m1[0][0] = m2[0][0];
- m1[0][1] = m2[0][1];
- m1[0][2] = m2[0][2];
+ m1[0][0] = m2[0][0];
+ m1[0][1] = m2[0][1];
+ m1[0][2] = m2[0][2];
- m1[1][0] = m2[1][0];
- m1[1][1] = m2[1][1];
- m1[1][2] = m2[1][2];
+ m1[1][0] = m2[1][0];
+ m1[1][1] = m2[1][1];
+ m1[1][2] = m2[1][2];
- m1[2][0] = m2[2][0];
- m1[2][1] = m2[2][1];
- m1[2][2] = m2[2][2];
+ m1[2][0] = m2[2][0];
+ m1[2][1] = m2[2][1];
+ m1[2][2] = m2[2][2];
}
void copy_m4_m3(float m1[4][4], const float m2[3][3]) /* no clear */
{
- m1[0][0] = m2[0][0];
- m1[0][1] = m2[0][1];
- m1[0][2] = m2[0][2];
-
- m1[1][0] = m2[1][0];
- m1[1][1] = m2[1][1];
- m1[1][2] = m2[1][2];
+ m1[0][0] = m2[0][0];
+ m1[0][1] = m2[0][1];
+ m1[0][2] = m2[0][2];
- m1[2][0] = m2[2][0];
- m1[2][1] = m2[2][1];
- m1[2][2] = m2[2][2];
+ m1[1][0] = m2[1][0];
+ m1[1][1] = m2[1][1];
+ m1[1][2] = m2[1][2];
- /* Reevan's Bugfix */
- m1[0][3] = 0.0f;
- m1[1][3] = 0.0f;
- m1[2][3] = 0.0f;
+ m1[2][0] = m2[2][0];
+ m1[2][1] = m2[2][1];
+ m1[2][2] = m2[2][2];
- m1[3][0] = 0.0f;
- m1[3][1] = 0.0f;
- m1[3][2] = 0.0f;
- m1[3][3] = 1.0f;
+ /* Reevan's Bugfix */
+ m1[0][3] = 0.0f;
+ m1[1][3] = 0.0f;
+ m1[2][3] = 0.0f;
+ m1[3][0] = 0.0f;
+ m1[3][1] = 0.0f;
+ m1[3][2] = 0.0f;
+ m1[3][3] = 1.0f;
}
void copy_m3_m3d(float R[3][3], const double A[3][3])
{
- /* Keep it stupid simple for better data flow in CPU. */
- R[0][0] = (float)A[0][0];
- R[0][1] = (float)A[0][1];
- R[0][2] = (float)A[0][2];
+ /* Keep it stupid simple for better data flow in CPU. */
+ R[0][0] = (float)A[0][0];
+ R[0][1] = (float)A[0][1];
+ R[0][2] = (float)A[0][2];
- R[1][0] = (float)A[1][0];
- R[1][1] = (float)A[1][1];
- R[1][2] = (float)A[1][2];
+ R[1][0] = (float)A[1][0];
+ R[1][1] = (float)A[1][1];
+ R[1][2] = (float)A[1][2];
- R[2][0] = (float)A[2][0];
- R[2][1] = (float)A[2][1];
- R[2][2] = (float)A[2][2];
+ R[2][0] = (float)A[2][0];
+ R[2][1] = (float)A[2][1];
+ R[2][2] = (float)A[2][2];
}
void swap_m3m3(float m1[3][3], float m2[3][3])
{
- float t;
- int i, j;
+ float t;
+ int i, j;
- for (i = 0; i < 3; i++) {
- for (j = 0; j < 3; j++) {
- t = m1[i][j];
- m1[i][j] = m2[i][j];
- m2[i][j] = t;
- }
- }
+ for (i = 0; i < 3; i++) {
+ for (j = 0; j < 3; j++) {
+ t = m1[i][j];
+ m1[i][j] = m2[i][j];
+ m2[i][j] = t;
+ }
+ }
}
void swap_m4m4(float m1[4][4], float m2[4][4])
{
- float t;
- int i, j;
+ float t;
+ int i, j;
- for (i = 0; i < 4; i++) {
- for (j = 0; j < 4; j++) {
- t = m1[i][j];
- m1[i][j] = m2[i][j];
- m2[i][j] = t;
- }
- }
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ t = m1[i][j];
+ m1[i][j] = m2[i][j];
+ m2[i][j] = t;
+ }
+ }
}
/******************************** Arithmetic *********************************/
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
{
- if (A == R) {
- mul_m4_m4_post(R, B);
- }
- else if (B == R) {
- mul_m4_m4_pre(R, A);
- }
- else {
- mul_m4_m4m4_uniq(R, A, B);
- }
+ if (A == R) {
+ mul_m4_m4_post(R, B);
+ }
+ else if (B == R) {
+ mul_m4_m4_pre(R, A);
+ }
+ else {
+ mul_m4_m4m4_uniq(R, A, B);
+ }
}
void mul_m4_m4m4_uniq(float R[4][4], const float A[4][4], const float B[4][4])
{
- BLI_assert(R != A && R != B);
+ BLI_assert(R != A && R != B);
- /* matrix product: R[j][k] = A[j][i] . B[i][k] */
+ /* matrix product: R[j][k] = A[j][i] . B[i][k] */
#ifdef __SSE2__
- __m128 A0 = _mm_loadu_ps(A[0]);
- __m128 A1 = _mm_loadu_ps(A[1]);
- __m128 A2 = _mm_loadu_ps(A[2]);
- __m128 A3 = _mm_loadu_ps(A[3]);
-
- for (int i = 0; i < 4; i++) {
- __m128 B0 = _mm_set1_ps(B[i][0]);
- __m128 B1 = _mm_set1_ps(B[i][1]);
- __m128 B2 = _mm_set1_ps(B[i][2]);
- __m128 B3 = _mm_set1_ps(B[i][3]);
-
- __m128 sum = _mm_add_ps(
- _mm_add_ps(_mm_mul_ps(B0, A0), _mm_mul_ps(B1, A1)),
- _mm_add_ps(_mm_mul_ps(B2, A2), _mm_mul_ps(B3, A3)));
-
- _mm_storeu_ps(R[i], sum);
- }
+ __m128 A0 = _mm_loadu_ps(A[0]);
+ __m128 A1 = _mm_loadu_ps(A[1]);
+ __m128 A2 = _mm_loadu_ps(A[2]);
+ __m128 A3 = _mm_loadu_ps(A[3]);
+
+ for (int i = 0; i < 4; i++) {
+ __m128 B0 = _mm_set1_ps(B[i][0]);
+ __m128 B1 = _mm_set1_ps(B[i][1]);
+ __m128 B2 = _mm_set1_ps(B[i][2]);
+ __m128 B3 = _mm_set1_ps(B[i][3]);
+
+ __m128 sum = _mm_add_ps(_mm_add_ps(_mm_mul_ps(B0, A0), _mm_mul_ps(B1, A1)),
+ _mm_add_ps(_mm_mul_ps(B2, A2), _mm_mul_ps(B3, A3)));
+
+ _mm_storeu_ps(R[i], sum);
+ }
#else
- R[0][0] = B[0][0] * A[0][0] + B[0][1] * A[1][0] + B[0][2] * A[2][0] + B[0][3] * A[3][0];
- R[0][1] = B[0][0] * A[0][1] + B[0][1] * A[1][1] + B[0][2] * A[2][1] + B[0][3] * A[3][1];
- R[0][2] = B[0][0] * A[0][2] + B[0][1] * A[1][2] + B[0][2] * A[2][2] + B[0][3] * A[3][2];
- R[0][3] = B[0][0] * A[0][3] + B[0][1] * A[1][3] + B[0][2] * A[2][3] + B[0][3] * A[3][3];
-
- R[1][0] = B[1][0] * A[0][0] + B[1][1] * A[1][0] + B[1][2] * A[2][0] + B[1][3] * A[3][0];
- R[1][1] = B[1][0] * A[0][1] + B[1][1] * A[1][1] + B[1][2] * A[2][1] + B[1][3] * A[3][1];
- R[1][2] = B[1][0] * A[0][2] + B[1][1] * A[1][2] + B[1][2] * A[2][2] + B[1][3] * A[3][2];
- R[1][3] = B[1][0] * A[0][3] + B[1][1] * A[1][3] + B[1][2] * A[2][3] + B[1][3] * A[3][3];
-
- R[2][0] = B[2][0] * A[0][0] + B[2][1] * A[1][0] + B[2][2] * A[2][0] + B[2][3] * A[3][0];
- R[2][1] = B[2][0] * A[0][1] + B[2][1] * A[1][1] + B[2][2] * A[2][1] + B[2][3] * A[3][1];
- R[2][2] = B[2][0] * A[0][2] + B[2][1] * A[1][2] + B[2][2] * A[2][2] + B[2][3] * A[3][2];
- R[2][3] = B[2][0] * A[0][3] + B[2][1] * A[1][3] + B[2][2] * A[2][3] + B[2][3] * A[3][3];
-
- R[3][0] = B[3][0] * A[0][0] + B[3][1] * A[1][0] + B[3][2] * A[2][0] + B[3][3] * A[3][0];
- R[3][1] = B[3][0] * A[0][1] + B[3][1] * A[1][1] + B[3][2] * A[2][1] + B[3][3] * A[3][1];
- R[3][2] = B[3][0] * A[0][2] + B[3][1] * A[1][2] + B[3][2] * A[2][2] + B[3][3] * A[3][2];
- R[3][3] = B[3][0] * A[0][3] + B[3][1] * A[1][3] + B[3][2] * A[2][3] + B[3][3] * A[3][3];
+ R[0][0] = B[0][0] * A[0][0] + B[0][1] * A[1][0] + B[0][2] * A[2][0] + B[0][3] * A[3][0];
+ R[0][1] = B[0][0] * A[0][1] + B[0][1] * A[1][1] + B[0][2] * A[2][1] + B[0][3] * A[3][1];
+ R[0][2] = B[0][0] * A[0][2] + B[0][1] * A[1][2] + B[0][2] * A[2][2] + B[0][3] * A[3][2];
+ R[0][3] = B[0][0] * A[0][3] + B[0][1] * A[1][3] + B[0][2] * A[2][3] + B[0][3] * A[3][3];
+
+ R[1][0] = B[1][0] * A[0][0] + B[1][1] * A[1][0] + B[1][2] * A[2][0] + B[1][3] * A[3][0];
+ R[1][1] = B[1][0] * A[0][1] + B[1][1] * A[1][1] + B[1][2] * A[2][1] + B[1][3] * A[3][1];
+ R[1][2] = B[1][0] * A[0][2] + B[1][1] * A[1][2] + B[1][2] * A[2][2] + B[1][3] * A[3][2];
+ R[1][3] = B[1][0] * A[0][3] + B[1][1] * A[1][3] + B[1][2] * A[2][3] + B[1][3] * A[3][3];
+
+ R[2][0] = B[2][0] * A[0][0] + B[2][1] * A[1][0] + B[2][2] * A[2][0] + B[2][3] * A[3][0];
+ R[2][1] = B[2][0] * A[0][1] + B[2][1] * A[1][1] + B[2][2] * A[2][1] + B[2][3] * A[3][1];
+ R[2][2] = B[2][0] * A[0][2] + B[2][1] * A[1][2] + B[2][2] * A[2][2] + B[2][3] * A[3][2];
+ R[2][3] = B[2][0] * A[0][3] + B[2][1] * A[1][3] + B[2][2] * A[2][3] + B[2][3] * A[3][3];
+
+ R[3][0] = B[3][0] * A[0][0] + B[3][1] * A[1][0] + B[3][2] * A[2][0] + B[3][3] * A[3][0];
+ R[3][1] = B[3][0] * A[0][1] + B[3][1] * A[1][1] + B[3][2] * A[2][1] + B[3][3] * A[3][1];
+ R[3][2] = B[3][0] * A[0][2] + B[3][1] * A[1][2] + B[3][2] * A[2][2] + B[3][3] * A[3][2];
+ R[3][3] = B[3][0] * A[0][3] + B[3][1] * A[1][3] + B[3][2] * A[2][3] + B[3][3] * A[3][3];
#endif
}
void mul_m4_m4_pre(float R[4][4], const float A[4][4])
{
- BLI_assert(A != R);
- float B[4][4];
- copy_m4_m4(B, R);
- mul_m4_m4m4_uniq(R, A, B);
+ BLI_assert(A != R);
+ float B[4][4];
+ copy_m4_m4(B, R);
+ mul_m4_m4m4_uniq(R, A, B);
}
void mul_m4_m4_post(float R[4][4], const float B[4][4])
{
- BLI_assert(B != R);
- float A[4][4];
- copy_m4_m4(A, R);
- mul_m4_m4m4_uniq(R, A, B);
+ BLI_assert(B != R);
+ float A[4][4];
+ copy_m4_m4(A, R);
+ mul_m4_m4m4_uniq(R, A, B);
}
void mul_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3])
{
- if (A == R) {
- mul_m3_m3_post(R, B);
- }
- else if (B == R) {
- mul_m3_m3_pre(R, A);
- }
- else {
- mul_m3_m3m3_uniq(R, A, B);
- }
+ if (A == R) {
+ mul_m3_m3_post(R, B);
+ }
+ else if (B == R) {
+ mul_m3_m3_pre(R, A);
+ }
+ else {
+ mul_m3_m3m3_uniq(R, A, B);
+ }
}
void mul_m3_m3_pre(float R[3][3], const float A[3][3])
{
- BLI_assert(A != R);
- float B[3][3];
- copy_m3_m3(B, R);
- mul_m3_m3m3_uniq(R, A, B);
+ BLI_assert(A != R);
+ float B[3][3];
+ copy_m3_m3(B, R);
+ mul_m3_m3m3_uniq(R, A, B);
}
void mul_m3_m3_post(float R[3][3], const float B[3][3])
{
- BLI_assert(B != R);
- float A[3][3];
- copy_m3_m3(A, R);
- mul_m3_m3m3_uniq(R, A, B);
+ BLI_assert(B != R);
+ float A[3][3];
+ copy_m3_m3(A, R);
+ mul_m3_m3m3_uniq(R, A, B);
}
void mul_m3_m3m3_uniq(float R[3][3], const float A[3][3], const float B[3][3])
{
- BLI_assert(R != A && R != B);
+ BLI_assert(R != A && R != B);
- R[0][0] = B[0][0] * A[0][0] + B[0][1] * A[1][0] + B[0][2] * A[2][0];
- R[0][1] = B[0][0] * A[0][1] + B[0][1] * A[1][1] + B[0][2] * A[2][1];
- R[0][2] = B[0][0] * A[0][2] + B[0][1] * A[1][2] + B[0][2] * A[2][2];
+ R[0][0] = B[0][0] * A[0][0] + B[0][1] * A[1][0] + B[0][2] * A[2][0];
+ R[0][1] = B[0][0] * A[0][1] + B[0][1] * A[1][1] + B[0][2] * A[2][1];
+ R[0][2] = B[0][0] * A[0][2] + B[0][1] * A[1][2] + B[0][2] * A[2][2];
- R[1][0] = B[1][0] * A[0][0] + B[1][1] * A[1][0] + B[1][2] * A[2][0];
- R[1][1] = B[1][0] * A[0][1] + B[1][1] * A[1][1] + B[1][2] * A[2][1];
- R[1][2] = B[1][0] * A[0][2] + B[1][1] * A[1][2] + B[1][2] * A[2][2];
+ R[1][0] = B[1][0] * A[0][0] + B[1][1] * A[1][0] + B[1][2] * A[2][0];
+ R[1][1] = B[1][0] * A[0][1] + B[1][1] * A[1][1] + B[1][2] * A[2][1];
+ R[1][2] = B[1][0] * A[0][2] + B[1][1] * A[1][2] + B[1][2] * A[2][2];
- R[2][0] = B[2][0] * A[0][0] + B[2][1] * A[1][0] + B[2][2] * A[2][0];
- R[2][1] = B[2][0] * A[0][1] + B[2][1] * A[1][1] + B[2][2] * A[2][1];
- R[2][2] = B[2][0] * A[0][2] + B[2][1] * A[1][2] + B[2][2] * A[2][2];
+ R[2][0] = B[2][0] * A[0][0] + B[2][1] * A[1][0] + B[2][2] * A[2][0];
+ R[2][1] = B[2][0] * A[0][1] + B[2][1] * A[1][1] + B[2][2] * A[2][1];
+ R[2][2] = B[2][0] * A[0][2] + B[2][1] * A[1][2] + B[2][2] * A[2][2];
}
void mul_m4_m4m3(float m1[4][4], const float m3_[4][4], const float m2_[3][3])
{
- float m2[3][3], m3[4][4];
+ float m2[3][3], m3[4][4];
- /* copy so it works when m1 is the same pointer as m2 or m3 */
- /* TODO: avoid copying when matrices are different */
- copy_m3_m3(m2, m2_);
- copy_m4_m4(m3, m3_);
+ /* copy so it works when m1 is the same pointer as m2 or m3 */
+ /* TODO: avoid copying when matrices are different */
+ copy_m3_m3(m2, m2_);
+ copy_m4_m4(m3, m3_);
- m1[0][0] = m2[0][0] * m3[0][0] + m2[0][1] * m3[1][0] + m2[0][2] * m3[2][0];
- m1[0][1] = m2[0][0] * m3[0][1] + m2[0][1] * m3[1][1] + m2[0][2] * m3[2][1];
- m1[0][2] = m2[0][0] * m3[0][2] + m2[0][1] * m3[1][2] + m2[0][2] * m3[2][2];
- m1[1][0] = m2[1][0] * m3[0][0] + m2[1][1] * m3[1][0] + m2[1][2] * m3[2][0];
- m1[1][1] = m2[1][0] * m3[0][1] + m2[1][1] * m3[1][1] + m2[1][2] * m3[2][1];
- m1[1][2] = m2[1][0] * m3[0][2] + m2[1][1] * m3[1][2] + m2[1][2] * m3[2][2];
- m1[2][0] = m2[2][0] * m3[0][0] + m2[2][1] * m3[1][0] + m2[2][2] * m3[2][0];
- m1[2][1] = m2[2][0] * m3[0][1] + m2[2][1] * m3[1][1] + m2[2][2] * m3[2][1];
- m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2];
+ m1[0][0] = m2[0][0] * m3[0][0] + m2[0][1] * m3[1][0] + m2[0][2] * m3[2][0];
+ m1[0][1] = m2[0][0] * m3[0][1] + m2[0][1] * m3[1][1] + m2[0][2] * m3[2][1];
+ m1[0][2] = m2[0][0] * m3[0][2] + m2[0][1] * m3[1][2] + m2[0][2] * m3[2][2];
+ m1[1][0] = m2[1][0] * m3[0][0] + m2[1][1] * m3[1][0] + m2[1][2] * m3[2][0];
+ m1[1][1] = m2[1][0] * m3[0][1] + m2[1][1] * m3[1][1] + m2[1][2] * m3[2][1];
+ m1[1][2] = m2[1][0] * m3[0][2] + m2[1][1] * m3[1][2] + m2[1][2] * m3[2][2];
+ m1[2][0] = m2[2][0] * m3[0][0] + m2[2][1] * m3[1][0] + m2[2][2] * m3[2][0];
+ m1[2][1] = m2[2][0] * m3[0][1] + m2[2][1] * m3[1][1] + m2[2][2] * m3[2][1];
+ m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2];
}
/* m1 = m2 * m3, ignore the elements on the 4th row/column of m2 */
void mul_m3_m3m4(float m1[3][3], const float m3_[3][3], const float m2_[4][4])
{
- float m2[4][4], m3[3][3];
+ float m2[4][4], m3[3][3];
- /* copy so it works when m1 is the same pointer as m2 or m3 */
- /* TODO: avoid copying when matrices are different */
- copy_m4_m4(m2, m2_);
- copy_m3_m3(m3, m3_);
+ /* copy so it works when m1 is the same pointer as m2 or m3 */
+ /* TODO: avoid copying when matrices are different */
+ copy_m4_m4(m2, m2_);
+ copy_m3_m3(m3, m3_);
- /* m1[i][j] = m2[i][k] * m3[k][j] */
- m1[0][0] = m2[0][0] * m3[0][0] + m2[0][1] * m3[1][0] + m2[0][2] * m3[2][0];
- m1[0][1] = m2[0][0] * m3[0][1] + m2[0][1] * m3[1][1] + m2[0][2] * m3[2][1];
- m1[0][2] = m2[0][0] * m3[0][2] + m2[0][1] * m3[1][2] + m2[0][2] * m3[2][2];
+ /* m1[i][j] = m2[i][k] * m3[k][j] */
+ m1[0][0] = m2[0][0] * m3[0][0] + m2[0][1] * m3[1][0] + m2[0][2] * m3[2][0];
+ m1[0][1] = m2[0][0] * m3[0][1] + m2[0][1] * m3[1][1] + m2[0][2] * m3[2][1];
+ m1[0][2] = m2[0][0] * m3[0][2] + m2[0][1] * m3[1][2] + m2[0][2] * m3[2][2];
- m1[1][0] = m2[1][0] * m3[0][0] + m2[1][1] * m3[1][0] + m2[1][2] * m3[2][0];
- m1[1][1] = m2[1][0] * m3[0][1] + m2[1][1] * m3[1][1] + m2[1][2] * m3[2][1];
- m1[1][2] = m2[1][0] * m3[0][2] + m2[1][1] * m3[1][2] + m2[1][2] * m3[2][2];
+ m1[1][0] = m2[1][0] * m3[0][0] + m2[1][1] * m3[1][0] + m2[1][2] * m3[2][0];
+ m1[1][1] = m2[1][0] * m3[0][1] + m2[1][1] * m3[1][1] + m2[1][2] * m3[2][1];
+ m1[1][2] = m2[1][0] * m3[0][2] + m2[1][1] * m3[1][2] + m2[1][2] * m3[2][2];
- m1[2][0] = m2[2][0] * m3[0][0] + m2[2][1] * m3[1][0] + m2[2][2] * m3[2][0];
- m1[2][1] = m2[2][0] * m3[0][1] + m2[2][1] * m3[1][1] + m2[2][2] * m3[2][1];
- m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2];
+ m1[2][0] = m2[2][0] * m3[0][0] + m2[2][1] * m3[1][0] + m2[2][2] * m3[2][0];
+ m1[2][1] = m2[2][0] * m3[0][1] + m2[2][1] * m3[1][1] + m2[2][2] * m3[2][1];
+ m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2];
}
/* m1 = m2 * m3, ignore the elements on the 4th row/column of m3 */
void mul_m3_m4m3(float m1[3][3], const float m3_[4][4], const float m2_[3][3])
{
- float m2[3][3], m3[4][4];
+ float m2[3][3], m3[4][4];
- /* copy so it works when m1 is the same pointer as m2 or m3 */
- /* TODO: avoid copying when matrices are different */
- copy_m3_m3(m2, m2_);
- copy_m4_m4(m3, m3_);
+ /* copy so it works when m1 is the same pointer as m2 or m3 */
+ /* TODO: avoid copying when matrices are different */
+ copy_m3_m3(m2, m2_);
+ copy_m4_m4(m3, m3_);
- /* m1[i][j] = m2[i][k] * m3[k][j] */
- m1[0][0] = m2[0][0] * m3[0][0] + m2[0][1] * m3[1][0] + m2[0][2] * m3[2][0];
- m1[0][1] = m2[0][0] * m3[0][1] + m2[0][1] * m3[1][1] + m2[0][2] * m3[2][1];
- m1[0][2] = m2[0][0] * m3[0][2] + m2[0][1] * m3[1][2] + m2[0][2] * m3[2][2];
+ /* m1[i][j] = m2[i][k] * m3[k][j] */
+ m1[0][0] = m2[0][0] * m3[0][0] + m2[0][1] * m3[1][0] + m2[0][2] * m3[2][0];
+ m1[0][1] = m2[0][0] * m3[0][1] + m2[0][1] * m3[1][1] + m2[0][2] * m3[2][1];
+ m1[0][2] = m2[0][0] * m3[0][2] + m2[0][1] * m3[1][2] + m2[0][2] * m3[2][2];
- m1[1][0] = m2[1][0] * m3[0][0] + m2[1][1] * m3[1][0] + m2[1][2] * m3[2][0];
- m1[1][1] = m2[1][0] * m3[0][1] + m2[1][1] * m3[1][1] + m2[1][2] * m3[2][1];
- m1[1][2] = m2[1][0] * m3[0][2] + m2[1][1] * m3[1][2] + m2[1][2] * m3[2][2];
+ m1[1][0] = m2[1][0] * m3[0][0] + m2[1][1] * m3[1][0] + m2[1][2] * m3[2][0];
+ m1[1][1] = m2[1][0] * m3[0][1] + m2[1][1] * m3[1][1] + m2[1][2] * m3[2][1];
+ m1[1][2] = m2[1][0] * m3[0][2] + m2[1][1] * m3[1][2] + m2[1][2] * m3[2][2];
- m1[2][0] = m2[2][0] * m3[0][0] + m2[2][1] * m3[1][0] + m2[2][2] * m3[2][0];
- m1[2][1] = m2[2][0] * m3[0][1] + m2[2][1] * m3[1][1] + m2[2][2] * m3[2][1];
- m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2];
+ m1[2][0] = m2[2][0] * m3[0][0] + m2[2][1] * m3[1][0] + m2[2][2] * m3[2][0];
+ m1[2][1] = m2[2][0] * m3[0][1] + m2[2][1] * m3[1][1] + m2[2][2] * m3[2][1];
+ m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2];
}
void mul_m4_m3m4(float m1[4][4], const float m3_[3][3], const float m2_[4][4])
{
- float m2[4][4], m3[3][3];
+ float m2[4][4], m3[3][3];
- /* copy so it works when m1 is the same pointer as m2 or m3 */
- /* TODO: avoid copying when matrices are different */
- copy_m4_m4(m2, m2_);
- copy_m3_m3(m3, m3_);
+ /* copy so it works when m1 is the same pointer as m2 or m3 */
+ /* TODO: avoid copying when matrices are different */
+ copy_m4_m4(m2, m2_);
+ copy_m3_m3(m3, m3_);
- m1[0][0] = m2[0][0] * m3[0][0] + m2[0][1] * m3[1][0] + m2[0][2] * m3[2][0];
- m1[0][1] = m2[0][0] * m3[0][1] + m2[0][1] * m3[1][1] + m2[0][2] * m3[2][1];
- m1[0][2] = m2[0][0] * m3[0][2] + m2[0][1] * m3[1][2] + m2[0][2] * m3[2][2];
- m1[1][0] = m2[1][0] * m3[0][0] + m2[1][1] * m3[1][0] + m2[1][2] * m3[2][0];
- m1[1][1] = m2[1][0] * m3[0][1] + m2[1][1] * m3[1][1] + m2[1][2] * m3[2][1];
- m1[1][2] = m2[1][0] * m3[0][2] + m2[1][1] * m3[1][2] + m2[1][2] * m3[2][2];
- m1[2][0] = m2[2][0] * m3[0][0] + m2[2][1] * m3[1][0] + m2[2][2] * m3[2][0];
- m1[2][1] = m2[2][0] * m3[0][1] + m2[2][1] * m3[1][1] + m2[2][2] * m3[2][1];
- m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2];
+ m1[0][0] = m2[0][0] * m3[0][0] + m2[0][1] * m3[1][0] + m2[0][2] * m3[2][0];
+ m1[0][1] = m2[0][0] * m3[0][1] + m2[0][1] * m3[1][1] + m2[0][2] * m3[2][1];
+ m1[0][2] = m2[0][0] * m3[0][2] + m2[0][1] * m3[1][2] + m2[0][2] * m3[2][2];
+ m1[1][0] = m2[1][0] * m3[0][0] + m2[1][1] * m3[1][0] + m2[1][2] * m3[2][0];
+ m1[1][1] = m2[1][0] * m3[0][1] + m2[1][1] * m3[1][1] + m2[1][2] * m3[2][1];
+ m1[1][2] = m2[1][0] * m3[0][2] + m2[1][1] * m3[1][2] + m2[1][2] * m3[2][2];
+ m1[2][0] = m2[2][0] * m3[0][0] + m2[2][1] * m3[1][0] + m2[2][2] * m3[2][0];
+ m1[2][1] = m2[2][0] * m3[0][1] + m2[2][1] * m3[1][1] + m2[2][2] * m3[2][1];
+ m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2];
}
void mul_m3_m4m4(float m1[3][3], const float m3[4][4], const float m2[4][4])
{
- m1[0][0] = m2[0][0] * m3[0][0] + m2[0][1] * m3[1][0] + m2[0][2] * m3[2][0];
- m1[0][1] = m2[0][0] * m3[0][1] + m2[0][1] * m3[1][1] + m2[0][2] * m3[2][1];
- m1[0][2] = m2[0][0] * m3[0][2] + m2[0][1] * m3[1][2] + m2[0][2] * m3[2][2];
- m1[1][0] = m2[1][0] * m3[0][0] + m2[1][1] * m3[1][0] + m2[1][2] * m3[2][0];
- m1[1][1] = m2[1][0] * m3[0][1] + m2[1][1] * m3[1][1] + m2[1][2] * m3[2][1];
- m1[1][2] = m2[1][0] * m3[0][2] + m2[1][1] * m3[1][2] + m2[1][2] * m3[2][2];
- m1[2][0] = m2[2][0] * m3[0][0] + m2[2][1] * m3[1][0] + m2[2][2] * m3[2][0];
- m1[2][1] = m2[2][0] * m3[0][1] + m2[2][1] * m3[1][1] + m2[2][2] * m3[2][1];
- m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2];
+ m1[0][0] = m2[0][0] * m3[0][0] + m2[0][1] * m3[1][0] + m2[0][2] * m3[2][0];
+ m1[0][1] = m2[0][0] * m3[0][1] + m2[0][1] * m3[1][1] + m2[0][2] * m3[2][1];
+ m1[0][2] = m2[0][0] * m3[0][2] + m2[0][1] * m3[1][2] + m2[0][2] * m3[2][2];
+ m1[1][0] = m2[1][0] * m3[0][0] + m2[1][1] * m3[1][0] + m2[1][2] * m3[2][0];
+ m1[1][1] = m2[1][0] * m3[0][1] + m2[1][1] * m3[1][1] + m2[1][2] * m3[2][1];
+ m1[1][2] = m2[1][0] * m3[0][2] + m2[1][1] * m3[1][2] + m2[1][2] * m3[2][2];
+ m1[2][0] = m2[2][0] * m3[0][0] + m2[2][1] * m3[1][0] + m2[2][2] * m3[2][0];
+ m1[2][1] = m2[2][0] * m3[0][1] + m2[2][1] * m3[1][1] + m2[2][2] * m3[2][1];
+ m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] + m2[2][2] * m3[2][2];
}
/** \name Macro helpers for: mul_m3_series
* \{ */
-void _va_mul_m3_series_3(
- float r[3][3],
- const float m1[3][3], const float m2[3][3])
-{
- mul_m3_m3m3(r, m1, m2);
-}
-void _va_mul_m3_series_4(
- float r[3][3],
- const float m1[3][3], const float m2[3][3], const float m3[3][3])
-{
- mul_m3_m3m3(r, m1, m2);
- mul_m3_m3m3(r, r, m3);
-}
-void _va_mul_m3_series_5(
- float r[3][3],
- const float m1[3][3], const float m2[3][3], const float m3[3][3], const float m4[3][3])
-{
- mul_m3_m3m3(r, m1, m2);
- mul_m3_m3m3(r, r, m3);
- mul_m3_m3m3(r, r, m4);
-}
-void _va_mul_m3_series_6(
- float r[3][3],
- const float m1[3][3], const float m2[3][3], const float m3[3][3], const float m4[3][3],
- const float m5[3][3])
-{
- mul_m3_m3m3(r, m1, m2);
- mul_m3_m3m3(r, r, m3);
- mul_m3_m3m3(r, r, m4);
- mul_m3_m3m3(r, r, m5);
-}
-void _va_mul_m3_series_7(
- float r[3][3],
- const float m1[3][3], const float m2[3][3], const float m3[3][3], const float m4[3][3],
- const float m5[3][3], const float m6[3][3])
-{
- mul_m3_m3m3(r, m1, m2);
- mul_m3_m3m3(r, r, m3);
- mul_m3_m3m3(r, r, m4);
- mul_m3_m3m3(r, r, m5);
- mul_m3_m3m3(r, r, m6);
-}
-void _va_mul_m3_series_8(
- float r[3][3],
- const float m1[3][3], const float m2[3][3], const float m3[3][3], const float m4[3][3],
- const float m5[3][3], const float m6[3][3], const float m7[3][3])
-{
- mul_m3_m3m3(r, m1, m2);
- mul_m3_m3m3(r, r, m3);
- mul_m3_m3m3(r, r, m4);
- mul_m3_m3m3(r, r, m5);
- mul_m3_m3m3(r, r, m6);
- mul_m3_m3m3(r, r, m7);
-}
-void _va_mul_m3_series_9(
- float r[3][3],
- const float m1[3][3], const float m2[3][3], const float m3[3][3], const float m4[3][3],
- const float m5[3][3], const float m6[3][3], const float m7[3][3], const float m8[3][3])
-{
- mul_m3_m3m3(r, m1, m2);
- mul_m3_m3m3(r, r, m3);
- mul_m3_m3m3(r, r, m4);
- mul_m3_m3m3(r, r, m5);
- mul_m3_m3m3(r, r, m6);
- mul_m3_m3m3(r, r, m7);
- mul_m3_m3m3(r, r, m8);
+void _va_mul_m3_series_3(float r[3][3], const float m1[3][3], const float m2[3][3])
+{
+ mul_m3_m3m3(r, m1, m2);
+}
+void _va_mul_m3_series_4(float r[3][3],
+ const float m1[3][3],
+ const float m2[3][3],
+ const float m3[3][3])
+{
+ mul_m3_m3m3(r, m1, m2);
+ mul_m3_m3m3(r, r, m3);
+}
+void _va_mul_m3_series_5(float r[3][3],
+ const float m1[3][3],
+ const float m2[3][3],
+ const float m3[3][3],
+ const float m4[3][3])
+{
+ mul_m3_m3m3(r, m1, m2);
+ mul_m3_m3m3(r, r, m3);
+ mul_m3_m3m3(r, r, m4);
+}
+void _va_mul_m3_series_6(float r[3][3],
+ const float m1[3][3],
+ const float m2[3][3],
+ const float m3[3][3],
+ const float m4[3][3],
+ const float m5[3][3])
+{
+ mul_m3_m3m3(r, m1, m2);
+ mul_m3_m3m3(r, r, m3);
+ mul_m3_m3m3(r, r, m4);
+ mul_m3_m3m3(r, r, m5);
+}
+void _va_mul_m3_series_7(float r[3][3],
+ const float m1[3][3],
+ const float m2[3][3],
+ const float m3[3][3],
+ const float m4[3][3],
+ const float m5[3][3],
+ const float m6[3][3])
+{
+ mul_m3_m3m3(r, m1, m2);
+ mul_m3_m3m3(r, r, m3);
+ mul_m3_m3m3(r, r, m4);
+ mul_m3_m3m3(r, r, m5);
+ mul_m3_m3m3(r, r, m6);
+}
+void _va_mul_m3_series_8(float r[3][3],
+ const float m1[3][3],
+ const float m2[3][3],
+ const float m3[3][3],
+ const float m4[3][3],
+ const float m5[3][3],
+ const float m6[3][3],
+ const float m7[3][3])
+{
+ mul_m3_m3m3(r, m1, m2);
+ mul_m3_m3m3(r, r, m3);
+ mul_m3_m3m3(r, r, m4);
+ mul_m3_m3m3(r, r, m5);
+ mul_m3_m3m3(r, r, m6);
+ mul_m3_m3m3(r, r, m7);
+}
+void _va_mul_m3_series_9(float r[3][3],
+ const float m1[3][3],
+ const float m2[3][3],
+ const float m3[3][3],
+ const float m4[3][3],
+ const float m5[3][3],
+ const float m6[3][3],
+ const float m7[3][3],
+ const float m8[3][3])
+{
+ mul_m3_m3m3(r, m1, m2);
+ mul_m3_m3m3(r, r, m3);
+ mul_m3_m3m3(r, r, m4);
+ mul_m3_m3m3(r, r, m5);
+ mul_m3_m3m3(r, r, m6);
+ mul_m3_m3m3(r, r, m7);
+ mul_m3_m3m3(r, r, m8);
}
/** \} */
/** \name Macro helpers for: mul_m4_series
* \{ */
-void _va_mul_m4_series_3(
- float r[4][4],
- const float m1[4][4], const float m2[4][4])
-{
- mul_m4_m4m4(r, m1, m2);
-}
-void _va_mul_m4_series_4(
- float r[4][4],
- const float m1[4][4], const float m2[4][4], const float m3[4][4])
-{
- mul_m4_m4m4(r, m1, m2);
- mul_m4_m4m4(r, r, m3);
-}
-void _va_mul_m4_series_5(
- float r[4][4],
- const float m1[4][4], const float m2[4][4], const float m3[4][4], const float m4[4][4])
-{
- mul_m4_m4m4(r, m1, m2);
- mul_m4_m4m4(r, r, m3);
- mul_m4_m4m4(r, r, m4);
-}
-void _va_mul_m4_series_6(
- float r[4][4],
- const float m1[4][4], const float m2[4][4], const float m3[4][4], const float m4[4][4],
- const float m5[4][4])
-{
- mul_m4_m4m4(r, m1, m2);
- mul_m4_m4m4(r, r, m3);
- mul_m4_m4m4(r, r, m4);
- mul_m4_m4m4(r, r, m5);
-}
-void _va_mul_m4_series_7(
- float r[4][4],
- const float m1[4][4], const float m2[4][4], const float m3[4][4], const float m4[4][4],
- const float m5[4][4], const float m6[4][4])
-{
- mul_m4_m4m4(r, m1, m2);
- mul_m4_m4m4(r, r, m3);
- mul_m4_m4m4(r, r, m4);
- mul_m4_m4m4(r, r, m5);
- mul_m4_m4m4(r, r, m6);
-}
-void _va_mul_m4_series_8(
- float r[4][4],
- const float m1[4][4], const float m2[4][4], const float m3[4][4], const float m4[4][4],
- const float m5[4][4], const float m6[4][4], const float m7[4][4])
-{
- mul_m4_m4m4(r, m1, m2);
- mul_m4_m4m4(r, r, m3);
- mul_m4_m4m4(r, r, m4);
- mul_m4_m4m4(r, r, m5);
- mul_m4_m4m4(r, r, m6);
- mul_m4_m4m4(r, r, m7);
-}
-void _va_mul_m4_series_9(
- float r[4][4],
- const float m1[4][4], const float m2[4][4], const float m3[4][4], const float m4[4][4],
- const float m5[4][4], const float m6[4][4], const float m7[4][4], const float m8[4][4])
-{
- mul_m4_m4m4(r, m1, m2);
- mul_m4_m4m4(r, r, m3);
- mul_m4_m4m4(r, r, m4);
- mul_m4_m4m4(r, r, m5);
- mul_m4_m4m4(r, r, m6);
- mul_m4_m4m4(r, r, m7);
- mul_m4_m4m4(r, r, m8);
+void _va_mul_m4_series_3(float r[4][4], const float m1[4][4], const float m2[4][4])
+{
+ mul_m4_m4m4(r, m1, m2);
+}
+void _va_mul_m4_series_4(float r[4][4],
+ const float m1[4][4],
+ const float m2[4][4],
+ const float m3[4][4])
+{
+ mul_m4_m4m4(r, m1, m2);
+ mul_m4_m4m4(r, r, m3);
+}
+void _va_mul_m4_series_5(float r[4][4],
+ const float m1[4][4],
+ const float m2[4][4],
+ const float m3[4][4],
+ const float m4[4][4])
+{
+ mul_m4_m4m4(r, m1, m2);
+ mul_m4_m4m4(r, r, m3);
+ mul_m4_m4m4(r, r, m4);
+}
+void _va_mul_m4_series_6(float r[4][4],
+ const float m1[4][4],
+ const float m2[4][4],
+ const float m3[4][4],
+ const float m4[4][4],
+ const float m5[4][4])
+{
+ mul_m4_m4m4(r, m1, m2);
+ mul_m4_m4m4(r, r, m3);
+ mul_m4_m4m4(r, r, m4);
+ mul_m4_m4m4(r, r, m5);
+}
+void _va_mul_m4_series_7(float r[4][4],
+ const float m1[4][4],
+ const float m2[4][4],
+ const float m3[4][4],
+ const float m4[4][4],
+ const float m5[4][4],
+ const float m6[4][4])
+{
+ mul_m4_m4m4(r, m1, m2);
+ mul_m4_m4m4(r, r, m3);
+ mul_m4_m4m4(r, r, m4);
+ mul_m4_m4m4(r, r, m5);
+ mul_m4_m4m4(r, r, m6);
+}
+void _va_mul_m4_series_8(float r[4][4],
+ const float m1[4][4],
+ const float m2[4][4],
+ const float m3[4][4],
+ const float m4[4][4],
+ const float m5[4][4],
+ const float m6[4][4],
+ const float m7[4][4])
+{
+ mul_m4_m4m4(r, m1, m2);
+ mul_m4_m4m4(r, r, m3);
+ mul_m4_m4m4(r, r, m4);
+ mul_m4_m4m4(r, r, m5);
+ mul_m4_m4m4(r, r, m6);
+ mul_m4_m4m4(r, r, m7);
+}
+void _va_mul_m4_series_9(float r[4][4],
+ const float m1[4][4],
+ const float m2[4][4],
+ const float m3[4][4],
+ const float m4[4][4],
+ const float m5[4][4],
+ const float m6[4][4],
+ const float m7[4][4],
+ const float m8[4][4])
+{
+ mul_m4_m4m4(r, m1, m2);
+ mul_m4_m4m4(r, r, m3);
+ mul_m4_m4m4(r, r, m4);
+ mul_m4_m4m4(r, r, m5);
+ mul_m4_m4m4(r, r, m6);
+ mul_m4_m4m4(r, r, m7);
+ mul_m4_m4m4(r, r, m8);
}
/** \} */
void mul_v2_m3v2(float r[2], const float m[3][3], const float v[2])
{
- float temp[3], warped[3];
+ float temp[3], warped[3];
- copy_v2_v2(temp, v);
- temp[2] = 1.0f;
+ copy_v2_v2(temp, v);
+ temp[2] = 1.0f;
- mul_v3_m3v3(warped, m, temp);
+ mul_v3_m3v3(warped, m, temp);
- r[0] = warped[0] / warped[2];
- r[1] = warped[1] / warped[2];
+ r[0] = warped[0] / warped[2];
+ r[1] = warped[1] / warped[2];
}
void mul_m3_v2(const float m[3][3], float r[2])
{
- mul_v2_m3v2(r, m, r);
+ mul_v2_m3v2(r, m, r);
}
void mul_m4_v3(const float mat[4][4], float vec[3])
{
- const float x = vec[0];
- const float y = vec[1];
+ const float x = vec[0];
+ const float y = vec[1];
- vec[0] = x * mat[0][0] + y * mat[1][0] + mat[2][0] * vec[2] + mat[3][0];
- vec[1] = x * mat[0][1] + y * mat[1][1] + mat[2][1] * vec[2] + mat[3][1];
- vec[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2] + mat[3][2];
+ vec[0] = x * mat[0][0] + y * mat[1][0] + mat[2][0] * vec[2] + mat[3][0];
+ vec[1] = x * mat[0][1] + y * mat[1][1] + mat[2][1] * vec[2] + mat[3][1];
+ vec[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2] + mat[3][2];
}
void mul_v3_m4v3(float r[3], const float mat[4][4], const float vec[3])
{
- const float x = vec[0];
- const float y = vec[1];
+ const float x = vec[0];
+ const float y = vec[1];
- r[0] = x * mat[0][0] + y * mat[1][0] + mat[2][0] * vec[2] + mat[3][0];
- r[1] = x * mat[0][1] + y * mat[1][1] + mat[2][1] * vec[2] + mat[3][1];
- r[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2] + mat[3][2];
+ r[0] = x * mat[0][0] + y * mat[1][0] + mat[2][0] * vec[2] + mat[3][0];
+ r[1] = x * mat[0][1] + y * mat[1][1] + mat[2][1] * vec[2] + mat[3][1];
+ r[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2] + mat[3][2];
}
void mul_v2_m4v3(float r[2], const float mat[4][4], const float vec[3])
{
- const float x = vec[0];
+ const float x = vec[0];
- r[0] = x * mat[0][0] + vec[1] * mat[1][0] + mat[2][0] * vec[2] + mat[3][0];
- r[1] = x * mat[0][1] + vec[1] * mat[1][1] + mat[2][1] * vec[2] + mat[3][1];
+ r[0] = x * mat[0][0] + vec[1] * mat[1][0] + mat[2][0] * vec[2] + mat[3][0];
+ r[1] = x * mat[0][1] + vec[1] * mat[1][1] + mat[2][1] * vec[2] + mat[3][1];
}
void mul_v2_m2v2(float r[2], const float mat[2][2], const float vec[2])
{
- const float x = vec[0];
+ const float x = vec[0];
- r[0] = mat[0][0] * x + mat[1][0] * vec[1];
- r[1] = mat[0][1] * x + mat[1][1] * vec[1];
+ r[0] = mat[0][0] * x + mat[1][0] * vec[1];
+ r[1] = mat[0][1] * x + mat[1][1] * vec[1];
}
void mul_m2v2(const float mat[2][2], float vec[2])
{
- mul_v2_m2v2(vec, mat, vec);
+ mul_v2_m2v2(vec, mat, vec);
}
/* same as mul_m4_v3() but doesnt apply translation component */
void mul_mat3_m4_v3(const float mat[4][4], float vec[3])
{
- const float x = vec[0];
- const float y = vec[1];
+ const float x = vec[0];
+ const float y = vec[1];
- vec[0] = x * mat[0][0] + y * mat[1][0] + mat[2][0] * vec[2];
- vec[1] = x * mat[0][1] + y * mat[1][1] + mat[2][1] * vec[2];
- vec[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2];
+ vec[0] = x * mat[0][0] + y * mat[1][0] + mat[2][0] * vec[2];
+ vec[1] = x * mat[0][1] + y * mat[1][1] + mat[2][1] * vec[2];
+ vec[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2];
}
void mul_v3_mat3_m4v3(float r[3], const float mat[4][4], const float vec[3])
{
- const float x = vec[0];
- const float y = vec[1];
+ const float x = vec[0];
+ const float y = vec[1];
- r[0] = x * mat[0][0] + y * mat[1][0] + mat[2][0] * vec[2];
- r[1] = x * mat[0][1] + y * mat[1][1] + mat[2][1] * vec[2];
- r[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2];
+ r[0] = x * mat[0][0] + y * mat[1][0] + mat[2][0] * vec[2];
+ r[1] = x * mat[0][1] + y * mat[1][1] + mat[2][1] * vec[2];
+ r[2] = x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2];
}
void mul_project_m4_v3(const float mat[4][4], float vec[3])
{
- /* absolute value to not flip the frustum upside down behind the camera */
- const float w = fabsf(mul_project_m4_v3_zfac(mat, vec));
- mul_m4_v3(mat, vec);
+ /* absolute value to not flip the frustum upside down behind the camera */
+ const float w = fabsf(mul_project_m4_v3_zfac(mat, vec));
+ mul_m4_v3(mat, vec);
- vec[0] /= w;
- vec[1] /= w;
- vec[2] /= w;
+ vec[0] /= w;
+ vec[1] /= w;
+ vec[2] /= w;
}
void mul_v3_project_m4_v3(float r[3], const float mat[4][4], const float vec[3])
{
- const float w = fabsf(mul_project_m4_v3_zfac(mat, vec));
- mul_v3_m4v3(r, mat, vec);
+ const float w = fabsf(mul_project_m4_v3_zfac(mat, vec));
+ mul_v3_m4v3(r, mat, vec);
- r[0] /= w;
- r[1] /= w;
- r[2] /= w;
+ r[0] /= w;
+ r[1] /= w;
+ r[2] /= w;
}
void mul_v2_project_m4_v3(float r[2], const float mat[4][4], const float vec[3])
{
- const float w = fabsf(mul_project_m4_v3_zfac(mat, vec));
- mul_v2_m4v3(r, mat, vec);
+ const float w = fabsf(mul_project_m4_v3_zfac(mat, vec));
+ mul_v2_m4v3(r, mat, vec);
- r[0] /= w;
- r[1] /= w;
+ r[0] /= w;
+ r[1] /= w;
}
void mul_v4_m4v4(float r[4], const float mat[4][4], const float v[4])
{
- const float x = v[0];
- const float y = v[1];
- const float z = v[2];
+ const float x = v[0];
+ const float y = v[1];
+ const float z = v[2];
- r[0] = x * mat[0][0] + y * mat[1][0] + z * mat[2][0] + mat[3][0] * v[3];
- r[1] = x * mat[0][1] + y * mat[1][1] + z * mat[2][1] + mat[3][1] * v[3];
- r[2] = x * mat[0][2] + y * mat[1][2] + z * mat[2][2] + mat[3][2] * v[3];
- r[3] = x * mat[0][3] + y * mat[1][3] + z * mat[2][3] + mat[3][3] * v[3];
+ r[0] = x * mat[0][0] + y * mat[1][0] + z * mat[2][0] + mat[3][0] * v[3];
+ r[1] = x * mat[0][1] + y * mat[1][1] + z * mat[2][1] + mat[3][1] * v[3];
+ r[2] = x * mat[0][2] + y * mat[1][2] + z * mat[2][2] + mat[3][2] * v[3];
+ r[3] = x * mat[0][3] + y * mat[1][3] + z * mat[2][3] + mat[3][3] * v[3];
}
void mul_m4_v4(const float mat[4][4], float r[4])
{
- mul_v4_m4v4(r, mat, r);
+ mul_v4_m4v4(r, mat, r);
}
void mul_v4d_m4v4d(double r[4], const float mat[4][4], const double v[4])
{
- const double x = v[0];
- const double y = v[1];
- const double z = v[2];
+ const double x = v[0];
+ const double y = v[1];
+ const double z = v[2];
- r[0] = x * (double)mat[0][0] + y * (double)mat[1][0] + z * (double)mat[2][0] + (double)mat[3][0] * v[3];
- r[1] = x * (double)mat[0][1] + y * (double)mat[1][1] + z * (double)mat[2][1] + (double)mat[3][1] * v[3];
- r[2] = x * (double)mat[0][2] + y * (double)mat[1][2] + z * (double)mat[2][2] + (double)mat[3][2] * v[3];
- r[3] = x * (double)mat[0][3] + y * (double)mat[1][3] + z * (double)mat[2][3] + (double)mat[3][3] * v[3];
+ r[0] = x * (double)mat[0][0] + y * (double)mat[1][0] + z * (double)mat[2][0] +
+ (double)mat[3][0] * v[3];
+ r[1] = x * (double)mat[0][1] + y * (double)mat[1][1] + z * (double)mat[2][1] +
+ (double)mat[3][1] * v[3];
+ r[2] = x * (double)mat[0][2] + y * (double)mat[1][2] + z * (double)mat[2][2] +
+ (double)mat[3][2] * v[3];
+ r[3] = x * (double)mat[0][3] + y * (double)mat[1][3] + z * (double)mat[2][3] +
+ (double)mat[3][3] * v[3];
}
void mul_m4_v4d(const float mat[4][4], double r[4])
{
- mul_v4d_m4v4d(r, mat, r);
+ mul_v4d_m4v4d(r, mat, r);
}
void mul_v4_m4v3(float r[4], const float M[4][4], const float v[3])
{
- /* v has implicit w = 1.0f */
- r[0] = v[0] * M[0][0] + v[1] * M[1][0] + M[2][0] * v[2] + M[3][0];
- r[1] = v[0] * M[0][1] + v[1] * M[1][1] + M[2][1] * v[2] + M[3][1];
- r[2] = v[0] * M[0][2] + v[1] * M[1][2] + M[2][2] * v[2] + M[3][2];
- r[3] = v[0] * M[0][3] + v[1] * M[1][3] + M[2][3] * v[2] + M[3][3];
+ /* v has implicit w = 1.0f */
+ r[0] = v[0] * M[0][0] + v[1] * M[1][0] + M[2][0] * v[2] + M[3][0];
+ r[1] = v[0] * M[0][1] + v[1] * M[1][1] + M[2][1] * v[2] + M[3][1];
+ r[2] = v[0] * M[0][2] + v[1] * M[1][2] + M[2][2] * v[2] + M[3][2];
+ r[3] = v[0] * M[0][3] + v[1] * M[1][3] + M[2][3] * v[2] + M[3][3];
}
void mul_v3_m3v3(float r[3], const float M[3][3], const float a[3])
{
- float t[3];
- copy_v3_v3(t, a);
+ float t[3];
+ copy_v3_v3(t, a);
- r[0] = M[0][0] * t[0] + M[1][0] * t[1] + M[2][0] * t[2];
- r[1] = M[0][1] * t[0] + M[1][1] * t[1] + M[2][1] * t[2];
- r[2] = M[0][2] * t[0] + M[1][2] * t[1] + M[2][2] * t[2];
+ r[0] = M[0][0] * t[0] + M[1][0] * t[1] + M[2][0] * t[2];
+ r[1] = M[0][1] * t[0] + M[1][1] * t[1] + M[2][1] * t[2];
+ r[2] = M[0][2] * t[0] + M[1][2] * t[1] + M[2][2] * t[2];
}
void mul_v3_m3v3_db(double r[3], const double M[3][3], const double a[3])
{
- double t[3];
- copy_v3_v3_db(t, a);
+ double t[3];
+ copy_v3_v3_db(t, a);
- r[0] = M[0][0] * t[0] + M[1][0] * t[1] + M[2][0] * t[2];
- r[1] = M[0][1] * t[0] + M[1][1] * t[1] + M[2][1] * t[2];
- r[2] = M[0][2] * t[0] + M[1][2] * t[1] + M[2][2] * t[2];
+ r[0] = M[0][0] * t[0] + M[1][0] * t[1] + M[2][0] * t[2];
+ r[1] = M[0][1] * t[0] + M[1][1] * t[1] + M[2][1] * t[2];
+ r[2] = M[0][2] * t[0] + M[1][2] * t[1] + M[2][2] * t[2];
}
void mul_v2_m3v3(float r[2], const float M[3][3], const float a[3])
{
- float t[3];
- copy_v3_v3(t, a);
+ float t[3];
+ copy_v3_v3(t, a);
- r[0] = M[0][0] * t[0] + M[1][0] * t[1] + M[2][0] * t[2];
- r[1] = M[0][1] * t[0] + M[1][1] * t[1] + M[2][1] * t[2];
+ r[0] = M[0][0] * t[0] + M[1][0] * t[1] + M[2][0] * t[2];
+ r[1] = M[0][1] * t[0] + M[1][1] * t[1] + M[2][1] * t[2];
}
void mul_m3_v3(const float M[3][3], float r[3])
{
- mul_v3_m3v3(r, M, (const float[3]){UNPACK3(r)});
+ mul_v3_m3v3(r, M, (const float[3]){UNPACK3(r)});
}
void mul_m3_v3_db(const double M[3][3], double r[3])
{
- mul_v3_m3v3_db(r, M, (const double[3]){UNPACK3(r)});
+ mul_v3_m3v3_db(r, M, (const double[3]){UNPACK3(r)});
}
void mul_transposed_m3_v3(const float mat[3][3], float vec[3])
{
- const float x = vec[0];
- const float y = vec[1];
+ const float x = vec[0];
+ const float y = vec[1];
- vec[0] = x * mat[0][0] + y * mat[0][1] + mat[0][2] * vec[2];
- vec[1] = x * mat[1][0] + y * mat[1][1] + mat[1][2] * vec[2];
- vec[2] = x * mat[2][0] + y * mat[2][1] + mat[2][2] * vec[2];
+ vec[0] = x * mat[0][0] + y * mat[0][1] + mat[0][2] * vec[2];
+ vec[1] = x * mat[1][0] + y * mat[1][1] + mat[1][2] * vec[2];
+ vec[2] = x * mat[2][0] + y * mat[2][1] + mat[2][2] * vec[2];
}
void mul_transposed_mat3_m4_v3(const float mat[4][4], float vec[3])
{
- const float x = vec[0];
- const float y = vec[1];
+ const float x = vec[0];
+ const float y = vec[1];
- vec[0] = x * mat[0][0] + y * mat[0][1] + mat[0][2] * vec[2];
- vec[1] = x * mat[1][0] + y * mat[1][1] + mat[1][2] * vec[2];
- vec[2] = x * mat[2][0] + y * mat[2][1] + mat[2][2] * vec[2];
+ vec[0] = x * mat[0][0] + y * mat[0][1] + mat[0][2] * vec[2];
+ vec[1] = x * mat[1][0] + y * mat[1][1] + mat[1][2] * vec[2];
+ vec[2] = x * mat[2][0] + y * mat[2][1] + mat[2][2] * vec[2];
}
void mul_m3_fl(float m[3][3], float f)
{
- int i, j;
+ int i, j;
- for (i = 0; i < 3; i++) {
- for (j = 0; j < 3; j++) {
- m[i][j] *= f;
- }
- }
+ for (i = 0; i < 3; i++) {
+ for (j = 0; j < 3; j++) {
+ m[i][j] *= f;
+ }
+ }
}
void mul_m4_fl(float m[4][4], float f)
{
- int i, j;
+ int i, j;
- for (i = 0; i < 4; i++) {
- for (j = 0; j < 4; j++) {
- m[i][j] *= f;
- }
- }
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ m[i][j] *= f;
+ }
+ }
}
void mul_mat3_m4_fl(float m[4][4], float f)
{
- int i, j;
+ int i, j;
- for (i = 0; i < 3; i++) {
- for (j = 0; j < 3; j++) {
- m[i][j] *= f;
- }
- }
+ for (i = 0; i < 3; i++) {
+ for (j = 0; j < 3; j++) {
+ m[i][j] *= f;
+ }
+ }
}
void negate_m3(float m[3][3])
{
- int i, j;
+ int i, j;
- for (i = 0; i < 3; i++) {
- for (j = 0; j < 3; j++) {
- m[i][j] *= -1.0f;
- }
- }
+ for (i = 0; i < 3; i++) {
+ for (j = 0; j < 3; j++) {
+ m[i][j] *= -1.0f;
+ }
+ }
}
void negate_mat3_m4(float m[4][4])
{
- int i, j;
+ int i, j;
- for (i = 0; i < 3; i++) {
- for (j = 0; j < 3; j++) {
- m[i][j] *= -1.0f;
- }
- }
+ 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;
+ int i, j;
- for (i = 0; i < 4; i++) {
- for (j = 0; j < 4; j++) {
- m[i][j] *= -1.0f;
- }
- }
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ m[i][j] *= -1.0f;
+ }
+ }
}
void mul_m3_v3_double(const float mat[3][3], double vec[3])
{
- const double x = vec[0];
- const double y = vec[1];
+ const double x = vec[0];
+ const double y = vec[1];
- vec[0] = x * (double)mat[0][0] + y * (double)mat[1][0] + (double)mat[2][0] * vec[2];
- vec[1] = x * (double)mat[0][1] + y * (double)mat[1][1] + (double)mat[2][1] * vec[2];
- vec[2] = x * (double)mat[0][2] + y * (double)mat[1][2] + (double)mat[2][2] * vec[2];
+ vec[0] = x * (double)mat[0][0] + y * (double)mat[1][0] + (double)mat[2][0] * vec[2];
+ vec[1] = x * (double)mat[0][1] + y * (double)mat[1][1] + (double)mat[2][1] * vec[2];
+ vec[2] = x * (double)mat[0][2] + y * (double)mat[1][2] + (double)mat[2][2] * vec[2];
}
void add_m3_m3m3(float m1[3][3], const float m2[3][3], const float m3[3][3])
{
- int i, j;
+ int i, j;
- for (i = 0; i < 3; i++) {
- for (j = 0; j < 3; j++) {
- m1[i][j] = m2[i][j] + m3[i][j];
- }
- }
+ for (i = 0; i < 3; i++) {
+ for (j = 0; j < 3; j++) {
+ m1[i][j] = m2[i][j] + m3[i][j];
+ }
+ }
}
void add_m4_m4m4(float m1[4][4], const float m2[4][4], const float m3[4][4])
{
- int i, j;
+ int i, j;
- for (i = 0; i < 4; i++) {
- for (j = 0; j < 4; j++) {
- m1[i][j] = m2[i][j] + m3[i][j];
- }
- }
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ m1[i][j] = m2[i][j] + m3[i][j];
+ }
+ }
}
void madd_m3_m3m3fl(float m1[3][3], const float m2[3][3], const float m3[3][3], const float f)
{
- int i, j;
+ int i, j;
- for (i = 0; i < 3; i++) {
- for (j = 0; j < 3; j++) {
- m1[i][j] = m2[i][j] + m3[i][j] * f;
- }
- }
+ for (i = 0; i < 3; i++) {
+ for (j = 0; j < 3; j++) {
+ m1[i][j] = m2[i][j] + m3[i][j] * f;
+ }
+ }
}
void madd_m4_m4m4fl(float m1[4][4], const float m2[4][4], const float m3[4][4], const float f)
{
- int i, j;
+ int i, j;
- for (i = 0; i < 4; i++) {
- for (j = 0; j < 4; j++) {
- m1[i][j] = m2[i][j] + m3[i][j] * f;
- }
- }
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ m1[i][j] = m2[i][j] + m3[i][j] * f;
+ }
+ }
}
void sub_m3_m3m3(float m1[3][3], const float m2[3][3], const float m3[3][3])
{
- int i, j;
+ int i, j;
- for (i = 0; i < 3; i++) {
- for (j = 0; j < 3; j++) {
- m1[i][j] = m2[i][j] - m3[i][j];
- }
- }
+ for (i = 0; i < 3; i++) {
+ for (j = 0; j < 3; j++) {
+ m1[i][j] = m2[i][j] - m3[i][j];
+ }
+ }
}
void sub_m4_m4m4(float m1[4][4], const float m2[4][4], const float m3[4][4])
{
- int i, j;
+ int i, j;
- for (i = 0; i < 4; i++) {
- for (j = 0; j < 4; j++) {
- m1[i][j] = m2[i][j] - m3[i][j];
- }
- }
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < 4; j++) {
+ m1[i][j] = m2[i][j] - m3[i][j];
+ }
+ }
}
float determinant_m3_array(const float m[3][3])
{
- return (m[0][0] * (m[1][1] * m[2][2] - m[1][2] * m[2][1]) -
- m[1][0] * (m[0][1] * m[2][2] - m[0][2] * m[2][1]) +
- m[2][0] * (m[0][1] * m[1][2] - m[0][2] * m[1][1]));
+ return (m[0][0] * (m[1][1] * m[2][2] - m[1][2] * m[2][1]) -
+ m[1][0] * (m[0][1] * m[2][2] - m[0][2] * m[2][1]) +
+ m[2][0] * (m[0][1] * m[1][2] - m[0][2] * m[1][1]));
}
bool invert_m3_ex(float m[3][3], const float epsilon)
{
- float tmp[3][3];
- const bool success = invert_m3_m3_ex(tmp, m, epsilon);
+ float tmp[3][3];
+ const bool success = invert_m3_m3_ex(tmp, m, epsilon);
- copy_m3_m3(m, tmp);
- return success;
+ copy_m3_m3(m, tmp);
+ return success;
}
bool invert_m3_m3_ex(float m1[3][3], const float m2[3][3], const float epsilon)
{
- float det;
- int a, b;
- bool success;
+ float det;
+ int a, b;
+ bool success;
- BLI_assert(epsilon >= 0.0f);
+ BLI_assert(epsilon >= 0.0f);
- /* calc adjoint */
- adjoint_m3_m3(m1, m2);
+ /* calc adjoint */
+ adjoint_m3_m3(m1, m2);
- /* then determinant old matrix! */
- det = determinant_m3_array(m2);
+ /* then determinant old matrix! */
+ det = determinant_m3_array(m2);
- success = (fabsf(det) > epsilon);
+ success = (fabsf(det) > epsilon);
- if (LIKELY(det != 0.0f)) {
- det = 1.0f / det;
- for (a = 0; a < 3; a++) {
- for (b = 0; b < 3; b++) {
- m1[a][b] *= det;
- }
- }
- }
- return success;
+ if (LIKELY(det != 0.0f)) {
+ det = 1.0f / det;
+ for (a = 0; a < 3; a++) {
+ for (b = 0; b < 3; b++) {
+ m1[a][b] *= det;
+ }
+ }
+ }
+ return success;
}
bool invert_m3(float m[3][3])
{
- float tmp[3][3];
- const bool success = invert_m3_m3(tmp, m);
+ float tmp[3][3];
+ const bool success = invert_m3_m3(tmp, m);
- copy_m3_m3(m, tmp);
- return success;
+ copy_m3_m3(m, tmp);
+ return success;
}
bool invert_m3_m3(float m1[3][3], const float m2[3][3])
{
- float det;
- int a, b;
- bool success;
+ float det;
+ int a, b;
+ bool success;
- /* calc adjoint */
- adjoint_m3_m3(m1, m2);
+ /* calc adjoint */
+ adjoint_m3_m3(m1, m2);
- /* then determinant old matrix! */
- det = determinant_m3_array(m2);
+ /* then determinant old matrix! */
+ det = determinant_m3_array(m2);
- success = (det != 0.0f);
+ success = (det != 0.0f);
- if (LIKELY(det != 0.0f)) {
- det = 1.0f / det;
- for (a = 0; a < 3; a++) {
- for (b = 0; b < 3; b++) {
- m1[a][b] *= det;
- }
- }
- }
+ if (LIKELY(det != 0.0f)) {
+ det = 1.0f / det;
+ for (a = 0; a < 3; a++) {
+ for (b = 0; b < 3; b++) {
+ m1[a][b] *= det;
+ }
+ }
+ }
- return success;
+ return success;
}
bool invert_m4(float m[4][4])
{
- float tmp[4][4];
- const bool success = invert_m4_m4(tmp, m);
+ float tmp[4][4];
+ const bool success = invert_m4_m4(tmp, m);
- copy_m4_m4(m, tmp);
- return success;
+ copy_m4_m4(m, tmp);
+ return success;
}
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
{
- /* Use optimized matrix inverse from Eigen, since performance
- * impact of this function is significant in complex rigs. */
- return EIG_invert_m4_m4(inverse, mat);
+ /* Use optimized matrix inverse from Eigen, since performance
+ * impact of this function is significant in complex rigs. */
+ return EIG_invert_m4_m4(inverse, mat);
}
/****************************** Linear Algebra *******************************/
void transpose_m3(float mat[3][3])
{
- float t;
+ float t;
- t = mat[0][1];
- mat[0][1] = mat[1][0];
- mat[1][0] = t;
- t = mat[0][2];
- mat[0][2] = mat[2][0];
- mat[2][0] = t;
- t = mat[1][2];
- mat[1][2] = mat[2][1];
- mat[2][1] = t;
+ t = mat[0][1];
+ mat[0][1] = mat[1][0];
+ mat[1][0] = t;
+ t = mat[0][2];
+ mat[0][2] = mat[2][0];
+ mat[2][0] = t;
+ t = mat[1][2];
+ mat[1][2] = mat[2][1];
+ mat[2][1] = t;
}
void transpose_m3_m3(float rmat[3][3], const float mat[3][3])
{
- BLI_assert(rmat != mat);
+ 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];
+ 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], const float mat[4][4])
{
- BLI_assert(&rmat[0][0] != &mat[0][0]);
+ 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];
+ 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;
+ float t;
- t = mat[0][1];
- mat[0][1] = mat[1][0];
- mat[1][0] = t;
- t = mat[0][2];
- mat[0][2] = mat[2][0];
- mat[2][0] = t;
- t = mat[0][3];
- mat[0][3] = mat[3][0];
- mat[3][0] = t;
+ t = mat[0][1];
+ mat[0][1] = mat[1][0];
+ mat[1][0] = t;
+ t = mat[0][2];
+ mat[0][2] = mat[2][0];
+ mat[2][0] = t;
+ t = mat[0][3];
+ mat[0][3] = mat[3][0];
+ mat[3][0] = t;
- t = mat[1][2];
- mat[1][2] = mat[2][1];
- mat[2][1] = t;
- t = mat[1][3];
- mat[1][3] = mat[3][1];
- mat[3][1] = t;
+ t = mat[1][2];
+ mat[1][2] = mat[2][1];
+ mat[2][1] = t;
+ t = mat[1][3];
+ mat[1][3] = mat[3][1];
+ mat[3][1] = t;
- t = mat[2][3];
- mat[2][3] = mat[3][2];
- mat[3][2] = t;
+ t = mat[2][3];
+ mat[2][3] = mat[3][2];
+ mat[3][2] = t;
}
void transpose_m4_m4(float rmat[4][4], const 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];
+ 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];
}
/* TODO: return bool */
int compare_m4m4(const float mat1[4][4], const float mat2[4][4], float limit)
{
- if (compare_v4v4(mat1[0], mat2[0], limit)) {
- if (compare_v4v4(mat1[1], mat2[1], limit)) {
- if (compare_v4v4(mat1[2], mat2[2], limit)) {
- if (compare_v4v4(mat1[3], mat2[3], limit)) {
- return 1;
- }
- }
- }
- }
- return 0;
+ if (compare_v4v4(mat1[0], mat2[0], limit)) {
+ if (compare_v4v4(mat1[1], mat2[1], limit)) {
+ if (compare_v4v4(mat1[2], mat2[2], limit)) {
+ if (compare_v4v4(mat1[3], mat2[3], limit)) {
+ return 1;
+ }
+ }
+ }
+ }
+ return 0;
}
/**
@@ -1105,86 +1136,86 @@ int compare_m4m4(const float mat1[4][4], const float mat2[4][4], float limit)
*/
void orthogonalize_m3(float mat[3][3], int axis)
{
- float size[3];
- mat3_to_size(size, mat);
- normalize_v3(mat[axis]);
- switch (axis) {
- case 0:
- if (dot_v3v3(mat[0], mat[1]) < 1) {
- cross_v3_v3v3(mat[2], mat[0], mat[1]);
- normalize_v3(mat[2]);
- cross_v3_v3v3(mat[1], mat[2], mat[0]);
- }
- else if (dot_v3v3(mat[0], mat[2]) < 1) {
- cross_v3_v3v3(mat[1], mat[2], mat[0]);
- normalize_v3(mat[1]);
- cross_v3_v3v3(mat[2], mat[0], mat[1]);
- }
- else {
- float vec[3];
-
- vec[0] = mat[0][1];
- vec[1] = mat[0][2];
- vec[2] = mat[0][0];
-
- cross_v3_v3v3(mat[2], mat[0], vec);
- normalize_v3(mat[2]);
- cross_v3_v3v3(mat[1], mat[2], mat[0]);
- }
- break;
- case 1:
- if (dot_v3v3(mat[1], mat[0]) < 1) {
- cross_v3_v3v3(mat[2], mat[0], mat[1]);
- normalize_v3(mat[2]);
- cross_v3_v3v3(mat[0], mat[1], mat[2]);
- }
- else if (dot_v3v3(mat[0], mat[2]) < 1) {
- cross_v3_v3v3(mat[0], mat[1], mat[2]);
- normalize_v3(mat[0]);
- cross_v3_v3v3(mat[2], mat[0], mat[1]);
- }
- else {
- float vec[3];
-
- vec[0] = mat[1][1];
- vec[1] = mat[1][2];
- vec[2] = mat[1][0];
-
- cross_v3_v3v3(mat[0], mat[1], vec);
- normalize_v3(mat[0]);
- cross_v3_v3v3(mat[2], mat[0], mat[1]);
- }
- break;
- case 2:
- if (dot_v3v3(mat[2], mat[0]) < 1) {
- cross_v3_v3v3(mat[1], mat[2], mat[0]);
- normalize_v3(mat[1]);
- cross_v3_v3v3(mat[0], mat[1], mat[2]);
- }
- else if (dot_v3v3(mat[2], mat[1]) < 1) {
- cross_v3_v3v3(mat[0], mat[1], mat[2]);
- normalize_v3(mat[0]);
- cross_v3_v3v3(mat[1], mat[2], mat[0]);
- }
- else {
- float vec[3];
-
- vec[0] = mat[2][1];
- vec[1] = mat[2][2];
- vec[2] = mat[2][0];
-
- cross_v3_v3v3(mat[0], vec, mat[2]);
- normalize_v3(mat[0]);
- cross_v3_v3v3(mat[1], mat[2], mat[0]);
- }
- break;
- default:
- BLI_assert(0);
- break;
- }
- mul_v3_fl(mat[0], size[0]);
- mul_v3_fl(mat[1], size[1]);
- mul_v3_fl(mat[2], size[2]);
+ float size[3];
+ mat3_to_size(size, mat);
+ normalize_v3(mat[axis]);
+ switch (axis) {
+ case 0:
+ if (dot_v3v3(mat[0], mat[1]) < 1) {
+ cross_v3_v3v3(mat[2], mat[0], mat[1]);
+ normalize_v3(mat[2]);
+ cross_v3_v3v3(mat[1], mat[2], mat[0]);
+ }
+ else if (dot_v3v3(mat[0], mat[2]) < 1) {
+ cross_v3_v3v3(mat[1], mat[2], mat[0]);
+ normalize_v3(mat[1]);
+ cross_v3_v3v3(mat[2], mat[0], mat[1]);
+ }
+ else {
+ float vec[3];
+
+ vec[0] = mat[0][1];
+ vec[1] = mat[0][2];
+ vec[2] = mat[0][0];
+
+ cross_v3_v3v3(mat[2], mat[0], vec);
+ normalize_v3(mat[2]);
+ cross_v3_v3v3(mat[1], mat[2], mat[0]);
+ }
+ break;
+ case 1:
+ if (dot_v3v3(mat[1], mat[0]) < 1) {
+ cross_v3_v3v3(mat[2], mat[0], mat[1]);
+ normalize_v3(mat[2]);
+ cross_v3_v3v3(mat[0], mat[1], mat[2]);
+ }
+ else if (dot_v3v3(mat[0], mat[2]) < 1) {
+ cross_v3_v3v3(mat[0], mat[1], mat[2]);
+ normalize_v3(mat[0]);
+ cross_v3_v3v3(mat[2], mat[0], mat[1]);
+ }
+ else {
+ float vec[3];
+
+ vec[0] = mat[1][1];
+ vec[1] = mat[1][2];
+ vec[2] = mat[1][0];
+
+ cross_v3_v3v3(mat[0], mat[1], vec);
+ normalize_v3(mat[0]);
+ cross_v3_v3v3(mat[2], mat[0], mat[1]);
+ }
+ break;
+ case 2:
+ if (dot_v3v3(mat[2], mat[0]) < 1) {
+ cross_v3_v3v3(mat[1], mat[2], mat[0]);
+ normalize_v3(mat[1]);
+ cross_v3_v3v3(mat[0], mat[1], mat[2]);
+ }
+ else if (dot_v3v3(mat[2], mat[1]) < 1) {
+ cross_v3_v3v3(mat[0], mat[1], mat[2]);
+ normalize_v3(mat[0]);
+ cross_v3_v3v3(mat[1], mat[2], mat[0]);
+ }
+ else {
+ float vec[3];
+
+ vec[0] = mat[2][1];
+ vec[1] = mat[2][2];
+ vec[2] = mat[2][0];
+
+ cross_v3_v3v3(mat[0], vec, mat[2]);
+ normalize_v3(mat[0]);
+ cross_v3_v3v3(mat[1], mat[2], mat[0]);
+ }
+ break;
+ default:
+ BLI_assert(0);
+ break;
+ }
+ mul_v3_fl(mat[0], size[0]);
+ mul_v3_fl(mat[1], size[1]);
+ mul_v3_fl(mat[2], size[2]);
}
/**
@@ -1194,428 +1225,420 @@ void orthogonalize_m3(float mat[3][3], int axis)
*/
void orthogonalize_m4(float mat[4][4], int axis)
{
- float size[3];
- mat4_to_size(size, mat);
- normalize_v3(mat[axis]);
- switch (axis) {
- case 0:
- if (dot_v3v3(mat[0], mat[1]) < 1) {
- cross_v3_v3v3(mat[2], mat[0], mat[1]);
- normalize_v3(mat[2]);
- cross_v3_v3v3(mat[1], mat[2], mat[0]);
- }
- else if (dot_v3v3(mat[0], mat[2]) < 1) {
- cross_v3_v3v3(mat[1], mat[2], mat[0]);
- normalize_v3(mat[1]);
- cross_v3_v3v3(mat[2], mat[0], mat[1]);
- }
- else {
- float vec[3];
-
- vec[0] = mat[0][1];
- vec[1] = mat[0][2];
- vec[2] = mat[0][0];
-
- cross_v3_v3v3(mat[2], mat[0], vec);
- normalize_v3(mat[2]);
- cross_v3_v3v3(mat[1], mat[2], mat[0]);
- }
- break;
- case 1:
- if (dot_v3v3(mat[1], mat[0]) < 1) {
- cross_v3_v3v3(mat[2], mat[0], mat[1]);
- normalize_v3(mat[2]);
- cross_v3_v3v3(mat[0], mat[1], mat[2]);
- }
- else if (dot_v3v3(mat[0], mat[2]) < 1) {
- cross_v3_v3v3(mat[0], mat[1], mat[2]);
- normalize_v3(mat[0]);
- cross_v3_v3v3(mat[2], mat[0], mat[1]);
- }
- else {
- float vec[3];
-
- vec[0] = mat[1][1];
- vec[1] = mat[1][2];
- vec[2] = mat[1][0];
-
- cross_v3_v3v3(mat[0], mat[1], vec);
- normalize_v3(mat[0]);
- cross_v3_v3v3(mat[2], mat[0], mat[1]);
- }
- break;
- case 2:
- if (dot_v3v3(mat[2], mat[0]) < 1) {
- cross_v3_v3v3(mat[1], mat[2], mat[0]);
- normalize_v3(mat[1]);
- cross_v3_v3v3(mat[0], mat[1], mat[2]);
- }
- else if (dot_v3v3(mat[2], mat[1]) < 1) {
- cross_v3_v3v3(mat[0], mat[1], mat[2]);
- normalize_v3(mat[0]);
- cross_v3_v3v3(mat[1], mat[2], mat[0]);
- }
- else {
- float vec[3];
-
- vec[0] = mat[2][1];
- vec[1] = mat[2][2];
- vec[2] = mat[2][0];
-
- cross_v3_v3v3(mat[0], vec, mat[2]);
- normalize_v3(mat[0]);
- cross_v3_v3v3(mat[1], mat[2], mat[0]);
- }
- break;
- default:
- BLI_assert(0);
- break;
- }
- mul_v3_fl(mat[0], size[0]);
- mul_v3_fl(mat[1], size[1]);
- mul_v3_fl(mat[2], size[2]);
+ float size[3];
+ mat4_to_size(size, mat);
+ normalize_v3(mat[axis]);
+ switch (axis) {
+ case 0:
+ if (dot_v3v3(mat[0], mat[1]) < 1) {
+ cross_v3_v3v3(mat[2], mat[0], mat[1]);
+ normalize_v3(mat[2]);
+ cross_v3_v3v3(mat[1], mat[2], mat[0]);
+ }
+ else if (dot_v3v3(mat[0], mat[2]) < 1) {
+ cross_v3_v3v3(mat[1], mat[2], mat[0]);
+ normalize_v3(mat[1]);
+ cross_v3_v3v3(mat[2], mat[0], mat[1]);
+ }
+ else {
+ float vec[3];
+
+ vec[0] = mat[0][1];
+ vec[1] = mat[0][2];
+ vec[2] = mat[0][0];
+
+ cross_v3_v3v3(mat[2], mat[0], vec);
+ normalize_v3(mat[2]);
+ cross_v3_v3v3(mat[1], mat[2], mat[0]);
+ }
+ break;
+ case 1:
+ if (dot_v3v3(mat[1], mat[0]) < 1) {
+ cross_v3_v3v3(mat[2], mat[0], mat[1]);
+ normalize_v3(mat[2]);
+ cross_v3_v3v3(mat[0], mat[1], mat[2]);
+ }
+ else if (dot_v3v3(mat[0], mat[2]) < 1) {
+ cross_v3_v3v3(mat[0], mat[1], mat[2]);
+ normalize_v3(mat[0]);
+ cross_v3_v3v3(mat[2], mat[0], mat[1]);
+ }
+ else {
+ float vec[3];
+
+ vec[0] = mat[1][1];
+ vec[1] = mat[1][2];
+ vec[2] = mat[1][0];
+
+ cross_v3_v3v3(mat[0], mat[1], vec);
+ normalize_v3(mat[0]);
+ cross_v3_v3v3(mat[2], mat[0], mat[1]);
+ }
+ break;
+ case 2:
+ if (dot_v3v3(mat[2], mat[0]) < 1) {
+ cross_v3_v3v3(mat[1], mat[2], mat[0]);
+ normalize_v3(mat[1]);
+ cross_v3_v3v3(mat[0], mat[1], mat[2]);
+ }
+ else if (dot_v3v3(mat[2], mat[1]) < 1) {
+ cross_v3_v3v3(mat[0], mat[1], mat[2]);
+ normalize_v3(mat[0]);
+ cross_v3_v3v3(mat[1], mat[2], mat[0]);
+ }
+ else {
+ float vec[3];
+
+ vec[0] = mat[2][1];
+ vec[1] = mat[2][2];
+ vec[2] = mat[2][0];
+
+ cross_v3_v3v3(mat[0], vec, mat[2]);
+ normalize_v3(mat[0]);
+ cross_v3_v3v3(mat[1], mat[2], mat[0]);
+ }
+ break;
+ default:
+ BLI_assert(0);
+ break;
+ }
+ mul_v3_fl(mat[0], size[0]);
+ mul_v3_fl(mat[1], size[1]);
+ mul_v3_fl(mat[2], size[2]);
}
bool is_orthogonal_m3(const float m[3][3])
{
- int i, j;
+ int i, j;
- for (i = 0; i < 3; i++) {
- for (j = 0; j < i; j++) {
- if (fabsf(dot_v3v3(m[i], m[j])) > 1e-5f) {
- return false;
- }
- }
- }
+ for (i = 0; i < 3; i++) {
+ for (j = 0; j < i; j++) {
+ if (fabsf(dot_v3v3(m[i], m[j])) > 1e-5f) {
+ return false;
+ }
+ }
+ }
- return true;
+ return true;
}
bool is_orthogonal_m4(const float m[4][4])
{
- int i, j;
-
- for (i = 0; i < 4; i++) {
- for (j = 0; j < i; j++) {
- if (fabsf(dot_v4v4(m[i], m[j])) > 1e-5f) {
- return false;
- }
- }
+ int i, j;
- }
+ for (i = 0; i < 4; i++) {
+ for (j = 0; j < i; j++) {
+ if (fabsf(dot_v4v4(m[i], m[j])) > 1e-5f) {
+ return false;
+ }
+ }
+ }
- return true;
+ return true;
}
bool is_orthonormal_m3(const float m[3][3])
{
- if (is_orthogonal_m3(m)) {
- int i;
+ if (is_orthogonal_m3(m)) {
+ int i;
- for (i = 0; i < 3; i++) {
- if (fabsf(dot_v3v3(m[i], m[i]) - 1) > 1e-5f) {
- return false;
- }
- }
+ for (i = 0; i < 3; i++) {
+ if (fabsf(dot_v3v3(m[i], m[i]) - 1) > 1e-5f) {
+ return false;
+ }
+ }
- return true;
- }
+ return true;
+ }
- return false;
+ return false;
}
bool is_orthonormal_m4(const float m[4][4])
{
- if (is_orthogonal_m4(m)) {
- int i;
+ if (is_orthogonal_m4(m)) {
+ int i;
- for (i = 0; i < 4; i++)
- if (fabsf(dot_v4v4(m[i], m[i]) - 1) > 1e-5f) {
- return false;
- }
+ for (i = 0; i < 4; i++)
+ if (fabsf(dot_v4v4(m[i], m[i]) - 1) > 1e-5f) {
+ return false;
+ }
- return true;
- }
+ return true;
+ }
- return false;
+ return false;
}
bool is_uniform_scaled_m3(const float m[3][3])
{
- const float eps = 1e-7f;
- float t[3][3];
- float l1, l2, l3, l4, l5, l6;
+ const float eps = 1e-7f;
+ float t[3][3];
+ float l1, l2, l3, l4, l5, l6;
- transpose_m3_m3(t, m);
+ transpose_m3_m3(t, m);
- l1 = len_squared_v3(m[0]);
- l2 = len_squared_v3(m[1]);
- l3 = len_squared_v3(m[2]);
+ l1 = len_squared_v3(m[0]);
+ l2 = len_squared_v3(m[1]);
+ l3 = len_squared_v3(m[2]);
- l4 = len_squared_v3(t[0]);
- l5 = len_squared_v3(t[1]);
- l6 = len_squared_v3(t[2]);
+ l4 = len_squared_v3(t[0]);
+ l5 = len_squared_v3(t[1]);
+ l6 = len_squared_v3(t[2]);
- if (fabsf(l2 - l1) <= eps &&
- fabsf(l3 - l1) <= eps &&
- fabsf(l4 - l1) <= eps &&
- fabsf(l5 - l1) <= eps &&
- fabsf(l6 - l1) <= eps)
- {
- return true;
- }
+ if (fabsf(l2 - l1) <= eps && fabsf(l3 - l1) <= eps && fabsf(l4 - l1) <= eps &&
+ fabsf(l5 - l1) <= eps && fabsf(l6 - l1) <= eps) {
+ return true;
+ }
- return false;
+ return false;
}
bool is_uniform_scaled_m4(const float m[4][4])
{
- float t[3][3];
- copy_m3_m4(t, m);
- return is_uniform_scaled_m3(t);
+ float t[3][3];
+ copy_m3_m4(t, m);
+ return is_uniform_scaled_m3(t);
}
void normalize_m3_ex(float mat[3][3], float r_scale[3])
{
- int i;
- for (i = 0; i < 3; i++) {
- r_scale[i] = normalize_v3(mat[i]);
- }
+ int i;
+ for (i = 0; i < 3; i++) {
+ r_scale[i] = normalize_v3(mat[i]);
+ }
}
void normalize_m3(float mat[3][3])
{
- int i;
- for (i = 0; i < 3; i++) {
- normalize_v3(mat[i]);
- }
+ int i;
+ for (i = 0; i < 3; i++) {
+ normalize_v3(mat[i]);
+ }
}
void normalize_m3_m3_ex(float rmat[3][3], const float mat[3][3], float r_scale[3])
{
- int i;
- for (i = 0; i < 3; i++) {
- r_scale[i] = normalize_v3_v3(rmat[i], mat[i]);
- }
+ int i;
+ for (i = 0; i < 3; i++) {
+ r_scale[i] = normalize_v3_v3(rmat[i], mat[i]);
+ }
}
void normalize_m3_m3(float rmat[3][3], const float mat[3][3])
{
- int i;
- for (i = 0; i < 3; i++) {
- normalize_v3_v3(rmat[i], mat[i]);
- }
+ int i;
+ for (i = 0; i < 3; i++) {
+ normalize_v3_v3(rmat[i], mat[i]);
+ }
}
void normalize_m4_ex(float mat[4][4], float r_scale[3])
{
- int i;
- for (i = 0; i < 3; i++) {
- r_scale[i] = normalize_v3(mat[i]);
- if (r_scale[i] != 0.0f) {
- mat[i][3] /= r_scale[i];
- }
- }
+ int i;
+ for (i = 0; i < 3; i++) {
+ r_scale[i] = normalize_v3(mat[i]);
+ if (r_scale[i] != 0.0f) {
+ mat[i][3] /= r_scale[i];
+ }
+ }
}
void normalize_m4(float mat[4][4])
{
- int i;
- for (i = 0; i < 3; i++) {
- float len = normalize_v3(mat[i]);
- if (len != 0.0f) {
- mat[i][3] /= len;
- }
- }
+ int i;
+ for (i = 0; i < 3; i++) {
+ float len = normalize_v3(mat[i]);
+ if (len != 0.0f) {
+ mat[i][3] /= len;
+ }
+ }
}
void normalize_m4_m4_ex(float rmat[4][4], const float mat[4][4], float r_scale[3])
{
- int i;
- for (i = 0; i < 3; i++) {
- r_scale[i] = normalize_v3_v3(rmat[i], mat[i]);
- rmat[i][3] = (r_scale[i] != 0.0f) ? (mat[i][3] / r_scale[i]) : mat[i][3];
- }
- copy_v4_v4(rmat[3], mat[3]);
+ int i;
+ for (i = 0; i < 3; i++) {
+ r_scale[i] = normalize_v3_v3(rmat[i], mat[i]);
+ rmat[i][3] = (r_scale[i] != 0.0f) ? (mat[i][3] / r_scale[i]) : mat[i][3];
+ }
+ copy_v4_v4(rmat[3], mat[3]);
}
void normalize_m4_m4(float rmat[4][4], const float mat[4][4])
{
- int i;
- for (i = 0; i < 3; i++) {
- float len = normalize_v3_v3(rmat[i], mat[i]);
- rmat[i][3] = (len != 0.0f) ? (mat[i][3] / len) : mat[i][3];
- }
- copy_v4_v4(rmat[3], mat[3]);
+ int i;
+ for (i = 0; i < 3; i++) {
+ float len = normalize_v3_v3(rmat[i], mat[i]);
+ rmat[i][3] = (len != 0.0f) ? (mat[i][3] / len) : mat[i][3];
+ }
+ copy_v4_v4(rmat[3], mat[3]);
}
void adjoint_m2_m2(float m1[2][2], const float m[2][2])
{
- BLI_assert(m1 != m);
- m1[0][0] = m[1][1];
- m1[0][1] = -m[0][1];
- m1[1][0] = -m[1][0];
- m1[1][1] = m[0][0];
+ BLI_assert(m1 != m);
+ m1[0][0] = m[1][1];
+ m1[0][1] = -m[0][1];
+ m1[1][0] = -m[1][0];
+ m1[1][1] = m[0][0];
}
void adjoint_m3_m3(float m1[3][3], const float m[3][3])
{
- BLI_assert(m1 != m);
- m1[0][0] = m[1][1] * m[2][2] - m[1][2] * m[2][1];
- m1[0][1] = -m[0][1] * m[2][2] + m[0][2] * m[2][1];
- m1[0][2] = m[0][1] * m[1][2] - m[0][2] * m[1][1];
+ BLI_assert(m1 != m);
+ m1[0][0] = m[1][1] * m[2][2] - m[1][2] * m[2][1];
+ m1[0][1] = -m[0][1] * m[2][2] + m[0][2] * m[2][1];
+ m1[0][2] = m[0][1] * m[1][2] - m[0][2] * m[1][1];
- m1[1][0] = -m[1][0] * m[2][2] + m[1][2] * m[2][0];
- m1[1][1] = m[0][0] * m[2][2] - m[0][2] * m[2][0];
- m1[1][2] = -m[0][0] * m[1][2] + m[0][2] * m[1][0];
+ m1[1][0] = -m[1][0] * m[2][2] + m[1][2] * m[2][0];
+ m1[1][1] = m[0][0] * m[2][2] - m[0][2] * m[2][0];
+ m1[1][2] = -m[0][0] * m[1][2] + m[0][2] * m[1][0];
- m1[2][0] = m[1][0] * m[2][1] - m[1][1] * m[2][0];
- m1[2][1] = -m[0][0] * m[2][1] + m[0][1] * m[2][0];
- m1[2][2] = m[0][0] * m[1][1] - m[0][1] * m[1][0];
+ m1[2][0] = m[1][0] * m[2][1] - m[1][1] * m[2][0];
+ m1[2][1] = -m[0][0] * m[2][1] + m[0][1] * m[2][0];
+ m1[2][2] = m[0][0] * m[1][1] - m[0][1] * m[1][0];
}
void adjoint_m4_m4(float out[4][4], const float in[4][4]) /* out = ADJ(in) */
{
- float a1, a2, a3, a4, b1, b2, b3, b4;
- float c1, c2, c3, c4, d1, d2, d3, d4;
+ float a1, a2, a3, a4, b1, b2, b3, b4;
+ float c1, c2, c3, c4, d1, d2, d3, d4;
- a1 = in[0][0];
- b1 = in[0][1];
- c1 = in[0][2];
- d1 = in[0][3];
+ a1 = in[0][0];
+ b1 = in[0][1];
+ c1 = in[0][2];
+ d1 = in[0][3];
- a2 = in[1][0];
- b2 = in[1][1];
- c2 = in[1][2];
- d2 = in[1][3];
+ a2 = in[1][0];
+ b2 = in[1][1];
+ c2 = in[1][2];
+ d2 = in[1][3];
- a3 = in[2][0];
- b3 = in[2][1];
- c3 = in[2][2];
- d3 = in[2][3];
+ a3 = in[2][0];
+ b3 = in[2][1];
+ c3 = in[2][2];
+ d3 = in[2][3];
- a4 = in[3][0];
- b4 = in[3][1];
- c4 = in[3][2];
- d4 = in[3][3];
+ a4 = in[3][0];
+ b4 = in[3][1];
+ c4 = in[3][2];
+ d4 = in[3][3];
+ out[0][0] = determinant_m3(b2, b3, b4, c2, c3, c4, d2, d3, d4);
+ out[1][0] = -determinant_m3(a2, a3, a4, c2, c3, c4, d2, d3, d4);
+ out[2][0] = determinant_m3(a2, a3, a4, b2, b3, b4, d2, d3, d4);
+ out[3][0] = -determinant_m3(a2, a3, a4, b2, b3, b4, c2, c3, c4);
- out[0][0] = determinant_m3(b2, b3, b4, c2, c3, c4, d2, d3, d4);
- out[1][0] = -determinant_m3(a2, a3, a4, c2, c3, c4, d2, d3, d4);
- out[2][0] = determinant_m3(a2, a3, a4, b2, b3, b4, d2, d3, d4);
- out[3][0] = -determinant_m3(a2, a3, a4, b2, b3, b4, c2, c3, c4);
+ out[0][1] = -determinant_m3(b1, b3, b4, c1, c3, c4, d1, d3, d4);
+ out[1][1] = determinant_m3(a1, a3, a4, c1, c3, c4, d1, d3, d4);
+ out[2][1] = -determinant_m3(a1, a3, a4, b1, b3, b4, d1, d3, d4);
+ out[3][1] = determinant_m3(a1, a3, a4, b1, b3, b4, c1, c3, c4);
- out[0][1] = -determinant_m3(b1, b3, b4, c1, c3, c4, d1, d3, d4);
- out[1][1] = determinant_m3(a1, a3, a4, c1, c3, c4, d1, d3, d4);
- out[2][1] = -determinant_m3(a1, a3, a4, b1, b3, b4, d1, d3, d4);
- out[3][1] = determinant_m3(a1, a3, a4, b1, b3, b4, c1, c3, c4);
+ out[0][2] = determinant_m3(b1, b2, b4, c1, c2, c4, d1, d2, d4);
+ out[1][2] = -determinant_m3(a1, a2, a4, c1, c2, c4, d1, d2, d4);
+ out[2][2] = determinant_m3(a1, a2, a4, b1, b2, b4, d1, d2, d4);
+ out[3][2] = -determinant_m3(a1, a2, a4, b1, b2, b4, c1, c2, c4);
- out[0][2] = determinant_m3(b1, b2, b4, c1, c2, c4, d1, d2, d4);
- out[1][2] = -determinant_m3(a1, a2, a4, c1, c2, c4, d1, d2, d4);
- out[2][2] = determinant_m3(a1, a2, a4, b1, b2, b4, d1, d2, d4);
- out[3][2] = -determinant_m3(a1, a2, a4, b1, b2, b4, c1, c2, c4);
-
- out[0][3] = -determinant_m3(b1, b2, b3, c1, c2, c3, d1, d2, d3);
- out[1][3] = determinant_m3(a1, a2, a3, c1, c2, c3, d1, d2, d3);
- out[2][3] = -determinant_m3(a1, a2, a3, b1, b2, b3, d1, d2, d3);
- out[3][3] = determinant_m3(a1, a2, a3, b1, b2, b3, c1, c2, c3);
+ out[0][3] = -determinant_m3(b1, b2, b3, c1, c2, c3, d1, d2, d3);
+ out[1][3] = determinant_m3(a1, a2, a3, c1, c2, c3, d1, d2, d3);
+ out[2][3] = -determinant_m3(a1, a2, a3, b1, b2, b3, d1, d2, d3);
+ out[3][3] = determinant_m3(a1, a2, a3, b1, b2, b3, c1, c2, c3);
}
float determinant_m2(float a, float b, float c, float d)
{
- return a * d - b * c;
+ return a * d - b * c;
}
-float determinant_m3(float a1, float a2, float a3,
- float b1, float b2, float b3,
- float c1, float c2, float c3)
+float determinant_m3(
+ float a1, float a2, float a3, float b1, float b2, float b3, float c1, float c2, float c3)
{
- float ans;
+ float ans;
- ans = (a1 * determinant_m2(b2, b3, c2, c3) -
- b1 * determinant_m2(a2, a3, c2, c3) +
- c1 * determinant_m2(a2, a3, b2, b3));
+ ans = (a1 * determinant_m2(b2, b3, c2, c3) - b1 * determinant_m2(a2, a3, c2, c3) +
+ c1 * determinant_m2(a2, a3, b2, b3));
- return ans;
+ return ans;
}
float determinant_m4(const float m[4][4])
{
- float ans;
- float a1, a2, a3, a4, b1, b2, b3, b4, c1, c2, c3, c4, d1, d2, d3, d4;
+ float ans;
+ float a1, a2, a3, a4, b1, b2, b3, b4, c1, c2, c3, c4, d1, d2, d3, d4;
- a1 = m[0][0];
- b1 = m[0][1];
- c1 = m[0][2];
- d1 = m[0][3];
+ a1 = m[0][0];
+ b1 = m[0][1];
+ c1 = m[0][2];
+ d1 = m[0][3];
- a2 = m[1][0];
- b2 = m[1][1];
- c2 = m[1][2];
- d2 = m[1][3];
+ a2 = m[1][0];
+ b2 = m[1][1];
+ c2 = m[1][2];
+ d2 = m[1][3];
- a3 = m[2][0];
- b3 = m[2][1];
- c3 = m[2][2];
- d3 = m[2][3];
+ a3 = m[2][0];
+ b3 = m[2][1];
+ c3 = m[2][2];
+ d3 = m[2][3];
- a4 = m[3][0];
- b4 = m[3][1];
- c4 = m[3][2];
- d4 = m[3][3];
+ a4 = m[3][0];
+ b4 = m[3][1];
+ c4 = m[3][2];
+ d4 = m[3][3];
- ans = (a1 * determinant_m3(b2, b3, b4, c2, c3, c4, d2, d3, d4) -
- b1 * determinant_m3(a2, a3, a4, c2, c3, c4, d2, d3, d4) +
- c1 * determinant_m3(a2, a3, a4, b2, b3, b4, d2, d3, d4) -
- d1 * determinant_m3(a2, a3, a4, b2, b3, b4, c2, c3, c4));
+ ans = (a1 * determinant_m3(b2, b3, b4, c2, c3, c4, d2, d3, d4) -
+ b1 * determinant_m3(a2, a3, a4, c2, c3, c4, d2, d3, d4) +
+ c1 * determinant_m3(a2, a3, a4, b2, b3, b4, d2, d3, d4) -
+ d1 * determinant_m3(a2, a3, a4, b2, b3, b4, c2, c3, c4));
- return ans;
+ return ans;
}
/****************************** Transformations ******************************/
void size_to_mat3(float mat[3][3], const float size[3])
{
- mat[0][0] = size[0];
- mat[0][1] = 0.0f;
- mat[0][2] = 0.0f;
- mat[1][1] = size[1];
- mat[1][0] = 0.0f;
- mat[1][2] = 0.0f;
- mat[2][2] = size[2];
- mat[2][1] = 0.0f;
- mat[2][0] = 0.0f;
+ mat[0][0] = size[0];
+ mat[0][1] = 0.0f;
+ mat[0][2] = 0.0f;
+ mat[1][1] = size[1];
+ mat[1][0] = 0.0f;
+ mat[1][2] = 0.0f;
+ mat[2][2] = size[2];
+ mat[2][1] = 0.0f;
+ mat[2][0] = 0.0f;
}
void size_to_mat4(float mat[4][4], const float size[3])
{
- mat[0][0] = size[0];
- mat[0][1] = 0.0f;
- mat[0][2] = 0.0f;
- mat[0][3] = 0.0f;
- mat[1][0] = 0.0f;
- mat[1][1] = size[1];
- mat[1][2] = 0.0f;
- mat[1][3] = 0.0f;
- mat[2][0] = 0.0f;
- mat[2][1] = 0.0f;
- mat[2][2] = size[2];
- mat[2][3] = 0.0f;
- mat[3][0] = 0.0f;
- mat[3][1] = 0.0f;
- mat[3][2] = 0.0f;
- mat[3][3] = 1.0f;
+ mat[0][0] = size[0];
+ mat[0][1] = 0.0f;
+ mat[0][2] = 0.0f;
+ mat[0][3] = 0.0f;
+ mat[1][0] = 0.0f;
+ mat[1][1] = size[1];
+ mat[1][2] = 0.0f;
+ mat[1][3] = 0.0f;
+ mat[2][0] = 0.0f;
+ mat[2][1] = 0.0f;
+ mat[2][2] = size[2];
+ mat[2][3] = 0.0f;
+ mat[3][0] = 0.0f;
+ mat[3][1] = 0.0f;
+ mat[3][2] = 0.0f;
+ mat[3][3] = 1.0f;
}
void mat3_to_size(float size[3], const float mat[3][3])
{
- size[0] = len_v3(mat[0]);
- size[1] = len_v3(mat[1]);
- size[2] = len_v3(mat[2]);
+ size[0] = len_v3(mat[0]);
+ size[1] = len_v3(mat[1]);
+ size[2] = len_v3(mat[2]);
}
void mat4_to_size(float size[3], const float mat[4][4])
{
- size[0] = len_v3(mat[0]);
- size[1] = len_v3(mat[1]);
- size[2] = len_v3(mat[2]);
+ size[0] = len_v3(mat[0]);
+ size[1] = len_v3(mat[1]);
+ size[2] = len_v3(mat[2]);
}
/* this gets the average scale of a matrix, only use when your scaling
@@ -1623,77 +1646,77 @@ void mat4_to_size(float size[3], const float mat[4][4])
* and curve radius */
float mat3_to_scale(const float mat[3][3])
{
- /* unit length vector */
- float unit_vec[3];
- copy_v3_fl(unit_vec, (float)M_SQRT1_3);
- mul_m3_v3(mat, unit_vec);
- return len_v3(unit_vec);
+ /* unit length vector */
+ float unit_vec[3];
+ copy_v3_fl(unit_vec, (float)M_SQRT1_3);
+ mul_m3_v3(mat, unit_vec);
+ return len_v3(unit_vec);
}
float mat4_to_scale(const float mat[4][4])
{
- /* unit length vector */
- float unit_vec[3];
- copy_v3_fl(unit_vec, (float)M_SQRT1_3);
- mul_mat3_m4_v3(mat, unit_vec);
- return len_v3(unit_vec);
+ /* unit length vector */
+ float unit_vec[3];
+ copy_v3_fl(unit_vec, (float)M_SQRT1_3);
+ mul_mat3_m4_v3(mat, unit_vec);
+ return len_v3(unit_vec);
}
/** Return 2D scale (in XY plane) of given mat4. */
float mat4_to_xy_scale(const float M[4][4])
{
- /* unit length vector in xy plane */
- float unit_vec[3] = {(float)M_SQRT1_2, (float)M_SQRT1_2, 0.0f};
- mul_mat3_m4_v3(M, unit_vec);
- return len_v3(unit_vec);
+ /* unit length vector in xy plane */
+ float unit_vec[3] = {(float)M_SQRT1_2, (float)M_SQRT1_2, 0.0f};
+ mul_mat3_m4_v3(M, unit_vec);
+ return len_v3(unit_vec);
}
void mat3_to_rot_size(float rot[3][3], float size[3], const float mat3[3][3])
{
- /* keep rot as a 3x3 matrix, the caller can convert into a quat or euler */
- size[0] = normalize_v3_v3(rot[0], mat3[0]);
- size[1] = normalize_v3_v3(rot[1], mat3[1]);
- size[2] = normalize_v3_v3(rot[2], mat3[2]);
- if (UNLIKELY(is_negative_m3(rot))) {
- negate_m3(rot);
- negate_v3(size);
- }
+ /* keep rot as a 3x3 matrix, the caller can convert into a quat or euler */
+ size[0] = normalize_v3_v3(rot[0], mat3[0]);
+ size[1] = normalize_v3_v3(rot[1], mat3[1]);
+ size[2] = normalize_v3_v3(rot[2], mat3[2]);
+ if (UNLIKELY(is_negative_m3(rot))) {
+ negate_m3(rot);
+ negate_v3(size);
+ }
}
void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], const float wmat[4][4])
{
- float mat3[3][3]; /* wmat -> 3x3 */
+ float mat3[3][3]; /* wmat -> 3x3 */
- copy_m3_m4(mat3, wmat);
- mat3_to_rot_size(rot, size, mat3);
+ copy_m3_m4(mat3, wmat);
+ mat3_to_rot_size(rot, size, mat3);
- /* location */
- copy_v3_v3(loc, wmat[3]);
+ /* location */
+ copy_v3_v3(loc, wmat[3]);
}
void mat4_to_loc_quat(float loc[3], float quat[4], const float wmat[4][4])
{
- float mat3[3][3];
- float mat3_n[3][3]; /* normalized mat3 */
+ float mat3[3][3];
+ float mat3_n[3][3]; /* normalized mat3 */
- copy_m3_m4(mat3, wmat);
- normalize_m3_m3(mat3_n, mat3);
+ copy_m3_m4(mat3, wmat);
+ normalize_m3_m3(mat3_n, mat3);
- /* 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_m3(mat3_n);
- }
+ /* 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_m3(mat3_n);
+ }
- mat3_normalized_to_quat(quat, mat3_n);
- copy_v3_v3(loc, wmat[3]);
+ mat3_normalized_to_quat(quat, mat3_n);
+ copy_v3_v3(loc, wmat[3]);
}
void mat4_decompose(float loc[3], float quat[4], float size[3], const float wmat[4][4])
{
- float rot[3][3];
- mat4_to_loc_rot_size(loc, rot, size, wmat);
- mat3_normalized_to_quat(quat, rot);
+ float rot[3][3];
+ mat4_to_loc_rot_size(loc, rot, size, wmat);
+ mat3_normalized_to_quat(quat, rot);
}
/**
@@ -1708,46 +1731,46 @@ void mat4_decompose(float loc[3], float quat[4], float size[3], const float wmat
#ifndef MATH_STANDALONE
void mat3_polar_decompose(const float mat3[3][3], float r_U[3][3], float r_P[3][3])
{
- /* From svd decomposition (M = WSV*), we have:
- * U = WV*
- * P = VSV*
- */
- float W[3][3], S[3][3], V[3][3], Vt[3][3];
- float sval[3];
+ /* From svd decomposition (M = WSV*), we have:
+ * U = WV*
+ * P = VSV*
+ */
+ float W[3][3], S[3][3], V[3][3], Vt[3][3];
+ float sval[3];
- BLI_svd_m3(mat3, W, sval, V);
+ BLI_svd_m3(mat3, W, sval, V);
- size_to_mat3(S, sval);
+ size_to_mat3(S, sval);
- transpose_m3_m3(Vt, V);
- mul_m3_m3m3(r_U, W, Vt);
- mul_m3_series(r_P, V, S, Vt);
+ transpose_m3_m3(Vt, V);
+ mul_m3_m3m3(r_U, W, Vt);
+ mul_m3_series(r_P, V, S, Vt);
}
#endif
void scale_m3_fl(float m[3][3], float scale)
{
- m[0][0] = m[1][1] = m[2][2] = scale;
- m[0][1] = m[0][2] = 0.0;
- m[1][0] = m[1][2] = 0.0;
- m[2][0] = m[2][1] = 0.0;
+ m[0][0] = m[1][1] = m[2][2] = scale;
+ m[0][1] = m[0][2] = 0.0;
+ m[1][0] = m[1][2] = 0.0;
+ m[2][0] = m[2][1] = 0.0;
}
void scale_m4_fl(float m[4][4], float scale)
{
- m[0][0] = m[1][1] = m[2][2] = scale;
- m[3][3] = 1.0;
- m[0][1] = m[0][2] = m[0][3] = 0.0;
- m[1][0] = m[1][2] = m[1][3] = 0.0;
- m[2][0] = m[2][1] = m[2][3] = 0.0;
- m[3][0] = m[3][1] = m[3][2] = 0.0;
+ m[0][0] = m[1][1] = m[2][2] = scale;
+ m[3][3] = 1.0;
+ m[0][1] = m[0][2] = m[0][3] = 0.0;
+ m[1][0] = m[1][2] = m[1][3] = 0.0;
+ m[2][0] = m[2][1] = m[2][3] = 0.0;
+ m[3][0] = m[3][1] = m[3][2] = 0.0;
}
void translate_m4(float mat[4][4], float Tx, float Ty, float Tz)
{
- mat[3][0] += (Tx * mat[0][0] + Ty * mat[1][0] + Tz * mat[2][0]);
- mat[3][1] += (Tx * mat[0][1] + Ty * mat[1][1] + Tz * mat[2][1]);
- mat[3][2] += (Tx * mat[0][2] + Ty * mat[1][2] + Tz * mat[2][2]);
+ mat[3][0] += (Tx * mat[0][0] + Ty * mat[1][0] + Tz * mat[2][0]);
+ mat[3][1] += (Tx * mat[0][1] + Ty * mat[1][1] + Tz * mat[2][1]);
+ mat[3][2] += (Tx * mat[0][2] + Ty * mat[1][2] + Tz * mat[2][2]);
}
/* TODO: enum for axis? */
@@ -1760,39 +1783,39 @@ void translate_m4(float mat[4][4], float Tx, float Ty, float Tz)
*/
void rotate_m4(float mat[4][4], const char axis, const float angle)
{
- const float angle_cos = cosf(angle);
- const float angle_sin = sinf(angle);
-
- assert(axis >= 'X' && axis <= 'Z');
-
- switch (axis) {
- case 'X':
- for (int col = 0; col < 4; col++) {
- float temp = angle_cos * mat[1][col] + angle_sin * mat[2][col];
- mat[2][col] = -angle_sin * mat[1][col] + angle_cos * mat[2][col];
- mat[1][col] = temp;
- }
- break;
-
- case 'Y':
- for (int col = 0; col < 4; col++) {
- float temp = angle_cos * mat[0][col] - angle_sin * mat[2][col];
- mat[2][col] = angle_sin * mat[0][col] + angle_cos * mat[2][col];
- mat[0][col] = temp;
- }
- break;
-
- case 'Z':
- for (int col = 0; col < 4; col++) {
- float temp = angle_cos * mat[0][col] + angle_sin * mat[1][col];
- mat[1][col] = -angle_sin * mat[0][col] + angle_cos * mat[1][col];
- mat[0][col] = temp;
- }
- break;
- default:
- BLI_assert(0);
- break;
- }
+ const float angle_cos = cosf(angle);
+ const float angle_sin = sinf(angle);
+
+ assert(axis >= 'X' && axis <= 'Z');
+
+ switch (axis) {
+ case 'X':
+ for (int col = 0; col < 4; col++) {
+ float temp = angle_cos * mat[1][col] + angle_sin * mat[2][col];
+ mat[2][col] = -angle_sin * mat[1][col] + angle_cos * mat[2][col];
+ mat[1][col] = temp;
+ }
+ break;
+
+ case 'Y':
+ for (int col = 0; col < 4; col++) {
+ float temp = angle_cos * mat[0][col] - angle_sin * mat[2][col];
+ mat[2][col] = angle_sin * mat[0][col] + angle_cos * mat[2][col];
+ mat[0][col] = temp;
+ }
+ break;
+
+ case 'Z':
+ for (int col = 0; col < 4; col++) {
+ float temp = angle_cos * mat[0][col] + angle_sin * mat[1][col];
+ mat[1][col] = -angle_sin * mat[0][col] + angle_cos * mat[1][col];
+ mat[0][col] = temp;
+ }
+ break;
+ default:
+ BLI_assert(0);
+ break;
+ }
}
/**
@@ -1805,61 +1828,67 @@ void rotate_m4(float mat[4][4], const char axis, const float angle)
*/
void transform_pivot_set_m4(float mat[4][4], const float pivot[3])
{
- float tmat[4][4];
+ float tmat[4][4];
- unit_m4(tmat);
+ unit_m4(tmat);
- copy_v3_v3(tmat[3], pivot);
- mul_m4_m4m4(mat, tmat, mat);
+ copy_v3_v3(tmat[3], pivot);
+ mul_m4_m4m4(mat, tmat, mat);
- /* invert the matrix */
- negate_v3(tmat[3]);
- mul_m4_m4m4(mat, mat, tmat);
+ /* invert the matrix */
+ negate_v3(tmat[3]);
+ mul_m4_m4m4(mat, mat, tmat);
}
-void blend_m3_m3m3(float out[3][3], const float dst[3][3], const float src[3][3], const float srcweight)
+void blend_m3_m3m3(float out[3][3],
+ const float dst[3][3],
+ const float src[3][3],
+ const float srcweight)
{
- float srot[3][3], drot[3][3];
- float squat[4], dquat[4], fquat[4];
- float sscale[3], dscale[3], fsize[3];
- float rmat[3][3], smat[3][3];
+ float srot[3][3], drot[3][3];
+ float squat[4], dquat[4], fquat[4];
+ float sscale[3], dscale[3], fsize[3];
+ float rmat[3][3], smat[3][3];
- mat3_to_rot_size(drot, dscale, dst);
- mat3_to_rot_size(srot, sscale, src);
+ mat3_to_rot_size(drot, dscale, dst);
+ mat3_to_rot_size(srot, sscale, src);
- mat3_normalized_to_quat(dquat, drot);
- mat3_normalized_to_quat(squat, srot);
+ mat3_normalized_to_quat(dquat, drot);
+ mat3_normalized_to_quat(squat, srot);
- /* do blending */
- interp_qt_qtqt(fquat, dquat, squat, srcweight);
- interp_v3_v3v3(fsize, dscale, sscale, srcweight);
+ /* do blending */
+ interp_qt_qtqt(fquat, dquat, squat, srcweight);
+ interp_v3_v3v3(fsize, dscale, sscale, srcweight);
- /* compose new matrix */
- quat_to_mat3(rmat, fquat);
- size_to_mat3(smat, fsize);
- mul_m3_m3m3(out, rmat, smat);
+ /* compose new matrix */
+ quat_to_mat3(rmat, fquat);
+ size_to_mat3(smat, fsize);
+ mul_m3_m3m3(out, rmat, smat);
}
-void blend_m4_m4m4(float out[4][4], const float dst[4][4], const float src[4][4], const float srcweight)
+void blend_m4_m4m4(float out[4][4],
+ const float dst[4][4],
+ const float src[4][4],
+ const float srcweight)
{
- float sloc[3], dloc[3], floc[3];
- float srot[3][3], drot[3][3];
- float squat[4], dquat[4], fquat[4];
- float sscale[3], dscale[3], fsize[3];
+ float sloc[3], dloc[3], floc[3];
+ float srot[3][3], drot[3][3];
+ float squat[4], dquat[4], fquat[4];
+ float sscale[3], dscale[3], fsize[3];
- mat4_to_loc_rot_size(dloc, drot, dscale, dst);
- mat4_to_loc_rot_size(sloc, srot, sscale, src);
+ mat4_to_loc_rot_size(dloc, drot, dscale, dst);
+ mat4_to_loc_rot_size(sloc, srot, sscale, src);
- mat3_normalized_to_quat(dquat, drot);
- mat3_normalized_to_quat(squat, srot);
+ mat3_normalized_to_quat(dquat, drot);
+ mat3_normalized_to_quat(squat, srot);
- /* do blending */
- interp_v3_v3v3(floc, dloc, sloc, srcweight);
- interp_qt_qtqt(fquat, dquat, squat, srcweight);
- interp_v3_v3v3(fsize, dscale, sscale, srcweight);
+ /* do blending */
+ interp_v3_v3v3(floc, dloc, sloc, srcweight);
+ interp_qt_qtqt(fquat, dquat, squat, srcweight);
+ interp_v3_v3v3(fsize, dscale, sscale, srcweight);
- /* compose new matrix */
- loc_quat_size_to_mat4(out, floc, fquat, fsize);
+ /* compose new matrix */
+ loc_quat_size_to_mat4(out, floc, fquat, fsize);
}
/* for builds without Eigen */
@@ -1880,31 +1909,31 @@ void blend_m4_m4m4(float out[4][4], const float dst[4][4], const float src[4][4]
*/
void interp_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3], const float t)
{
- /* 'Rotation' component ('U' part of polar decomposition,
- * the closest orthogonal matrix to M3 rot/scale
- * transformation matrix), spherically interpolated. */
- float U_A[3][3], U_B[3][3], U[3][3];
- float quat_A[4], quat_B[4], quat[4];
- /* 'Scaling' component ('P' part of polar decomposition, i.e. scaling in U-defined space),
- * linearly interpolated. */
- float P_A[3][3], P_B[3][3], P[3][3];
+ /* 'Rotation' component ('U' part of polar decomposition,
+ * the closest orthogonal matrix to M3 rot/scale
+ * transformation matrix), spherically interpolated. */
+ float U_A[3][3], U_B[3][3], U[3][3];
+ float quat_A[4], quat_B[4], quat[4];
+ /* 'Scaling' component ('P' part of polar decomposition, i.e. scaling in U-defined space),
+ * linearly interpolated. */
+ float P_A[3][3], P_B[3][3], P[3][3];
- int i;
+ int i;
- mat3_polar_decompose(A, U_A, P_A);
- mat3_polar_decompose(B, U_B, P_B);
+ mat3_polar_decompose(A, U_A, P_A);
+ mat3_polar_decompose(B, U_B, P_B);
- mat3_to_quat(quat_A, U_A);
- mat3_to_quat(quat_B, U_B);
- interp_qt_qtqt(quat, quat_A, quat_B, t);
- quat_to_mat3(U, quat);
+ mat3_to_quat(quat_A, U_A);
+ mat3_to_quat(quat_B, U_B);
+ interp_qt_qtqt(quat, quat_A, quat_B, t);
+ quat_to_mat3(U, quat);
- for (i = 0; i < 3; i++) {
- interp_v3_v3v3(P[i], P_A[i], P_B[i], t);
- }
+ for (i = 0; i < 3; i++) {
+ interp_v3_v3v3(P[i], P_A[i], P_B[i], t);
+ }
- /* And we reconstruct rot/scale matrix from interpolated polar components */
- mul_m3_m3m3(R, U, P);
+ /* And we reconstruct rot/scale matrix from interpolated polar components */
+ mul_m3_m3m3(R, U, P);
}
/**
@@ -1917,168 +1946,173 @@ void interp_m3_m3m3(float R[3][3], const float A[3][3], const float B[3][3], con
*/
void interp_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4], const float t)
{
- float A3[3][3], B3[3][3], R3[3][3];
+ float A3[3][3], B3[3][3], R3[3][3];
- /* Location component, linearly interpolated. */
- float loc_A[3], loc_B[3], loc[3];
+ /* Location component, linearly interpolated. */
+ float loc_A[3], loc_B[3], loc[3];
- copy_v3_v3(loc_A, A[3]);
- copy_v3_v3(loc_B, B[3]);
- interp_v3_v3v3(loc, loc_A, loc_B, t);
+ copy_v3_v3(loc_A, A[3]);
+ copy_v3_v3(loc_B, B[3]);
+ interp_v3_v3v3(loc, loc_A, loc_B, t);
- copy_m3_m4(A3, A);
- copy_m3_m4(B3, B);
+ copy_m3_m4(A3, A);
+ copy_m3_m4(B3, B);
- interp_m3_m3m3(R3, A3, B3, t);
+ interp_m3_m3m3(R3, A3, B3, t);
- copy_m4_m3(R, R3);
- copy_v3_v3(R[3], loc);
+ copy_m4_m3(R, R3);
+ copy_v3_v3(R[3], loc);
}
-#endif /* MATH_STANDALONE */
+#endif /* MATH_STANDALONE */
bool is_negative_m3(const float mat[3][3])
{
- float vec[3];
- cross_v3_v3v3(vec, mat[0], mat[1]);
- return (dot_v3v3(vec, mat[2]) < 0.0f);
+ float vec[3];
+ cross_v3_v3v3(vec, mat[0], mat[1]);
+ return (dot_v3v3(vec, mat[2]) < 0.0f);
}
bool is_negative_m4(const float mat[4][4])
{
- float vec[3];
- cross_v3_v3v3(vec, mat[0], mat[1]);
- return (dot_v3v3(vec, mat[2]) < 0.0f);
+ float vec[3];
+ cross_v3_v3v3(vec, mat[0], mat[1]);
+ return (dot_v3v3(vec, mat[2]) < 0.0f);
}
bool is_zero_m3(const float mat[3][3])
{
- return (is_zero_v3(mat[0]) &&
- is_zero_v3(mat[1]) &&
- is_zero_v3(mat[2]));
+ return (is_zero_v3(mat[0]) && is_zero_v3(mat[1]) && is_zero_v3(mat[2]));
}
bool is_zero_m4(const float mat[4][4])
{
- return (is_zero_v4(mat[0]) &&
- is_zero_v4(mat[1]) &&
- is_zero_v4(mat[2]) &&
- is_zero_v4(mat[3]));
+ return (is_zero_v4(mat[0]) && is_zero_v4(mat[1]) && is_zero_v4(mat[2]) && is_zero_v4(mat[3]));
}
bool equals_m3m3(const float mat1[3][3], const float mat2[3][3])
{
- return (equals_v3v3(mat1[0], mat2[0]) &&
- equals_v3v3(mat1[1], mat2[1]) &&
- equals_v3v3(mat1[2], mat2[2]));
+ return (equals_v3v3(mat1[0], mat2[0]) && equals_v3v3(mat1[1], mat2[1]) &&
+ equals_v3v3(mat1[2], mat2[2]));
}
bool equals_m4m4(const float mat1[4][4], const float mat2[4][4])
{
- return (equals_v4v4(mat1[0], mat2[0]) &&
- equals_v4v4(mat1[1], mat2[1]) &&
- equals_v4v4(mat1[2], mat2[2]) &&
- equals_v4v4(mat1[3], mat2[3]));
+ return (equals_v4v4(mat1[0], mat2[0]) && equals_v4v4(mat1[1], mat2[1]) &&
+ equals_v4v4(mat1[2], mat2[2]) && equals_v4v4(mat1[3], mat2[3]));
}
/* make a 4x4 matrix out of 3 transform components */
/* matrices are made in the order: scale * rot * loc */
/* TODO: need to have a version that allows for rotation order... */
-void loc_eul_size_to_mat4(float mat[4][4], const float loc[3], const float eul[3], const float size[3])
+void loc_eul_size_to_mat4(float mat[4][4],
+ const float loc[3],
+ const float eul[3],
+ const float size[3])
{
- float rmat[3][3], smat[3][3], tmat[3][3];
+ float rmat[3][3], smat[3][3], tmat[3][3];
- /* initialize new matrix */
- unit_m4(mat);
+ /* initialize new matrix */
+ unit_m4(mat);
- /* make rotation + scaling part */
- eul_to_mat3(rmat, eul);
- size_to_mat3(smat, size);
- mul_m3_m3m3(tmat, rmat, smat);
+ /* make rotation + scaling part */
+ eul_to_mat3(rmat, eul);
+ size_to_mat3(smat, size);
+ mul_m3_m3m3(tmat, rmat, smat);
- /* copy rot/scale part to output matrix*/
- copy_m4_m3(mat, tmat);
+ /* copy rot/scale part to output matrix*/
+ copy_m4_m3(mat, tmat);
- /* copy location to matrix */
- mat[3][0] = loc[0];
- mat[3][1] = loc[1];
- mat[3][2] = loc[2];
+ /* copy location to matrix */
+ mat[3][0] = loc[0];
+ mat[3][1] = loc[1];
+ mat[3][2] = loc[2];
}
/* make a 4x4 matrix out of 3 transform components */
/* matrices are made in the order: scale * rot * loc */
-void loc_eulO_size_to_mat4(float mat[4][4], const float loc[3], const float eul[3], const float size[3], const short rotOrder)
+void loc_eulO_size_to_mat4(float mat[4][4],
+ const float loc[3],
+ const float eul[3],
+ const float size[3],
+ const short rotOrder)
{
- float rmat[3][3], smat[3][3], tmat[3][3];
+ float rmat[3][3], smat[3][3], tmat[3][3];
- /* initialize new matrix */
- unit_m4(mat);
+ /* initialize new matrix */
+ unit_m4(mat);
- /* make rotation + scaling part */
- eulO_to_mat3(rmat, eul, rotOrder);
- size_to_mat3(smat, size);
- mul_m3_m3m3(tmat, rmat, smat);
+ /* make rotation + scaling part */
+ eulO_to_mat3(rmat, eul, rotOrder);
+ size_to_mat3(smat, size);
+ mul_m3_m3m3(tmat, rmat, smat);
- /* copy rot/scale part to output matrix*/
- copy_m4_m3(mat, tmat);
+ /* copy rot/scale part to output matrix*/
+ copy_m4_m3(mat, tmat);
- /* copy location to matrix */
- mat[3][0] = loc[0];
- mat[3][1] = loc[1];
- mat[3][2] = loc[2];
+ /* copy location to matrix */
+ mat[3][0] = loc[0];
+ mat[3][1] = loc[1];
+ mat[3][2] = loc[2];
}
-
/* make a 4x4 matrix out of 3 transform components */
/* matrices are made in the order: scale * rot * loc */
-void loc_quat_size_to_mat4(float mat[4][4], const float loc[3], const float quat[4], const float size[3])
+void loc_quat_size_to_mat4(float mat[4][4],
+ const float loc[3],
+ const float quat[4],
+ const float size[3])
{
- float rmat[3][3], smat[3][3], tmat[3][3];
+ float rmat[3][3], smat[3][3], tmat[3][3];
- /* initialize new matrix */
- unit_m4(mat);
+ /* initialize new matrix */
+ unit_m4(mat);
- /* make rotation + scaling part */
- quat_to_mat3(rmat, quat);
- size_to_mat3(smat, size);
- mul_m3_m3m3(tmat, rmat, smat);
+ /* make rotation + scaling part */
+ quat_to_mat3(rmat, quat);
+ size_to_mat3(smat, size);
+ mul_m3_m3m3(tmat, rmat, smat);
- /* copy rot/scale part to output matrix*/
- copy_m4_m3(mat, tmat);
+ /* copy rot/scale part to output matrix*/
+ copy_m4_m3(mat, tmat);
- /* copy location to matrix */
- mat[3][0] = loc[0];
- mat[3][1] = loc[1];
- mat[3][2] = loc[2];
+ /* copy location to matrix */
+ mat[3][0] = loc[0];
+ mat[3][1] = loc[1];
+ mat[3][2] = loc[2];
}
-void loc_axisangle_size_to_mat4(float mat[4][4], const float loc[3], const float axis[3], const float angle, const float size[3])
+void loc_axisangle_size_to_mat4(float mat[4][4],
+ const float loc[3],
+ const float axis[3],
+ const float angle,
+ const float size[3])
{
- float q[4];
- axis_angle_to_quat(q, axis, angle);
- loc_quat_size_to_mat4(mat, loc, q, size);
+ float q[4];
+ axis_angle_to_quat(q, axis, angle);
+ loc_quat_size_to_mat4(mat, loc, q, size);
}
/*********************************** Other ***********************************/
void print_m3(const char *str, const float m[3][3])
{
- printf("%s\n", str);
- printf("%f %f %f\n", m[0][0], m[1][0], m[2][0]);
- printf("%f %f %f\n", m[0][1], m[1][1], m[2][1]);
- printf("%f %f %f\n", m[0][2], m[1][2], m[2][2]);
- printf("\n");
+ printf("%s\n", str);
+ printf("%f %f %f\n", m[0][0], m[1][0], m[2][0]);
+ printf("%f %f %f\n", m[0][1], m[1][1], m[2][1]);
+ printf("%f %f %f\n", m[0][2], m[1][2], m[2][2]);
+ printf("\n");
}
void print_m4(const char *str, const float m[4][4])
{
- printf("%s\n", str);
- printf("%f %f %f %f\n", m[0][0], m[1][0], m[2][0], m[3][0]);
- printf("%f %f %f %f\n", m[0][1], m[1][1], m[2][1], m[3][1]);
- printf("%f %f %f %f\n", m[0][2], m[1][2], m[2][2], m[3][2]);
- printf("%f %f %f %f\n", m[0][3], m[1][3], m[2][3], m[3][3]);
- printf("\n");
+ printf("%s\n", str);
+ printf("%f %f %f %f\n", m[0][0], m[1][0], m[2][0], m[3][0]);
+ printf("%f %f %f %f\n", m[0][1], m[1][1], m[2][1], m[3][1]);
+ printf("%f %f %f %f\n", m[0][2], m[1][2], m[2][2], m[3][2]);
+ printf("%f %f %f %f\n", m[0][3], m[1][3], m[2][3], m[3][3]);
+ printf("\n");
}
/*********************************** SVD ************************************
@@ -2093,501 +2127,495 @@ void print_m4(const char *str, const float m[4][4])
void svd_m4(float U[4][4], float s[4], float V[4][4], float A_[4][4])
{
- float A[4][4];
- float work1[4], work2[4];
- int m = 4;
- int n = 4;
- int maxiter = 200;
- int nu = min_ii(m, n);
-
- float *work = work1;
- float *e = work2;
- float eps;
-
- int i = 0, j = 0, k = 0, p, pp, iter;
-
- /* Reduce A to bidiagonal form, storing the diagonal elements
- * in s and the super-diagonal elements in e. */
-
- int nct = min_ii(m - 1, n);
- int nrt = max_ii(0, min_ii(n - 2, m));
-
- copy_m4_m4(A, A_);
- zero_m4(U);
- zero_v4(s);
-
- for (k = 0; k < max_ii(nct, nrt); k++) {
- if (k < nct) {
-
- /* Compute the transformation for the k-th column and
- * place the k-th diagonal in s[k].
- * Compute 2-norm of k-th column without under/overflow. */
- s[k] = 0;
- for (i = k; i < m; i++) {
- s[k] = hypotf(s[k], A[i][k]);
- }
- if (s[k] != 0.0f) {
- float invsk;
- if (A[k][k] < 0.0f) {
- s[k] = -s[k];
- }
- invsk = 1.0f / s[k];
- for (i = k; i < m; i++) {
- A[i][k] *= invsk;
- }
- A[k][k] += 1.0f;
- }
- s[k] = -s[k];
- }
- for (j = k + 1; j < n; j++) {
- if ((k < nct) && (s[k] != 0.0f)) {
-
- /* Apply the transformation. */
-
- float t = 0;
- for (i = k; i < m; i++) {
- t += A[i][k] * A[i][j];
- }
- t = -t / A[k][k];
- for (i = k; i < m; i++) {
- A[i][j] += t * A[i][k];
- }
- }
-
- /* Place the k-th row of A into e for the */
- /* subsequent calculation of the row transformation. */
-
- e[j] = A[k][j];
- }
- if (k < nct) {
-
- /* Place the transformation in U for subsequent back
- * multiplication. */
-
- for (i = k; i < m; i++) {
- U[i][k] = A[i][k];
- }
- }
- if (k < nrt) {
-
- /* Compute the k-th row transformation and place the
- * k-th super-diagonal in e[k].
- * Compute 2-norm without under/overflow. */
- e[k] = 0;
- for (i = k + 1; i < n; i++) {
- e[k] = hypotf(e[k], e[i]);
- }
- if (e[k] != 0.0f) {
- float invek;
- if (e[k + 1] < 0.0f) {
- e[k] = -e[k];
- }
- invek = 1.0f / e[k];
- for (i = k + 1; i < n; i++) {
- e[i] *= invek;
- }
- e[k + 1] += 1.0f;
- }
- e[k] = -e[k];
- if ((k + 1 < m) & (e[k] != 0.0f)) {
- float invek1;
-
- /* Apply the transformation. */
-
- for (i = k + 1; i < m; i++) {
- work[i] = 0.0f;
- }
- for (j = k + 1; j < n; j++) {
- for (i = k + 1; i < m; i++) {
- work[i] += e[j] * A[i][j];
- }
- }
- invek1 = 1.0f / e[k + 1];
- for (j = k + 1; j < n; j++) {
- float t = -e[j] * invek1;
- for (i = k + 1; i < m; i++) {
- A[i][j] += t * work[i];
- }
- }
- }
-
- /* Place the transformation in V for subsequent
- * back multiplication. */
-
- for (i = k + 1; i < n; i++) {
- V[i][k] = e[i];
- }
- }
- }
-
- /* Set up the final bidiagonal matrix or order p. */
-
- p = min_ii(n, m + 1);
- if (nct < n) {
- s[nct] = A[nct][nct];
- }
- if (m < p) {
- s[p - 1] = 0.0f;
- }
- if (nrt + 1 < p) {
- e[nrt] = A[nrt][p - 1];
- }
- e[p - 1] = 0.0f;
-
- /* If required, generate U. */
-
- for (j = nct; j < nu; j++) {
- for (i = 0; i < m; i++) {
- U[i][j] = 0.0f;
- }
- U[j][j] = 1.0f;
- }
- for (k = nct - 1; k >= 0; k--) {
- if (s[k] != 0.0f) {
- for (j = k + 1; j < nu; j++) {
- float t = 0;
- for (i = k; i < m; i++) {
- t += U[i][k] * U[i][j];
- }
- t = -t / U[k][k];
- for (i = k; i < m; i++) {
- U[i][j] += t * U[i][k];
- }
- }
- for (i = k; i < m; i++) {
- U[i][k] = -U[i][k];
- }
- U[k][k] = 1.0f + U[k][k];
- for (i = 0; i < k - 1; i++) {
- U[i][k] = 0.0f;
- }
- }
- else {
- for (i = 0; i < m; i++) {
- U[i][k] = 0.0f;
- }
- U[k][k] = 1.0f;
- }
- }
-
- /* If required, generate V. */
-
- for (k = n - 1; k >= 0; k--) {
- if ((k < nrt) & (e[k] != 0.0f)) {
- for (j = k + 1; j < nu; j++) {
- float t = 0;
- for (i = k + 1; i < n; i++) {
- t += V[i][k] * V[i][j];
- }
- t = -t / V[k + 1][k];
- for (i = k + 1; i < n; i++) {
- V[i][j] += t * V[i][k];
- }
- }
- }
- for (i = 0; i < n; i++) {
- V[i][k] = 0.0f;
- }
- V[k][k] = 1.0f;
- }
-
- /* Main iteration loop for the singular values. */
-
- pp = p - 1;
- iter = 0;
- eps = powf(2.0f, -52.0f);
- while (p > 0) {
- int kase = 0;
-
- /* Test for maximum iterations to avoid infinite loop */
- if (maxiter == 0) {
- break;
- }
- maxiter--;
-
- /* This section of the program inspects for
- * negligible elements in the s and e arrays. On
- * completion the variables kase and k are set as follows.
- *
- * kase = 1: if s(p) and e[k - 1] are negligible and k<p
- * kase = 2: if s(k) is negligible and k<p
- * kase = 3: if e[k - 1] is negligible, k<p, and
- * s(k), ..., s(p) are not negligible (qr step).
- * kase = 4: if e(p - 1) is negligible (convergence). */
-
- for (k = p - 2; k >= -1; k--) {
- if (k == -1) {
- break;
- }
- if (fabsf(e[k]) <= eps * (fabsf(s[k]) + fabsf(s[k + 1]))) {
- e[k] = 0.0f;
- break;
- }
- }
- if (k == p - 2) {
- kase = 4;
- }
- else {
- int ks;
- for (ks = p - 1; ks >= k; ks--) {
- float t;
- if (ks == k) {
- break;
- }
- t = (ks != p ? fabsf(e[ks]) : 0.f) +
- (ks != k + 1 ? fabsf(e[ks - 1]) : 0.0f);
- if (fabsf(s[ks]) <= eps * t) {
- s[ks] = 0.0f;
- break;
- }
- }
- if (ks == k) {
- kase = 3;
- }
- else if (ks == p - 1) {
- kase = 1;
- }
- else {
- kase = 2;
- k = ks;
- }
- }
- k++;
-
- /* Perform the task indicated by kase. */
-
- switch (kase) {
-
- /* Deflate negligible s(p). */
-
- case 1:
- {
- float f = e[p - 2];
- e[p - 2] = 0.0f;
- for (j = p - 2; j >= k; j--) {
- float t = hypotf(s[j], f);
- float invt = 1.0f / t;
- float cs = s[j] * invt;
- float sn = f * invt;
- s[j] = t;
- if (j != k) {
- f = -sn * e[j - 1];
- e[j - 1] = cs * e[j - 1];
- }
-
- for (i = 0; i < n; i++) {
- t = cs * V[i][j] + sn * V[i][p - 1];
- V[i][p - 1] = -sn * V[i][j] + cs * V[i][p - 1];
- V[i][j] = t;
- }
- }
- break;
- }
-
- /* Split at negligible s(k). */
-
- case 2:
- {
- float f = e[k - 1];
- e[k - 1] = 0.0f;
- for (j = k; j < p; j++) {
- float t = hypotf(s[j], f);
- float invt = 1.0f / t;
- float cs = s[j] * invt;
- float sn = f * invt;
- s[j] = t;
- f = -sn * e[j];
- e[j] = cs * e[j];
-
- for (i = 0; i < m; i++) {
- t = cs * U[i][j] + sn * U[i][k - 1];
- U[i][k - 1] = -sn * U[i][j] + cs * U[i][k - 1];
- U[i][j] = t;
- }
- }
- break;
- }
-
- /* Perform one qr step. */
-
- case 3:
- {
-
- /* Calculate the shift. */
-
- float scale = max_ff(max_ff(max_ff(max_ff(
- fabsf(s[p - 1]), fabsf(s[p - 2])), fabsf(e[p - 2])),
- fabsf(s[k])), fabsf(e[k]));
- float invscale = 1.0f / scale;
- float sp = s[p - 1] * invscale;
- float spm1 = s[p - 2] * invscale;
- float epm1 = e[p - 2] * invscale;
- float sk = s[k] * invscale;
- float ek = e[k] * invscale;
- float b = ((spm1 + sp) * (spm1 - sp) + epm1 * epm1) * 0.5f;
- float c = (sp * epm1) * (sp * epm1);
- float shift = 0.0f;
- float f, g;
- if ((b != 0.0f) || (c != 0.0f)) {
- shift = sqrtf(b * b + c);
- if (b < 0.0f) {
- shift = -shift;
- }
- shift = c / (b + shift);
- }
- f = (sk + sp) * (sk - sp) + shift;
- g = sk * ek;
-
- /* Chase zeros. */
-
- for (j = k; j < p - 1; j++) {
- float t = hypotf(f, g);
- /* division by zero checks added to avoid NaN (brecht) */
- float cs = (t == 0.0f) ? 0.0f : f / t;
- float sn = (t == 0.0f) ? 0.0f : g / t;
- if (j != k) {
- e[j - 1] = t;
- }
- f = cs * s[j] + sn * e[j];
- e[j] = cs * e[j] - sn * s[j];
- g = sn * s[j + 1];
- s[j + 1] = cs * s[j + 1];
-
- for (i = 0; i < n; i++) {
- t = cs * V[i][j] + sn * V[i][j + 1];
- V[i][j + 1] = -sn * V[i][j] + cs * V[i][j + 1];
- V[i][j] = t;
- }
-
- t = hypotf(f, g);
- /* division by zero checks added to avoid NaN (brecht) */
- cs = (t == 0.0f) ? 0.0f : f / t;
- sn = (t == 0.0f) ? 0.0f : g / t;
- s[j] = t;
- f = cs * e[j] + sn * s[j + 1];
- s[j + 1] = -sn * e[j] + cs * s[j + 1];
- g = sn * e[j + 1];
- e[j + 1] = cs * e[j + 1];
- if (j < m - 1) {
- for (i = 0; i < m; i++) {
- t = cs * U[i][j] + sn * U[i][j + 1];
- U[i][j + 1] = -sn * U[i][j] + cs * U[i][j + 1];
- U[i][j] = t;
- }
- }
- }
- e[p - 2] = f;
- iter = iter + 1;
- break;
- }
- /* Convergence. */
-
- case 4:
- {
-
- /* Make the singular values positive. */
-
- if (s[k] <= 0.0f) {
- s[k] = (s[k] < 0.0f ? -s[k] : 0.0f);
-
- for (i = 0; i <= pp; i++) {
- V[i][k] = -V[i][k];
- }
- }
-
- /* Order the singular values. */
-
- while (k < pp) {
- float t;
- if (s[k] >= s[k + 1]) {
- break;
- }
- t = s[k];
- s[k] = s[k + 1];
- s[k + 1] = t;
- if (k < n - 1) {
- for (i = 0; i < n; i++) {
- t = V[i][k + 1];
- V[i][k + 1] = V[i][k];
- V[i][k] = t;
- }
- }
- if (k < m - 1) {
- for (i = 0; i < m; i++) {
- t = U[i][k + 1];
- U[i][k + 1] = U[i][k];
- U[i][k] = t;
- }
- }
- k++;
- }
- iter = 0;
- p--;
- break;
- }
- }
- }
+ float A[4][4];
+ float work1[4], work2[4];
+ int m = 4;
+ int n = 4;
+ int maxiter = 200;
+ int nu = min_ii(m, n);
+
+ float *work = work1;
+ float *e = work2;
+ float eps;
+
+ int i = 0, j = 0, k = 0, p, pp, iter;
+
+ /* Reduce A to bidiagonal form, storing the diagonal elements
+ * in s and the super-diagonal elements in e. */
+
+ int nct = min_ii(m - 1, n);
+ int nrt = max_ii(0, min_ii(n - 2, m));
+
+ copy_m4_m4(A, A_);
+ zero_m4(U);
+ zero_v4(s);
+
+ for (k = 0; k < max_ii(nct, nrt); k++) {
+ if (k < nct) {
+
+ /* Compute the transformation for the k-th column and
+ * place the k-th diagonal in s[k].
+ * Compute 2-norm of k-th column without under/overflow. */
+ s[k] = 0;
+ for (i = k; i < m; i++) {
+ s[k] = hypotf(s[k], A[i][k]);
+ }
+ if (s[k] != 0.0f) {
+ float invsk;
+ if (A[k][k] < 0.0f) {
+ s[k] = -s[k];
+ }
+ invsk = 1.0f / s[k];
+ for (i = k; i < m; i++) {
+ A[i][k] *= invsk;
+ }
+ A[k][k] += 1.0f;
+ }
+ s[k] = -s[k];
+ }
+ for (j = k + 1; j < n; j++) {
+ if ((k < nct) && (s[k] != 0.0f)) {
+
+ /* Apply the transformation. */
+
+ float t = 0;
+ for (i = k; i < m; i++) {
+ t += A[i][k] * A[i][j];
+ }
+ t = -t / A[k][k];
+ for (i = k; i < m; i++) {
+ A[i][j] += t * A[i][k];
+ }
+ }
+
+ /* Place the k-th row of A into e for the */
+ /* subsequent calculation of the row transformation. */
+
+ e[j] = A[k][j];
+ }
+ if (k < nct) {
+
+ /* Place the transformation in U for subsequent back
+ * multiplication. */
+
+ for (i = k; i < m; i++) {
+ U[i][k] = A[i][k];
+ }
+ }
+ if (k < nrt) {
+
+ /* Compute the k-th row transformation and place the
+ * k-th super-diagonal in e[k].
+ * Compute 2-norm without under/overflow. */
+ e[k] = 0;
+ for (i = k + 1; i < n; i++) {
+ e[k] = hypotf(e[k], e[i]);
+ }
+ if (e[k] != 0.0f) {
+ float invek;
+ if (e[k + 1] < 0.0f) {
+ e[k] = -e[k];
+ }
+ invek = 1.0f / e[k];
+ for (i = k + 1; i < n; i++) {
+ e[i] *= invek;
+ }
+ e[k + 1] += 1.0f;
+ }
+ e[k] = -e[k];
+ if ((k + 1 < m) & (e[k] != 0.0f)) {
+ float invek1;
+
+ /* Apply the transformation. */
+
+ for (i = k + 1; i < m; i++) {
+ work[i] = 0.0f;
+ }
+ for (j = k + 1; j < n; j++) {
+ for (i = k + 1; i < m; i++) {
+ work[i] += e[j] * A[i][j];
+ }
+ }
+ invek1 = 1.0f / e[k + 1];
+ for (j = k + 1; j < n; j++) {
+ float t = -e[j] * invek1;
+ for (i = k + 1; i < m; i++) {
+ A[i][j] += t * work[i];
+ }
+ }
+ }
+
+ /* Place the transformation in V for subsequent
+ * back multiplication. */
+
+ for (i = k + 1; i < n; i++) {
+ V[i][k] = e[i];
+ }
+ }
+ }
+
+ /* Set up the final bidiagonal matrix or order p. */
+
+ p = min_ii(n, m + 1);
+ if (nct < n) {
+ s[nct] = A[nct][nct];
+ }
+ if (m < p) {
+ s[p - 1] = 0.0f;
+ }
+ if (nrt + 1 < p) {
+ e[nrt] = A[nrt][p - 1];
+ }
+ e[p - 1] = 0.0f;
+
+ /* If required, generate U. */
+
+ for (j = nct; j < nu; j++) {
+ for (i = 0; i < m; i++) {
+ U[i][j] = 0.0f;
+ }
+ U[j][j] = 1.0f;
+ }
+ for (k = nct - 1; k >= 0; k--) {
+ if (s[k] != 0.0f) {
+ for (j = k + 1; j < nu; j++) {
+ float t = 0;
+ for (i = k; i < m; i++) {
+ t += U[i][k] * U[i][j];
+ }
+ t = -t / U[k][k];
+ for (i = k; i < m; i++) {
+ U[i][j] += t * U[i][k];
+ }
+ }
+ for (i = k; i < m; i++) {
+ U[i][k] = -U[i][k];
+ }
+ U[k][k] = 1.0f + U[k][k];
+ for (i = 0; i < k - 1; i++) {
+ U[i][k] = 0.0f;
+ }
+ }
+ else {
+ for (i = 0; i < m; i++) {
+ U[i][k] = 0.0f;
+ }
+ U[k][k] = 1.0f;
+ }
+ }
+
+ /* If required, generate V. */
+
+ for (k = n - 1; k >= 0; k--) {
+ if ((k < nrt) & (e[k] != 0.0f)) {
+ for (j = k + 1; j < nu; j++) {
+ float t = 0;
+ for (i = k + 1; i < n; i++) {
+ t += V[i][k] * V[i][j];
+ }
+ t = -t / V[k + 1][k];
+ for (i = k + 1; i < n; i++) {
+ V[i][j] += t * V[i][k];
+ }
+ }
+ }
+ for (i = 0; i < n; i++) {
+ V[i][k] = 0.0f;
+ }
+ V[k][k] = 1.0f;
+ }
+
+ /* Main iteration loop for the singular values. */
+
+ pp = p - 1;
+ iter = 0;
+ eps = powf(2.0f, -52.0f);
+ while (p > 0) {
+ int kase = 0;
+
+ /* Test for maximum iterations to avoid infinite loop */
+ if (maxiter == 0) {
+ break;
+ }
+ maxiter--;
+
+ /* This section of the program inspects for
+ * negligible elements in the s and e arrays. On
+ * completion the variables kase and k are set as follows.
+ *
+ * kase = 1: if s(p) and e[k - 1] are negligible and k<p
+ * kase = 2: if s(k) is negligible and k<p
+ * kase = 3: if e[k - 1] is negligible, k<p, and
+ * s(k), ..., s(p) are not negligible (qr step).
+ * kase = 4: if e(p - 1) is negligible (convergence). */
+
+ for (k = p - 2; k >= -1; k--) {
+ if (k == -1) {
+ break;
+ }
+ if (fabsf(e[k]) <= eps * (fabsf(s[k]) + fabsf(s[k + 1]))) {
+ e[k] = 0.0f;
+ break;
+ }
+ }
+ if (k == p - 2) {
+ kase = 4;
+ }
+ else {
+ int ks;
+ for (ks = p - 1; ks >= k; ks--) {
+ float t;
+ if (ks == k) {
+ break;
+ }
+ t = (ks != p ? fabsf(e[ks]) : 0.f) + (ks != k + 1 ? fabsf(e[ks - 1]) : 0.0f);
+ if (fabsf(s[ks]) <= eps * t) {
+ s[ks] = 0.0f;
+ break;
+ }
+ }
+ if (ks == k) {
+ kase = 3;
+ }
+ else if (ks == p - 1) {
+ kase = 1;
+ }
+ else {
+ kase = 2;
+ k = ks;
+ }
+ }
+ k++;
+
+ /* Perform the task indicated by kase. */
+
+ switch (kase) {
+
+ /* Deflate negligible s(p). */
+
+ case 1: {
+ float f = e[p - 2];
+ e[p - 2] = 0.0f;
+ for (j = p - 2; j >= k; j--) {
+ float t = hypotf(s[j], f);
+ float invt = 1.0f / t;
+ float cs = s[j] * invt;
+ float sn = f * invt;
+ s[j] = t;
+ if (j != k) {
+ f = -sn * e[j - 1];
+ e[j - 1] = cs * e[j - 1];
+ }
+
+ for (i = 0; i < n; i++) {
+ t = cs * V[i][j] + sn * V[i][p - 1];
+ V[i][p - 1] = -sn * V[i][j] + cs * V[i][p - 1];
+ V[i][j] = t;
+ }
+ }
+ break;
+ }
+
+ /* Split at negligible s(k). */
+
+ case 2: {
+ float f = e[k - 1];
+ e[k - 1] = 0.0f;
+ for (j = k; j < p; j++) {
+ float t = hypotf(s[j], f);
+ float invt = 1.0f / t;
+ float cs = s[j] * invt;
+ float sn = f * invt;
+ s[j] = t;
+ f = -sn * e[j];
+ e[j] = cs * e[j];
+
+ for (i = 0; i < m; i++) {
+ t = cs * U[i][j] + sn * U[i][k - 1];
+ U[i][k - 1] = -sn * U[i][j] + cs * U[i][k - 1];
+ U[i][j] = t;
+ }
+ }
+ break;
+ }
+
+ /* Perform one qr step. */
+
+ case 3: {
+
+ /* Calculate the shift. */
+
+ float scale = max_ff(
+ max_ff(max_ff(max_ff(fabsf(s[p - 1]), fabsf(s[p - 2])), fabsf(e[p - 2])), fabsf(s[k])),
+ fabsf(e[k]));
+ float invscale = 1.0f / scale;
+ float sp = s[p - 1] * invscale;
+ float spm1 = s[p - 2] * invscale;
+ float epm1 = e[p - 2] * invscale;
+ float sk = s[k] * invscale;
+ float ek = e[k] * invscale;
+ float b = ((spm1 + sp) * (spm1 - sp) + epm1 * epm1) * 0.5f;
+ float c = (sp * epm1) * (sp * epm1);
+ float shift = 0.0f;
+ float f, g;
+ if ((b != 0.0f) || (c != 0.0f)) {
+ shift = sqrtf(b * b + c);
+ if (b < 0.0f) {
+ shift = -shift;
+ }
+ shift = c / (b + shift);
+ }
+ f = (sk + sp) * (sk - sp) + shift;
+ g = sk * ek;
+
+ /* Chase zeros. */
+
+ for (j = k; j < p - 1; j++) {
+ float t = hypotf(f, g);
+ /* division by zero checks added to avoid NaN (brecht) */
+ float cs = (t == 0.0f) ? 0.0f : f / t;
+ float sn = (t == 0.0f) ? 0.0f : g / t;
+ if (j != k) {
+ e[j - 1] = t;
+ }
+ f = cs * s[j] + sn * e[j];
+ e[j] = cs * e[j] - sn * s[j];
+ g = sn * s[j + 1];
+ s[j + 1] = cs * s[j + 1];
+
+ for (i = 0; i < n; i++) {
+ t = cs * V[i][j] + sn * V[i][j + 1];
+ V[i][j + 1] = -sn * V[i][j] + cs * V[i][j + 1];
+ V[i][j] = t;
+ }
+
+ t = hypotf(f, g);
+ /* division by zero checks added to avoid NaN (brecht) */
+ cs = (t == 0.0f) ? 0.0f : f / t;
+ sn = (t == 0.0f) ? 0.0f : g / t;
+ s[j] = t;
+ f = cs * e[j] + sn * s[j + 1];
+ s[j + 1] = -sn * e[j] + cs * s[j + 1];
+ g = sn * e[j + 1];
+ e[j + 1] = cs * e[j + 1];
+ if (j < m - 1) {
+ for (i = 0; i < m; i++) {
+ t = cs * U[i][j] + sn * U[i][j + 1];
+ U[i][j + 1] = -sn * U[i][j] + cs * U[i][j + 1];
+ U[i][j] = t;
+ }
+ }
+ }
+ e[p - 2] = f;
+ iter = iter + 1;
+ break;
+ }
+ /* Convergence. */
+
+ case 4: {
+
+ /* Make the singular values positive. */
+
+ if (s[k] <= 0.0f) {
+ s[k] = (s[k] < 0.0f ? -s[k] : 0.0f);
+
+ for (i = 0; i <= pp; i++) {
+ V[i][k] = -V[i][k];
+ }
+ }
+
+ /* Order the singular values. */
+
+ while (k < pp) {
+ float t;
+ if (s[k] >= s[k + 1]) {
+ break;
+ }
+ t = s[k];
+ s[k] = s[k + 1];
+ s[k + 1] = t;
+ if (k < n - 1) {
+ for (i = 0; i < n; i++) {
+ t = V[i][k + 1];
+ V[i][k + 1] = V[i][k];
+ V[i][k] = t;
+ }
+ }
+ if (k < m - 1) {
+ for (i = 0; i < m; i++) {
+ t = U[i][k + 1];
+ U[i][k + 1] = U[i][k];
+ U[i][k] = t;
+ }
+ }
+ k++;
+ }
+ iter = 0;
+ p--;
+ break;
+ }
+ }
+ }
}
void pseudoinverse_m4_m4(float Ainv[4][4], const float A_[4][4], float epsilon)
{
- /* compute Moore-Penrose pseudo inverse of matrix, singular values
- * below epsilon are ignored for stability (truncated SVD) */
- float A[4][4], V[4][4], W[4], Wm[4][4], U[4][4];
- int i;
+ /* compute Moore-Penrose pseudo inverse of matrix, singular values
+ * below epsilon are ignored for stability (truncated SVD) */
+ float A[4][4], V[4][4], W[4], Wm[4][4], U[4][4];
+ int i;
- transpose_m4_m4(A, A_);
- svd_m4(V, W, U, A);
- transpose_m4(U);
- transpose_m4(V);
+ transpose_m4_m4(A, A_);
+ svd_m4(V, W, U, A);
+ transpose_m4(U);
+ transpose_m4(V);
- zero_m4(Wm);
- for (i = 0; i < 4; i++) {
- Wm[i][i] = (W[i] < epsilon) ? 0.0f : 1.0f / W[i];
- }
+ zero_m4(Wm);
+ for (i = 0; i < 4; i++) {
+ Wm[i][i] = (W[i] < epsilon) ? 0.0f : 1.0f / W[i];
+ }
- transpose_m4(V);
+ transpose_m4(V);
- mul_m4_series(Ainv, U, Wm, V);
+ mul_m4_series(Ainv, U, Wm, V);
}
void pseudoinverse_m3_m3(float Ainv[3][3], const float A[3][3], float epsilon)
{
- /* try regular inverse when possible, otherwise fall back to slow svd */
- if (!invert_m3_m3(Ainv, A)) {
- float tmp[4][4], tmpinv[4][4];
+ /* try regular inverse when possible, otherwise fall back to slow svd */
+ if (!invert_m3_m3(Ainv, A)) {
+ float tmp[4][4], tmpinv[4][4];
- copy_m4_m3(tmp, A);
- pseudoinverse_m4_m4(tmpinv, tmp, epsilon);
- copy_m3_m4(Ainv, tmpinv);
- }
+ copy_m4_m3(tmp, A);
+ pseudoinverse_m4_m4(tmpinv, tmp, epsilon);
+ copy_m3_m4(Ainv, tmpinv);
+ }
}
bool has_zero_axis_m4(const float matrix[4][4])
{
- return len_squared_v3(matrix[0]) < FLT_EPSILON ||
- len_squared_v3(matrix[1]) < FLT_EPSILON ||
- len_squared_v3(matrix[2]) < FLT_EPSILON;
+ return len_squared_v3(matrix[0]) < FLT_EPSILON || len_squared_v3(matrix[1]) < FLT_EPSILON ||
+ len_squared_v3(matrix[2]) < FLT_EPSILON;
}
void invert_m4_m4_safe(float Ainv[4][4], const float A[4][4])
{
- if (!invert_m4_m4(Ainv, A)) {
- float Atemp[4][4];
+ if (!invert_m4_m4(Ainv, A)) {
+ float Atemp[4][4];
- copy_m4_m4(Atemp, A);
+ copy_m4_m4(Atemp, A);
- /* Matrix is degenerate (e.g. 0 scale on some axis), ideally we should
- * never be in this situation, but try to invert it anyway with tweak.
- */
- Atemp[0][0] += 1e-8f;
- Atemp[1][1] += 1e-8f;
- Atemp[2][2] += 1e-8f;
+ /* Matrix is degenerate (e.g. 0 scale on some axis), ideally we should
+ * never be in this situation, but try to invert it anyway with tweak.
+ */
+ Atemp[0][0] += 1e-8f;
+ Atemp[1][1] += 1e-8f;
+ Atemp[2][2] += 1e-8f;
- if (!invert_m4_m4(Ainv, Atemp)) {
- unit_m4(Ainv);
- }
- }
+ if (!invert_m4_m4(Ainv, Atemp)) {
+ unit_m4(Ainv);
+ }
+ }
}
/**
@@ -2617,12 +2645,14 @@ void invert_m4_m4_safe(float Ainv[4][4], const float A[4][4])
* this defines a transform matrix TM such that (x', y', z') = TM * (x, y, z)
* where (x', y', z') are the coordinates of P' in target space such that it keeps (X, Y, Z) coordinates in global space.
*/
-void BLI_space_transform_from_matrices(SpaceTransform *data, const float local[4][4], const float target[4][4])
+void BLI_space_transform_from_matrices(SpaceTransform *data,
+ const float local[4][4],
+ const float target[4][4])
{
- float itarget[4][4];
- invert_m4_m4(itarget, target);
- mul_m4_m4m4(data->local2target, itarget, local);
- invert_m4_m4(data->target2local, data->local2target);
+ float itarget[4][4];
+ invert_m4_m4(itarget, target);
+ mul_m4_m4m4(data->local2target, itarget, local);
+ invert_m4_m4(data->target2local, data->local2target);
}
/**
@@ -2635,32 +2665,34 @@ void BLI_space_transform_from_matrices(SpaceTransform *data, const float local[4
* this defines a transform matrix TM such that (X', Y', Z') = TM * (X, Y, Z)
* where (X', Y', Z') are the coordinates of p' in global space such that it keeps (x, y, z) coordinates in target space.
*/
-void BLI_space_transform_global_from_matrices(SpaceTransform *data, const float local[4][4], const float target[4][4])
+void BLI_space_transform_global_from_matrices(SpaceTransform *data,
+ const float local[4][4],
+ const float target[4][4])
{
- float ilocal[4][4];
- invert_m4_m4(ilocal, local);
- mul_m4_m4m4(data->local2target, target, ilocal);
- invert_m4_m4(data->target2local, data->local2target);
+ float ilocal[4][4];
+ invert_m4_m4(ilocal, local);
+ mul_m4_m4m4(data->local2target, target, ilocal);
+ invert_m4_m4(data->target2local, data->local2target);
}
void BLI_space_transform_apply(const SpaceTransform *data, float co[3])
{
- mul_v3_m4v3(co, ((SpaceTransform *)data)->local2target, co);
+ mul_v3_m4v3(co, ((SpaceTransform *)data)->local2target, co);
}
void BLI_space_transform_invert(const SpaceTransform *data, float co[3])
{
- mul_v3_m4v3(co, ((SpaceTransform *)data)->target2local, co);
+ mul_v3_m4v3(co, ((SpaceTransform *)data)->target2local, co);
}
void BLI_space_transform_apply_normal(const SpaceTransform *data, float no[3])
{
- mul_mat3_m4_v3(((SpaceTransform *)data)->local2target, no);
- normalize_v3(no);
+ mul_mat3_m4_v3(((SpaceTransform *)data)->local2target, no);
+ normalize_v3(no);
}
void BLI_space_transform_invert_normal(const SpaceTransform *data, float no[3])
{
- mul_mat3_m4_v3(((SpaceTransform *)data)->target2local, no);
- normalize_v3(no);
+ mul_mat3_m4_v3(((SpaceTransform *)data)->target2local, no);
+ normalize_v3(no);
}
diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c
index b1bed27d2bd..47814b1080c 100644
--- a/source/blender/blenlib/intern/math_rotation.c
+++ b/source/blender/blenlib/intern/math_rotation.c
@@ -38,42 +38,42 @@
/* convenience, avoids setting Y axis everywhere */
void unit_axis_angle(float axis[3], float *angle)
{
- axis[0] = 0.0f;
- axis[1] = 1.0f;
- axis[2] = 0.0f;
- *angle = 0.0f;
+ axis[0] = 0.0f;
+ axis[1] = 1.0f;
+ axis[2] = 0.0f;
+ *angle = 0.0f;
}
void unit_qt(float q[4])
{
- q[0] = 1.0f;
- q[1] = q[2] = q[3] = 0.0f;
+ q[0] = 1.0f;
+ q[1] = q[2] = q[3] = 0.0f;
}
void copy_qt_qt(float q1[4], const float q2[4])
{
- q1[0] = q2[0];
- q1[1] = q2[1];
- q1[2] = q2[2];
- q1[3] = q2[3];
+ q1[0] = q2[0];
+ q1[1] = q2[1];
+ q1[2] = q2[2];
+ q1[3] = q2[3];
}
bool is_zero_qt(const float q[4])
{
- return (q[0] == 0 && q[1] == 0 && q[2] == 0 && q[3] == 0);
+ return (q[0] == 0 && q[1] == 0 && q[2] == 0 && q[3] == 0);
}
void mul_qt_qtqt(float q[4], const float q1[4], const float q2[4])
{
- float t0, t1, t2;
+ float t0, t1, t2;
- t0 = q1[0] * q2[0] - q1[1] * q2[1] - q1[2] * q2[2] - q1[3] * q2[3];
- t1 = q1[0] * q2[1] + q1[1] * q2[0] + q1[2] * q2[3] - q1[3] * q2[2];
- t2 = q1[0] * q2[2] + q1[2] * q2[0] + q1[3] * q2[1] - q1[1] * q2[3];
- q[3] = q1[0] * q2[3] + q1[3] * q2[0] + q1[1] * q2[2] - q1[2] * q2[1];
- q[0] = t0;
- q[1] = t1;
- q[2] = t2;
+ t0 = q1[0] * q2[0] - q1[1] * q2[1] - q1[2] * q2[2] - q1[3] * q2[3];
+ t1 = q1[0] * q2[1] + q1[1] * q2[0] + q1[2] * q2[3] - q1[3] * q2[2];
+ t2 = q1[0] * q2[2] + q1[2] * q2[0] + q1[3] * q2[1] - q1[1] * q2[3];
+ q[3] = q1[0] * q2[3] + q1[3] * q2[0] + q1[1] * q2[2] - q1[2] * q2[1];
+ q[0] = t0;
+ q[1] = t1;
+ q[2] = t2;
}
/**
@@ -97,58 +97,58 @@ void mul_qt_qtqt(float q[4], const float q1[4], const float q2[4])
*/
void mul_qt_v3(const float q[4], float v[3])
{
- float t0, t1, t2;
+ float t0, t1, t2;
- t0 = -q[1] * v[0] - q[2] * v[1] - q[3] * v[2];
- t1 = q[0] * v[0] + q[2] * v[2] - q[3] * v[1];
- t2 = q[0] * v[1] + q[3] * v[0] - q[1] * v[2];
- v[2] = q[0] * v[2] + q[1] * v[1] - q[2] * v[0];
- v[0] = t1;
- v[1] = t2;
+ t0 = -q[1] * v[0] - q[2] * v[1] - q[3] * v[2];
+ t1 = q[0] * v[0] + q[2] * v[2] - q[3] * v[1];
+ t2 = q[0] * v[1] + q[3] * v[0] - q[1] * v[2];
+ v[2] = q[0] * v[2] + q[1] * v[1] - q[2] * v[0];
+ v[0] = t1;
+ v[1] = t2;
- t1 = t0 * -q[1] + v[0] * q[0] - v[1] * q[3] + v[2] * q[2];
- t2 = t0 * -q[2] + v[1] * q[0] - v[2] * q[1] + v[0] * q[3];
- v[2] = t0 * -q[3] + v[2] * q[0] - v[0] * q[2] + v[1] * q[1];
- v[0] = t1;
- v[1] = t2;
+ t1 = t0 * -q[1] + v[0] * q[0] - v[1] * q[3] + v[2] * q[2];
+ t2 = t0 * -q[2] + v[1] * q[0] - v[2] * q[1] + v[0] * q[3];
+ v[2] = t0 * -q[3] + v[2] * q[0] - v[0] * q[2] + v[1] * q[1];
+ v[0] = t1;
+ v[1] = t2;
}
void conjugate_qt_qt(float q1[4], const float q2[4])
{
- q1[0] = q2[0];
- q1[1] = -q2[1];
- q1[2] = -q2[2];
- q1[3] = -q2[3];
+ q1[0] = q2[0];
+ q1[1] = -q2[1];
+ q1[2] = -q2[2];
+ q1[3] = -q2[3];
}
void conjugate_qt(float q[4])
{
- q[1] = -q[1];
- q[2] = -q[2];
- q[3] = -q[3];
+ q[1] = -q[1];
+ q[2] = -q[2];
+ q[3] = -q[3];
}
float dot_qtqt(const float q1[4], const float q2[4])
{
- return q1[0] * q2[0] + q1[1] * q2[1] + q1[2] * q2[2] + q1[3] * q2[3];
+ return q1[0] * q2[0] + q1[1] * q2[1] + q1[2] * q2[2] + q1[3] * q2[3];
}
void invert_qt(float q[4])
{
- const float f = dot_qtqt(q, q);
+ const float f = dot_qtqt(q, q);
- if (f == 0.0f) {
- return;
- }
+ if (f == 0.0f) {
+ return;
+ }
- conjugate_qt(q);
- mul_qt_fl(q, 1.0f / f);
+ conjugate_qt(q);
+ mul_qt_fl(q, 1.0f / f);
}
void invert_qt_qt(float q1[4], const float q2[4])
{
- copy_qt_qt(q1, q2);
- invert_qt(q1);
+ copy_qt_qt(q1, q2);
+ invert_qt(q1);
}
/**
@@ -158,48 +158,47 @@ void invert_qt_qt(float q1[4], const float q2[4])
*/
void invert_qt_normalized(float q[4])
{
- BLI_ASSERT_UNIT_QUAT(q);
- conjugate_qt(q);
-
+ BLI_ASSERT_UNIT_QUAT(q);
+ conjugate_qt(q);
}
void invert_qt_qt_normalized(float q1[4], const float q2[4])
{
- copy_qt_qt(q1, q2);
- invert_qt_normalized(q1);
+ copy_qt_qt(q1, q2);
+ invert_qt_normalized(q1);
}
/* simple mult */
void mul_qt_fl(float q[4], const float f)
{
- q[0] *= f;
- q[1] *= f;
- q[2] *= f;
- q[3] *= f;
+ q[0] *= f;
+ q[1] *= f;
+ q[2] *= f;
+ q[3] *= f;
}
void sub_qt_qtqt(float q[4], const float q1[4], const float q2[4])
{
- float nq2[4];
+ float nq2[4];
- nq2[0] = -q2[0];
- nq2[1] = q2[1];
- nq2[2] = q2[2];
- nq2[3] = q2[3];
+ nq2[0] = -q2[0];
+ nq2[1] = q2[1];
+ nq2[2] = q2[2];
+ nq2[3] = q2[3];
- mul_qt_qtqt(q, q1, nq2);
+ mul_qt_qtqt(q, q1, nq2);
}
/* raise a unit quaternion to the specified power */
void pow_qt_fl_normalized(float q[4], const float fac)
{
- BLI_ASSERT_UNIT_QUAT(q);
- const float angle = fac * saacos(q[0]); /* quat[0] = cos(0.5 * angle),
- * but now the 0.5 and 2.0 rule out */
- const float co = cosf(angle);
- const float si = sinf(angle);
- q[0] = co;
- normalize_v3_length(q + 1, si);
+ BLI_ASSERT_UNIT_QUAT(q);
+ const float angle = fac * saacos(q[0]); /* quat[0] = cos(0.5 * angle),
+ * but now the 0.5 and 2.0 rule out */
+ const float co = cosf(angle);
+ const float si = sinf(angle);
+ q[0] = co;
+ normalize_v3_length(q + 1, si);
}
/**
@@ -208,248 +207,252 @@ void pow_qt_fl_normalized(float q[4], const float fac)
*/
void quat_to_compatible_quat(float q[4], const float a[4], const float old[4])
{
- const float eps = 1e-4f;
- BLI_ASSERT_UNIT_QUAT(a);
- float old_unit[4];
- /* Skips `!finite_v4(old)` case too. */
- if (normalize_qt_qt(old_unit, old) > eps) {
- float delta[4];
- rotation_between_quats_to_quat(delta, old_unit, a);
- mul_qt_qtqt(q, old, delta);
- if ((q[0] < 0.0f) != (old[0] < 0.0f)) {
- negate_v4(q);
- }
- }
- else {
- copy_qt_qt(q, a);
- }
+ const float eps = 1e-4f;
+ BLI_ASSERT_UNIT_QUAT(a);
+ float old_unit[4];
+ /* Skips `!finite_v4(old)` case too. */
+ if (normalize_qt_qt(old_unit, old) > eps) {
+ float delta[4];
+ rotation_between_quats_to_quat(delta, old_unit, a);
+ mul_qt_qtqt(q, old, delta);
+ if ((q[0] < 0.0f) != (old[0] < 0.0f)) {
+ negate_v4(q);
+ }
+ }
+ else {
+ copy_qt_qt(q, a);
+ }
}
/* skip error check, currently only needed by mat3_to_quat_is_ok */
static void quat_to_mat3_no_error(float m[3][3], const float q[4])
{
- double q0, q1, q2, q3, qda, qdb, qdc, qaa, qab, qac, qbb, qbc, qcc;
+ double q0, q1, q2, q3, qda, qdb, qdc, qaa, qab, qac, qbb, qbc, qcc;
- q0 = M_SQRT2 * (double)q[0];
- q1 = M_SQRT2 * (double)q[1];
- q2 = M_SQRT2 * (double)q[2];
- q3 = M_SQRT2 * (double)q[3];
+ q0 = M_SQRT2 * (double)q[0];
+ q1 = M_SQRT2 * (double)q[1];
+ q2 = M_SQRT2 * (double)q[2];
+ q3 = M_SQRT2 * (double)q[3];
- qda = q0 * q1;
- qdb = q0 * q2;
- qdc = q0 * q3;
- qaa = q1 * q1;
- qab = q1 * q2;
- qac = q1 * q3;
- qbb = q2 * q2;
- qbc = q2 * q3;
- qcc = q3 * q3;
+ qda = q0 * q1;
+ qdb = q0 * q2;
+ qdc = q0 * q3;
+ qaa = q1 * q1;
+ qab = q1 * q2;
+ qac = q1 * q3;
+ qbb = q2 * q2;
+ qbc = q2 * q3;
+ qcc = q3 * q3;
- m[0][0] = (float)(1.0 - qbb - qcc);
- m[0][1] = (float)(qdc + qab);
- m[0][2] = (float)(-qdb + qac);
+ m[0][0] = (float)(1.0 - qbb - qcc);
+ m[0][1] = (float)(qdc + qab);
+ m[0][2] = (float)(-qdb + qac);
- m[1][0] = (float)(-qdc + qab);
- m[1][1] = (float)(1.0 - qaa - qcc);
- m[1][2] = (float)(qda + qbc);
+ m[1][0] = (float)(-qdc + qab);
+ m[1][1] = (float)(1.0 - qaa - qcc);
+ m[1][2] = (float)(qda + qbc);
- m[2][0] = (float)(qdb + qac);
- m[2][1] = (float)(-qda + qbc);
- m[2][2] = (float)(1.0 - qaa - qbb);
+ m[2][0] = (float)(qdb + qac);
+ m[2][1] = (float)(-qda + qbc);
+ m[2][2] = (float)(1.0 - qaa - qbb);
}
void quat_to_mat3(float m[3][3], const float q[4])
{
#ifdef DEBUG
- float f;
- if (!((f = dot_qtqt(q, q)) == 0.0f || (fabsf(f - 1.0f) < (float)QUAT_EPSILON))) {
- fprintf(stderr, "Warning! quat_to_mat3() called with non-normalized: size %.8f *** report a bug ***\n", f);
- }
+ float f;
+ if (!((f = dot_qtqt(q, q)) == 0.0f || (fabsf(f - 1.0f) < (float)QUAT_EPSILON))) {
+ fprintf(stderr,
+ "Warning! quat_to_mat3() called with non-normalized: size %.8f *** report a bug ***\n",
+ f);
+ }
#endif
- quat_to_mat3_no_error(m, q);
+ quat_to_mat3_no_error(m, q);
}
void quat_to_mat4(float m[4][4], const float q[4])
{
- double q0, q1, q2, q3, qda, qdb, qdc, qaa, qab, qac, qbb, qbc, qcc;
+ double q0, q1, q2, q3, qda, qdb, qdc, qaa, qab, qac, qbb, qbc, qcc;
#ifdef DEBUG
- if (!((q0 = dot_qtqt(q, q)) == 0.0 || (fabs(q0 - 1.0) < QUAT_EPSILON))) {
- fprintf(stderr, "Warning! quat_to_mat4() called with non-normalized: size %.8f *** report a bug ***\n", (float)q0);
- }
+ if (!((q0 = dot_qtqt(q, q)) == 0.0 || (fabs(q0 - 1.0) < QUAT_EPSILON))) {
+ fprintf(stderr,
+ "Warning! quat_to_mat4() called with non-normalized: size %.8f *** report a bug ***\n",
+ (float)q0);
+ }
#endif
- q0 = M_SQRT2 * (double)q[0];
- q1 = M_SQRT2 * (double)q[1];
- q2 = M_SQRT2 * (double)q[2];
- q3 = M_SQRT2 * (double)q[3];
+ q0 = M_SQRT2 * (double)q[0];
+ q1 = M_SQRT2 * (double)q[1];
+ q2 = M_SQRT2 * (double)q[2];
+ q3 = M_SQRT2 * (double)q[3];
- qda = q0 * q1;
- qdb = q0 * q2;
- qdc = q0 * q3;
- qaa = q1 * q1;
- qab = q1 * q2;
- qac = q1 * q3;
- qbb = q2 * q2;
- qbc = q2 * q3;
- qcc = q3 * q3;
+ qda = q0 * q1;
+ qdb = q0 * q2;
+ qdc = q0 * q3;
+ qaa = q1 * q1;
+ qab = q1 * q2;
+ qac = q1 * q3;
+ qbb = q2 * q2;
+ qbc = q2 * q3;
+ qcc = q3 * q3;
- m[0][0] = (float)(1.0 - qbb - qcc);
- m[0][1] = (float)(qdc + qab);
- m[0][2] = (float)(-qdb + qac);
- m[0][3] = 0.0f;
+ m[0][0] = (float)(1.0 - qbb - qcc);
+ m[0][1] = (float)(qdc + qab);
+ m[0][2] = (float)(-qdb + qac);
+ m[0][3] = 0.0f;
- m[1][0] = (float)(-qdc + qab);
- m[1][1] = (float)(1.0 - qaa - qcc);
- m[1][2] = (float)(qda + qbc);
- m[1][3] = 0.0f;
+ m[1][0] = (float)(-qdc + qab);
+ m[1][1] = (float)(1.0 - qaa - qcc);
+ m[1][2] = (float)(qda + qbc);
+ m[1][3] = 0.0f;
- m[2][0] = (float)(qdb + qac);
- m[2][1] = (float)(-qda + qbc);
- m[2][2] = (float)(1.0 - qaa - qbb);
- m[2][3] = 0.0f;
+ m[2][0] = (float)(qdb + qac);
+ m[2][1] = (float)(-qda + qbc);
+ m[2][2] = (float)(1.0 - qaa - qbb);
+ m[2][3] = 0.0f;
- m[3][0] = m[3][1] = m[3][2] = 0.0f;
- m[3][3] = 1.0f;
+ m[3][0] = m[3][1] = m[3][2] = 0.0f;
+ m[3][3] = 1.0f;
}
void mat3_normalized_to_quat(float q[4], const float mat[3][3])
{
- double tr, s;
-
- BLI_ASSERT_UNIT_M3(mat);
-
- tr = 0.25 * (double)(1.0f + mat[0][0] + mat[1][1] + mat[2][2]);
-
- if (tr > (double)1e-4f) {
- s = sqrt(tr);
- q[0] = (float)s;
- s = 1.0 / (4.0 * s);
- q[1] = (float)((double)(mat[1][2] - mat[2][1]) * s);
- q[2] = (float)((double)(mat[2][0] - mat[0][2]) * s);
- q[3] = (float)((double)(mat[0][1] - mat[1][0]) * s);
- }
- else {
- if (mat[0][0] > mat[1][1] && mat[0][0] > mat[2][2]) {
- s = 2.0f * sqrtf(1.0f + mat[0][0] - mat[1][1] - mat[2][2]);
- q[1] = (float)(0.25 * s);
-
- s = 1.0 / s;
- q[0] = (float)((double)(mat[1][2] - mat[2][1]) * s);
- q[2] = (float)((double)(mat[1][0] + mat[0][1]) * s);
- q[3] = (float)((double)(mat[2][0] + mat[0][2]) * s);
- }
- else if (mat[1][1] > mat[2][2]) {
- s = 2.0f * sqrtf(1.0f + mat[1][1] - mat[0][0] - mat[2][2]);
- q[2] = (float)(0.25 * s);
-
- s = 1.0 / s;
- q[0] = (float)((double)(mat[2][0] - mat[0][2]) * s);
- q[1] = (float)((double)(mat[1][0] + mat[0][1]) * s);
- q[3] = (float)((double)(mat[2][1] + mat[1][2]) * s);
- }
- else {
- s = 2.0f * sqrtf(1.0f + mat[2][2] - mat[0][0] - mat[1][1]);
- q[3] = (float)(0.25 * s);
-
- s = 1.0 / s;
- q[0] = (float)((double)(mat[0][1] - mat[1][0]) * s);
- q[1] = (float)((double)(mat[2][0] + mat[0][2]) * s);
- q[2] = (float)((double)(mat[2][1] + mat[1][2]) * s);
- }
- }
-
- normalize_qt(q);
+ double tr, s;
+
+ BLI_ASSERT_UNIT_M3(mat);
+
+ tr = 0.25 * (double)(1.0f + mat[0][0] + mat[1][1] + mat[2][2]);
+
+ if (tr > (double)1e-4f) {
+ s = sqrt(tr);
+ q[0] = (float)s;
+ s = 1.0 / (4.0 * s);
+ q[1] = (float)((double)(mat[1][2] - mat[2][1]) * s);
+ q[2] = (float)((double)(mat[2][0] - mat[0][2]) * s);
+ q[3] = (float)((double)(mat[0][1] - mat[1][0]) * s);
+ }
+ else {
+ if (mat[0][0] > mat[1][1] && mat[0][0] > mat[2][2]) {
+ s = 2.0f * sqrtf(1.0f + mat[0][0] - mat[1][1] - mat[2][2]);
+ q[1] = (float)(0.25 * s);
+
+ s = 1.0 / s;
+ q[0] = (float)((double)(mat[1][2] - mat[2][1]) * s);
+ q[2] = (float)((double)(mat[1][0] + mat[0][1]) * s);
+ q[3] = (float)((double)(mat[2][0] + mat[0][2]) * s);
+ }
+ else if (mat[1][1] > mat[2][2]) {
+ s = 2.0f * sqrtf(1.0f + mat[1][1] - mat[0][0] - mat[2][2]);
+ q[2] = (float)(0.25 * s);
+
+ s = 1.0 / s;
+ q[0] = (float)((double)(mat[2][0] - mat[0][2]) * s);
+ q[1] = (float)((double)(mat[1][0] + mat[0][1]) * s);
+ q[3] = (float)((double)(mat[2][1] + mat[1][2]) * s);
+ }
+ else {
+ s = 2.0f * sqrtf(1.0f + mat[2][2] - mat[0][0] - mat[1][1]);
+ q[3] = (float)(0.25 * s);
+
+ s = 1.0 / s;
+ q[0] = (float)((double)(mat[0][1] - mat[1][0]) * s);
+ q[1] = (float)((double)(mat[2][0] + mat[0][2]) * s);
+ q[2] = (float)((double)(mat[2][1] + mat[1][2]) * s);
+ }
+ }
+
+ normalize_qt(q);
}
void mat3_to_quat(float q[4], const float m[3][3])
{
- float unit_mat[3][3];
+ float unit_mat[3][3];
- /* work on a copy */
- /* this is needed AND a 'normalize_qt' in the end */
- normalize_m3_m3(unit_mat, m);
- mat3_normalized_to_quat(q, unit_mat);
+ /* work on a copy */
+ /* this is needed AND a 'normalize_qt' in the end */
+ normalize_m3_m3(unit_mat, m);
+ mat3_normalized_to_quat(q, unit_mat);
}
void mat4_normalized_to_quat(float q[4], const float m[4][4])
{
- float mat3[3][3];
+ float mat3[3][3];
- copy_m3_m4(mat3, m);
- mat3_normalized_to_quat(q, mat3);
+ copy_m3_m4(mat3, m);
+ mat3_normalized_to_quat(q, mat3);
}
void mat4_to_quat(float q[4], const float m[4][4])
{
- float mat3[3][3];
+ float mat3[3][3];
- copy_m3_m4(mat3, m);
- mat3_to_quat(q, mat3);
+ copy_m3_m4(mat3, m);
+ mat3_to_quat(q, mat3);
}
void mat3_to_quat_is_ok(float q[4], const float wmat[3][3])
{
- float mat[3][3], matr[3][3], matn[3][3], q1[4], q2[4], angle, si, co, nor[3];
+ float mat[3][3], matr[3][3], matn[3][3], q1[4], q2[4], angle, si, co, nor[3];
- /* work on a copy */
- copy_m3_m3(mat, wmat);
- normalize_m3(mat);
+ /* work on a copy */
+ copy_m3_m3(mat, wmat);
+ normalize_m3(mat);
- /* rotate z-axis of matrix to z-axis */
+ /* rotate z-axis of matrix to z-axis */
- nor[0] = mat[2][1]; /* cross product with (0,0,1) */
- nor[1] = -mat[2][0];
- nor[2] = 0.0;
- normalize_v3(nor);
+ nor[0] = mat[2][1]; /* cross product with (0,0,1) */
+ nor[1] = -mat[2][0];
+ nor[2] = 0.0;
+ normalize_v3(nor);
- co = mat[2][2];
- angle = 0.5f * saacos(co);
+ co = mat[2][2];
+ angle = 0.5f * saacos(co);
- co = cosf(angle);
- si = sinf(angle);
- q1[0] = co;
- q1[1] = -nor[0] * si; /* negative here, but why? */
- q1[2] = -nor[1] * si;
- q1[3] = -nor[2] * si;
+ co = cosf(angle);
+ si = sinf(angle);
+ q1[0] = co;
+ q1[1] = -nor[0] * si; /* negative here, but why? */
+ q1[2] = -nor[1] * si;
+ q1[3] = -nor[2] * si;
- /* rotate back x-axis from mat, using inverse q1 */
- quat_to_mat3_no_error(matr, q1);
- invert_m3_m3(matn, matr);
- mul_m3_v3(matn, mat[0]);
+ /* rotate back x-axis from mat, using inverse q1 */
+ quat_to_mat3_no_error(matr, q1);
+ invert_m3_m3(matn, matr);
+ mul_m3_v3(matn, mat[0]);
- /* and align x-axes */
- angle = 0.5f * atan2f(mat[0][1], mat[0][0]);
+ /* and align x-axes */
+ angle = 0.5f * atan2f(mat[0][1], mat[0][0]);
- co = cosf(angle);
- si = sinf(angle);
- q2[0] = co;
- q2[1] = 0.0f;
- q2[2] = 0.0f;
- q2[3] = si;
+ co = cosf(angle);
+ si = sinf(angle);
+ q2[0] = co;
+ q2[1] = 0.0f;
+ q2[2] = 0.0f;
+ q2[3] = si;
- mul_qt_qtqt(q, q1, q2);
+ mul_qt_qtqt(q, q1, q2);
}
float normalize_qt(float q[4])
{
- const float len = sqrtf(dot_qtqt(q, q));
+ const float len = sqrtf(dot_qtqt(q, q));
- if (len != 0.0f) {
- mul_qt_fl(q, 1.0f / len);
- }
- else {
- q[1] = 1.0f;
- q[0] = q[2] = q[3] = 0.0f;
- }
+ if (len != 0.0f) {
+ mul_qt_fl(q, 1.0f / len);
+ }
+ else {
+ q[1] = 1.0f;
+ q[0] = q[2] = q[3] = 0.0f;
+ }
- return len;
+ return len;
}
float normalize_qt_qt(float r[4], const float q[4])
{
- copy_qt_qt(r, q);
- return normalize_qt(r);
+ copy_qt_qt(r, q);
+ return normalize_qt(r);
}
/**
@@ -457,82 +460,81 @@ float normalize_qt_qt(float r[4], const float q[4])
*/
void rotation_between_vecs_to_mat3(float m[3][3], const float v1[3], const float v2[3])
{
- float axis[3];
- /* avoid calculating the angle */
- float angle_sin;
- float angle_cos;
-
- BLI_ASSERT_UNIT_V3(v1);
- BLI_ASSERT_UNIT_V3(v2);
-
- cross_v3_v3v3(axis, v1, v2);
-
- angle_sin = normalize_v3(axis);
- angle_cos = dot_v3v3(v1, v2);
-
- if (angle_sin > FLT_EPSILON) {
-axis_calc:
- BLI_ASSERT_UNIT_V3(axis);
- axis_angle_normalized_to_mat3_ex(m, axis, angle_sin, angle_cos);
- BLI_ASSERT_UNIT_M3(m);
- }
- else {
- if (angle_cos > 0.0f) {
- /* Same vectors, zero rotation... */
- unit_m3(m);
- }
- else {
- /* Colinear but opposed vectors, 180 rotation... */
- ortho_v3_v3(axis, v1);
- normalize_v3(axis);
- angle_sin = 0.0f; /* sin(M_PI) */
- angle_cos = -1.0f; /* cos(M_PI) */
- goto axis_calc;
- }
- }
+ float axis[3];
+ /* avoid calculating the angle */
+ float angle_sin;
+ float angle_cos;
+
+ BLI_ASSERT_UNIT_V3(v1);
+ BLI_ASSERT_UNIT_V3(v2);
+
+ cross_v3_v3v3(axis, v1, v2);
+
+ angle_sin = normalize_v3(axis);
+ angle_cos = dot_v3v3(v1, v2);
+
+ if (angle_sin > FLT_EPSILON) {
+ axis_calc:
+ BLI_ASSERT_UNIT_V3(axis);
+ axis_angle_normalized_to_mat3_ex(m, axis, angle_sin, angle_cos);
+ BLI_ASSERT_UNIT_M3(m);
+ }
+ else {
+ if (angle_cos > 0.0f) {
+ /* Same vectors, zero rotation... */
+ unit_m3(m);
+ }
+ else {
+ /* Colinear but opposed vectors, 180 rotation... */
+ ortho_v3_v3(axis, v1);
+ normalize_v3(axis);
+ angle_sin = 0.0f; /* sin(M_PI) */
+ angle_cos = -1.0f; /* cos(M_PI) */
+ goto axis_calc;
+ }
+ }
}
/* note: expects vectors to be normalized */
void rotation_between_vecs_to_quat(float q[4], const float v1[3], const float v2[3])
{
- float axis[3];
+ float axis[3];
- cross_v3_v3v3(axis, v1, v2);
+ cross_v3_v3v3(axis, v1, v2);
- if (normalize_v3(axis) > FLT_EPSILON) {
- float angle;
+ if (normalize_v3(axis) > FLT_EPSILON) {
+ float angle;
- angle = angle_normalized_v3v3(v1, v2);
+ angle = angle_normalized_v3v3(v1, v2);
- axis_angle_normalized_to_quat(q, axis, angle);
- }
- else {
- /* degenerate case */
+ axis_angle_normalized_to_quat(q, axis, angle);
+ }
+ else {
+ /* degenerate case */
- if (dot_v3v3(v1, v2) > 0.0f) {
- /* Same vectors, zero rotation... */
- unit_qt(q);
- }
- else {
- /* Colinear but opposed vectors, 180 rotation... */
- ortho_v3_v3(axis, v1);
- axis_angle_to_quat(q, axis, (float)M_PI);
- }
- }
+ if (dot_v3v3(v1, v2) > 0.0f) {
+ /* Same vectors, zero rotation... */
+ unit_qt(q);
+ }
+ else {
+ /* Colinear but opposed vectors, 180 rotation... */
+ ortho_v3_v3(axis, v1);
+ axis_angle_to_quat(q, axis, (float)M_PI);
+ }
+ }
}
void rotation_between_quats_to_quat(float q[4], const float q1[4], const float q2[4])
{
- float tquat[4];
+ float tquat[4];
- conjugate_qt_qt(tquat, q1);
+ conjugate_qt_qt(tquat, q1);
- mul_qt_fl(tquat, 1.0f / dot_qtqt(tquat, tquat));
+ mul_qt_fl(tquat, 1.0f / dot_qtqt(tquat, tquat));
- mul_qt_qtqt(q, tquat, q2);
+ mul_qt_qtqt(q, tquat, q2);
}
-
/* -------------------------------------------------------------------- */
/** \name Quaternion Angle
*
@@ -543,39 +545,39 @@ void rotation_between_quats_to_quat(float q[4], const float q1[4], const float q
float angle_normalized_qt(const float q[4])
{
- BLI_ASSERT_UNIT_QUAT(q);
- return 2.0f * saacos(q[0]);
+ BLI_ASSERT_UNIT_QUAT(q);
+ return 2.0f * saacos(q[0]);
}
float angle_qt(const float q[4])
{
- float tquat[4];
+ float tquat[4];
- normalize_qt_qt(tquat, q);
+ normalize_qt_qt(tquat, q);
- return angle_normalized_qt(tquat);
+ return angle_normalized_qt(tquat);
}
float angle_normalized_qtqt(const float q1[4], const float q2[4])
{
- float qdelta[4];
+ float qdelta[4];
- BLI_ASSERT_UNIT_QUAT(q1);
- BLI_ASSERT_UNIT_QUAT(q2);
+ BLI_ASSERT_UNIT_QUAT(q1);
+ BLI_ASSERT_UNIT_QUAT(q2);
- rotation_between_quats_to_quat(qdelta, q1, q2);
+ rotation_between_quats_to_quat(qdelta, q1, q2);
- return angle_normalized_qt(qdelta);
+ return angle_normalized_qt(qdelta);
}
float angle_qtqt(const float q1[4], const float q2[4])
{
- float quat1[4], quat2[4];
+ float quat1[4], quat2[4];
- normalize_qt_qt(quat1, q1);
- normalize_qt_qt(quat2, q2);
+ normalize_qt_qt(quat1, q1);
+ normalize_qt_qt(quat2, q2);
- return angle_normalized_qtqt(quat1, quat2);
+ return angle_normalized_qtqt(quat1, quat2);
}
/** \} */
@@ -592,148 +594,160 @@ float angle_qtqt(const float q1[4], const float q2[4])
float angle_signed_normalized_qt(const float q[4])
{
- BLI_ASSERT_UNIT_QUAT(q);
- if (q[0] >= 0.0f) {
- return 2.0f * saacos(q[0]);
- }
- else {
- return -2.0f * saacos(-q[0]);
- }
+ BLI_ASSERT_UNIT_QUAT(q);
+ if (q[0] >= 0.0f) {
+ return 2.0f * saacos(q[0]);
+ }
+ else {
+ return -2.0f * saacos(-q[0]);
+ }
}
float angle_signed_normalized_qtqt(const float q1[4], const float q2[4])
{
- if (dot_qtqt(q1, q2) >= 0.0f) {
- return angle_normalized_qtqt(q1, q2);
- }
- else {
- float q2_copy[4];
- negate_v4_v4(q2_copy, q2);
- return -angle_normalized_qtqt(q1, q2_copy);
- }
+ if (dot_qtqt(q1, q2) >= 0.0f) {
+ return angle_normalized_qtqt(q1, q2);
+ }
+ else {
+ float q2_copy[4];
+ negate_v4_v4(q2_copy, q2);
+ return -angle_normalized_qtqt(q1, q2_copy);
+ }
}
float angle_signed_qt(const float q[4])
{
- float tquat[4];
+ float tquat[4];
- normalize_qt_qt(tquat, q);
+ normalize_qt_qt(tquat, q);
- return angle_signed_normalized_qt(tquat);
+ return angle_signed_normalized_qt(tquat);
}
float angle_signed_qtqt(const float q1[4], const float q2[4])
{
- if (dot_qtqt(q1, q2) >= 0.0f) {
- return angle_qtqt(q1, q2);
- }
- else {
- float q2_copy[4];
- negate_v4_v4(q2_copy, q2);
- return -angle_qtqt(q1, q2_copy);
- }
+ if (dot_qtqt(q1, q2) >= 0.0f) {
+ return angle_qtqt(q1, q2);
+ }
+ else {
+ float q2_copy[4];
+ negate_v4_v4(q2_copy, q2);
+ return -angle_qtqt(q1, q2_copy);
+ }
}
/** \} */
void vec_to_quat(float q[4], const float vec[3], short axis, const short upflag)
{
- const float eps = 1e-4f;
- float nor[3], tvec[3];
- float angle, si, co, len;
-
- assert(axis >= 0 && axis <= 5);
- assert(upflag >= 0 && upflag <= 2);
-
- /* first set the quat to unit */
- unit_qt(q);
-
- len = len_v3(vec);
-
- if (UNLIKELY(len == 0.0f)) {
- return;
- }
-
- /* rotate to axis */
- if (axis > 2) {
- copy_v3_v3(tvec, vec);
- axis = (short)(axis - 3);
- }
- else {
- negate_v3_v3(tvec, vec);
- }
-
- /* nasty! I need a good routine for this...
- * problem is a rotation of an Y axis to the negative Y-axis for example.
- */
-
- if (axis == 0) { /* x-axis */
- nor[0] = 0.0;
- nor[1] = -tvec[2];
- nor[2] = tvec[1];
-
- if (fabsf(tvec[1]) + fabsf(tvec[2]) < eps) {
- nor[1] = 1.0f;
- }
-
- co = tvec[0];
- }
- else if (axis == 1) { /* y-axis */
- nor[0] = tvec[2];
- nor[1] = 0.0;
- nor[2] = -tvec[0];
-
- if (fabsf(tvec[0]) + fabsf(tvec[2]) < eps) {
- nor[2] = 1.0f;
- }
-
- co = tvec[1];
- }
- else { /* z-axis */
- nor[0] = -tvec[1];
- nor[1] = tvec[0];
- nor[2] = 0.0;
-
- if (fabsf(tvec[0]) + fabsf(tvec[1]) < eps) {
- nor[0] = 1.0f;
- }
-
- co = tvec[2];
- }
- co /= len;
-
- normalize_v3(nor);
-
- axis_angle_normalized_to_quat(q, nor, saacos(co));
-
- if (axis != upflag) {
- float mat[3][3];
- float q2[4];
- const float *fp = mat[2];
- quat_to_mat3(mat, q);
-
- if (axis == 0) {
- if (upflag == 1) { angle = 0.5f * atan2f(fp[2], fp[1]); }
- else { angle = -0.5f * atan2f(fp[1], fp[2]); }
- }
- else if (axis == 1) {
- if (upflag == 0) { angle = -0.5f * atan2f(fp[2], fp[0]); }
- else { angle = 0.5f * atan2f(fp[0], fp[2]); }
- }
- else {
- if (upflag == 0) { angle = 0.5f * atan2f(-fp[1], -fp[0]); }
- else { angle = -0.5f * atan2f(-fp[0], -fp[1]); }
- }
-
- co = cosf(angle);
- si = sinf(angle) / len;
- q2[0] = co;
- q2[1] = tvec[0] * si;
- q2[2] = tvec[1] * si;
- q2[3] = tvec[2] * si;
-
- mul_qt_qtqt(q, q2, q);
- }
+ const float eps = 1e-4f;
+ float nor[3], tvec[3];
+ float angle, si, co, len;
+
+ assert(axis >= 0 && axis <= 5);
+ assert(upflag >= 0 && upflag <= 2);
+
+ /* first set the quat to unit */
+ unit_qt(q);
+
+ len = len_v3(vec);
+
+ if (UNLIKELY(len == 0.0f)) {
+ return;
+ }
+
+ /* rotate to axis */
+ if (axis > 2) {
+ copy_v3_v3(tvec, vec);
+ axis = (short)(axis - 3);
+ }
+ else {
+ negate_v3_v3(tvec, vec);
+ }
+
+ /* nasty! I need a good routine for this...
+ * problem is a rotation of an Y axis to the negative Y-axis for example.
+ */
+
+ if (axis == 0) { /* x-axis */
+ nor[0] = 0.0;
+ nor[1] = -tvec[2];
+ nor[2] = tvec[1];
+
+ if (fabsf(tvec[1]) + fabsf(tvec[2]) < eps) {
+ nor[1] = 1.0f;
+ }
+
+ co = tvec[0];
+ }
+ else if (axis == 1) { /* y-axis */
+ nor[0] = tvec[2];
+ nor[1] = 0.0;
+ nor[2] = -tvec[0];
+
+ if (fabsf(tvec[0]) + fabsf(tvec[2]) < eps) {
+ nor[2] = 1.0f;
+ }
+
+ co = tvec[1];
+ }
+ else { /* z-axis */
+ nor[0] = -tvec[1];
+ nor[1] = tvec[0];
+ nor[2] = 0.0;
+
+ if (fabsf(tvec[0]) + fabsf(tvec[1]) < eps) {
+ nor[0] = 1.0f;
+ }
+
+ co = tvec[2];
+ }
+ co /= len;
+
+ normalize_v3(nor);
+
+ axis_angle_normalized_to_quat(q, nor, saacos(co));
+
+ if (axis != upflag) {
+ float mat[3][3];
+ float q2[4];
+ const float *fp = mat[2];
+ quat_to_mat3(mat, q);
+
+ if (axis == 0) {
+ if (upflag == 1) {
+ angle = 0.5f * atan2f(fp[2], fp[1]);
+ }
+ else {
+ angle = -0.5f * atan2f(fp[1], fp[2]);
+ }
+ }
+ else if (axis == 1) {
+ if (upflag == 0) {
+ angle = -0.5f * atan2f(fp[2], fp[0]);
+ }
+ else {
+ angle = 0.5f * atan2f(fp[0], fp[2]);
+ }
+ }
+ else {
+ if (upflag == 0) {
+ angle = 0.5f * atan2f(-fp[1], -fp[0]);
+ }
+ else {
+ angle = -0.5f * atan2f(-fp[0], -fp[1]);
+ }
+ }
+
+ co = cosf(angle);
+ si = sinf(angle) / len;
+ q2[0] = co;
+ q2[1] = tvec[0] * si;
+ q2[2] = tvec[1] * si;
+ q2[3] = tvec[2] * si;
+
+ mul_qt_qtqt(q, q2, q);
+ }
}
#if 0
@@ -741,42 +755,42 @@ void vec_to_quat(float q[4], const float vec[3], short axis, const short upflag)
/* A & M Watt, Advanced animation and rendering techniques, 1992 ACM press */
void QuatInterpolW(float *result, float quat1[4], float quat2[4], float t)
{
- float omega, cosom, sinom, sc1, sc2;
-
- cosom = quat1[0] * quat2[0] + quat1[1] * quat2[1] + quat1[2] * quat2[2] + quat1[3] * quat2[3];
-
- /* rotate around shortest angle */
- if ((1.0f + cosom) > 0.0001f) {
-
- if ((1.0f - cosom) > 0.0001f) {
- omega = (float)acos(cosom);
- sinom = sinf(omega);
- sc1 = sinf((1.0 - t) * omega) / sinom;
- sc2 = sinf(t * omega) / sinom;
- }
- else {
- sc1 = 1.0f - t;
- sc2 = t;
- }
- result[0] = sc1 * quat1[0] + sc2 * quat2[0];
- result[1] = sc1 * quat1[1] + sc2 * quat2[1];
- result[2] = sc1 * quat1[2] + sc2 * quat2[2];
- result[3] = sc1 * quat1[3] + sc2 * quat2[3];
- }
- else {
- result[0] = quat2[3];
- result[1] = -quat2[2];
- result[2] = quat2[1];
- result[3] = -quat2[0];
-
- sc1 = sinf((1.0 - t) * M_PI_2);
- sc2 = sinf(t * M_PI_2);
-
- result[0] = sc1 * quat1[0] + sc2 * result[0];
- result[1] = sc1 * quat1[1] + sc2 * result[1];
- result[2] = sc1 * quat1[2] + sc2 * result[2];
- result[3] = sc1 * quat1[3] + sc2 * result[3];
- }
+ float omega, cosom, sinom, sc1, sc2;
+
+ cosom = quat1[0] * quat2[0] + quat1[1] * quat2[1] + quat1[2] * quat2[2] + quat1[3] * quat2[3];
+
+ /* rotate around shortest angle */
+ if ((1.0f + cosom) > 0.0001f) {
+
+ if ((1.0f - cosom) > 0.0001f) {
+ omega = (float)acos(cosom);
+ sinom = sinf(omega);
+ sc1 = sinf((1.0 - t) * omega) / sinom;
+ sc2 = sinf(t * omega) / sinom;
+ }
+ else {
+ sc1 = 1.0f - t;
+ sc2 = t;
+ }
+ result[0] = sc1 * quat1[0] + sc2 * quat2[0];
+ result[1] = sc1 * quat1[1] + sc2 * quat2[1];
+ result[2] = sc1 * quat1[2] + sc2 * quat2[2];
+ result[3] = sc1 * quat1[3] + sc2 * quat2[3];
+ }
+ else {
+ result[0] = quat2[3];
+ result[1] = -quat2[2];
+ result[2] = quat2[1];
+ result[3] = -quat2[0];
+
+ sc1 = sinf((1.0 - t) * M_PI_2);
+ sc2 = sinf(t * M_PI_2);
+
+ result[0] = sc1 * quat1[0] + sc2 * result[0];
+ result[1] = sc1 * quat1[1] + sc2 * result[1];
+ result[2] = sc1 * quat1[2] + sc2 * result[2];
+ result[3] = sc1 * quat1[3] + sc2 * result[3];
+ }
}
#endif
@@ -790,112 +804,112 @@ void QuatInterpolW(float *result, float quat1[4], float quat2[4], float t)
*/
void interp_dot_slerp(const float t, const float cosom, float r_w[2])
{
- const float eps = 1e-4f;
+ const float eps = 1e-4f;
- BLI_assert(IN_RANGE_INCL(cosom, -1.0001f, 1.0001f));
+ BLI_assert(IN_RANGE_INCL(cosom, -1.0001f, 1.0001f));
- /* within [-1..1] range, avoid aligned axis */
- if (LIKELY(fabsf(cosom) < (1.0f - eps))) {
- float omega, sinom;
+ /* within [-1..1] range, avoid aligned axis */
+ if (LIKELY(fabsf(cosom) < (1.0f - eps))) {
+ float omega, sinom;
- omega = acosf(cosom);
- sinom = sinf(omega);
- r_w[0] = sinf((1.0f - t) * omega) / sinom;
- r_w[1] = sinf(t * omega) / sinom;
- }
- else {
- /* fallback to lerp */
- r_w[0] = 1.0f - t;
- r_w[1] = t;
- }
+ omega = acosf(cosom);
+ sinom = sinf(omega);
+ r_w[0] = sinf((1.0f - t) * omega) / sinom;
+ r_w[1] = sinf(t * omega) / sinom;
+ }
+ else {
+ /* fallback to lerp */
+ r_w[0] = 1.0f - t;
+ r_w[1] = t;
+ }
}
void interp_qt_qtqt(float result[4], const float quat1[4], const float quat2[4], const float t)
{
- float quat[4], cosom, w[2];
+ float quat[4], cosom, w[2];
- BLI_ASSERT_UNIT_QUAT(quat1);
- BLI_ASSERT_UNIT_QUAT(quat2);
+ BLI_ASSERT_UNIT_QUAT(quat1);
+ BLI_ASSERT_UNIT_QUAT(quat2);
- cosom = dot_qtqt(quat1, quat2);
+ cosom = dot_qtqt(quat1, quat2);
- /* rotate around shortest angle */
- if (cosom < 0.0f) {
- cosom = -cosom;
- negate_v4_v4(quat, quat1);
- }
- else {
- copy_qt_qt(quat, quat1);
- }
+ /* rotate around shortest angle */
+ if (cosom < 0.0f) {
+ cosom = -cosom;
+ negate_v4_v4(quat, quat1);
+ }
+ else {
+ copy_qt_qt(quat, quat1);
+ }
- interp_dot_slerp(t, cosom, w);
+ interp_dot_slerp(t, cosom, w);
- result[0] = w[0] * quat[0] + w[1] * quat2[0];
- result[1] = w[0] * quat[1] + w[1] * quat2[1];
- result[2] = w[0] * quat[2] + w[1] * quat2[2];
- result[3] = w[0] * quat[3] + w[1] * quat2[3];
+ result[0] = w[0] * quat[0] + w[1] * quat2[0];
+ result[1] = w[0] * quat[1] + w[1] * quat2[1];
+ result[2] = w[0] * quat[2] + w[1] * quat2[2];
+ result[3] = w[0] * quat[3] + w[1] * quat2[3];
}
void add_qt_qtqt(float result[4], const float quat1[4], const float quat2[4], const float t)
{
- result[0] = quat1[0] + t * quat2[0];
- result[1] = quat1[1] + t * quat2[1];
- result[2] = quat1[2] + t * quat2[2];
- result[3] = quat1[3] + t * quat2[3];
+ result[0] = quat1[0] + t * quat2[0];
+ result[1] = quat1[1] + t * quat2[1];
+ result[2] = quat1[2] + t * quat2[2];
+ result[3] = quat1[3] + t * quat2[3];
}
/* same as tri_to_quat() but takes pre-computed normal from the triangle
* used for ngons when we know their normal */
-void tri_to_quat_ex(float quat[4], const float v1[3], const float v2[3], const float v3[3],
- const float no_orig[3])
+void tri_to_quat_ex(
+ float quat[4], const float v1[3], const float v2[3], const float v3[3], const float no_orig[3])
{
- /* imaginary x-axis, y-axis triangle is being rotated */
- float vec[3], q1[4], q2[4], n[3], si, co, angle, mat[3][3], imat[3][3];
+ /* imaginary x-axis, y-axis triangle is being rotated */
+ float vec[3], q1[4], q2[4], n[3], si, co, angle, mat[3][3], imat[3][3];
- /* move z-axis to face-normal */
+ /* move z-axis to face-normal */
#if 0
- normal_tri_v3(vec, v1, v2, v3);
+ normal_tri_v3(vec, v1, v2, v3);
#else
- copy_v3_v3(vec, no_orig);
- (void)v3;
+ copy_v3_v3(vec, no_orig);
+ (void)v3;
#endif
- n[0] = vec[1];
- n[1] = -vec[0];
- n[2] = 0.0f;
- normalize_v3(n);
+ n[0] = vec[1];
+ n[1] = -vec[0];
+ n[2] = 0.0f;
+ normalize_v3(n);
- if (n[0] == 0.0f && n[1] == 0.0f) {
- n[0] = 1.0f;
- }
+ if (n[0] == 0.0f && n[1] == 0.0f) {
+ n[0] = 1.0f;
+ }
- angle = -0.5f * saacos(vec[2]);
- co = cosf(angle);
- si = sinf(angle);
- q1[0] = co;
- q1[1] = n[0] * si;
- q1[2] = n[1] * si;
- q1[3] = 0.0f;
+ angle = -0.5f * saacos(vec[2]);
+ co = cosf(angle);
+ si = sinf(angle);
+ q1[0] = co;
+ q1[1] = n[0] * si;
+ q1[2] = n[1] * si;
+ q1[3] = 0.0f;
- /* rotate back line v1-v2 */
- quat_to_mat3(mat, q1);
- invert_m3_m3(imat, mat);
- sub_v3_v3v3(vec, v2, v1);
- mul_m3_v3(imat, vec);
+ /* rotate back line v1-v2 */
+ quat_to_mat3(mat, q1);
+ invert_m3_m3(imat, mat);
+ sub_v3_v3v3(vec, v2, v1);
+ mul_m3_v3(imat, vec);
- /* what angle has this line with x-axis? */
- vec[2] = 0.0f;
- normalize_v3(vec);
+ /* what angle has this line with x-axis? */
+ vec[2] = 0.0f;
+ normalize_v3(vec);
- angle = 0.5f * atan2f(vec[1], vec[0]);
- co = cosf(angle);
- si = sinf(angle);
- q2[0] = co;
- q2[1] = 0.0f;
- q2[2] = 0.0f;
- q2[3] = si;
+ angle = 0.5f * atan2f(vec[1], vec[0]);
+ co = cosf(angle);
+ si = sinf(angle);
+ q2[0] = co;
+ q2[1] = 0.0f;
+ q2[2] = 0.0f;
+ q2[3] = si;
- mul_qt_qtqt(quat, q1, q2);
+ mul_qt_qtqt(quat, q1, q2);
}
/**
@@ -903,91 +917,94 @@ void tri_to_quat_ex(float quat[4], const float v1[3], const float v2[3], const f
*/
float tri_to_quat(float quat[4], const float v1[3], const float v2[3], const float v3[3])
{
- float vec[3];
- const float len = normal_tri_v3(vec, v1, v2, v3);
+ float vec[3];
+ const float len = normal_tri_v3(vec, v1, v2, v3);
- tri_to_quat_ex(quat, v1, v2, v3, vec);
- return len;
+ tri_to_quat_ex(quat, v1, v2, v3, vec);
+ return len;
}
void print_qt(const char *str, const float q[4])
{
- printf("%s: %.3f %.3f %.3f %.3f\n", str, q[0], q[1], q[2], q[3]);
+ printf("%s: %.3f %.3f %.3f %.3f\n", str, q[0], q[1], q[2], q[3]);
}
/******************************** Axis Angle *********************************/
void axis_angle_normalized_to_quat(float q[4], const float axis[3], const float angle)
{
- const float phi = 0.5f * angle;
- const float si = sinf(phi);
- const float co = cosf(phi);
- BLI_ASSERT_UNIT_V3(axis);
- q[0] = co;
- mul_v3_v3fl(q + 1, axis, si);
+ const float phi = 0.5f * angle;
+ const float si = sinf(phi);
+ const float co = cosf(phi);
+ BLI_ASSERT_UNIT_V3(axis);
+ q[0] = co;
+ mul_v3_v3fl(q + 1, axis, si);
}
void axis_angle_to_quat(float q[4], const float axis[3], const float angle)
{
- float nor[3];
+ float nor[3];
- if (LIKELY(normalize_v3_v3(nor, axis) != 0.0f)) {
- axis_angle_normalized_to_quat(q, nor, angle);
- }
- else {
- unit_qt(q);
- }
+ if (LIKELY(normalize_v3_v3(nor, axis) != 0.0f)) {
+ axis_angle_normalized_to_quat(q, nor, angle);
+ }
+ else {
+ unit_qt(q);
+ }
}
/* Quaternions to Axis Angle */
void quat_to_axis_angle(float axis[3], float *angle, const float q[4])
{
- float ha, si;
+ float ha, si;
#ifdef DEBUG
- if (!((ha = dot_qtqt(q, q)) == 0.0f || (fabsf(ha - 1.0f) < (float)QUAT_EPSILON))) {
- fprintf(stderr, "Warning! quat_to_axis_angle() called with non-normalized: size %.8f *** report a bug ***\n", ha);
- }
+ if (!((ha = dot_qtqt(q, q)) == 0.0f || (fabsf(ha - 1.0f) < (float)QUAT_EPSILON))) {
+ fprintf(stderr,
+ "Warning! quat_to_axis_angle() called with non-normalized: size %.8f *** report a bug "
+ "***\n",
+ ha);
+ }
#endif
- /* calculate angle/2, and sin(angle/2) */
- ha = acosf(q[0]);
- si = sinf(ha);
+ /* calculate angle/2, and sin(angle/2) */
+ ha = acosf(q[0]);
+ si = sinf(ha);
- /* from half-angle to angle */
- *angle = ha * 2;
+ /* from half-angle to angle */
+ *angle = ha * 2;
- /* prevent division by zero for axis conversion */
- if (fabsf(si) < 0.0005f) {
- si = 1.0f;
- }
+ /* prevent division by zero for axis conversion */
+ if (fabsf(si) < 0.0005f) {
+ si = 1.0f;
+ }
- axis[0] = q[1] / si;
- axis[1] = q[2] / si;
- axis[2] = q[3] / si;
- if (is_zero_v3(axis)) {
- axis[1] = 1.0f;
- }
+ axis[0] = q[1] / si;
+ axis[1] = q[2] / si;
+ axis[2] = q[3] / si;
+ if (is_zero_v3(axis)) {
+ axis[1] = 1.0f;
+ }
}
/* Axis Angle to Euler Rotation */
void axis_angle_to_eulO(float eul[3], const short order, const float axis[3], const float angle)
{
- float q[4];
+ float q[4];
- /* use quaternions as intermediate representation for now... */
- axis_angle_to_quat(q, axis, angle);
- quat_to_eulO(eul, order, q);
+ /* use quaternions as intermediate representation for now... */
+ axis_angle_to_quat(q, axis, angle);
+ quat_to_eulO(eul, order, q);
}
/* Euler Rotation to Axis Angle */
void eulO_to_axis_angle(float axis[3], float *angle, const float eul[3], const short order)
{
- float q[4];
+ float q[4];
- /* use quaternions as intermediate representation for now... */
- eulO_to_quat(q, eul, order);
- quat_to_axis_angle(axis, angle, q);
+ /* use quaternions as intermediate representation for now... */
+ eulO_to_quat(q, eul, order);
+ quat_to_axis_angle(axis, angle, q);
}
/**
@@ -999,223 +1016,224 @@ void eulO_to_axis_angle(float axis[3], float *angle, const float eul[3], const s
* \param angle_sin: sin(angle)
* \param angle_cos: cos(angle)
*/
-void axis_angle_normalized_to_mat3_ex(float mat[3][3], const float axis[3],
- const float angle_sin, const float angle_cos)
+void axis_angle_normalized_to_mat3_ex(float mat[3][3],
+ const float axis[3],
+ const float angle_sin,
+ const float angle_cos)
{
- float nsi[3], ico;
- float n_00, n_01, n_11, n_02, n_12, n_22;
+ float nsi[3], ico;
+ float n_00, n_01, n_11, n_02, n_12, n_22;
- BLI_ASSERT_UNIT_V3(axis);
+ BLI_ASSERT_UNIT_V3(axis);
- /* now convert this to a 3x3 matrix */
+ /* now convert this to a 3x3 matrix */
- ico = (1.0f - angle_cos);
- nsi[0] = axis[0] * angle_sin;
- nsi[1] = axis[1] * angle_sin;
- nsi[2] = axis[2] * angle_sin;
+ ico = (1.0f - angle_cos);
+ nsi[0] = axis[0] * angle_sin;
+ nsi[1] = axis[1] * angle_sin;
+ nsi[2] = axis[2] * angle_sin;
- n_00 = (axis[0] * axis[0]) * ico;
- n_01 = (axis[0] * axis[1]) * ico;
- n_11 = (axis[1] * axis[1]) * ico;
- n_02 = (axis[0] * axis[2]) * ico;
- n_12 = (axis[1] * axis[2]) * ico;
- n_22 = (axis[2] * axis[2]) * ico;
+ n_00 = (axis[0] * axis[0]) * ico;
+ n_01 = (axis[0] * axis[1]) * ico;
+ n_11 = (axis[1] * axis[1]) * ico;
+ n_02 = (axis[0] * axis[2]) * ico;
+ n_12 = (axis[1] * axis[2]) * ico;
+ n_22 = (axis[2] * axis[2]) * ico;
- mat[0][0] = n_00 + angle_cos;
- mat[0][1] = n_01 + nsi[2];
- mat[0][2] = n_02 - nsi[1];
- mat[1][0] = n_01 - nsi[2];
- mat[1][1] = n_11 + angle_cos;
- mat[1][2] = n_12 + nsi[0];
- mat[2][0] = n_02 + nsi[1];
- mat[2][1] = n_12 - nsi[0];
- mat[2][2] = n_22 + angle_cos;
+ mat[0][0] = n_00 + angle_cos;
+ mat[0][1] = n_01 + nsi[2];
+ mat[0][2] = n_02 - nsi[1];
+ mat[1][0] = n_01 - nsi[2];
+ mat[1][1] = n_11 + angle_cos;
+ mat[1][2] = n_12 + nsi[0];
+ mat[2][0] = n_02 + nsi[1];
+ mat[2][1] = n_12 - nsi[0];
+ mat[2][2] = n_22 + angle_cos;
}
void axis_angle_normalized_to_mat3(float mat[3][3], const float axis[3], const float angle)
{
- axis_angle_normalized_to_mat3_ex(mat, axis, sinf(angle), cosf(angle));
+ axis_angle_normalized_to_mat3_ex(mat, axis, sinf(angle), cosf(angle));
}
-
/* axis angle to 3x3 matrix - safer version (normalization of axis performed) */
void axis_angle_to_mat3(float mat[3][3], const float axis[3], const float angle)
{
- float nor[3];
+ float nor[3];
- /* normalize the axis first (to remove unwanted scaling) */
- if (normalize_v3_v3(nor, axis) == 0.0f) {
- unit_m3(mat);
- return;
- }
+ /* normalize the axis first (to remove unwanted scaling) */
+ if (normalize_v3_v3(nor, axis) == 0.0f) {
+ unit_m3(mat);
+ return;
+ }
- axis_angle_normalized_to_mat3(mat, nor, angle);
+ axis_angle_normalized_to_mat3(mat, nor, angle);
}
/* axis angle to 4x4 matrix - safer version (normalization of axis performed) */
void axis_angle_to_mat4(float mat[4][4], const float axis[3], const float angle)
{
- float tmat[3][3];
+ float tmat[3][3];
- axis_angle_to_mat3(tmat, axis, angle);
- unit_m4(mat);
- copy_m4_m3(mat, tmat);
+ axis_angle_to_mat3(tmat, axis, angle);
+ unit_m4(mat);
+ copy_m4_m3(mat, tmat);
}
/* 3x3 matrix to axis angle */
void mat3_normalized_to_axis_angle(float axis[3], float *angle, const float mat[3][3])
{
- float q[4];
+ float q[4];
- /* use quaternions as intermediate representation */
- /* TODO: it would be nicer to go straight there... */
- mat3_normalized_to_quat(q, mat);
- quat_to_axis_angle(axis, angle, q);
+ /* use quaternions as intermediate representation */
+ /* TODO: it would be nicer to go straight there... */
+ mat3_normalized_to_quat(q, mat);
+ quat_to_axis_angle(axis, angle, q);
}
void mat3_to_axis_angle(float axis[3], float *angle, const float mat[3][3])
{
- float q[4];
+ float q[4];
- /* use quaternions as intermediate representation */
- /* TODO: it would be nicer to go straight there... */
- mat3_to_quat(q, mat);
- quat_to_axis_angle(axis, angle, q);
+ /* use quaternions as intermediate representation */
+ /* TODO: it would be nicer to go straight there... */
+ mat3_to_quat(q, mat);
+ quat_to_axis_angle(axis, angle, q);
}
/* 4x4 matrix to axis angle */
void mat4_normalized_to_axis_angle(float axis[3], float *angle, const float mat[4][4])
{
- float q[4];
+ float q[4];
- /* use quaternions as intermediate representation */
- /* TODO: it would be nicer to go straight there... */
- mat4_normalized_to_quat(q, mat);
- quat_to_axis_angle(axis, angle, q);
+ /* use quaternions as intermediate representation */
+ /* TODO: it would be nicer to go straight there... */
+ mat4_normalized_to_quat(q, mat);
+ quat_to_axis_angle(axis, angle, q);
}
/* 4x4 matrix to axis angle */
void mat4_to_axis_angle(float axis[3], float *angle, const float mat[4][4])
{
- float q[4];
+ float q[4];
- /* use quaternions as intermediate representation */
- /* TODO: it would be nicer to go straight there... */
- mat4_to_quat(q, mat);
- quat_to_axis_angle(axis, angle, q);
+ /* use quaternions as intermediate representation */
+ /* TODO: it would be nicer to go straight there... */
+ mat4_to_quat(q, mat);
+ quat_to_axis_angle(axis, angle, q);
}
void axis_angle_to_mat4_single(float mat[4][4], const char axis, const float angle)
{
- float mat3[3][3];
- axis_angle_to_mat3_single(mat3, axis, angle);
- copy_m4_m3(mat, mat3);
+ float mat3[3][3];
+ axis_angle_to_mat3_single(mat3, axis, angle);
+ copy_m4_m3(mat, mat3);
}
/* rotation matrix from a single axis */
void axis_angle_to_mat3_single(float mat[3][3], const char axis, const float angle)
{
- const float angle_cos = cosf(angle);
- const float angle_sin = sinf(angle);
-
- switch (axis) {
- case 'X': /* rotation around X */
- mat[0][0] = 1.0f;
- mat[0][1] = 0.0f;
- mat[0][2] = 0.0f;
- mat[1][0] = 0.0f;
- mat[1][1] = angle_cos;
- mat[1][2] = angle_sin;
- mat[2][0] = 0.0f;
- mat[2][1] = -angle_sin;
- mat[2][2] = angle_cos;
- break;
- case 'Y': /* rotation around Y */
- mat[0][0] = angle_cos;
- mat[0][1] = 0.0f;
- mat[0][2] = -angle_sin;
- mat[1][0] = 0.0f;
- mat[1][1] = 1.0f;
- mat[1][2] = 0.0f;
- mat[2][0] = angle_sin;
- mat[2][1] = 0.0f;
- mat[2][2] = angle_cos;
- break;
- case 'Z': /* rotation around Z */
- mat[0][0] = angle_cos;
- mat[0][1] = angle_sin;
- mat[0][2] = 0.0f;
- mat[1][0] = -angle_sin;
- mat[1][1] = angle_cos;
- mat[1][2] = 0.0f;
- mat[2][0] = 0.0f;
- mat[2][1] = 0.0f;
- mat[2][2] = 1.0f;
- break;
- default:
- BLI_assert(0);
- break;
- }
+ const float angle_cos = cosf(angle);
+ const float angle_sin = sinf(angle);
+
+ switch (axis) {
+ case 'X': /* rotation around X */
+ mat[0][0] = 1.0f;
+ mat[0][1] = 0.0f;
+ mat[0][2] = 0.0f;
+ mat[1][0] = 0.0f;
+ mat[1][1] = angle_cos;
+ mat[1][2] = angle_sin;
+ mat[2][0] = 0.0f;
+ mat[2][1] = -angle_sin;
+ mat[2][2] = angle_cos;
+ break;
+ case 'Y': /* rotation around Y */
+ mat[0][0] = angle_cos;
+ mat[0][1] = 0.0f;
+ mat[0][2] = -angle_sin;
+ mat[1][0] = 0.0f;
+ mat[1][1] = 1.0f;
+ mat[1][2] = 0.0f;
+ mat[2][0] = angle_sin;
+ mat[2][1] = 0.0f;
+ mat[2][2] = angle_cos;
+ break;
+ case 'Z': /* rotation around Z */
+ mat[0][0] = angle_cos;
+ mat[0][1] = angle_sin;
+ mat[0][2] = 0.0f;
+ mat[1][0] = -angle_sin;
+ mat[1][1] = angle_cos;
+ mat[1][2] = 0.0f;
+ mat[2][0] = 0.0f;
+ mat[2][1] = 0.0f;
+ mat[2][2] = 1.0f;
+ break;
+ default:
+ BLI_assert(0);
+ break;
+ }
}
void angle_to_mat2(float mat[2][2], const float angle)
{
- const float angle_cos = cosf(angle);
- const float angle_sin = sinf(angle);
+ const float angle_cos = cosf(angle);
+ const float angle_sin = sinf(angle);
- /* 2D rotation matrix */
- mat[0][0] = angle_cos;
- mat[0][1] = angle_sin;
- mat[1][0] = -angle_sin;
- mat[1][1] = angle_cos;
+ /* 2D rotation matrix */
+ mat[0][0] = angle_cos;
+ mat[0][1] = angle_sin;
+ mat[1][0] = -angle_sin;
+ mat[1][1] = angle_cos;
}
void axis_angle_to_quat_single(float q[4], const char axis, const float angle)
{
- const float angle_half = angle * 0.5f;
- const float angle_cos = cosf(angle_half);
- const float angle_sin = sinf(angle_half);
- const int axis_index = (axis - 'X');
+ const float angle_half = angle * 0.5f;
+ const float angle_cos = cosf(angle_half);
+ const float angle_sin = sinf(angle_half);
+ const int axis_index = (axis - 'X');
- assert(axis >= 'X' && axis <= 'Z');
+ assert(axis >= 'X' && axis <= 'Z');
- q[0] = angle_cos;
- zero_v3(q + 1);
- q[axis_index + 1] = angle_sin;
+ q[0] = angle_cos;
+ zero_v3(q + 1);
+ q[axis_index + 1] = angle_sin;
}
/****************************** Exponential Map ******************************/
void quat_normalized_to_expmap(float expmap[3], const float q[4])
{
- float angle;
- BLI_ASSERT_UNIT_QUAT(q);
+ float angle;
+ BLI_ASSERT_UNIT_QUAT(q);
- /* Obtain axis/angle representation. */
- quat_to_axis_angle(expmap, &angle, q);
+ /* Obtain axis/angle representation. */
+ quat_to_axis_angle(expmap, &angle, q);
- /* Convert to exponential map. */
- mul_v3_fl(expmap, angle);
+ /* Convert to exponential map. */
+ mul_v3_fl(expmap, angle);
}
void quat_to_expmap(float expmap[3], const float q[4])
{
- float q_no[4];
- normalize_qt_qt(q_no, q);
- quat_normalized_to_expmap(expmap, q_no);
+ float q_no[4];
+ normalize_qt_qt(q_no, q);
+ quat_normalized_to_expmap(expmap, q_no);
}
void expmap_to_quat(float r[4], const float expmap[3])
{
- float axis[3];
- float angle;
+ float axis[3];
+ float angle;
- /* Obtain axis/angle representation. */
- if (LIKELY((angle = normalize_v3_v3(axis, expmap)) != 0.0f)) {
- axis_angle_normalized_to_quat(r, axis, angle_wrap_rad(angle));
- }
- else {
- unit_qt(r);
- }
+ /* Obtain axis/angle representation. */
+ if (LIKELY((angle = normalize_v3_v3(axis, expmap)) != 0.0f)) {
+ axis_angle_normalized_to_quat(r, axis, angle_wrap_rad(angle));
+ }
+ else {
+ unit_qt(r);
+ }
}
/******************************** XYZ Eulers *********************************/
@@ -1223,60 +1241,58 @@ void expmap_to_quat(float r[4], const float expmap[3])
/* XYZ order */
void eul_to_mat3(float mat[3][3], const float eul[3])
{
- double ci, cj, ch, si, sj, sh, cc, cs, sc, ss;
-
- ci = cos(eul[0]);
- cj = cos(eul[1]);
- ch = cos(eul[2]);
- si = sin(eul[0]);
- sj = sin(eul[1]);
- sh = sin(eul[2]);
- cc = ci * ch;
- cs = ci * sh;
- sc = si * ch;
- ss = si * sh;
-
- mat[0][0] = (float)(cj * ch);
- mat[1][0] = (float)(sj * sc - cs);
- mat[2][0] = (float)(sj * cc + ss);
- mat[0][1] = (float)(cj * sh);
- mat[1][1] = (float)(sj * ss + cc);
- mat[2][1] = (float)(sj * cs - sc);
- mat[0][2] = (float)-sj;
- mat[1][2] = (float)(cj * si);
- mat[2][2] = (float)(cj * ci);
-
+ double ci, cj, ch, si, sj, sh, cc, cs, sc, ss;
+
+ ci = cos(eul[0]);
+ cj = cos(eul[1]);
+ ch = cos(eul[2]);
+ si = sin(eul[0]);
+ sj = sin(eul[1]);
+ sh = sin(eul[2]);
+ cc = ci * ch;
+ cs = ci * sh;
+ sc = si * ch;
+ ss = si * sh;
+
+ mat[0][0] = (float)(cj * ch);
+ mat[1][0] = (float)(sj * sc - cs);
+ mat[2][0] = (float)(sj * cc + ss);
+ mat[0][1] = (float)(cj * sh);
+ mat[1][1] = (float)(sj * ss + cc);
+ mat[2][1] = (float)(sj * cs - sc);
+ mat[0][2] = (float)-sj;
+ mat[1][2] = (float)(cj * si);
+ mat[2][2] = (float)(cj * ci);
}
/* XYZ order */
void eul_to_mat4(float mat[4][4], const float eul[3])
{
- double ci, cj, ch, si, sj, sh, cc, cs, sc, ss;
-
- ci = cos(eul[0]);
- cj = cos(eul[1]);
- ch = cos(eul[2]);
- si = sin(eul[0]);
- sj = sin(eul[1]);
- sh = sin(eul[2]);
- cc = ci * ch;
- cs = ci * sh;
- sc = si * ch;
- ss = si * sh;
-
- mat[0][0] = (float)(cj * ch);
- mat[1][0] = (float)(sj * sc - cs);
- mat[2][0] = (float)(sj * cc + ss);
- mat[0][1] = (float)(cj * sh);
- mat[1][1] = (float)(sj * ss + cc);
- mat[2][1] = (float)(sj * cs - sc);
- mat[0][2] = (float)-sj;
- mat[1][2] = (float)(cj * si);
- mat[2][2] = (float)(cj * ci);
-
-
- mat[3][0] = mat[3][1] = mat[3][2] = mat[0][3] = mat[1][3] = mat[2][3] = 0.0f;
- mat[3][3] = 1.0f;
+ double ci, cj, ch, si, sj, sh, cc, cs, sc, ss;
+
+ ci = cos(eul[0]);
+ cj = cos(eul[1]);
+ ch = cos(eul[2]);
+ si = sin(eul[0]);
+ sj = sin(eul[1]);
+ sh = sin(eul[2]);
+ cc = ci * ch;
+ cs = ci * sh;
+ sc = si * ch;
+ ss = si * sh;
+
+ mat[0][0] = (float)(cj * ch);
+ mat[1][0] = (float)(sj * sc - cs);
+ mat[2][0] = (float)(sj * cc + ss);
+ mat[0][1] = (float)(cj * sh);
+ mat[1][1] = (float)(sj * ss + cc);
+ mat[2][1] = (float)(sj * cs - sc);
+ mat[0][2] = (float)-sj;
+ mat[1][2] = (float)(cj * si);
+ mat[2][2] = (float)(cj * ci);
+
+ mat[3][0] = mat[3][1] = mat[3][2] = mat[0][3] = mat[1][3] = mat[2][3] = 0.0f;
+ mat[3][3] = 1.0f;
}
/* returns two euler calculation methods, so we can pick the best */
@@ -1284,162 +1300,174 @@ void eul_to_mat4(float mat[4][4], const float eul[3])
/* XYZ order */
static void mat3_normalized_to_eul2(const float mat[3][3], float eul1[3], float eul2[3])
{
- const float cy = hypotf(mat[0][0], mat[0][1]);
+ const float cy = hypotf(mat[0][0], mat[0][1]);
- BLI_ASSERT_UNIT_M3(mat);
+ BLI_ASSERT_UNIT_M3(mat);
- if (cy > 16.0f * FLT_EPSILON) {
+ if (cy > 16.0f * FLT_EPSILON) {
- eul1[0] = atan2f(mat[1][2], mat[2][2]);
- eul1[1] = atan2f(-mat[0][2], cy);
- eul1[2] = atan2f(mat[0][1], mat[0][0]);
+ eul1[0] = atan2f(mat[1][2], mat[2][2]);
+ eul1[1] = atan2f(-mat[0][2], cy);
+ eul1[2] = atan2f(mat[0][1], mat[0][0]);
- eul2[0] = atan2f(-mat[1][2], -mat[2][2]);
- eul2[1] = atan2f(-mat[0][2], -cy);
- eul2[2] = atan2f(-mat[0][1], -mat[0][0]);
+ eul2[0] = atan2f(-mat[1][2], -mat[2][2]);
+ eul2[1] = atan2f(-mat[0][2], -cy);
+ eul2[2] = atan2f(-mat[0][1], -mat[0][0]);
+ }
+ else {
+ eul1[0] = atan2f(-mat[2][1], mat[1][1]);
+ eul1[1] = atan2f(-mat[0][2], cy);
+ eul1[2] = 0.0f;
- }
- else {
- eul1[0] = atan2f(-mat[2][1], mat[1][1]);
- eul1[1] = atan2f(-mat[0][2], cy);
- eul1[2] = 0.0f;
-
- copy_v3_v3(eul2, eul1);
- }
+ copy_v3_v3(eul2, eul1);
+ }
}
/* XYZ order */
void mat3_normalized_to_eul(float eul[3], const float mat[3][3])
{
- float eul1[3], eul2[3];
+ float eul1[3], eul2[3];
- mat3_normalized_to_eul2(mat, eul1, eul2);
+ mat3_normalized_to_eul2(mat, eul1, eul2);
- /* return best, which is just the one with lowest values it in */
- if (fabsf(eul1[0]) + fabsf(eul1[1]) + fabsf(eul1[2]) > fabsf(eul2[0]) + fabsf(eul2[1]) + fabsf(eul2[2])) {
- copy_v3_v3(eul, eul2);
- }
- else {
- copy_v3_v3(eul, eul1);
- }
+ /* return best, which is just the one with lowest values it in */
+ if (fabsf(eul1[0]) + fabsf(eul1[1]) + fabsf(eul1[2]) >
+ fabsf(eul2[0]) + fabsf(eul2[1]) + fabsf(eul2[2])) {
+ copy_v3_v3(eul, eul2);
+ }
+ else {
+ copy_v3_v3(eul, eul1);
+ }
}
void mat3_to_eul(float eul[3], const float mat[3][3])
{
- float unit_mat[3][3];
- normalize_m3_m3(unit_mat, mat);
- mat3_normalized_to_eul(eul, unit_mat);
+ float unit_mat[3][3];
+ normalize_m3_m3(unit_mat, mat);
+ mat3_normalized_to_eul(eul, unit_mat);
}
/* XYZ order */
void mat4_normalized_to_eul(float eul[3], const float m[4][4])
{
- float mat3[3][3];
- copy_m3_m4(mat3, m);
- mat3_normalized_to_eul(eul, mat3);
+ float mat3[3][3];
+ copy_m3_m4(mat3, m);
+ mat3_normalized_to_eul(eul, mat3);
}
void mat4_to_eul(float eul[3], const float m[4][4])
{
- float mat3[3][3];
- copy_m3_m4(mat3, m);
- mat3_to_eul(eul, mat3);
+ float mat3[3][3];
+ copy_m3_m4(mat3, m);
+ mat3_to_eul(eul, mat3);
}
/* XYZ order */
void quat_to_eul(float eul[3], const float quat[4])
{
- float unit_mat[3][3];
- quat_to_mat3(unit_mat, quat);
- mat3_normalized_to_eul(eul, unit_mat);
+ float unit_mat[3][3];
+ quat_to_mat3(unit_mat, quat);
+ mat3_normalized_to_eul(eul, unit_mat);
}
/* XYZ order */
void eul_to_quat(float quat[4], const float eul[3])
{
- float ti, tj, th, ci, cj, ch, si, sj, sh, cc, cs, sc, ss;
+ float ti, tj, th, ci, cj, ch, si, sj, sh, cc, cs, sc, ss;
- ti = eul[0] * 0.5f;
- tj = eul[1] * 0.5f;
- th = eul[2] * 0.5f;
- ci = cosf(ti);
- cj = cosf(tj);
- ch = cosf(th);
- si = sinf(ti);
- sj = sinf(tj);
- sh = sinf(th);
- cc = ci * ch;
- cs = ci * sh;
- sc = si * ch;
- ss = si * sh;
+ ti = eul[0] * 0.5f;
+ tj = eul[1] * 0.5f;
+ th = eul[2] * 0.5f;
+ ci = cosf(ti);
+ cj = cosf(tj);
+ ch = cosf(th);
+ si = sinf(ti);
+ sj = sinf(tj);
+ sh = sinf(th);
+ cc = ci * ch;
+ cs = ci * sh;
+ sc = si * ch;
+ ss = si * sh;
- quat[0] = cj * cc + sj * ss;
- quat[1] = cj * sc - sj * cs;
- quat[2] = cj * ss + sj * cc;
- quat[3] = cj * cs - sj * sc;
+ quat[0] = cj * cc + sj * ss;
+ quat[1] = cj * sc - sj * cs;
+ quat[2] = cj * ss + sj * cc;
+ quat[3] = cj * cs - sj * sc;
}
/* XYZ order */
void rotate_eul(float beul[3], const char axis, const float ang)
{
- float eul[3], mat1[3][3], mat2[3][3], totmat[3][3];
+ float eul[3], mat1[3][3], mat2[3][3], totmat[3][3];
- assert(axis >= 'X' && axis <= 'Z');
+ assert(axis >= 'X' && axis <= 'Z');
- eul[0] = eul[1] = eul[2] = 0.0f;
- if (axis == 'X') {
- eul[0] = ang;
- }
- else if (axis == 'Y') {
- eul[1] = ang;
- }
- else {
- eul[2] = ang;
- }
+ eul[0] = eul[1] = eul[2] = 0.0f;
+ if (axis == 'X') {
+ eul[0] = ang;
+ }
+ else if (axis == 'Y') {
+ eul[1] = ang;
+ }
+ else {
+ eul[2] = ang;
+ }
- eul_to_mat3(mat1, eul);
- eul_to_mat3(mat2, beul);
+ eul_to_mat3(mat1, eul);
+ eul_to_mat3(mat2, beul);
- mul_m3_m3m3(totmat, mat2, mat1);
+ mul_m3_m3m3(totmat, mat2, mat1);
- mat3_to_eul(beul, totmat);
+ mat3_to_eul(beul, totmat);
}
/* order independent! */
void compatible_eul(float eul[3], const float oldrot[3])
{
- /* we could use M_PI as pi_thresh: which is correct but 5.1 gives better results.
- * Checked with baking actions to fcurves - campbell */
- const float pi_thresh = (5.1f);
- const float pi_x2 = (2.0f * (float)M_PI);
-
- float deul[3];
- unsigned int i;
-
- /* correct differences of about 360 degrees first */
- for (i = 0; i < 3; i++) {
- deul[i] = eul[i] - oldrot[i];
- if (deul[i] > pi_thresh) {
- eul[i] -= floorf(( deul[i] / pi_x2) + 0.5f) * pi_x2;
- deul[i] = eul[i] - oldrot[i];
- }
- else if (deul[i] < -pi_thresh) {
- eul[i] += floorf((-deul[i] / pi_x2) + 0.5f) * pi_x2;
- deul[i] = eul[i] - oldrot[i];
- }
- }
-
- /* is 1 of the axis rotations larger than 180 degrees and the other small? NO ELSE IF!! */
- if (fabsf(deul[0]) > 3.2f && fabsf(deul[1]) < 1.6f && fabsf(deul[2]) < 1.6f) {
- if (deul[0] > 0.0f) { eul[0] -= pi_x2; }
- else { eul[0] += pi_x2; }
- }
- if (fabsf(deul[1]) > 3.2f && fabsf(deul[2]) < 1.6f && fabsf(deul[0]) < 1.6f) {
- if (deul[1] > 0.0f) { eul[1] -= pi_x2; }
- else { eul[1] += pi_x2; }
- }
- if (fabsf(deul[2]) > 3.2f && fabsf(deul[0]) < 1.6f && fabsf(deul[1]) < 1.6f) {
- if (deul[2] > 0.0f) { eul[2] -= pi_x2; }
- else { eul[2] += pi_x2; }
- }
+ /* we could use M_PI as pi_thresh: which is correct but 5.1 gives better results.
+ * Checked with baking actions to fcurves - campbell */
+ const float pi_thresh = (5.1f);
+ const float pi_x2 = (2.0f * (float)M_PI);
+
+ float deul[3];
+ unsigned int i;
+
+ /* correct differences of about 360 degrees first */
+ for (i = 0; i < 3; i++) {
+ deul[i] = eul[i] - oldrot[i];
+ if (deul[i] > pi_thresh) {
+ eul[i] -= floorf((deul[i] / pi_x2) + 0.5f) * pi_x2;
+ deul[i] = eul[i] - oldrot[i];
+ }
+ else if (deul[i] < -pi_thresh) {
+ eul[i] += floorf((-deul[i] / pi_x2) + 0.5f) * pi_x2;
+ deul[i] = eul[i] - oldrot[i];
+ }
+ }
+
+ /* is 1 of the axis rotations larger than 180 degrees and the other small? NO ELSE IF!! */
+ if (fabsf(deul[0]) > 3.2f && fabsf(deul[1]) < 1.6f && fabsf(deul[2]) < 1.6f) {
+ if (deul[0] > 0.0f) {
+ eul[0] -= pi_x2;
+ }
+ else {
+ eul[0] += pi_x2;
+ }
+ }
+ if (fabsf(deul[1]) > 3.2f && fabsf(deul[2]) < 1.6f && fabsf(deul[0]) < 1.6f) {
+ if (deul[1] > 0.0f) {
+ eul[1] -= pi_x2;
+ }
+ else {
+ eul[1] += pi_x2;
+ }
+ }
+ if (fabsf(deul[2]) > 3.2f && fabsf(deul[0]) < 1.6f && fabsf(deul[1]) < 1.6f) {
+ if (deul[2] > 0.0f) {
+ eul[2] -= pi_x2;
+ }
+ else {
+ eul[2] += pi_x2;
+ }
+ }
}
/* uses 2 methods to retrieve eulers, and picks the closest */
@@ -1447,37 +1475,37 @@ void compatible_eul(float eul[3], const float oldrot[3])
/* XYZ order */
void mat3_normalized_to_compatible_eul(float eul[3], const float oldrot[3], float mat[3][3])
{
- float eul1[3], eul2[3];
- float d1, d2;
+ float eul1[3], eul2[3];
+ float d1, d2;
- mat3_normalized_to_eul2(mat, eul1, eul2);
+ mat3_normalized_to_eul2(mat, eul1, eul2);
- compatible_eul(eul1, oldrot);
- compatible_eul(eul2, oldrot);
+ compatible_eul(eul1, oldrot);
+ compatible_eul(eul2, oldrot);
- d1 = fabsf(eul1[0] - oldrot[0]) + fabsf(eul1[1] - oldrot[1]) + fabsf(eul1[2] - oldrot[2]);
- d2 = fabsf(eul2[0] - oldrot[0]) + fabsf(eul2[1] - oldrot[1]) + fabsf(eul2[2] - oldrot[2]);
+ d1 = fabsf(eul1[0] - oldrot[0]) + fabsf(eul1[1] - oldrot[1]) + fabsf(eul1[2] - oldrot[2]);
+ d2 = fabsf(eul2[0] - oldrot[0]) + fabsf(eul2[1] - oldrot[1]) + fabsf(eul2[2] - oldrot[2]);
- /* return best, which is just the one with lowest difference */
- if (d1 > d2) {
- copy_v3_v3(eul, eul2);
- }
- else {
- copy_v3_v3(eul, eul1);
- }
+ /* return best, which is just the one with lowest difference */
+ if (d1 > d2) {
+ copy_v3_v3(eul, eul2);
+ }
+ else {
+ copy_v3_v3(eul, eul1);
+ }
}
void mat3_to_compatible_eul(float eul[3], const float oldrot[3], float mat[3][3])
{
- float unit_mat[3][3];
- normalize_m3_m3(unit_mat, mat);
- mat3_normalized_to_compatible_eul(eul, oldrot, unit_mat);
+ float unit_mat[3][3];
+ normalize_m3_m3(unit_mat, mat);
+ mat3_normalized_to_compatible_eul(eul, oldrot, unit_mat);
}
void quat_to_compatible_eul(float eul[3], const float oldrot[3], const float quat[4])
{
- float unit_mat[3][3];
- quat_to_mat3(unit_mat, quat);
- mat3_normalized_to_compatible_eul(eul, oldrot, unit_mat);
+ float unit_mat[3][3];
+ quat_to_mat3(unit_mat, quat);
+ mat3_normalized_to_compatible_eul(eul, oldrot, unit_mat);
}
/************************** Arbitrary Order Eulers ***************************/
@@ -1493,21 +1521,21 @@ void quat_to_compatible_eul(float eul[3], const float oldrot[3], const float qua
/* Type for rotation order info - see wiki for derivation details */
typedef struct RotOrderInfo {
- short axis[3];
- short parity; /* parity of axis permutation (even=0, odd=1) - 'n' in original code */
+ short axis[3];
+ short parity; /* parity of axis permutation (even=0, odd=1) - 'n' in original code */
} RotOrderInfo;
/* Array of info for Rotation Order calculations
* WARNING: must be kept in same order as eEulerRotationOrders
*/
static const RotOrderInfo rotOrders[] = {
- /* i, j, k, n */
- {{0, 1, 2}, 0}, /* XYZ */
- {{0, 2, 1}, 1}, /* XZY */
- {{1, 0, 2}, 1}, /* YXZ */
- {{1, 2, 0}, 0}, /* YZX */
- {{2, 0, 1}, 0}, /* ZXY */
- {{2, 1, 0}, 1} /* ZYX */
+ /* i, j, k, n */
+ {{0, 1, 2}, 0}, /* XYZ */
+ {{0, 2, 1}, 1}, /* XZY */
+ {{1, 0, 2}, 1}, /* YXZ */
+ {{1, 2, 0}, 0}, /* YZX */
+ {{2, 0, 1}, 0}, /* ZXY */
+ {{2, 1, 0}, 1} /* ZYX */
};
/* Get relevant pointer to rotation order set from the array
@@ -1516,254 +1544,266 @@ static const RotOrderInfo rotOrders[] = {
*/
static const RotOrderInfo *get_rotation_order_info(const short order)
{
- assert(order >= 0 && order <= 6);
- if (order < 1) {
- return &rotOrders[0];
- }
- else if (order < 6) {
- return &rotOrders[order - 1];
- }
- else {
- return &rotOrders[5];
- }
+ assert(order >= 0 && order <= 6);
+ if (order < 1) {
+ return &rotOrders[0];
+ }
+ else if (order < 6) {
+ return &rotOrders[order - 1];
+ }
+ else {
+ return &rotOrders[5];
+ }
}
/* Construct quaternion from Euler angles (in radians). */
void eulO_to_quat(float q[4], const float e[3], const short order)
{
- const RotOrderInfo *R = get_rotation_order_info(order);
- short i = R->axis[0], j = R->axis[1], k = R->axis[2];
- double ti, tj, th, ci, cj, ch, si, sj, sh, cc, cs, sc, ss;
- double a[3];
+ const RotOrderInfo *R = get_rotation_order_info(order);
+ short i = R->axis[0], j = R->axis[1], k = R->axis[2];
+ double ti, tj, th, ci, cj, ch, si, sj, sh, cc, cs, sc, ss;
+ double a[3];
- ti = e[i] * 0.5f;
- tj = e[j] * (R->parity ? -0.5f : 0.5f);
- th = e[k] * 0.5f;
+ ti = e[i] * 0.5f;
+ tj = e[j] * (R->parity ? -0.5f : 0.5f);
+ th = e[k] * 0.5f;
- ci = cos(ti);
- cj = cos(tj);
- ch = cos(th);
- si = sin(ti);
- sj = sin(tj);
- sh = sin(th);
+ ci = cos(ti);
+ cj = cos(tj);
+ ch = cos(th);
+ si = sin(ti);
+ sj = sin(tj);
+ sh = sin(th);
- cc = ci * ch;
- cs = ci * sh;
- sc = si * ch;
- ss = si * sh;
+ cc = ci * ch;
+ cs = ci * sh;
+ sc = si * ch;
+ ss = si * sh;
- a[i] = cj * sc - sj * cs;
- a[j] = cj * ss + sj * cc;
- a[k] = cj * cs - sj * sc;
+ a[i] = cj * sc - sj * cs;
+ a[j] = cj * ss + sj * cc;
+ a[k] = cj * cs - sj * sc;
- q[0] = (float)(cj * cc + sj * ss);
- q[1] = (float)(a[0]);
- q[2] = (float)(a[1]);
- q[3] = (float)(a[2]);
+ q[0] = (float)(cj * cc + sj * ss);
+ q[1] = (float)(a[0]);
+ q[2] = (float)(a[1]);
+ q[3] = (float)(a[2]);
- if (R->parity) {
- q[j + 1] = -q[j + 1];
- }
+ if (R->parity) {
+ q[j + 1] = -q[j + 1];
+ }
}
/* Convert quaternion to Euler angles (in radians). */
void quat_to_eulO(float e[3], short const order, const float q[4])
{
- float unit_mat[3][3];
+ float unit_mat[3][3];
- quat_to_mat3(unit_mat, q);
- mat3_normalized_to_eulO(e, order, unit_mat);
+ quat_to_mat3(unit_mat, q);
+ mat3_normalized_to_eulO(e, order, unit_mat);
}
/* Construct 3x3 matrix from Euler angles (in radians). */
void eulO_to_mat3(float M[3][3], const float e[3], const short order)
{
- const RotOrderInfo *R = get_rotation_order_info(order);
- short i = R->axis[0], j = R->axis[1], k = R->axis[2];
- double ti, tj, th, ci, cj, ch, si, sj, sh, cc, cs, sc, ss;
-
- if (R->parity) {
- ti = -e[i];
- tj = -e[j];
- th = -e[k];
- }
- else {
- ti = e[i];
- tj = e[j];
- th = e[k];
- }
-
- ci = cos(ti);
- cj = cos(tj);
- ch = cos(th);
- si = sin(ti);
- sj = sin(tj);
- sh = sin(th);
-
- cc = ci * ch;
- cs = ci * sh;
- sc = si * ch;
- ss = si * sh;
-
- M[i][i] = (float)(cj * ch);
- M[j][i] = (float)(sj * sc - cs);
- M[k][i] = (float)(sj * cc + ss);
- M[i][j] = (float)(cj * sh);
- M[j][j] = (float)(sj * ss + cc);
- M[k][j] = (float)(sj * cs - sc);
- M[i][k] = (float)(-sj);
- M[j][k] = (float)(cj * si);
- M[k][k] = (float)(cj * ci);
+ const RotOrderInfo *R = get_rotation_order_info(order);
+ short i = R->axis[0], j = R->axis[1], k = R->axis[2];
+ double ti, tj, th, ci, cj, ch, si, sj, sh, cc, cs, sc, ss;
+
+ if (R->parity) {
+ ti = -e[i];
+ tj = -e[j];
+ th = -e[k];
+ }
+ else {
+ ti = e[i];
+ tj = e[j];
+ th = e[k];
+ }
+
+ ci = cos(ti);
+ cj = cos(tj);
+ ch = cos(th);
+ si = sin(ti);
+ sj = sin(tj);
+ sh = sin(th);
+
+ cc = ci * ch;
+ cs = ci * sh;
+ sc = si * ch;
+ ss = si * sh;
+
+ M[i][i] = (float)(cj * ch);
+ M[j][i] = (float)(sj * sc - cs);
+ M[k][i] = (float)(sj * cc + ss);
+ M[i][j] = (float)(cj * sh);
+ M[j][j] = (float)(sj * ss + cc);
+ M[k][j] = (float)(sj * cs - sc);
+ M[i][k] = (float)(-sj);
+ M[j][k] = (float)(cj * si);
+ M[k][k] = (float)(cj * ci);
}
/* returns two euler calculation methods, so we can pick the best */
-static void mat3_normalized_to_eulo2(const float mat[3][3], float eul1[3], float eul2[3], const short order)
+static void mat3_normalized_to_eulo2(const float mat[3][3],
+ float eul1[3],
+ float eul2[3],
+ const short order)
{
- const RotOrderInfo *R = get_rotation_order_info(order);
- short i = R->axis[0], j = R->axis[1], k = R->axis[2];
- float cy;
+ const RotOrderInfo *R = get_rotation_order_info(order);
+ short i = R->axis[0], j = R->axis[1], k = R->axis[2];
+ float cy;
- BLI_ASSERT_UNIT_M3(mat);
+ BLI_ASSERT_UNIT_M3(mat);
- cy = hypotf(mat[i][i], mat[i][j]);
+ cy = hypotf(mat[i][i], mat[i][j]);
- if (cy > 16.0f * FLT_EPSILON) {
- eul1[i] = atan2f(mat[j][k], mat[k][k]);
- eul1[j] = atan2f(-mat[i][k], cy);
- eul1[k] = atan2f(mat[i][j], mat[i][i]);
+ if (cy > 16.0f * FLT_EPSILON) {
+ eul1[i] = atan2f(mat[j][k], mat[k][k]);
+ eul1[j] = atan2f(-mat[i][k], cy);
+ eul1[k] = atan2f(mat[i][j], mat[i][i]);
- eul2[i] = atan2f(-mat[j][k], -mat[k][k]);
- eul2[j] = atan2f(-mat[i][k], -cy);
- eul2[k] = atan2f(-mat[i][j], -mat[i][i]);
- }
- else {
- eul1[i] = atan2f(-mat[k][j], mat[j][j]);
- eul1[j] = atan2f(-mat[i][k], cy);
- eul1[k] = 0;
+ eul2[i] = atan2f(-mat[j][k], -mat[k][k]);
+ eul2[j] = atan2f(-mat[i][k], -cy);
+ eul2[k] = atan2f(-mat[i][j], -mat[i][i]);
+ }
+ else {
+ eul1[i] = atan2f(-mat[k][j], mat[j][j]);
+ eul1[j] = atan2f(-mat[i][k], cy);
+ eul1[k] = 0;
- copy_v3_v3(eul2, eul1);
- }
+ copy_v3_v3(eul2, eul1);
+ }
- if (R->parity) {
- negate_v3(eul1);
- negate_v3(eul2);
- }
+ if (R->parity) {
+ negate_v3(eul1);
+ negate_v3(eul2);
+ }
}
/* Construct 4x4 matrix from Euler angles (in radians). */
void eulO_to_mat4(float mat[4][4], const float e[3], const short order)
{
- float unit_mat[3][3];
+ float unit_mat[3][3];
- /* for now, we'll just do this the slow way (i.e. copying matrices) */
- eulO_to_mat3(unit_mat, e, order);
- copy_m4_m3(mat, unit_mat);
+ /* for now, we'll just do this the slow way (i.e. copying matrices) */
+ eulO_to_mat3(unit_mat, e, order);
+ copy_m4_m3(mat, unit_mat);
}
/* Convert 3x3 matrix to Euler angles (in radians). */
void mat3_normalized_to_eulO(float eul[3], const short order, const float m[3][3])
{
- float eul1[3], eul2[3];
- float d1, d2;
+ float eul1[3], eul2[3];
+ float d1, d2;
- mat3_normalized_to_eulo2(m, eul1, eul2, order);
+ mat3_normalized_to_eulo2(m, eul1, eul2, order);
- d1 = fabsf(eul1[0]) + fabsf(eul1[1]) + fabsf(eul1[2]);
- d2 = fabsf(eul2[0]) + fabsf(eul2[1]) + fabsf(eul2[2]);
+ d1 = fabsf(eul1[0]) + fabsf(eul1[1]) + fabsf(eul1[2]);
+ d2 = fabsf(eul2[0]) + fabsf(eul2[1]) + fabsf(eul2[2]);
- /* return best, which is just the one with lowest values it in */
- if (d1 > d2) {
- copy_v3_v3(eul, eul2);
- }
- else {
- copy_v3_v3(eul, eul1);
- }
+ /* return best, which is just the one with lowest values it in */
+ if (d1 > d2) {
+ copy_v3_v3(eul, eul2);
+ }
+ else {
+ copy_v3_v3(eul, eul1);
+ }
}
void mat3_to_eulO(float eul[3], const short order, const float m[3][3])
{
- float unit_mat[3][3];
- normalize_m3_m3(unit_mat, m);
- mat3_normalized_to_eulO(eul, order, unit_mat);
+ float unit_mat[3][3];
+ normalize_m3_m3(unit_mat, m);
+ mat3_normalized_to_eulO(eul, order, unit_mat);
}
/* Convert 4x4 matrix to Euler angles (in radians). */
void mat4_normalized_to_eulO(float eul[3], const short order, const float m[4][4])
{
- float mat3[3][3];
+ float mat3[3][3];
- /* for now, we'll just do this the slow way (i.e. copying matrices) */
- copy_m3_m4(mat3, m);
- mat3_normalized_to_eulO(eul, order, mat3);
+ /* for now, we'll just do this the slow way (i.e. copying matrices) */
+ copy_m3_m4(mat3, m);
+ mat3_normalized_to_eulO(eul, order, mat3);
}
void mat4_to_eulO(float eul[3], const short order, const float m[4][4])
{
- float mat3[3][3];
- copy_m3_m4(mat3, m);
- normalize_m3(mat3);
- mat3_normalized_to_eulO(eul, order, mat3);
+ float mat3[3][3];
+ copy_m3_m4(mat3, m);
+ normalize_m3(mat3);
+ mat3_normalized_to_eulO(eul, order, mat3);
}
-
/* uses 2 methods to retrieve eulers, and picks the closest */
-void mat3_normalized_to_compatible_eulO(
- float eul[3], const float oldrot[3], const short order, const float mat[3][3])
+void mat3_normalized_to_compatible_eulO(float eul[3],
+ const float oldrot[3],
+ const short order,
+ const float mat[3][3])
{
- float eul1[3], eul2[3];
- float d1, d2;
+ float eul1[3], eul2[3];
+ float d1, d2;
- mat3_normalized_to_eulo2(mat, eul1, eul2, order);
+ mat3_normalized_to_eulo2(mat, eul1, eul2, order);
- compatible_eul(eul1, oldrot);
- compatible_eul(eul2, oldrot);
+ compatible_eul(eul1, oldrot);
+ compatible_eul(eul2, oldrot);
- d1 = fabsf(eul1[0] - oldrot[0]) + fabsf(eul1[1] - oldrot[1]) + fabsf(eul1[2] - oldrot[2]);
- d2 = fabsf(eul2[0] - oldrot[0]) + fabsf(eul2[1] - oldrot[1]) + fabsf(eul2[2] - oldrot[2]);
+ d1 = fabsf(eul1[0] - oldrot[0]) + fabsf(eul1[1] - oldrot[1]) + fabsf(eul1[2] - oldrot[2]);
+ d2 = fabsf(eul2[0] - oldrot[0]) + fabsf(eul2[1] - oldrot[1]) + fabsf(eul2[2] - oldrot[2]);
- /* return best, which is just the one with lowest difference */
- if (d1 > d2) {
- copy_v3_v3(eul, eul2);
- }
- else {
- copy_v3_v3(eul, eul1);
- }
+ /* return best, which is just the one with lowest difference */
+ if (d1 > d2) {
+ copy_v3_v3(eul, eul2);
+ }
+ else {
+ copy_v3_v3(eul, eul1);
+ }
}
-void mat3_to_compatible_eulO(
- float eul[3], const float oldrot[3], const short order, const float mat[3][3])
+void mat3_to_compatible_eulO(float eul[3],
+ const float oldrot[3],
+ const short order,
+ const float mat[3][3])
{
- float unit_mat[3][3];
+ float unit_mat[3][3];
- normalize_m3_m3(unit_mat, mat);
- mat3_normalized_to_compatible_eulO(eul, oldrot, order, unit_mat);
+ normalize_m3_m3(unit_mat, mat);
+ mat3_normalized_to_compatible_eulO(eul, oldrot, order, unit_mat);
}
-void mat4_normalized_to_compatible_eulO(
- float eul[3], const float oldrot[3], const short order, const float m[4][4])
+void mat4_normalized_to_compatible_eulO(float eul[3],
+ const float oldrot[3],
+ const short order,
+ const float m[4][4])
{
- float mat3[3][3];
+ float mat3[3][3];
- /* for now, we'll just do this the slow way (i.e. copying matrices) */
- copy_m3_m4(mat3, m);
- mat3_normalized_to_compatible_eulO(eul, oldrot, order, mat3);
+ /* for now, we'll just do this the slow way (i.e. copying matrices) */
+ copy_m3_m4(mat3, m);
+ mat3_normalized_to_compatible_eulO(eul, oldrot, order, mat3);
}
-void mat4_to_compatible_eulO(
- float eul[3], const float oldrot[3], const short order, const float m[4][4])
+void mat4_to_compatible_eulO(float eul[3],
+ const float oldrot[3],
+ const short order,
+ const float m[4][4])
{
- float mat3[3][3];
+ float mat3[3][3];
- /* for now, we'll just do this the slow way (i.e. copying matrices) */
- copy_m3_m4(mat3, m);
- normalize_m3(mat3);
- mat3_normalized_to_compatible_eulO(eul, oldrot, order, mat3);
+ /* for now, we'll just do this the slow way (i.e. copying matrices) */
+ copy_m3_m4(mat3, m);
+ normalize_m3(mat3);
+ mat3_normalized_to_compatible_eulO(eul, oldrot, order, mat3);
}
-void quat_to_compatible_eulO(
- float eul[3], const float oldrot[3], const short order, const float quat[4])
+void quat_to_compatible_eulO(float eul[3],
+ const float oldrot[3],
+ const short order,
+ const float quat[4])
{
- float unit_mat[3][3];
+ float unit_mat[3][3];
- quat_to_mat3(unit_mat, quat);
- mat3_normalized_to_compatible_eulO(eul, oldrot, order, unit_mat);
+ quat_to_mat3(unit_mat, quat);
+ mat3_normalized_to_compatible_eulO(eul, oldrot, order, unit_mat);
}
/* rotate the given euler by the given angle on the specified axis */
@@ -1771,52 +1811,51 @@ void quat_to_compatible_eulO(
void rotate_eulO(float beul[3], const short order, char axis, float ang)
{
- float eul[3], mat1[3][3], mat2[3][3], totmat[3][3];
+ float eul[3], mat1[3][3], mat2[3][3], totmat[3][3];
- assert(axis >= 'X' && axis <= 'Z');
+ assert(axis >= 'X' && axis <= 'Z');
- zero_v3(eul);
+ zero_v3(eul);
- if (axis == 'X') {
- eul[0] = ang;
- }
- else if (axis == 'Y') {
- eul[1] = ang;
- }
- else {
- eul[2] = ang;
- }
+ if (axis == 'X') {
+ eul[0] = ang;
+ }
+ else if (axis == 'Y') {
+ eul[1] = ang;
+ }
+ else {
+ eul[2] = ang;
+ }
- eulO_to_mat3(mat1, eul, order);
- eulO_to_mat3(mat2, beul, order);
+ eulO_to_mat3(mat1, eul, order);
+ eulO_to_mat3(mat2, beul, order);
- mul_m3_m3m3(totmat, mat2, mat1);
+ mul_m3_m3m3(totmat, mat2, mat1);
- mat3_to_eulO(beul, order, totmat);
+ mat3_to_eulO(beul, order, totmat);
}
/* the matrix is written to as 3 axis vectors */
void eulO_to_gimbal_axis(float gmat[3][3], const float eul[3], const short order)
{
- const RotOrderInfo *R = get_rotation_order_info(order);
-
- float mat[3][3];
- float teul[3];
+ const RotOrderInfo *R = get_rotation_order_info(order);
- /* first axis is local */
- eulO_to_mat3(mat, eul, order);
- copy_v3_v3(gmat[R->axis[0]], mat[R->axis[0]]);
+ float mat[3][3];
+ float teul[3];
- /* second axis is local minus first rotation */
- copy_v3_v3(teul, eul);
- teul[R->axis[0]] = 0;
- eulO_to_mat3(mat, teul, order);
- copy_v3_v3(gmat[R->axis[1]], mat[R->axis[1]]);
+ /* first axis is local */
+ eulO_to_mat3(mat, eul, order);
+ copy_v3_v3(gmat[R->axis[0]], mat[R->axis[0]]);
+ /* second axis is local minus first rotation */
+ copy_v3_v3(teul, eul);
+ teul[R->axis[0]] = 0;
+ eulO_to_mat3(mat, teul, order);
+ copy_v3_v3(gmat[R->axis[1]], mat[R->axis[1]]);
- /* Last axis is global */
- zero_v3(gmat[R->axis[2]]);
- gmat[R->axis[2]][R->axis[2]] = 1;
+ /* Last axis is global */
+ zero_v3(gmat[R->axis[2]]);
+ gmat[R->axis[2]][R->axis[2]] = 1;
}
/******************************* Dual Quaternions ****************************/
@@ -1852,431 +1891,409 @@ void eulO_to_gimbal_axis(float gmat[3][3], const float eul[3], const short order
void mat4_to_dquat(DualQuat *dq, const float basemat[4][4], const float mat[4][4])
{
- float *t, *q, dscale[3], scale[3], basequat[4], mat3[3][3];
- float baseRS[4][4], baseinv[4][4], baseR[4][4], baseRinv[4][4];
- float R[4][4], S[4][4];
+ float *t, *q, dscale[3], scale[3], basequat[4], mat3[3][3];
+ float baseRS[4][4], baseinv[4][4], baseR[4][4], baseRinv[4][4];
+ float R[4][4], S[4][4];
- /* split scaling and rotation, there is probably a faster way to do
- * this, it's done like this now to correctly get negative scaling */
- mul_m4_m4m4(baseRS, mat, basemat);
- mat4_to_size(scale, baseRS);
+ /* split scaling and rotation, there is probably a faster way to do
+ * this, it's done like this now to correctly get negative scaling */
+ mul_m4_m4m4(baseRS, mat, basemat);
+ mat4_to_size(scale, baseRS);
- dscale[0] = scale[0] - 1.0f;
- dscale[1] = scale[1] - 1.0f;
- dscale[2] = scale[2] - 1.0f;
+ dscale[0] = scale[0] - 1.0f;
+ dscale[1] = scale[1] - 1.0f;
+ dscale[2] = scale[2] - 1.0f;
- copy_m3_m4(mat3, mat);
+ copy_m3_m4(mat3, mat);
- if (!is_orthonormal_m3(mat3) || (determinant_m4(mat) < 0.0f) || len_squared_v3(dscale) > SQUARE(1e-4f)) {
- /* extract R and S */
- float tmp[4][4];
+ if (!is_orthonormal_m3(mat3) || (determinant_m4(mat) < 0.0f) ||
+ len_squared_v3(dscale) > SQUARE(1e-4f)) {
+ /* extract R and S */
+ float tmp[4][4];
- /* extra orthogonalize, to avoid flipping with stretched bones */
- copy_m4_m4(tmp, baseRS);
- orthogonalize_m4(tmp, 1);
- mat4_to_quat(basequat, tmp);
+ /* extra orthogonalize, to avoid flipping with stretched bones */
+ copy_m4_m4(tmp, baseRS);
+ orthogonalize_m4(tmp, 1);
+ mat4_to_quat(basequat, tmp);
- quat_to_mat4(baseR, basequat);
- copy_v3_v3(baseR[3], baseRS[3]);
+ quat_to_mat4(baseR, basequat);
+ copy_v3_v3(baseR[3], baseRS[3]);
- invert_m4_m4(baseinv, basemat);
- mul_m4_m4m4(R, baseR, baseinv);
+ invert_m4_m4(baseinv, basemat);
+ mul_m4_m4m4(R, baseR, baseinv);
- invert_m4_m4(baseRinv, baseR);
- mul_m4_m4m4(S, baseRinv, baseRS);
+ invert_m4_m4(baseRinv, baseR);
+ mul_m4_m4m4(S, baseRinv, baseRS);
- /* set scaling part */
- mul_m4_series(dq->scale, basemat, S, baseinv);
- dq->scale_weight = 1.0f;
- }
- else {
- /* matrix does not contain scaling */
- copy_m4_m4(R, mat);
- dq->scale_weight = 0.0f;
- }
+ /* set scaling part */
+ mul_m4_series(dq->scale, basemat, S, baseinv);
+ dq->scale_weight = 1.0f;
+ }
+ else {
+ /* matrix does not contain scaling */
+ copy_m4_m4(R, mat);
+ dq->scale_weight = 0.0f;
+ }
- /* non-dual part */
- mat4_to_quat(dq->quat, R);
+ /* non-dual part */
+ mat4_to_quat(dq->quat, R);
- /* dual part */
- t = R[3];
- q = dq->quat;
- dq->trans[0] = -0.5f * ( t[0] * q[1] + t[1] * q[2] + t[2] * q[3]);
- dq->trans[1] = 0.5f * ( t[0] * q[0] + t[1] * q[3] - t[2] * q[2]);
- dq->trans[2] = 0.5f * (-t[0] * q[3] + t[1] * q[0] + t[2] * q[1]);
- dq->trans[3] = 0.5f * ( t[0] * q[2] - t[1] * q[1] + t[2] * q[0]);
+ /* dual part */
+ t = R[3];
+ q = dq->quat;
+ dq->trans[0] = -0.5f * (t[0] * q[1] + t[1] * q[2] + t[2] * q[3]);
+ dq->trans[1] = 0.5f * (t[0] * q[0] + t[1] * q[3] - t[2] * q[2]);
+ dq->trans[2] = 0.5f * (-t[0] * q[3] + t[1] * q[0] + t[2] * q[1]);
+ dq->trans[3] = 0.5f * (t[0] * q[2] - t[1] * q[1] + t[2] * q[0]);
}
void dquat_to_mat4(float mat[4][4], const DualQuat *dq)
{
- float len, q0[4];
- const float *t;
+ float len, q0[4];
+ const float *t;
- /* regular quaternion */
- copy_qt_qt(q0, dq->quat);
+ /* regular quaternion */
+ copy_qt_qt(q0, dq->quat);
- /* normalize */
- len = sqrtf(dot_qtqt(q0, q0));
- if (len != 0.0f) {
- len = 1.0f / len;
- }
- mul_qt_fl(q0, len);
+ /* normalize */
+ len = sqrtf(dot_qtqt(q0, q0));
+ if (len != 0.0f) {
+ len = 1.0f / len;
+ }
+ mul_qt_fl(q0, len);
- /* rotation */
- quat_to_mat4(mat, q0);
+ /* rotation */
+ quat_to_mat4(mat, q0);
- /* translation */
- t = dq->trans;
- mat[3][0] = 2.0f * (-t[0] * q0[1] + t[1] * q0[0] - t[2] * q0[3] + t[3] * q0[2]) * len;
- mat[3][1] = 2.0f * (-t[0] * q0[2] + t[1] * q0[3] + t[2] * q0[0] - t[3] * q0[1]) * len;
- mat[3][2] = 2.0f * (-t[0] * q0[3] - t[1] * q0[2] + t[2] * q0[1] + t[3] * q0[0]) * len;
+ /* translation */
+ t = dq->trans;
+ mat[3][0] = 2.0f * (-t[0] * q0[1] + t[1] * q0[0] - t[2] * q0[3] + t[3] * q0[2]) * len;
+ mat[3][1] = 2.0f * (-t[0] * q0[2] + t[1] * q0[3] + t[2] * q0[0] - t[3] * q0[1]) * len;
+ mat[3][2] = 2.0f * (-t[0] * q0[3] - t[1] * q0[2] + t[2] * q0[1] + t[3] * q0[0]) * len;
- /* scaling */
- if (dq->scale_weight) {
- mul_m4_m4m4(mat, mat, dq->scale);
- }
+ /* scaling */
+ if (dq->scale_weight) {
+ mul_m4_m4m4(mat, mat, dq->scale);
+ }
}
void add_weighted_dq_dq(DualQuat *dqsum, const DualQuat *dq, float weight)
{
- bool flipped = false;
+ bool flipped = false;
- /* make sure we interpolate quats in the right direction */
- if (dot_qtqt(dq->quat, dqsum->quat) < 0) {
- flipped = true;
- weight = -weight;
- }
+ /* make sure we interpolate quats in the right direction */
+ if (dot_qtqt(dq->quat, dqsum->quat) < 0) {
+ flipped = true;
+ weight = -weight;
+ }
- /* interpolate rotation and translation */
- dqsum->quat[0] += weight * dq->quat[0];
- dqsum->quat[1] += weight * dq->quat[1];
- dqsum->quat[2] += weight * dq->quat[2];
- dqsum->quat[3] += weight * dq->quat[3];
+ /* interpolate rotation and translation */
+ dqsum->quat[0] += weight * dq->quat[0];
+ dqsum->quat[1] += weight * dq->quat[1];
+ dqsum->quat[2] += weight * dq->quat[2];
+ dqsum->quat[3] += weight * dq->quat[3];
- dqsum->trans[0] += weight * dq->trans[0];
- dqsum->trans[1] += weight * dq->trans[1];
- dqsum->trans[2] += weight * dq->trans[2];
- dqsum->trans[3] += weight * dq->trans[3];
+ dqsum->trans[0] += weight * dq->trans[0];
+ dqsum->trans[1] += weight * dq->trans[1];
+ dqsum->trans[2] += weight * dq->trans[2];
+ dqsum->trans[3] += weight * dq->trans[3];
- /* Interpolate scale - but only if there is scale present. If any dual
- * quaternions without scale are added, they will be compensated for in
- * normalize_dq. */
- if (dq->scale_weight) {
- float wmat[4][4];
+ /* Interpolate scale - but only if there is scale present. If any dual
+ * quaternions without scale are added, they will be compensated for in
+ * normalize_dq. */
+ if (dq->scale_weight) {
+ float wmat[4][4];
- if (flipped) {
- /* we don't want negative weights for scaling */
- weight = -weight;
- }
+ if (flipped) {
+ /* we don't want negative weights for scaling */
+ weight = -weight;
+ }
- copy_m4_m4(wmat, (float(*)[4])dq->scale);
- mul_m4_fl(wmat, weight);
- add_m4_m4m4(dqsum->scale, dqsum->scale, wmat);
- dqsum->scale_weight += weight;
- }
+ copy_m4_m4(wmat, (float(*)[4])dq->scale);
+ mul_m4_fl(wmat, weight);
+ add_m4_m4m4(dqsum->scale, dqsum->scale, wmat);
+ dqsum->scale_weight += weight;
+ }
}
void normalize_dq(DualQuat *dq, float totweight)
{
- const float scale = 1.0f / totweight;
+ const float scale = 1.0f / totweight;
- mul_qt_fl(dq->quat, scale);
- mul_qt_fl(dq->trans, scale);
+ mul_qt_fl(dq->quat, scale);
+ mul_qt_fl(dq->trans, scale);
- /* Handle scale if needed. */
- if (dq->scale_weight) {
- /* Compensate for any dual quaternions added without scale. This is an
- * optimization so that we can skip the scale part when not needed. */
- float addweight = totweight - dq->scale_weight;
+ /* Handle scale if needed. */
+ if (dq->scale_weight) {
+ /* Compensate for any dual quaternions added without scale. This is an
+ * optimization so that we can skip the scale part when not needed. */
+ float addweight = totweight - dq->scale_weight;
- if (addweight) {
- dq->scale[0][0] += addweight;
- dq->scale[1][1] += addweight;
- dq->scale[2][2] += addweight;
- dq->scale[3][3] += addweight;
- }
+ if (addweight) {
+ dq->scale[0][0] += addweight;
+ dq->scale[1][1] += addweight;
+ dq->scale[2][2] += addweight;
+ dq->scale[3][3] += addweight;
+ }
- mul_m4_fl(dq->scale, scale);
- dq->scale_weight = 1.0f;
- }
+ mul_m4_fl(dq->scale, scale);
+ dq->scale_weight = 1.0f;
+ }
}
void mul_v3m3_dq(float co[3], float mat[3][3], DualQuat *dq)
{
- float M[3][3], t[3], scalemat[3][3], len2;
- float w = dq->quat[0], x = dq->quat[1], y = dq->quat[2], z = dq->quat[3];
- float t0 = dq->trans[0], t1 = dq->trans[1], t2 = dq->trans[2], t3 = dq->trans[3];
-
- /* rotation matrix */
- M[0][0] = w * w + x * x - y * y - z * z;
- M[1][0] = 2 * (x * y - w * z);
- M[2][0] = 2 * (x * z + w * y);
-
- M[0][1] = 2 * (x * y + w * z);
- M[1][1] = w * w + y * y - x * x - z * z;
- M[2][1] = 2 * (y * z - w * x);
-
- M[0][2] = 2 * (x * z - w * y);
- M[1][2] = 2 * (y * z + w * x);
- M[2][2] = w * w + z * z - x * x - y * y;
-
- len2 = dot_qtqt(dq->quat, dq->quat);
- if (len2 > 0.0f) {
- len2 = 1.0f / len2;
- }
-
- /* translation */
- t[0] = 2 * (-t0 * x + w * t1 - t2 * z + y * t3);
- t[1] = 2 * (-t0 * y + t1 * z - x * t3 + w * t2);
- t[2] = 2 * (-t0 * z + x * t2 + w * t3 - t1 * y);
-
- /* apply scaling */
- if (dq->scale_weight) {
- mul_m4_v3(dq->scale, co);
- }
-
- /* apply rotation and translation */
- mul_m3_v3(M, co);
- co[0] = (co[0] + t[0]) * len2;
- co[1] = (co[1] + t[1]) * len2;
- co[2] = (co[2] + t[2]) * len2;
-
- /* compute crazyspace correction mat */
- if (mat) {
- if (dq->scale_weight) {
- copy_m3_m4(scalemat, dq->scale);
- mul_m3_m3m3(mat, M, scalemat);
- }
- else {
- copy_m3_m3(mat, M);
- }
- mul_m3_fl(mat, len2);
- }
+ float M[3][3], t[3], scalemat[3][3], len2;
+ float w = dq->quat[0], x = dq->quat[1], y = dq->quat[2], z = dq->quat[3];
+ float t0 = dq->trans[0], t1 = dq->trans[1], t2 = dq->trans[2], t3 = dq->trans[3];
+
+ /* rotation matrix */
+ M[0][0] = w * w + x * x - y * y - z * z;
+ M[1][0] = 2 * (x * y - w * z);
+ M[2][0] = 2 * (x * z + w * y);
+
+ M[0][1] = 2 * (x * y + w * z);
+ M[1][1] = w * w + y * y - x * x - z * z;
+ M[2][1] = 2 * (y * z - w * x);
+
+ M[0][2] = 2 * (x * z - w * y);
+ M[1][2] = 2 * (y * z + w * x);
+ M[2][2] = w * w + z * z - x * x - y * y;
+
+ len2 = dot_qtqt(dq->quat, dq->quat);
+ if (len2 > 0.0f) {
+ len2 = 1.0f / len2;
+ }
+
+ /* translation */
+ t[0] = 2 * (-t0 * x + w * t1 - t2 * z + y * t3);
+ t[1] = 2 * (-t0 * y + t1 * z - x * t3 + w * t2);
+ t[2] = 2 * (-t0 * z + x * t2 + w * t3 - t1 * y);
+
+ /* apply scaling */
+ if (dq->scale_weight) {
+ mul_m4_v3(dq->scale, co);
+ }
+
+ /* apply rotation and translation */
+ mul_m3_v3(M, co);
+ co[0] = (co[0] + t[0]) * len2;
+ co[1] = (co[1] + t[1]) * len2;
+ co[2] = (co[2] + t[2]) * len2;
+
+ /* compute crazyspace correction mat */
+ if (mat) {
+ if (dq->scale_weight) {
+ copy_m3_m4(scalemat, dq->scale);
+ mul_m3_m3m3(mat, M, scalemat);
+ }
+ else {
+ copy_m3_m3(mat, M);
+ }
+ mul_m3_fl(mat, len2);
+ }
}
void copy_dq_dq(DualQuat *dq1, const DualQuat *dq2)
{
- memcpy(dq1, dq2, sizeof(DualQuat));
+ memcpy(dq1, dq2, sizeof(DualQuat));
}
/* axis matches eTrackToAxis_Modes */
void quat_apply_track(float quat[4], short axis, short upflag)
{
- /* rotations are hard coded to match vec_to_quat */
- const float sqrt_1_2 = (float)M_SQRT1_2;
- const float quat_track[][4] = {
- /* pos-y90 */
- {sqrt_1_2, 0.0, -sqrt_1_2, 0.0},
- /* Quaternion((1,0,0), radians(90)) * Quaternion((0,1,0), radians(90)) */
- {0.5, 0.5, 0.5, 0.5},
- /* pos-z90 */
- {sqrt_1_2, 0.0, 0.0, sqrt_1_2},
- /* neg-y90 */
- {sqrt_1_2, 0.0, sqrt_1_2, 0.0},
- /* Quaternion((1,0,0), radians(-90)) * Quaternion((0,1,0), radians(-90)) */
- {0.5, -0.5, -0.5, 0.5},
- /* no rotation */
- {0.0, sqrt_1_2, sqrt_1_2, 0.0},
- };
-
- assert(axis >= 0 && axis <= 5);
- assert(upflag >= 0 && upflag <= 2);
-
- mul_qt_qtqt(quat, quat, quat_track[axis]);
-
- if (axis > 2) {
- axis = (short)(axis - 3);
- }
-
- /* there are 2 possible up-axis for each axis used, the 'quat_track' applies so the first
- * up axis is used X->Y, Y->X, Z->X, if this first up axis isn't used then rotate 90d
- * the strange bit shift below just find the low axis {X:Y, Y:X, Z:X} */
- if (upflag != (2 - axis) >> 1) {
- float q[4] = {sqrt_1_2, 0.0, 0.0, 0.0}; /* assign 90d rotation axis */
- q[axis + 1] = ((axis == 1)) ? sqrt_1_2 : -sqrt_1_2; /* flip non Y axis */
- mul_qt_qtqt(quat, quat, q);
- }
+ /* rotations are hard coded to match vec_to_quat */
+ const float sqrt_1_2 = (float)M_SQRT1_2;
+ const float quat_track[][4] = {
+ /* pos-y90 */
+ {sqrt_1_2, 0.0, -sqrt_1_2, 0.0},
+ /* Quaternion((1,0,0), radians(90)) * Quaternion((0,1,0), radians(90)) */
+ {0.5, 0.5, 0.5, 0.5},
+ /* pos-z90 */
+ {sqrt_1_2, 0.0, 0.0, sqrt_1_2},
+ /* neg-y90 */
+ {sqrt_1_2, 0.0, sqrt_1_2, 0.0},
+ /* Quaternion((1,0,0), radians(-90)) * Quaternion((0,1,0), radians(-90)) */
+ {0.5, -0.5, -0.5, 0.5},
+ /* no rotation */
+ {0.0, sqrt_1_2, sqrt_1_2, 0.0},
+ };
+
+ assert(axis >= 0 && axis <= 5);
+ assert(upflag >= 0 && upflag <= 2);
+
+ mul_qt_qtqt(quat, quat, quat_track[axis]);
+
+ if (axis > 2) {
+ axis = (short)(axis - 3);
+ }
+
+ /* there are 2 possible up-axis for each axis used, the 'quat_track' applies so the first
+ * up axis is used X->Y, Y->X, Z->X, if this first up axis isn't used then rotate 90d
+ * the strange bit shift below just find the low axis {X:Y, Y:X, Z:X} */
+ if (upflag != (2 - axis) >> 1) {
+ float q[4] = {sqrt_1_2, 0.0, 0.0, 0.0}; /* assign 90d rotation axis */
+ q[axis + 1] = ((axis == 1)) ? sqrt_1_2 : -sqrt_1_2; /* flip non Y axis */
+ mul_qt_qtqt(quat, quat, q);
+ }
}
void vec_apply_track(float vec[3], short axis)
{
- float tvec[3];
-
- assert(axis >= 0 && axis <= 5);
-
- copy_v3_v3(tvec, vec);
-
- switch (axis) {
- case 0: /* pos-x */
- /* vec[0] = 0.0; */
- vec[1] = tvec[2];
- vec[2] = -tvec[1];
- break;
- case 1: /* pos-y */
- /* vec[0] = tvec[0]; */
- /* vec[1] = 0.0; */
- /* vec[2] = tvec[2]; */
- break;
- case 2: /* pos-z */
- /* vec[0] = tvec[0]; */
- /* vec[1] = tvec[1]; */
- /* vec[2] = 0.0; */
- break;
- case 3: /* neg-x */
- /* vec[0] = 0.0; */
- vec[1] = tvec[2];
- vec[2] = -tvec[1];
- break;
- case 4: /* neg-y */
- vec[0] = -tvec[2];
- /* vec[1] = 0.0; */
- vec[2] = tvec[0];
- break;
- case 5: /* neg-z */
- vec[0] = -tvec[0];
- vec[1] = -tvec[1];
- /* vec[2] = 0.0; */
- break;
- }
+ float tvec[3];
+
+ assert(axis >= 0 && axis <= 5);
+
+ copy_v3_v3(tvec, vec);
+
+ switch (axis) {
+ case 0: /* pos-x */
+ /* vec[0] = 0.0; */
+ vec[1] = tvec[2];
+ vec[2] = -tvec[1];
+ break;
+ case 1: /* pos-y */
+ /* vec[0] = tvec[0]; */
+ /* vec[1] = 0.0; */
+ /* vec[2] = tvec[2]; */
+ break;
+ case 2: /* pos-z */
+ /* vec[0] = tvec[0]; */
+ /* vec[1] = tvec[1]; */
+ /* vec[2] = 0.0; */
+ break;
+ case 3: /* neg-x */
+ /* vec[0] = 0.0; */
+ vec[1] = tvec[2];
+ vec[2] = -tvec[1];
+ break;
+ case 4: /* neg-y */
+ vec[0] = -tvec[2];
+ /* vec[1] = 0.0; */
+ vec[2] = tvec[0];
+ break;
+ case 5: /* neg-z */
+ vec[0] = -tvec[0];
+ vec[1] = -tvec[1];
+ /* vec[2] = 0.0; */
+ break;
+ }
}
/* lens/angle conversion (radians) */
float focallength_to_fov(float focal_length, float sensor)
{
- return 2.0f * atanf((sensor / 2.0f) / focal_length);
+ return 2.0f * atanf((sensor / 2.0f) / focal_length);
}
float fov_to_focallength(float hfov, float sensor)
{
- return (sensor / 2.0f) / tanf(hfov * 0.5f);
+ return (sensor / 2.0f) / tanf(hfov * 0.5f);
}
/* 'mod_inline(-3, 4)= 1', 'fmod(-3, 4)= -3' */
static float mod_inline(float a, float b)
{
- return a - (b * floorf(a / b));
+ return a - (b * floorf(a / b));
}
float angle_wrap_rad(float angle)
{
- return mod_inline(angle + (float)M_PI, (float)M_PI * 2.0f) - (float)M_PI;
+ return mod_inline(angle + (float)M_PI, (float)M_PI * 2.0f) - (float)M_PI;
}
float angle_wrap_deg(float angle)
{
- return mod_inline(angle + 180.0f, 360.0f) - 180.0f;
+ return mod_inline(angle + 180.0f, 360.0f) - 180.0f;
}
/* returns an angle compatible with angle_compat */
float angle_compat_rad(float angle, float angle_compat)
{
- return angle_compat + angle_wrap_rad(angle - angle_compat);
+ return angle_compat + angle_wrap_rad(angle - angle_compat);
}
/* axis conversion */
static float _axis_convert_matrix[23][3][3] = {
- {{-1.0, 0.0, 0.0}, {0.0, -1.0, 0.0}, {0.0, 0.0, 1.0}},
- {{-1.0, 0.0, 0.0}, {0.0, 0.0, -1.0}, {0.0, -1.0, 0.0}},
- {{-1.0, 0.0, 0.0}, {0.0, 0.0, 1.0}, {0.0, 1.0, 0.0}},
- {{-1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, -1.0}},
- {{0.0, -1.0, 0.0}, {-1.0, 0.0, 0.0}, {0.0, 0.0, -1.0}},
- {{0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0}, {0.0, -1.0, 0.0}},
- {{0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}},
- {{0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0}, {0.0, 0.0, 1.0}},
- {{0.0, -1.0, 0.0}, {0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0}},
- {{0.0, 0.0, -1.0}, {0.0, -1.0, 0.0}, {-1.0, 0.0, 0.0}},
- {{0.0, 0.0, 1.0}, {0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0}},
- {{0.0, 1.0, 0.0}, {0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0}},
- {{0.0, -1.0, 0.0}, {0.0, 0.0, -1.0}, {1.0, 0.0, 0.0}},
- {{0.0, 0.0, 1.0}, {0.0, -1.0, 0.0}, {1.0, 0.0, 0.0}},
- {{0.0, 0.0, -1.0}, {0.0, 1.0, 0.0}, {1.0, 0.0, 0.0}},
- {{0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}, {1.0, 0.0, 0.0}},
- {{0.0, -1.0, 0.0}, {1.0, 0.0, 0.0}, {0.0, 0.0, 1.0}},
- {{0.0, 0.0, -1.0}, {1.0, 0.0, 0.0}, {0.0, -1.0, 0.0}},
- {{0.0, 0.0, 1.0}, {1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}},
- {{0.0, 1.0, 0.0}, {1.0, 0.0, 0.0}, {0.0, 0.0, -1.0}},
- {{1.0, 0.0, 0.0}, {0.0, -1.0, 0.0}, {0.0, 0.0, -1.0}},
- {{1.0, 0.0, 0.0}, {0.0, 0.0, 1.0}, {0.0, -1.0, 0.0}},
- {{1.0, 0.0, 0.0}, {0.0, 0.0, -1.0}, {0.0, 1.0, 0.0}},
+ {{-1.0, 0.0, 0.0}, {0.0, -1.0, 0.0}, {0.0, 0.0, 1.0}},
+ {{-1.0, 0.0, 0.0}, {0.0, 0.0, -1.0}, {0.0, -1.0, 0.0}},
+ {{-1.0, 0.0, 0.0}, {0.0, 0.0, 1.0}, {0.0, 1.0, 0.0}},
+ {{-1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}, {0.0, 0.0, -1.0}},
+ {{0.0, -1.0, 0.0}, {-1.0, 0.0, 0.0}, {0.0, 0.0, -1.0}},
+ {{0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0}, {0.0, -1.0, 0.0}},
+ {{0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}},
+ {{0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0}, {0.0, 0.0, 1.0}},
+ {{0.0, -1.0, 0.0}, {0.0, 0.0, 1.0}, {-1.0, 0.0, 0.0}},
+ {{0.0, 0.0, -1.0}, {0.0, -1.0, 0.0}, {-1.0, 0.0, 0.0}},
+ {{0.0, 0.0, 1.0}, {0.0, 1.0, 0.0}, {-1.0, 0.0, 0.0}},
+ {{0.0, 1.0, 0.0}, {0.0, 0.0, -1.0}, {-1.0, 0.0, 0.0}},
+ {{0.0, -1.0, 0.0}, {0.0, 0.0, -1.0}, {1.0, 0.0, 0.0}},
+ {{0.0, 0.0, 1.0}, {0.0, -1.0, 0.0}, {1.0, 0.0, 0.0}},
+ {{0.0, 0.0, -1.0}, {0.0, 1.0, 0.0}, {1.0, 0.0, 0.0}},
+ {{0.0, 1.0, 0.0}, {0.0, 0.0, 1.0}, {1.0, 0.0, 0.0}},
+ {{0.0, -1.0, 0.0}, {1.0, 0.0, 0.0}, {0.0, 0.0, 1.0}},
+ {{0.0, 0.0, -1.0}, {1.0, 0.0, 0.0}, {0.0, -1.0, 0.0}},
+ {{0.0, 0.0, 1.0}, {1.0, 0.0, 0.0}, {0.0, 1.0, 0.0}},
+ {{0.0, 1.0, 0.0}, {1.0, 0.0, 0.0}, {0.0, 0.0, -1.0}},
+ {{1.0, 0.0, 0.0}, {0.0, -1.0, 0.0}, {0.0, 0.0, -1.0}},
+ {{1.0, 0.0, 0.0}, {0.0, 0.0, 1.0}, {0.0, -1.0, 0.0}},
+ {{1.0, 0.0, 0.0}, {0.0, 0.0, -1.0}, {0.0, 1.0, 0.0}},
};
static int _axis_convert_lut[23][24] = {
- {0x8C8, 0x4D0, 0x2E0, 0xAE8, 0x701, 0x511, 0x119, 0xB29, 0x682, 0x88A,
- 0x09A, 0x2A2, 0x80B, 0x413, 0x223, 0xA2B, 0x644, 0x454, 0x05C, 0xA6C,
- 0x745, 0x94D, 0x15D, 0x365},
- {0xAC8, 0x8D0, 0x4E0, 0x2E8, 0x741, 0x951, 0x159, 0x369, 0x702, 0xB0A,
- 0x11A, 0x522, 0xA0B, 0x813, 0x423, 0x22B, 0x684, 0x894, 0x09C, 0x2AC,
- 0x645, 0xA4D, 0x05D, 0x465},
- {0x4C8, 0x2D0, 0xAE0, 0x8E8, 0x681, 0x291, 0x099, 0x8A9, 0x642, 0x44A,
- 0x05A, 0xA62, 0x40B, 0x213, 0xA23, 0x82B, 0x744, 0x354, 0x15C, 0x96C,
- 0x705, 0x50D, 0x11D, 0xB25},
- {0x2C8, 0xAD0, 0x8E0, 0x4E8, 0x641, 0xA51, 0x059, 0x469, 0x742, 0x34A,
- 0x15A, 0x962, 0x20B, 0xA13, 0x823, 0x42B, 0x704, 0xB14, 0x11C, 0x52C,
- 0x685, 0x28D, 0x09D, 0x8A5},
- {0x708, 0xB10, 0x120, 0x528, 0x8C1, 0xAD1, 0x2D9, 0x4E9, 0x942, 0x74A,
- 0x35A, 0x162, 0x64B, 0xA53, 0x063, 0x46B, 0x804, 0xA14, 0x21C, 0x42C,
- 0x885, 0x68D, 0x29D, 0x0A5},
- {0xB08, 0x110, 0x520, 0x728, 0x941, 0x151, 0x359, 0x769, 0x802, 0xA0A,
- 0x21A, 0x422, 0xA4B, 0x053, 0x463, 0x66B, 0x884, 0x094, 0x29C, 0x6AC,
- 0x8C5, 0xACD, 0x2DD, 0x4E5},
- {0x508, 0x710, 0xB20, 0x128, 0x881, 0x691, 0x299, 0x0A9, 0x8C2, 0x4CA,
- 0x2DA, 0xAE2, 0x44B, 0x653, 0xA63, 0x06B, 0x944, 0x754, 0x35C, 0x16C,
- 0x805, 0x40D, 0x21D, 0xA25},
- {0x108, 0x510, 0x720, 0xB28, 0x801, 0x411, 0x219, 0xA29, 0x882, 0x08A,
- 0x29A, 0x6A2, 0x04B, 0x453, 0x663, 0xA6B, 0x8C4, 0x4D4, 0x2DC, 0xAEC,
- 0x945, 0x14D, 0x35D, 0x765},
- {0x748, 0x350, 0x160, 0x968, 0xAC1, 0x2D1, 0x4D9, 0x8E9, 0xA42, 0x64A,
- 0x45A, 0x062, 0x68B, 0x293, 0x0A3, 0x8AB, 0xA04, 0x214, 0x41C, 0x82C,
- 0xB05, 0x70D, 0x51D, 0x125},
- {0x948, 0x750, 0x360, 0x168, 0xB01, 0x711, 0x519, 0x129, 0xAC2, 0x8CA,
- 0x4DA, 0x2E2, 0x88B, 0x693, 0x2A3, 0x0AB, 0xA44, 0x654, 0x45C, 0x06C,
- 0xA05, 0x80D, 0x41D, 0x225},
- {0x348, 0x150, 0x960, 0x768, 0xA41, 0x051, 0x459, 0x669, 0xA02, 0x20A,
- 0x41A, 0x822, 0x28B, 0x093, 0x8A3, 0x6AB, 0xB04, 0x114, 0x51C, 0x72C,
- 0xAC5, 0x2CD, 0x4DD, 0x8E5},
- {0x148, 0x950, 0x760, 0x368, 0xA01, 0x811, 0x419, 0x229, 0xB02, 0x10A,
- 0x51A, 0x722, 0x08B, 0x893, 0x6A3, 0x2AB, 0xAC4, 0x8D4, 0x4DC, 0x2EC,
- 0xA45, 0x04D, 0x45D, 0x665},
- {0x688, 0x890, 0x0A0, 0x2A8, 0x4C1, 0x8D1, 0xAD9, 0x2E9, 0x502, 0x70A,
- 0xB1A, 0x122, 0x74B, 0x953, 0x163, 0x36B, 0x404, 0x814, 0xA1C, 0x22C,
- 0x445, 0x64D, 0xA5D, 0x065},
- {0x888, 0x090, 0x2A0, 0x6A8, 0x501, 0x111, 0xB19, 0x729, 0x402, 0x80A,
- 0xA1A, 0x222, 0x94B, 0x153, 0x363, 0x76B, 0x444, 0x054, 0xA5C, 0x66C,
- 0x4C5, 0x8CD, 0xADD, 0x2E5},
- {0x288, 0x690, 0x8A0, 0x0A8, 0x441, 0x651, 0xA59, 0x069, 0x4C2, 0x2CA,
- 0xADA, 0x8E2, 0x34B, 0x753, 0x963, 0x16B, 0x504, 0x714, 0xB1C, 0x12C,
- 0x405, 0x20D, 0xA1D, 0x825},
- {0x088, 0x290, 0x6A0, 0x8A8, 0x401, 0x211, 0xA19, 0x829, 0x442, 0x04A,
- 0xA5A, 0x662, 0x14B, 0x353, 0x763, 0x96B, 0x4C4, 0x2D4, 0xADC, 0x8EC,
- 0x505, 0x10D, 0xB1D, 0x725},
- {0x648, 0x450, 0x060, 0xA68, 0x2C1, 0x4D1, 0x8D9, 0xAE9, 0x282, 0x68A,
- 0x89A, 0x0A2, 0x70B, 0x513, 0x123, 0xB2B, 0x204, 0x414, 0x81C, 0xA2C,
- 0x345, 0x74D, 0x95D, 0x165},
- {0xA48, 0x650, 0x460, 0x068, 0x341, 0x751, 0x959, 0x169, 0x2C2, 0xACA,
- 0x8DA, 0x4E2, 0xB0B, 0x713, 0x523, 0x12B, 0x284, 0x694, 0x89C, 0x0AC,
- 0x205, 0xA0D, 0x81D, 0x425},
- {0x448, 0x050, 0xA60, 0x668, 0x281, 0x091, 0x899, 0x6A9, 0x202, 0x40A,
- 0x81A, 0xA22, 0x50B, 0x113, 0xB23, 0x72B, 0x344, 0x154, 0x95C, 0x76C,
- 0x2C5, 0x4CD, 0x8DD, 0xAE5},
- {0x048, 0xA50, 0x660, 0x468, 0x201, 0xA11, 0x819, 0x429, 0x342, 0x14A,
- 0x95A, 0x762, 0x10B, 0xB13, 0x723, 0x52B, 0x2C4, 0xAD4, 0x8DC, 0x4EC,
- 0x285, 0x08D, 0x89D, 0x6A5},
- {0x808, 0xA10, 0x220, 0x428, 0x101, 0xB11, 0x719, 0x529, 0x142, 0x94A,
- 0x75A, 0x362, 0x8CB, 0xAD3, 0x2E3, 0x4EB, 0x044, 0xA54, 0x65C, 0x46C,
- 0x085, 0x88D, 0x69D, 0x2A5},
- {0xA08, 0x210, 0x420, 0x828, 0x141, 0x351, 0x759, 0x969, 0x042, 0xA4A,
- 0x65A, 0x462, 0xACB, 0x2D3, 0x4E3, 0x8EB, 0x084, 0x294, 0x69C, 0x8AC,
- 0x105, 0xB0D, 0x71D, 0x525},
- {0x408, 0x810, 0xA20, 0x228, 0x081, 0x891, 0x699, 0x2A9, 0x102, 0x50A,
- 0x71A, 0xB22, 0x4CB, 0x8D3, 0xAE3, 0x2EB, 0x144, 0x954, 0x75C, 0x36C,
- 0x045, 0x44D, 0x65D, 0xA65},
+ {0x8C8, 0x4D0, 0x2E0, 0xAE8, 0x701, 0x511, 0x119, 0xB29, 0x682, 0x88A, 0x09A, 0x2A2,
+ 0x80B, 0x413, 0x223, 0xA2B, 0x644, 0x454, 0x05C, 0xA6C, 0x745, 0x94D, 0x15D, 0x365},
+ {0xAC8, 0x8D0, 0x4E0, 0x2E8, 0x741, 0x951, 0x159, 0x369, 0x702, 0xB0A, 0x11A, 0x522,
+ 0xA0B, 0x813, 0x423, 0x22B, 0x684, 0x894, 0x09C, 0x2AC, 0x645, 0xA4D, 0x05D, 0x465},
+ {0x4C8, 0x2D0, 0xAE0, 0x8E8, 0x681, 0x291, 0x099, 0x8A9, 0x642, 0x44A, 0x05A, 0xA62,
+ 0x40B, 0x213, 0xA23, 0x82B, 0x744, 0x354, 0x15C, 0x96C, 0x705, 0x50D, 0x11D, 0xB25},
+ {0x2C8, 0xAD0, 0x8E0, 0x4E8, 0x641, 0xA51, 0x059, 0x469, 0x742, 0x34A, 0x15A, 0x962,
+ 0x20B, 0xA13, 0x823, 0x42B, 0x704, 0xB14, 0x11C, 0x52C, 0x685, 0x28D, 0x09D, 0x8A5},
+ {0x708, 0xB10, 0x120, 0x528, 0x8C1, 0xAD1, 0x2D9, 0x4E9, 0x942, 0x74A, 0x35A, 0x162,
+ 0x64B, 0xA53, 0x063, 0x46B, 0x804, 0xA14, 0x21C, 0x42C, 0x885, 0x68D, 0x29D, 0x0A5},
+ {0xB08, 0x110, 0x520, 0x728, 0x941, 0x151, 0x359, 0x769, 0x802, 0xA0A, 0x21A, 0x422,
+ 0xA4B, 0x053, 0x463, 0x66B, 0x884, 0x094, 0x29C, 0x6AC, 0x8C5, 0xACD, 0x2DD, 0x4E5},
+ {0x508, 0x710, 0xB20, 0x128, 0x881, 0x691, 0x299, 0x0A9, 0x8C2, 0x4CA, 0x2DA, 0xAE2,
+ 0x44B, 0x653, 0xA63, 0x06B, 0x944, 0x754, 0x35C, 0x16C, 0x805, 0x40D, 0x21D, 0xA25},
+ {0x108, 0x510, 0x720, 0xB28, 0x801, 0x411, 0x219, 0xA29, 0x882, 0x08A, 0x29A, 0x6A2,
+ 0x04B, 0x453, 0x663, 0xA6B, 0x8C4, 0x4D4, 0x2DC, 0xAEC, 0x945, 0x14D, 0x35D, 0x765},
+ {0x748, 0x350, 0x160, 0x968, 0xAC1, 0x2D1, 0x4D9, 0x8E9, 0xA42, 0x64A, 0x45A, 0x062,
+ 0x68B, 0x293, 0x0A3, 0x8AB, 0xA04, 0x214, 0x41C, 0x82C, 0xB05, 0x70D, 0x51D, 0x125},
+ {0x948, 0x750, 0x360, 0x168, 0xB01, 0x711, 0x519, 0x129, 0xAC2, 0x8CA, 0x4DA, 0x2E2,
+ 0x88B, 0x693, 0x2A3, 0x0AB, 0xA44, 0x654, 0x45C, 0x06C, 0xA05, 0x80D, 0x41D, 0x225},
+ {0x348, 0x150, 0x960, 0x768, 0xA41, 0x051, 0x459, 0x669, 0xA02, 0x20A, 0x41A, 0x822,
+ 0x28B, 0x093, 0x8A3, 0x6AB, 0xB04, 0x114, 0x51C, 0x72C, 0xAC5, 0x2CD, 0x4DD, 0x8E5},
+ {0x148, 0x950, 0x760, 0x368, 0xA01, 0x811, 0x419, 0x229, 0xB02, 0x10A, 0x51A, 0x722,
+ 0x08B, 0x893, 0x6A3, 0x2AB, 0xAC4, 0x8D4, 0x4DC, 0x2EC, 0xA45, 0x04D, 0x45D, 0x665},
+ {0x688, 0x890, 0x0A0, 0x2A8, 0x4C1, 0x8D1, 0xAD9, 0x2E9, 0x502, 0x70A, 0xB1A, 0x122,
+ 0x74B, 0x953, 0x163, 0x36B, 0x404, 0x814, 0xA1C, 0x22C, 0x445, 0x64D, 0xA5D, 0x065},
+ {0x888, 0x090, 0x2A0, 0x6A8, 0x501, 0x111, 0xB19, 0x729, 0x402, 0x80A, 0xA1A, 0x222,
+ 0x94B, 0x153, 0x363, 0x76B, 0x444, 0x054, 0xA5C, 0x66C, 0x4C5, 0x8CD, 0xADD, 0x2E5},
+ {0x288, 0x690, 0x8A0, 0x0A8, 0x441, 0x651, 0xA59, 0x069, 0x4C2, 0x2CA, 0xADA, 0x8E2,
+ 0x34B, 0x753, 0x963, 0x16B, 0x504, 0x714, 0xB1C, 0x12C, 0x405, 0x20D, 0xA1D, 0x825},
+ {0x088, 0x290, 0x6A0, 0x8A8, 0x401, 0x211, 0xA19, 0x829, 0x442, 0x04A, 0xA5A, 0x662,
+ 0x14B, 0x353, 0x763, 0x96B, 0x4C4, 0x2D4, 0xADC, 0x8EC, 0x505, 0x10D, 0xB1D, 0x725},
+ {0x648, 0x450, 0x060, 0xA68, 0x2C1, 0x4D1, 0x8D9, 0xAE9, 0x282, 0x68A, 0x89A, 0x0A2,
+ 0x70B, 0x513, 0x123, 0xB2B, 0x204, 0x414, 0x81C, 0xA2C, 0x345, 0x74D, 0x95D, 0x165},
+ {0xA48, 0x650, 0x460, 0x068, 0x341, 0x751, 0x959, 0x169, 0x2C2, 0xACA, 0x8DA, 0x4E2,
+ 0xB0B, 0x713, 0x523, 0x12B, 0x284, 0x694, 0x89C, 0x0AC, 0x205, 0xA0D, 0x81D, 0x425},
+ {0x448, 0x050, 0xA60, 0x668, 0x281, 0x091, 0x899, 0x6A9, 0x202, 0x40A, 0x81A, 0xA22,
+ 0x50B, 0x113, 0xB23, 0x72B, 0x344, 0x154, 0x95C, 0x76C, 0x2C5, 0x4CD, 0x8DD, 0xAE5},
+ {0x048, 0xA50, 0x660, 0x468, 0x201, 0xA11, 0x819, 0x429, 0x342, 0x14A, 0x95A, 0x762,
+ 0x10B, 0xB13, 0x723, 0x52B, 0x2C4, 0xAD4, 0x8DC, 0x4EC, 0x285, 0x08D, 0x89D, 0x6A5},
+ {0x808, 0xA10, 0x220, 0x428, 0x101, 0xB11, 0x719, 0x529, 0x142, 0x94A, 0x75A, 0x362,
+ 0x8CB, 0xAD3, 0x2E3, 0x4EB, 0x044, 0xA54, 0x65C, 0x46C, 0x085, 0x88D, 0x69D, 0x2A5},
+ {0xA08, 0x210, 0x420, 0x828, 0x141, 0x351, 0x759, 0x969, 0x042, 0xA4A, 0x65A, 0x462,
+ 0xACB, 0x2D3, 0x4E3, 0x8EB, 0x084, 0x294, 0x69C, 0x8AC, 0x105, 0xB0D, 0x71D, 0x525},
+ {0x408, 0x810, 0xA20, 0x228, 0x081, 0x891, 0x699, 0x2A9, 0x102, 0x50A, 0x71A, 0xB22,
+ 0x4CB, 0x8D3, 0xAE3, 0x2EB, 0x144, 0x954, 0x75C, 0x36C, 0x045, 0x44D, 0x65D, 0xA65},
};
// _axis_convert_num = {'X': 0, 'Y': 1, 'Z': 2, '-X': 3, '-Y': 4, '-Z': 5}
BLI_INLINE int _axis_signed(const int axis)
{
- return (axis < 3) ? axis : axis - 3;
+ return (axis < 3) ? axis : axis - 3;
}
/**
@@ -2284,63 +2301,56 @@ BLI_INLINE int _axis_signed(const int axis)
* where the first 2 are a source and the second 2 are the target.
*/
bool mat3_from_axis_conversion(
- int src_forward, int src_up, int dst_forward, int dst_up,
- float r_mat[3][3])
-{
- // from functools import reduce
- int value;
-
- if (src_forward == dst_forward && src_up == dst_up) {
- unit_m3(r_mat);
- return false;
- }
-
- if ((_axis_signed(src_forward) == _axis_signed(src_up)) ||
- (_axis_signed(dst_forward) == _axis_signed(dst_up)))
- {
- /* we could assert here! */
- unit_m3(r_mat);
- return false;
- }
-
- value = ((src_forward << (0 * 3)) |
- (src_up << (1 * 3)) |
- (dst_forward << (2 * 3)) |
- (dst_up << (3 * 3)));
-
- for (uint i = 0; i < (sizeof(_axis_convert_matrix) / sizeof(*_axis_convert_matrix)); i++) {
- for (uint j = 0; j < (sizeof(*_axis_convert_lut) / sizeof(*_axis_convert_lut[0])); j++) {
- if (_axis_convert_lut[i][j] == value) {
- copy_m3_m3(r_mat, _axis_convert_matrix[i]);
- return true;
- }
- }
-
- }
-// BLI_assert(0);
- return false;
+ int src_forward, int src_up, int dst_forward, int dst_up, float r_mat[3][3])
+{
+ // from functools import reduce
+ int value;
+
+ if (src_forward == dst_forward && src_up == dst_up) {
+ unit_m3(r_mat);
+ return false;
+ }
+
+ if ((_axis_signed(src_forward) == _axis_signed(src_up)) ||
+ (_axis_signed(dst_forward) == _axis_signed(dst_up))) {
+ /* we could assert here! */
+ unit_m3(r_mat);
+ return false;
+ }
+
+ value = ((src_forward << (0 * 3)) | (src_up << (1 * 3)) | (dst_forward << (2 * 3)) |
+ (dst_up << (3 * 3)));
+
+ for (uint i = 0; i < (sizeof(_axis_convert_matrix) / sizeof(*_axis_convert_matrix)); i++) {
+ for (uint j = 0; j < (sizeof(*_axis_convert_lut) / sizeof(*_axis_convert_lut[0])); j++) {
+ if (_axis_convert_lut[i][j] == value) {
+ copy_m3_m3(r_mat, _axis_convert_matrix[i]);
+ return true;
+ }
+ }
+ }
+ // BLI_assert(0);
+ return false;
}
/**
* Use when the second axis can be guessed.
*/
-bool mat3_from_axis_conversion_single(
- int src_axis, int dst_axis,
- float r_mat[3][3])
+bool mat3_from_axis_conversion_single(int src_axis, int dst_axis, float r_mat[3][3])
{
- if (src_axis == dst_axis) {
- unit_m3(r_mat);
- return false;
- }
+ if (src_axis == dst_axis) {
+ unit_m3(r_mat);
+ return false;
+ }
- /* Pick predictable next axis. */
- int src_axis_next = (src_axis + 1) % 3;
- int dst_axis_next = (dst_axis + 1) % 3;
+ /* Pick predictable next axis. */
+ int src_axis_next = (src_axis + 1) % 3;
+ int dst_axis_next = (dst_axis + 1) % 3;
- if ((src_axis < 3) != (dst_axis < 3)) {
- /* Flip both axis so matrix sign remains positive. */
- dst_axis_next += 3;
- }
+ if ((src_axis < 3) != (dst_axis < 3)) {
+ /* Flip both axis so matrix sign remains positive. */
+ dst_axis_next += 3;
+ }
- return mat3_from_axis_conversion(src_axis, src_axis_next, dst_axis, dst_axis_next, r_mat);
+ return mat3_from_axis_conversion(src_axis, src_axis_next, dst_axis, dst_axis_next, r_mat);
}
diff --git a/source/blender/blenlib/intern/math_solvers.c b/source/blender/blenlib/intern/math_solvers.c
index 2669ac89b25..a6331aaadd8 100644
--- a/source/blender/blenlib/intern/math_solvers.c
+++ b/source/blender/blenlib/intern/math_solvers.c
@@ -39,19 +39,19 @@
* \return r_eigen_values the computed eigen values (NULL if not needed).
* \return r_eigen_vectors the computed eigen vectors (NULL if not needed).
*/
-bool BLI_eigen_solve_selfadjoint_m3(const float m3[3][3], float r_eigen_values[3], float r_eigen_vectors[3][3])
+bool BLI_eigen_solve_selfadjoint_m3(const float m3[3][3],
+ float r_eigen_values[3],
+ float r_eigen_vectors[3][3])
{
#ifndef NDEBUG
- /* We must assert given matrix is self-adjoint (i.e. symmetric) */
- if ((m3[0][1] != m3[1][0]) ||
- (m3[0][2] != m3[2][0]) ||
- (m3[1][2] != m3[2][1]))
- {
- BLI_assert(0);
- }
+ /* We must assert given matrix is self-adjoint (i.e. symmetric) */
+ if ((m3[0][1] != m3[1][0]) || (m3[0][2] != m3[2][0]) || (m3[1][2] != m3[2][1])) {
+ BLI_assert(0);
+ }
#endif
- return EIG_self_adjoint_eigen_solve(3, (const float *)m3, r_eigen_values, (float *)r_eigen_vectors);
+ return EIG_self_adjoint_eigen_solve(
+ 3, (const float *)m3, r_eigen_values, (float *)r_eigen_vectors);
}
/**
@@ -64,7 +64,7 @@ bool BLI_eigen_solve_selfadjoint_m3(const float m3[3][3], float r_eigen_values[3
*/
void BLI_svd_m3(const float m3[3][3], float r_U[3][3], float r_S[3], float r_V[3][3])
{
- EIG_svd_square_matrix(3, (const float *)m3, (float *)r_U, (float *)r_S, (float *)r_V);
+ EIG_svd_square_matrix(3, (const float *)m3, (float *)r_U, (float *)r_S, (float *)r_V);
}
/***************************** Simple Solvers ************************************/
@@ -79,48 +79,49 @@ void BLI_svd_m3(const float m3[3][3], float r_U[3][3], float r_S[3], float r_V[3
* \param r_x: output vector, may be shared with any of the input ones
* \return true if success
*/
-bool BLI_tridiagonal_solve(const float *a, const float *b, const float *c, const float *d, float *r_x, const int count)
+bool BLI_tridiagonal_solve(
+ const float *a, const float *b, const float *c, const float *d, float *r_x, const int count)
{
- if (count < 1) {
- return false;
- }
+ if (count < 1) {
+ return false;
+ }
- size_t bytes = sizeof(double) * (unsigned)count;
- double *c1 = (double *)MEM_mallocN(bytes * 2, "tridiagonal_c1d1");
- double *d1 = c1 + count;
+ size_t bytes = sizeof(double) * (unsigned)count;
+ double *c1 = (double *)MEM_mallocN(bytes * 2, "tridiagonal_c1d1");
+ double *d1 = c1 + count;
- if (!c1) {
- return false;
- }
+ if (!c1) {
+ return false;
+ }
- int i;
- double c_prev, d_prev, x_prev;
+ int i;
+ double c_prev, d_prev, x_prev;
- /* forward pass */
+ /* forward pass */
- c1[0] = c_prev = ((double)c[0]) / b[0];
- d1[0] = d_prev = ((double)d[0]) / b[0];
+ c1[0] = c_prev = ((double)c[0]) / b[0];
+ d1[0] = d_prev = ((double)d[0]) / b[0];
- for (i = 1; i < count; i++) {
- double denum = b[i] - a[i] * c_prev;
+ for (i = 1; i < count; i++) {
+ double denum = b[i] - a[i] * c_prev;
- c1[i] = c_prev = c[i] / denum;
- d1[i] = d_prev = (d[i] - a[i] * d_prev) / denum;
- }
+ c1[i] = c_prev = c[i] / denum;
+ d1[i] = d_prev = (d[i] - a[i] * d_prev) / denum;
+ }
- /* back pass */
+ /* back pass */
- x_prev = d_prev;
- r_x[--i] = ((float)x_prev);
+ x_prev = d_prev;
+ r_x[--i] = ((float)x_prev);
- while (--i >= 0) {
- x_prev = d1[i] - c1[i] * x_prev;
- r_x[i] = ((float)x_prev);
- }
+ while (--i >= 0) {
+ x_prev = d1[i] - c1[i] * x_prev;
+ r_x[i] = ((float)x_prev);
+ }
- MEM_freeN(c1);
+ MEM_freeN(c1);
- return isfinite(x_prev);
+ return isfinite(x_prev);
}
/**
@@ -129,53 +130,53 @@ bool BLI_tridiagonal_solve(const float *a, const float *b, const float *c, const
* \param r_x: output vector, may be shared with any of the input ones
* \return true if success
*/
-bool BLI_tridiagonal_solve_cyclic(const float *a, const float *b, const float *c, const float *d, float *r_x, const int count)
+bool BLI_tridiagonal_solve_cyclic(
+ const float *a, const float *b, const float *c, const float *d, float *r_x, const int count)
{
- if (count < 1) {
- return false;
- }
+ if (count < 1) {
+ return false;
+ }
- float a0 = a[0], cN = c[count - 1];
+ float a0 = a[0], cN = c[count - 1];
- /* if not really cyclic, fall back to the simple solver */
- if (a0 == 0.0f && cN == 0.0f) {
- return BLI_tridiagonal_solve(a, b, c, d, r_x, count);
- }
+ /* if not really cyclic, fall back to the simple solver */
+ if (a0 == 0.0f && cN == 0.0f) {
+ return BLI_tridiagonal_solve(a, b, c, d, r_x, count);
+ }
- size_t bytes = sizeof(float) * (unsigned)count;
- float *tmp = (float *)MEM_mallocN(bytes * 2, "tridiagonal_ex");
- float *b2 = tmp + count;
+ size_t bytes = sizeof(float) * (unsigned)count;
+ float *tmp = (float *)MEM_mallocN(bytes * 2, "tridiagonal_ex");
+ float *b2 = tmp + count;
- if (!tmp) {
- return false;
- }
+ if (!tmp) {
+ return false;
+ }
- /* prepare the noncyclic system; relies on tridiagonal_solve ignoring values */
- memcpy(b2, b, bytes);
- b2[0] -= a0;
- b2[count - 1] -= cN;
+ /* prepare the noncyclic system; relies on tridiagonal_solve ignoring values */
+ memcpy(b2, b, bytes);
+ b2[0] -= a0;
+ b2[count - 1] -= cN;
- memset(tmp, 0, bytes);
- tmp[0] = a0;
- tmp[count - 1] = cN;
+ memset(tmp, 0, bytes);
+ tmp[0] = a0;
+ tmp[count - 1] = cN;
- /* solve for partial solution and adjustment vector */
- bool success =
- BLI_tridiagonal_solve(a, b2, c, tmp, tmp, count) &&
- BLI_tridiagonal_solve(a, b2, c, d, r_x, count);
+ /* solve for partial solution and adjustment vector */
+ bool success = BLI_tridiagonal_solve(a, b2, c, tmp, tmp, count) &&
+ BLI_tridiagonal_solve(a, b2, c, d, r_x, count);
- /* apply adjustment */
- if (success) {
- float coeff = (r_x[0] + r_x[count - 1]) / (1.0f + tmp[0] + tmp[count - 1]);
+ /* apply adjustment */
+ if (success) {
+ float coeff = (r_x[0] + r_x[count - 1]) / (1.0f + tmp[0] + tmp[count - 1]);
- for (int i = 0; i < count; i++) {
- r_x[i] -= coeff * tmp[i];
- }
- }
+ for (int i = 0; i < count; i++) {
+ r_x[i] -= coeff * tmp[i];
+ }
+ }
- MEM_freeN(tmp);
+ MEM_freeN(tmp);
- return success;
+ return success;
}
/**
@@ -192,82 +193,88 @@ bool BLI_tridiagonal_solve_cyclic(const float *a, const float *b, const float *c
* \param result: Final result.
* \return true if success
*/
-bool BLI_newton3d_solve(
- Newton3D_DeltaFunc func_delta, Newton3D_JacobianFunc func_jacobian, Newton3D_CorrectionFunc func_correction, void *userdata,
- float epsilon, int max_iterations, bool trace, const float x_init[3], float result[3])
+bool BLI_newton3d_solve(Newton3D_DeltaFunc func_delta,
+ Newton3D_JacobianFunc func_jacobian,
+ Newton3D_CorrectionFunc func_correction,
+ void *userdata,
+ float epsilon,
+ int max_iterations,
+ bool trace,
+ const float x_init[3],
+ float result[3])
{
- float fdelta[3], fdeltav, next_fdeltav;
- float jacobian[3][3], step[3], x[3], x_next[3];
+ float fdelta[3], fdeltav, next_fdeltav;
+ float jacobian[3][3], step[3], x[3], x_next[3];
- epsilon *= epsilon;
+ epsilon *= epsilon;
- copy_v3_v3(x, x_init);
+ copy_v3_v3(x, x_init);
- func_delta(userdata, x, fdelta);
- fdeltav = len_squared_v3(fdelta);
+ func_delta(userdata, x, fdelta);
+ fdeltav = len_squared_v3(fdelta);
- if (trace) {
- printf("START (%g, %g, %g) %g\n", x[0], x[1], x[2], fdeltav);
- }
+ if (trace) {
+ printf("START (%g, %g, %g) %g\n", x[0], x[1], x[2], fdeltav);
+ }
- for (int i = 0; i < max_iterations && fdeltav > epsilon; i++) {
- /* Newton's method step. */
- func_jacobian(userdata, x, jacobian);
+ for (int i = 0; i < max_iterations && fdeltav > epsilon; i++) {
+ /* Newton's method step. */
+ func_jacobian(userdata, x, jacobian);
- if (!invert_m3(jacobian)) {
- return false;
- }
+ if (!invert_m3(jacobian)) {
+ return false;
+ }
- mul_v3_m3v3(step, jacobian, fdelta);
- sub_v3_v3v3(x_next, x, step);
+ mul_v3_m3v3(step, jacobian, fdelta);
+ sub_v3_v3v3(x_next, x, step);
- /* Custom out-of-bounds value correction. */
- if (func_correction) {
- if (trace) {
- printf("%3d * (%g, %g, %g)\n", i, x_next[0], x_next[1], x_next[2]);
- }
+ /* Custom out-of-bounds value correction. */
+ if (func_correction) {
+ if (trace) {
+ printf("%3d * (%g, %g, %g)\n", i, x_next[0], x_next[1], x_next[2]);
+ }
- if (!func_correction(userdata, x, step, x_next)) {
- return false;
- }
- }
+ if (!func_correction(userdata, x, step, x_next)) {
+ return false;
+ }
+ }
- func_delta(userdata, x_next, fdelta);
- next_fdeltav = len_squared_v3(fdelta);
+ func_delta(userdata, x_next, fdelta);
+ next_fdeltav = len_squared_v3(fdelta);
- if (trace) {
- printf("%3d ? (%g, %g, %g) %g\n", i, x_next[0], x_next[1], x_next[2], next_fdeltav);
- }
+ if (trace) {
+ printf("%3d ? (%g, %g, %g) %g\n", i, x_next[0], x_next[1], x_next[2], next_fdeltav);
+ }
- /* Line search correction. */
- while (next_fdeltav > fdeltav) {
- float g0 = sqrtf(fdeltav), g1 = sqrtf(next_fdeltav);
- float g01 = -g0 / len_v3(step);
- float det = 2.0f * (g1 - g0 - g01);
- float l = (det == 0.0f) ? 0.1f : -g01 / det;
- CLAMP_MIN(l, 0.1f);
+ /* Line search correction. */
+ while (next_fdeltav > fdeltav) {
+ float g0 = sqrtf(fdeltav), g1 = sqrtf(next_fdeltav);
+ float g01 = -g0 / len_v3(step);
+ float det = 2.0f * (g1 - g0 - g01);
+ float l = (det == 0.0f) ? 0.1f : -g01 / det;
+ CLAMP_MIN(l, 0.1f);
- mul_v3_fl(step, l);
- sub_v3_v3v3(x_next, x, step);
+ mul_v3_fl(step, l);
+ sub_v3_v3v3(x_next, x, step);
- func_delta(userdata, x_next, fdelta);
- next_fdeltav = len_squared_v3(fdelta);
+ func_delta(userdata, x_next, fdelta);
+ next_fdeltav = len_squared_v3(fdelta);
- if (trace) {
- printf("%3d . (%g, %g, %g) %g\n", i, x_next[0], x_next[1], x_next[2], next_fdeltav);
- }
- }
+ if (trace) {
+ printf("%3d . (%g, %g, %g) %g\n", i, x_next[0], x_next[1], x_next[2], next_fdeltav);
+ }
+ }
- copy_v3_v3(x, x_next);
- fdeltav = next_fdeltav;
- }
+ copy_v3_v3(x, x_next);
+ fdeltav = next_fdeltav;
+ }
- bool success = (fdeltav <= epsilon);
+ bool success = (fdeltav <= epsilon);
- if (trace) {
- printf("%s (%g, %g, %g) %g\n", success ? "OK " : "FAIL", x[0], x[1], x[2], fdeltav);
- }
+ if (trace) {
+ printf("%s (%g, %g, %g) %g\n", success ? "OK " : "FAIL", x[0], x[1], x[2], fdeltav);
+ }
- copy_v3_v3(result, x);
- return success;
+ copy_v3_v3(result, x);
+ return success;
}
diff --git a/source/blender/blenlib/intern/math_statistics.c b/source/blender/blenlib/intern/math_statistics.c
index 50fa7556134..dbfc68adb9b 100644
--- a/source/blender/blenlib/intern/math_statistics.c
+++ b/source/blender/blenlib/intern/math_statistics.c
@@ -32,60 +32,59 @@
/********************************** Covariance Matrices *********************************/
typedef struct CovarianceData {
- const float *cos_vn;
- const float *center;
- float *r_covmat;
- float covfac;
- int n;
- int nbr_cos_vn;
+ const float *cos_vn;
+ const float *center;
+ float *r_covmat;
+ float covfac;
+ int n;
+ int nbr_cos_vn;
} CovarianceData;
-static void covariance_m_vn_ex_task_cb(
- void *__restrict userdata,
- const int a,
- const ParallelRangeTLS *__restrict UNUSED(tls))
+static void covariance_m_vn_ex_task_cb(void *__restrict userdata,
+ const int a,
+ const ParallelRangeTLS *__restrict UNUSED(tls))
{
- CovarianceData *data = userdata;
- const float *cos_vn = data->cos_vn;
- const float *center = data->center;
- float *r_covmat = data->r_covmat;
- const int n = data->n;
- const int nbr_cos_vn = data->nbr_cos_vn;
-
- int k;
-
- /* Covariance matrices are always symmetrical, so we can compute only one half of it,
- * and mirror it to the other half (at the end of the func).
- *
- * This allows using a flat loop of n*n with same results as imbricated one over half the matrix:
- *
- * for (i = 0; i < n; i++) {
- * for (j = i; j < n; j++) {
- * ...
- * }
- * }
- */
- const int i = a / n;
- const int j = a % n;
- if (j < i) {
- return;
- }
-
- if (center) {
- for (k = 0; k < nbr_cos_vn; k++) {
- r_covmat[a] += (cos_vn[k * n + i] - center[i]) * (cos_vn[k * n + j] - center[j]);
- }
- }
- else {
- for (k = 0; k < nbr_cos_vn; k++) {
- r_covmat[a] += cos_vn[k * n + i] * cos_vn[k * n + j];
- }
- }
- r_covmat[a] *= data->covfac;
- if (j != i) {
- /* Mirror result to other half... */
- r_covmat[j * n + i] = r_covmat[a];
- }
+ CovarianceData *data = userdata;
+ const float *cos_vn = data->cos_vn;
+ const float *center = data->center;
+ float *r_covmat = data->r_covmat;
+ const int n = data->n;
+ const int nbr_cos_vn = data->nbr_cos_vn;
+
+ int k;
+
+ /* Covariance matrices are always symmetrical, so we can compute only one half of it,
+ * and mirror it to the other half (at the end of the func).
+ *
+ * This allows using a flat loop of n*n with same results as imbricated one over half the matrix:
+ *
+ * for (i = 0; i < n; i++) {
+ * for (j = i; j < n; j++) {
+ * ...
+ * }
+ * }
+ */
+ const int i = a / n;
+ const int j = a % n;
+ if (j < i) {
+ return;
+ }
+
+ if (center) {
+ for (k = 0; k < nbr_cos_vn; k++) {
+ r_covmat[a] += (cos_vn[k * n + i] - center[i]) * (cos_vn[k * n + j] - center[j]);
+ }
+ }
+ else {
+ for (k = 0; k < nbr_cos_vn; k++) {
+ r_covmat[a] += cos_vn[k * n + i] * cos_vn[k * n + j];
+ }
+ }
+ r_covmat[a] *= data->covfac;
+ if (j != i) {
+ /* Mirror result to other half... */
+ r_covmat[j * n + i] = r_covmat[a];
+ }
}
/**
@@ -99,30 +98,33 @@ static void covariance_m_vn_ex_task_cb(
* (i.e. get 'sample varince' instead of 'population variance').
* \return r_covmat the computed covariance matrix.
*/
-void BLI_covariance_m_vn_ex(
- const int n, const float *cos_vn, const int nbr_cos_vn, const float *center, const bool use_sample_correction,
- float *r_covmat)
+void BLI_covariance_m_vn_ex(const int n,
+ const float *cos_vn,
+ const int nbr_cos_vn,
+ const float *center,
+ const bool use_sample_correction,
+ float *r_covmat)
{
- /* Note about that division: see https://en.wikipedia.org/wiki/Bessel%27s_correction.
- * In a nutshell, it must be 1 / (n - 1) for 'sample data', and 1 / n for 'population data'...
- */
- const float covfac = 1.0f / (float)(use_sample_correction ? nbr_cos_vn - 1 : nbr_cos_vn);
-
- memset(r_covmat, 0, sizeof(*r_covmat) * (size_t)(n * n));
-
- CovarianceData data = {
- .cos_vn = cos_vn, .center = center, .r_covmat = r_covmat,
- .covfac = covfac, .n = n, .nbr_cos_vn = nbr_cos_vn,
- };
-
- ParallelRangeSettings settings;
- BLI_parallel_range_settings_defaults(&settings);
- settings.use_threading = ((nbr_cos_vn * n * n) >= 10000);
- BLI_task_parallel_range(
- 0, n * n,
- &data,
- covariance_m_vn_ex_task_cb,
- &settings);
+ /* Note about that division: see https://en.wikipedia.org/wiki/Bessel%27s_correction.
+ * In a nutshell, it must be 1 / (n - 1) for 'sample data', and 1 / n for 'population data'...
+ */
+ const float covfac = 1.0f / (float)(use_sample_correction ? nbr_cos_vn - 1 : nbr_cos_vn);
+
+ memset(r_covmat, 0, sizeof(*r_covmat) * (size_t)(n * n));
+
+ CovarianceData data = {
+ .cos_vn = cos_vn,
+ .center = center,
+ .r_covmat = r_covmat,
+ .covfac = covfac,
+ .n = n,
+ .nbr_cos_vn = nbr_cos_vn,
+ };
+
+ ParallelRangeSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ settings.use_threading = ((nbr_cos_vn * n * n) >= 10000);
+ BLI_task_parallel_range(0, n * n, &data, covariance_m_vn_ex_task_cb, &settings);
}
/**
@@ -133,23 +135,26 @@ void BLI_covariance_m_vn_ex(
* \return r_covmat the computed covariance matrix.
* \return r_center the computed center (mean) of 3D points (may be NULL).
*/
-void BLI_covariance_m3_v3n(
- const float (*cos_v3)[3], const int nbr_cos_v3, const bool use_sample_correction,
- float r_covmat[3][3], float r_center[3])
+void BLI_covariance_m3_v3n(const float (*cos_v3)[3],
+ const int nbr_cos_v3,
+ const bool use_sample_correction,
+ float r_covmat[3][3],
+ float r_center[3])
{
- float center[3];
- const float mean_fac = 1.0f / (float)nbr_cos_v3;
- int i;
-
- zero_v3(center);
- for (i = 0; i < nbr_cos_v3; i++) {
- /* Applying mean_fac here rather than once at the end reduce compute errors... */
- madd_v3_v3fl(center, cos_v3[i], mean_fac);
- }
-
- if (r_center) {
- copy_v3_v3(r_center, center);
- }
-
- BLI_covariance_m_vn_ex(3, (const float *)cos_v3, nbr_cos_v3, center, use_sample_correction, (float *)r_covmat);
+ float center[3];
+ const float mean_fac = 1.0f / (float)nbr_cos_v3;
+ int i;
+
+ zero_v3(center);
+ for (i = 0; i < nbr_cos_v3; i++) {
+ /* Applying mean_fac here rather than once at the end reduce compute errors... */
+ madd_v3_v3fl(center, cos_v3[i], mean_fac);
+ }
+
+ if (r_center) {
+ copy_v3_v3(r_center, center);
+ }
+
+ BLI_covariance_m_vn_ex(
+ 3, (const float *)cos_v3, nbr_cos_v3, center, use_sample_correction, (float *)r_covmat);
}
diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c
index 0aacfd6cde1..1977558ac88 100644
--- a/source/blender/blenlib/intern/math_vector.c
+++ b/source/blender/blenlib/intern/math_vector.c
@@ -32,37 +32,38 @@
void interp_v2_v2v2(float target[2], const float a[2], const float b[2], const float t)
{
- const float s = 1.0f - t;
+ const float s = 1.0f - t;
- target[0] = s * a[0] + t * b[0];
- target[1] = s * a[1] + t * b[1];
+ target[0] = s * a[0] + t * b[0];
+ target[1] = s * a[1] + t * b[1];
}
/* weight 3 2D vectors,
* 'w' must be unit length but is not a vector, just 3 weights */
-void interp_v2_v2v2v2(float p[2], const float v1[2], const float v2[2], const float v3[2], const float w[3])
+void interp_v2_v2v2v2(
+ float p[2], const float v1[2], const float v2[2], const float v3[2], const float w[3])
{
- p[0] = v1[0] * w[0] + v2[0] * w[1] + v3[0] * w[2];
- p[1] = v1[1] * w[0] + v2[1] * w[1] + v3[1] * w[2];
+ p[0] = v1[0] * w[0] + v2[0] * w[1] + v3[0] * w[2];
+ p[1] = v1[1] * w[0] + v2[1] * w[1] + v3[1] * w[2];
}
void interp_v3_v3v3(float target[3], const float a[3], const float b[3], const float t)
{
- const float s = 1.0f - t;
+ const float s = 1.0f - t;
- target[0] = s * a[0] + t * b[0];
- target[1] = s * a[1] + t * b[1];
- target[2] = s * a[2] + t * b[2];
+ target[0] = s * a[0] + t * b[0];
+ target[1] = s * a[1] + t * b[1];
+ target[2] = s * a[2] + t * b[2];
}
void interp_v4_v4v4(float target[4], const float a[4], const float b[4], const float t)
{
- const float s = 1.0f - t;
+ const float s = 1.0f - t;
- target[0] = s * a[0] + t * b[0];
- target[1] = s * a[1] + t * b[1];
- target[2] = s * a[2] + t * b[2];
- target[3] = s * a[3] + t * b[3];
+ target[0] = s * a[0] + t * b[0];
+ target[1] = s * a[1] + t * b[1];
+ target[2] = s * a[2] + t * b[2];
+ target[3] = s * a[3] + t * b[3];
}
/**
@@ -73,46 +74,46 @@ void interp_v4_v4v4(float target[4], const float a[4], const float b[4], const f
*/
bool interp_v3_v3v3_slerp(float target[3], const float a[3], const float b[3], const float t)
{
- float cosom, w[2];
+ float cosom, w[2];
- BLI_ASSERT_UNIT_V3(a);
- BLI_ASSERT_UNIT_V3(b);
+ BLI_ASSERT_UNIT_V3(a);
+ BLI_ASSERT_UNIT_V3(b);
- cosom = dot_v3v3(a, b);
+ cosom = dot_v3v3(a, b);
- /* direct opposites */
- if (UNLIKELY(cosom < (-1.0f + FLT_EPSILON))) {
- return false;
- }
+ /* direct opposites */
+ if (UNLIKELY(cosom < (-1.0f + FLT_EPSILON))) {
+ return false;
+ }
- interp_dot_slerp(t, cosom, w);
+ interp_dot_slerp(t, cosom, w);
- target[0] = w[0] * a[0] + w[1] * b[0];
- target[1] = w[0] * a[1] + w[1] * b[1];
- target[2] = w[0] * a[2] + w[1] * b[2];
+ target[0] = w[0] * a[0] + w[1] * b[0];
+ target[1] = w[0] * a[1] + w[1] * b[1];
+ target[2] = w[0] * a[2] + w[1] * b[2];
- return true;
+ return true;
}
bool interp_v2_v2v2_slerp(float target[2], const float a[2], const float b[2], const float t)
{
- float cosom, w[2];
+ float cosom, w[2];
- BLI_ASSERT_UNIT_V2(a);
- BLI_ASSERT_UNIT_V2(b);
+ BLI_ASSERT_UNIT_V2(a);
+ BLI_ASSERT_UNIT_V2(b);
- cosom = dot_v2v2(a, b);
+ cosom = dot_v2v2(a, b);
- /* direct opposites */
- if (UNLIKELY(cosom < (1.0f + FLT_EPSILON))) {
- return false;
- }
+ /* direct opposites */
+ if (UNLIKELY(cosom < (1.0f + FLT_EPSILON))) {
+ return false;
+ }
- interp_dot_slerp(t, cosom, w);
+ interp_dot_slerp(t, cosom, w);
- target[0] = w[0] * a[0] + w[1] * b[0];
- target[1] = w[0] * a[1] + w[1] * b[1];
+ target[0] = w[0] * a[0] + w[1] * b[0];
+ target[1] = w[0] * a[1] + w[1] * b[1];
- return true;
+ return true;
}
/**
@@ -120,171 +121,196 @@ bool interp_v2_v2v2_slerp(float target[2], const float a[2], const float b[2], c
*/
void interp_v3_v3v3_slerp_safe(float target[3], const float a[3], const float b[3], const float t)
{
- if (UNLIKELY(!interp_v3_v3v3_slerp(target, a, b, t))) {
- /* axis are aligned so any otho vector is acceptable */
- float ab_ortho[3];
- ortho_v3_v3(ab_ortho, a);
- normalize_v3(ab_ortho);
- if (t < 0.5f) {
- if (UNLIKELY(!interp_v3_v3v3_slerp(target, a, ab_ortho, t * 2.0f))) {
- BLI_assert(0);
- copy_v3_v3(target, a);
- }
- }
- else {
- if (UNLIKELY(!interp_v3_v3v3_slerp(target, ab_ortho, b, (t - 0.5f) * 2.0f))) {
- BLI_assert(0);
- copy_v3_v3(target, b);
- }
- }
- }
+ if (UNLIKELY(!interp_v3_v3v3_slerp(target, a, b, t))) {
+ /* axis are aligned so any otho vector is acceptable */
+ float ab_ortho[3];
+ ortho_v3_v3(ab_ortho, a);
+ normalize_v3(ab_ortho);
+ if (t < 0.5f) {
+ if (UNLIKELY(!interp_v3_v3v3_slerp(target, a, ab_ortho, t * 2.0f))) {
+ BLI_assert(0);
+ copy_v3_v3(target, a);
+ }
+ }
+ else {
+ if (UNLIKELY(!interp_v3_v3v3_slerp(target, ab_ortho, b, (t - 0.5f) * 2.0f))) {
+ BLI_assert(0);
+ copy_v3_v3(target, b);
+ }
+ }
+ }
}
void interp_v2_v2v2_slerp_safe(float target[2], const float a[2], const float b[2], const float t)
{
- if (UNLIKELY(!interp_v2_v2v2_slerp(target, a, b, t))) {
- /* axis are aligned so any otho vector is acceptable */
- float ab_ortho[2];
- ortho_v2_v2(ab_ortho, a);
- // normalize_v2(ab_ortho);
- if (t < 0.5f) {
- if (UNLIKELY(!interp_v2_v2v2_slerp(target, a, ab_ortho, t * 2.0f))) {
- BLI_assert(0);
- copy_v2_v2(target, a);
- }
- }
- else {
- if (UNLIKELY(!interp_v2_v2v2_slerp(target, ab_ortho, b, (t - 0.5f) * 2.0f))) {
- BLI_assert(0);
- copy_v2_v2(target, b);
- }
- }
- }
+ if (UNLIKELY(!interp_v2_v2v2_slerp(target, a, b, t))) {
+ /* axis are aligned so any otho vector is acceptable */
+ float ab_ortho[2];
+ ortho_v2_v2(ab_ortho, a);
+ // normalize_v2(ab_ortho);
+ if (t < 0.5f) {
+ if (UNLIKELY(!interp_v2_v2v2_slerp(target, a, ab_ortho, t * 2.0f))) {
+ BLI_assert(0);
+ copy_v2_v2(target, a);
+ }
+ }
+ else {
+ if (UNLIKELY(!interp_v2_v2v2_slerp(target, ab_ortho, b, (t - 0.5f) * 2.0f))) {
+ BLI_assert(0);
+ copy_v2_v2(target, b);
+ }
+ }
+ }
}
/** \name Cubic curve interpolation (bezier spline).
* \{ */
-void interp_v2_v2v2v2v2_cubic(
- float p[2], const float v1[2], const float v2[2], const float v3[2], const float v4[2],
- const float u)
+void interp_v2_v2v2v2v2_cubic(float p[2],
+ const float v1[2],
+ const float v2[2],
+ const float v3[2],
+ const float v4[2],
+ const float u)
{
- float q0[2], q1[2], q2[2], r0[2], r1[2];
+ float q0[2], q1[2], q2[2], r0[2], r1[2];
- interp_v2_v2v2(q0, v1, v2, u);
- interp_v2_v2v2(q1, v2, v3, u);
- interp_v2_v2v2(q2, v3, v4, u);
+ interp_v2_v2v2(q0, v1, v2, u);
+ interp_v2_v2v2(q1, v2, v3, u);
+ interp_v2_v2v2(q2, v3, v4, u);
- interp_v2_v2v2(r0, q0, q1, u);
- interp_v2_v2v2(r1, q1, q2, u);
+ interp_v2_v2v2(r0, q0, q1, u);
+ interp_v2_v2v2(r1, q1, q2, u);
- interp_v2_v2v2(p, r0, r1, u);
+ interp_v2_v2v2(p, r0, r1, u);
}
/** \} */
/* weight 3 vectors,
* 'w' must be unit length but is not a vector, just 3 weights */
-void interp_v3_v3v3v3(float p[3], const float v1[3], const float v2[3], const float v3[3], const float w[3])
+void interp_v3_v3v3v3(
+ float p[3], const float v1[3], const float v2[3], const float v3[3], const float w[3])
{
- p[0] = v1[0] * w[0] + v2[0] * w[1] + v3[0] * w[2];
- p[1] = v1[1] * w[0] + v2[1] * w[1] + v3[1] * w[2];
- p[2] = v1[2] * w[0] + v2[2] * w[1] + v3[2] * w[2];
+ p[0] = v1[0] * w[0] + v2[0] * w[1] + v3[0] * w[2];
+ p[1] = v1[1] * w[0] + v2[1] * w[1] + v3[1] * w[2];
+ p[2] = v1[2] * w[0] + v2[2] * w[1] + v3[2] * w[2];
}
/* weight 3 vectors,
* 'w' must be unit length but is not a vector, just 4 weights */
-void interp_v3_v3v3v3v3(float p[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3], const float w[4])
+void interp_v3_v3v3v3v3(float p[3],
+ const float v1[3],
+ const float v2[3],
+ const float v3[3],
+ const float v4[3],
+ const float w[4])
{
- p[0] = v1[0] * w[0] + v2[0] * w[1] + v3[0] * w[2] + v4[0] * w[3];
- p[1] = v1[1] * w[0] + v2[1] * w[1] + v3[1] * w[2] + v4[1] * w[3];
- p[2] = v1[2] * w[0] + v2[2] * w[1] + v3[2] * w[2] + v4[2] * w[3];
+ p[0] = v1[0] * w[0] + v2[0] * w[1] + v3[0] * w[2] + v4[0] * w[3];
+ p[1] = v1[1] * w[0] + v2[1] * w[1] + v3[1] * w[2] + v4[1] * w[3];
+ p[2] = v1[2] * w[0] + v2[2] * w[1] + v3[2] * w[2] + v4[2] * w[3];
}
-void interp_v4_v4v4v4(float p[4], const float v1[4], const float v2[4], const float v3[4], const float w[3])
+void interp_v4_v4v4v4(
+ float p[4], const float v1[4], const float v2[4], const float v3[4], const float w[3])
{
- p[0] = v1[0] * w[0] + v2[0] * w[1] + v3[0] * w[2];
- p[1] = v1[1] * w[0] + v2[1] * w[1] + v3[1] * w[2];
- p[2] = v1[2] * w[0] + v2[2] * w[1] + v3[2] * w[2];
- p[3] = v1[3] * w[0] + v2[3] * w[1] + v3[3] * w[2];
+ p[0] = v1[0] * w[0] + v2[0] * w[1] + v3[0] * w[2];
+ p[1] = v1[1] * w[0] + v2[1] * w[1] + v3[1] * w[2];
+ p[2] = v1[2] * w[0] + v2[2] * w[1] + v3[2] * w[2];
+ p[3] = v1[3] * w[0] + v2[3] * w[1] + v3[3] * w[2];
}
-void interp_v4_v4v4v4v4(float p[4], const float v1[4], const float v2[4], const float v3[4], const float v4[4], const float w[4])
+void interp_v4_v4v4v4v4(float p[4],
+ const float v1[4],
+ const float v2[4],
+ const float v3[4],
+ const float v4[4],
+ const float w[4])
{
- p[0] = v1[0] * w[0] + v2[0] * w[1] + v3[0] * w[2] + v4[0] * w[3];
- p[1] = v1[1] * w[0] + v2[1] * w[1] + v3[1] * w[2] + v4[1] * w[3];
- p[2] = v1[2] * w[0] + v2[2] * w[1] + v3[2] * w[2] + v4[2] * w[3];
- p[3] = v1[3] * w[0] + v2[3] * w[1] + v3[3] * w[2] + v4[3] * w[3];
+ p[0] = v1[0] * w[0] + v2[0] * w[1] + v3[0] * w[2] + v4[0] * w[3];
+ p[1] = v1[1] * w[0] + v2[1] * w[1] + v3[1] * w[2] + v4[1] * w[3];
+ p[2] = v1[2] * w[0] + v2[2] * w[1] + v3[2] * w[2] + v4[2] * w[3];
+ p[3] = v1[3] * w[0] + v2[3] * w[1] + v3[3] * w[2] + v4[3] * w[3];
}
-void interp_v3_v3v3v3_uv(float p[3], const float v1[3], const float v2[3], const float v3[3], const float uv[2])
+void interp_v3_v3v3v3_uv(
+ float p[3], const float v1[3], const float v2[3], const float v3[3], const float uv[2])
{
- p[0] = v1[0] + ((v2[0] - v1[0]) * uv[0]) + ((v3[0] - v1[0]) * uv[1]);
- p[1] = v1[1] + ((v2[1] - v1[1]) * uv[0]) + ((v3[1] - v1[1]) * uv[1]);
- p[2] = v1[2] + ((v2[2] - v1[2]) * uv[0]) + ((v3[2] - v1[2]) * uv[1]);
+ p[0] = v1[0] + ((v2[0] - v1[0]) * uv[0]) + ((v3[0] - v1[0]) * uv[1]);
+ p[1] = v1[1] + ((v2[1] - v1[1]) * uv[0]) + ((v3[1] - v1[1]) * uv[1]);
+ p[2] = v1[2] + ((v2[2] - v1[2]) * uv[0]) + ((v3[2] - v1[2]) * uv[1]);
}
-void interp_v3_v3v3_uchar(char unsigned target[3], const unsigned char a[3], const unsigned char b[3], const float t)
+void interp_v3_v3v3_uchar(char unsigned target[3],
+ const unsigned char a[3],
+ const unsigned char b[3],
+ const float t)
{
- const float s = 1.0f - t;
+ const float s = 1.0f - t;
- target[0] = (char)floorf(s * a[0] + t * b[0]);
- target[1] = (char)floorf(s * a[1] + t * b[1]);
- target[2] = (char)floorf(s * a[2] + t * b[2]);
+ target[0] = (char)floorf(s * a[0] + t * b[0]);
+ target[1] = (char)floorf(s * a[1] + t * b[1]);
+ target[2] = (char)floorf(s * a[2] + t * b[2]);
}
void interp_v3_v3v3_char(char target[3], const char a[3], const char b[3], const float t)
{
- interp_v3_v3v3_uchar((unsigned char *)target, (const unsigned char *)a, (const unsigned char *)b, t);
+ interp_v3_v3v3_uchar(
+ (unsigned char *)target, (const unsigned char *)a, (const unsigned char *)b, t);
}
-void interp_v4_v4v4_uchar(char unsigned target[4], const unsigned char a[4], const unsigned char b[4], const float t)
+void interp_v4_v4v4_uchar(char unsigned target[4],
+ const unsigned char a[4],
+ const unsigned char b[4],
+ const float t)
{
- const float s = 1.0f - t;
+ const float s = 1.0f - t;
- target[0] = (char)floorf(s * a[0] + t * b[0]);
- target[1] = (char)floorf(s * a[1] + t * b[1]);
- target[2] = (char)floorf(s * a[2] + t * b[2]);
- target[3] = (char)floorf(s * a[3] + t * b[3]);
+ target[0] = (char)floorf(s * a[0] + t * b[0]);
+ target[1] = (char)floorf(s * a[1] + t * b[1]);
+ target[2] = (char)floorf(s * a[2] + t * b[2]);
+ target[3] = (char)floorf(s * a[3] + t * b[3]);
}
void interp_v4_v4v4_char(char target[4], const char a[4], const char b[4], const float t)
{
- interp_v4_v4v4_uchar((unsigned char *)target, (const unsigned char *)a, (const unsigned char *)b, t);
+ interp_v4_v4v4_uchar(
+ (unsigned char *)target, (const unsigned char *)a, (const unsigned char *)b, t);
}
void mid_v3_v3v3(float v[3], const float v1[3], const float v2[3])
{
- v[0] = 0.5f * (v1[0] + v2[0]);
- v[1] = 0.5f * (v1[1] + v2[1]);
- v[2] = 0.5f * (v1[2] + v2[2]);
+ v[0] = 0.5f * (v1[0] + v2[0]);
+ v[1] = 0.5f * (v1[1] + v2[1]);
+ v[2] = 0.5f * (v1[2] + v2[2]);
}
void mid_v2_v2v2(float v[2], const float v1[2], const float v2[2])
{
- v[0] = 0.5f * (v1[0] + v2[0]);
- v[1] = 0.5f * (v1[1] + v2[1]);
+ v[0] = 0.5f * (v1[0] + v2[0]);
+ v[1] = 0.5f * (v1[1] + v2[1]);
}
void mid_v3_v3v3v3(float v[3], const float v1[3], const float v2[3], const float v3[3])
{
- v[0] = (v1[0] + v2[0] + v3[0]) / 3.0f;
- v[1] = (v1[1] + v2[1] + v3[1]) / 3.0f;
- v[2] = (v1[2] + v2[2] + v3[2]) / 3.0f;
+ v[0] = (v1[0] + v2[0] + v3[0]) / 3.0f;
+ v[1] = (v1[1] + v2[1] + v3[1]) / 3.0f;
+ v[2] = (v1[2] + v2[2] + v3[2]) / 3.0f;
}
-void mid_v3_v3v3v3v3(float v[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3])
+void mid_v3_v3v3v3v3(
+ float v[3], const float v1[3], const float v2[3], const float v3[3], const float v4[3])
{
- v[0] = (v1[0] + v2[0] + v3[0] + v4[0]) / 4.0f;
- v[1] = (v1[1] + v2[1] + v3[1] + v4[1]) / 4.0f;
- v[2] = (v1[2] + v2[2] + v3[2] + v4[2]) / 4.0f;
+ v[0] = (v1[0] + v2[0] + v3[0] + v4[0]) / 4.0f;
+ v[1] = (v1[1] + v2[1] + v3[1] + v4[1]) / 4.0f;
+ v[2] = (v1[2] + v2[2] + v3[2] + v4[2]) / 4.0f;
}
void mid_v3_v3_array(float r[3], const float (*vec_arr)[3], const unsigned int nbr)
{
- const float factor = 1.0f / (float)nbr;
- zero_v3(r);
+ const float factor = 1.0f / (float)nbr;
+ zero_v3(r);
- for (unsigned int i = 0; i < nbr; i++) {
- madd_v3_v3fl(r, vec_arr[i], factor);
- }
+ for (unsigned int i = 0; i < nbr; i++) {
+ madd_v3_v3fl(r, vec_arr[i], factor);
+ }
}
/**
@@ -301,21 +327,21 @@ void mid_v3_v3_array(float r[3], const float (*vec_arr)[3], const unsigned int n
*/
void mid_v3_v3v3_angle_weighted(float r[3], const float a[3], const float b[3])
{
- /* trick, we want the middle of 2 normals as well as the angle between them
- * avoid multiple calculations by */
- float angle;
+ /* trick, we want the middle of 2 normals as well as the angle between them
+ * avoid multiple calculations by */
+ float angle;
- /* double check they are normalized */
- BLI_ASSERT_UNIT_V3(a);
- BLI_ASSERT_UNIT_V3(b);
+ /* double check they are normalized */
+ BLI_ASSERT_UNIT_V3(a);
+ BLI_ASSERT_UNIT_V3(b);
- add_v3_v3v3(r, a, b);
- angle = ((float)(1.0 / (M_PI / 2.0)) *
- /* normally we would only multiply by 2,
- * but instead of an angle make this 0-1 factor */
- 2.0f) *
- acosf(normalize_v3(r) / 2.0f);
- mul_v3_fl(r, angle);
+ add_v3_v3v3(r, a, b);
+ angle = ((float)(1.0 / (M_PI / 2.0)) *
+ /* normally we would only multiply by 2,
+ * but instead of an angle make this 0-1 factor */
+ 2.0f) *
+ acosf(normalize_v3(r) / 2.0f);
+ mul_v3_fl(r, angle);
}
/**
* Same as mid_v3_v3v3_angle_weighted
@@ -323,19 +349,19 @@ void mid_v3_v3v3_angle_weighted(float r[3], const float a[3], const float b[3])
*/
void mid_v3_angle_weighted(float r[3])
{
- /* trick, we want the middle of 2 normals as well as the angle between them
- * avoid multiple calculations by */
- float angle;
+ /* trick, we want the middle of 2 normals as well as the angle between them
+ * avoid multiple calculations by */
+ float angle;
- /* double check they are normalized */
- BLI_assert(len_squared_v3(r) <= 1.0f + FLT_EPSILON);
+ /* double check they are normalized */
+ BLI_assert(len_squared_v3(r) <= 1.0f + FLT_EPSILON);
- angle = ((float)(1.0 / (M_PI / 2.0)) *
- /* normally we would only multiply by 2,
- * but instead of an angle make this 0-1 factor */
- 2.0f) *
- acosf(normalize_v3(r));
- mul_v3_fl(r, angle);
+ angle = ((float)(1.0 / (M_PI / 2.0)) *
+ /* normally we would only multiply by 2,
+ * but instead of an angle make this 0-1 factor */
+ 2.0f) *
+ acosf(normalize_v3(r));
+ mul_v3_fl(r, angle);
}
/**
@@ -345,44 +371,42 @@ void mid_v3_angle_weighted(float r[3])
void flip_v4_v4v4(float v[4], const float v1[4], const float v2[4])
{
- v[0] = v1[0] + (v1[0] - v2[0]);
- v[1] = v1[1] + (v1[1] - v2[1]);
- v[2] = v1[2] + (v1[2] - v2[2]);
- v[3] = v1[3] + (v1[3] - v2[3]);
+ v[0] = v1[0] + (v1[0] - v2[0]);
+ v[1] = v1[1] + (v1[1] - v2[1]);
+ v[2] = v1[2] + (v1[2] - v2[2]);
+ v[3] = v1[3] + (v1[3] - v2[3]);
}
void flip_v3_v3v3(float v[3], const float v1[3], const float v2[3])
{
- v[0] = v1[0] + (v1[0] - v2[0]);
- v[1] = v1[1] + (v1[1] - v2[1]);
- v[2] = v1[2] + (v1[2] - v2[2]);
+ v[0] = v1[0] + (v1[0] - v2[0]);
+ v[1] = v1[1] + (v1[1] - v2[1]);
+ v[2] = v1[2] + (v1[2] - v2[2]);
}
void flip_v2_v2v2(float v[2], const float v1[2], const float v2[2])
{
- v[0] = v1[0] + (v1[0] - v2[0]);
- v[1] = v1[1] + (v1[1] - v2[1]);
+ v[0] = v1[0] + (v1[0] - v2[0]);
+ v[1] = v1[1] + (v1[1] - v2[1]);
}
-
/********************************* Comparison ********************************/
bool is_finite_v2(const float v[2])
{
- return (isfinite(v[0]) && isfinite(v[1]));
+ return (isfinite(v[0]) && isfinite(v[1]));
}
bool is_finite_v3(const float v[3])
{
- return (isfinite(v[0]) && isfinite(v[1]) && isfinite(v[2]));
+ return (isfinite(v[0]) && isfinite(v[1]) && isfinite(v[2]));
}
bool is_finite_v4(const float v[4])
{
- return (isfinite(v[0]) && isfinite(v[1]) && isfinite(v[2]) && isfinite(v[3]));
+ return (isfinite(v[0]) && isfinite(v[1]) && isfinite(v[2]) && isfinite(v[3]));
}
-
/********************************** Angles ***********************************/
/* Return the angle in radians between vecs 1-2 and 2-3 in radians
@@ -394,124 +418,124 @@ bool is_finite_v4(const float v[4])
*/
float angle_v3v3v3(const float v1[3], const float v2[3], const float v3[3])
{
- float vec1[3], vec2[3];
+ float vec1[3], vec2[3];
- sub_v3_v3v3(vec1, v2, v1);
- sub_v3_v3v3(vec2, v2, v3);
- normalize_v3(vec1);
- normalize_v3(vec2);
+ sub_v3_v3v3(vec1, v2, v1);
+ sub_v3_v3v3(vec2, v2, v3);
+ normalize_v3(vec1);
+ normalize_v3(vec2);
- return angle_normalized_v3v3(vec1, vec2);
+ return angle_normalized_v3v3(vec1, vec2);
}
/* Quicker than full angle computation */
float cos_v3v3v3(const float p1[3], const float p2[3], const float p3[3])
{
- float vec1[3], vec2[3];
+ float vec1[3], vec2[3];
- sub_v3_v3v3(vec1, p2, p1);
- sub_v3_v3v3(vec2, p2, p3);
- normalize_v3(vec1);
- normalize_v3(vec2);
+ sub_v3_v3v3(vec1, p2, p1);
+ sub_v3_v3v3(vec2, p2, p3);
+ normalize_v3(vec1);
+ normalize_v3(vec2);
- return dot_v3v3(vec1, vec2);
+ return dot_v3v3(vec1, vec2);
}
/* Return the shortest angle in radians between the 2 vectors */
float angle_v3v3(const float v1[3], const float v2[3])
{
- float vec1[3], vec2[3];
+ float vec1[3], vec2[3];
- normalize_v3_v3(vec1, v1);
- normalize_v3_v3(vec2, v2);
+ normalize_v3_v3(vec1, v1);
+ normalize_v3_v3(vec2, v2);
- return angle_normalized_v3v3(vec1, vec2);
+ return angle_normalized_v3v3(vec1, vec2);
}
float angle_v2v2v2(const float v1[2], const float v2[2], const float v3[2])
{
- float vec1[2], vec2[2];
+ float vec1[2], vec2[2];
- vec1[0] = v2[0] - v1[0];
- vec1[1] = v2[1] - v1[1];
+ vec1[0] = v2[0] - v1[0];
+ vec1[1] = v2[1] - v1[1];
- vec2[0] = v2[0] - v3[0];
- vec2[1] = v2[1] - v3[1];
+ vec2[0] = v2[0] - v3[0];
+ vec2[1] = v2[1] - v3[1];
- normalize_v2(vec1);
- normalize_v2(vec2);
+ normalize_v2(vec1);
+ normalize_v2(vec2);
- return angle_normalized_v2v2(vec1, vec2);
+ return angle_normalized_v2v2(vec1, vec2);
}
/* Quicker than full angle computation */
float cos_v2v2v2(const float p1[2], const float p2[2], const float p3[2])
{
- float vec1[2], vec2[2];
+ float vec1[2], vec2[2];
- sub_v2_v2v2(vec1, p2, p1);
- sub_v2_v2v2(vec2, p2, p3);
- normalize_v2(vec1);
- normalize_v2(vec2);
+ sub_v2_v2v2(vec1, p2, p1);
+ sub_v2_v2v2(vec2, p2, p3);
+ normalize_v2(vec1);
+ normalize_v2(vec2);
- return dot_v2v2(vec1, vec2);
+ return dot_v2v2(vec1, vec2);
}
/* Return the shortest angle in radians between the 2 vectors */
float angle_v2v2(const float v1[2], const float v2[2])
{
- float vec1[2], vec2[2];
+ float vec1[2], vec2[2];
- vec1[0] = v1[0];
- vec1[1] = v1[1];
+ vec1[0] = v1[0];
+ vec1[1] = v1[1];
- vec2[0] = v2[0];
- vec2[1] = v2[1];
+ vec2[0] = v2[0];
+ vec2[1] = v2[1];
- normalize_v2(vec1);
- normalize_v2(vec2);
+ normalize_v2(vec1);
+ normalize_v2(vec2);
- return angle_normalized_v2v2(vec1, vec2);
+ return angle_normalized_v2v2(vec1, vec2);
}
float angle_signed_v2v2(const float v1[2], const float v2[2])
{
- const float perp_dot = (v1[1] * v2[0]) - (v1[0] * v2[1]);
- return atan2f(perp_dot, dot_v2v2(v1, v2));
+ const float perp_dot = (v1[1] * v2[0]) - (v1[0] * v2[1]);
+ return atan2f(perp_dot, dot_v2v2(v1, v2));
}
float angle_normalized_v3v3(const float v1[3], const float v2[3])
{
- /* double check they are normalized */
- BLI_ASSERT_UNIT_V3(v1);
- BLI_ASSERT_UNIT_V3(v2);
+ /* double check they are normalized */
+ BLI_ASSERT_UNIT_V3(v1);
+ BLI_ASSERT_UNIT_V3(v2);
- /* this is the same as acos(dot_v3v3(v1, v2)), but more accurate */
- if (dot_v3v3(v1, v2) >= 0.0f) {
- return 2.0f * saasin(len_v3v3(v1, v2) / 2.0f);
- }
- else {
- float v2_n[3];
- negate_v3_v3(v2_n, v2);
- return (float)M_PI - 2.0f * saasin(len_v3v3(v1, v2_n) / 2.0f);
- }
+ /* this is the same as acos(dot_v3v3(v1, v2)), but more accurate */
+ if (dot_v3v3(v1, v2) >= 0.0f) {
+ return 2.0f * saasin(len_v3v3(v1, v2) / 2.0f);
+ }
+ else {
+ float v2_n[3];
+ negate_v3_v3(v2_n, v2);
+ return (float)M_PI - 2.0f * saasin(len_v3v3(v1, v2_n) / 2.0f);
+ }
}
float angle_normalized_v2v2(const float v1[2], const float v2[2])
{
- /* double check they are normalized */
- BLI_ASSERT_UNIT_V2(v1);
- BLI_ASSERT_UNIT_V2(v2);
+ /* double check they are normalized */
+ BLI_ASSERT_UNIT_V2(v1);
+ BLI_ASSERT_UNIT_V2(v2);
- /* this is the same as acos(dot_v3v3(v1, v2)), but more accurate */
- if (dot_v2v2(v1, v2) >= 0.0f) {
- return 2.0f * saasin(len_v2v2(v1, v2) / 2.0f);
- }
- else {
- float v2_n[2];
- negate_v2_v2(v2_n, v2);
- return (float)M_PI - 2.0f * saasin(len_v2v2(v1, v2_n) / 2.0f);
- }
+ /* this is the same as acos(dot_v3v3(v1, v2)), but more accurate */
+ if (dot_v2v2(v1, v2) >= 0.0f) {
+ return 2.0f * saasin(len_v2v2(v1, v2) / 2.0f);
+ }
+ else {
+ float v2_n[2];
+ negate_v2_v2(v2_n, v2);
+ return (float)M_PI - 2.0f * saasin(len_v2v2(v1, v2_n) / 2.0f);
+ }
}
/**
@@ -519,108 +543,115 @@ float angle_normalized_v2v2(const float v1[2], const float v2[2])
*/
float angle_on_axis_v3v3_v3(const float v1[3], const float v2[3], const float axis[3])
{
- float v1_proj[3], v2_proj[3];
+ float v1_proj[3], v2_proj[3];
- /* project the vectors onto the axis */
- project_plane_normalized_v3_v3v3(v1_proj, v1, axis);
- project_plane_normalized_v3_v3v3(v2_proj, v2, axis);
+ /* project the vectors onto the axis */
+ project_plane_normalized_v3_v3v3(v1_proj, v1, axis);
+ project_plane_normalized_v3_v3v3(v2_proj, v2, axis);
- return angle_v3v3(v1_proj, v2_proj);
+ return angle_v3v3(v1_proj, v2_proj);
}
float angle_signed_on_axis_v3v3_v3(const float v1[3], const float v2[3], const float axis[3])
{
- float v1_proj[3], v2_proj[3], tproj[3];
- float angle;
+ float v1_proj[3], v2_proj[3], tproj[3];
+ float angle;
- /* project the vectors onto the axis */
- project_plane_normalized_v3_v3v3(v1_proj, v1, axis);
- project_plane_normalized_v3_v3v3(v2_proj, v2, axis);
+ /* project the vectors onto the axis */
+ project_plane_normalized_v3_v3v3(v1_proj, v1, axis);
+ project_plane_normalized_v3_v3v3(v2_proj, v2, axis);
- angle = angle_v3v3(v1_proj, v2_proj);
+ angle = angle_v3v3(v1_proj, v2_proj);
- /* calculate the sign (reuse 'tproj') */
- cross_v3_v3v3(tproj, v2_proj, v1_proj);
- if (dot_v3v3(tproj, axis) < 0.0f) {
- angle = ((float)(M_PI * 2.0)) - angle;
- }
+ /* calculate the sign (reuse 'tproj') */
+ cross_v3_v3v3(tproj, v2_proj, v1_proj);
+ if (dot_v3v3(tproj, axis) < 0.0f) {
+ angle = ((float)(M_PI * 2.0)) - angle;
+ }
- return angle;
+ return angle;
}
/**
* Angle between 2 vectors defined by 3 coords, about an axis (axis can be considered a plane).
*/
-float angle_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], const float axis[3])
+float angle_on_axis_v3v3v3_v3(const float v1[3],
+ const float v2[3],
+ const float v3[3],
+ const float axis[3])
{
- float vec1[3], vec2[3];
+ float vec1[3], vec2[3];
- sub_v3_v3v3(vec1, v1, v2);
- sub_v3_v3v3(vec2, v3, v2);
+ sub_v3_v3v3(vec1, v1, v2);
+ sub_v3_v3v3(vec2, v3, v2);
- return angle_on_axis_v3v3_v3(vec1, vec2, axis);
+ return angle_on_axis_v3v3_v3(vec1, vec2, axis);
}
-float angle_signed_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], const float axis[3])
+float angle_signed_on_axis_v3v3v3_v3(const float v1[3],
+ const float v2[3],
+ const float v3[3],
+ const float axis[3])
{
- float vec1[3], vec2[3];
+ float vec1[3], vec2[3];
- sub_v3_v3v3(vec1, v1, v2);
- sub_v3_v3v3(vec2, v3, v2);
+ sub_v3_v3v3(vec1, v1, v2);
+ sub_v3_v3v3(vec2, v3, v2);
- return angle_signed_on_axis_v3v3_v3(vec1, vec2, axis);
+ return angle_signed_on_axis_v3v3_v3(vec1, vec2, axis);
}
void angle_tri_v3(float angles[3], const float v1[3], const float v2[3], const float v3[3])
{
- float ed1[3], ed2[3], ed3[3];
+ float ed1[3], ed2[3], ed3[3];
- sub_v3_v3v3(ed1, v3, v1);
- sub_v3_v3v3(ed2, v1, v2);
- sub_v3_v3v3(ed3, v2, v3);
+ sub_v3_v3v3(ed1, v3, v1);
+ sub_v3_v3v3(ed2, v1, v2);
+ sub_v3_v3v3(ed3, v2, v3);
- normalize_v3(ed1);
- normalize_v3(ed2);
- normalize_v3(ed3);
+ normalize_v3(ed1);
+ normalize_v3(ed2);
+ normalize_v3(ed3);
- angles[0] = (float)M_PI - angle_normalized_v3v3(ed1, ed2);
- angles[1] = (float)M_PI - angle_normalized_v3v3(ed2, ed3);
- // face_angles[2] = M_PI - angle_normalized_v3v3(ed3, ed1);
- angles[2] = (float)M_PI - (angles[0] + angles[1]);
+ angles[0] = (float)M_PI - angle_normalized_v3v3(ed1, ed2);
+ angles[1] = (float)M_PI - angle_normalized_v3v3(ed2, ed3);
+ // face_angles[2] = M_PI - angle_normalized_v3v3(ed3, ed1);
+ angles[2] = (float)M_PI - (angles[0] + angles[1]);
}
-void angle_quad_v3(float angles[4], const float v1[3], const float v2[3], const float v3[3], const float v4[3])
+void angle_quad_v3(
+ float angles[4], const float v1[3], const float v2[3], const float v3[3], const float v4[3])
{
- float ed1[3], ed2[3], ed3[3], ed4[3];
+ float ed1[3], ed2[3], ed3[3], ed4[3];
- sub_v3_v3v3(ed1, v4, v1);
- sub_v3_v3v3(ed2, v1, v2);
- sub_v3_v3v3(ed3, v2, v3);
- sub_v3_v3v3(ed4, v3, v4);
+ sub_v3_v3v3(ed1, v4, v1);
+ sub_v3_v3v3(ed2, v1, v2);
+ sub_v3_v3v3(ed3, v2, v3);
+ sub_v3_v3v3(ed4, v3, v4);
- normalize_v3(ed1);
- normalize_v3(ed2);
- normalize_v3(ed3);
- normalize_v3(ed4);
+ normalize_v3(ed1);
+ normalize_v3(ed2);
+ normalize_v3(ed3);
+ normalize_v3(ed4);
- angles[0] = (float)M_PI - angle_normalized_v3v3(ed1, ed2);
- angles[1] = (float)M_PI - angle_normalized_v3v3(ed2, ed3);
- angles[2] = (float)M_PI - angle_normalized_v3v3(ed3, ed4);
- angles[3] = (float)M_PI - angle_normalized_v3v3(ed4, ed1);
+ angles[0] = (float)M_PI - angle_normalized_v3v3(ed1, ed2);
+ angles[1] = (float)M_PI - angle_normalized_v3v3(ed2, ed3);
+ angles[2] = (float)M_PI - angle_normalized_v3v3(ed3, ed4);
+ angles[3] = (float)M_PI - angle_normalized_v3v3(ed4, ed1);
}
void angle_poly_v3(float *angles, const float *verts[3], int len)
{
- int i;
- float vec[3][3];
+ int i;
+ float vec[3][3];
- sub_v3_v3v3(vec[2], verts[len - 1], verts[0]);
- normalize_v3(vec[2]);
- for (i = 0; i < len; i++) {
- sub_v3_v3v3(vec[i % 3], verts[i % len], verts[(i + 1) % len]);
- normalize_v3(vec[i % 3]);
- angles[i] = (float)M_PI - angle_normalized_v3v3(vec[(i + 2) % 3], vec[i % 3]);
- }
+ sub_v3_v3v3(vec[2], verts[len - 1], verts[0]);
+ normalize_v3(vec[2]);
+ for (i = 0; i < len; i++) {
+ sub_v3_v3v3(vec[i % 3], verts[i % len], verts[(i + 1) % len]);
+ normalize_v3(vec[i % 3]);
+ angles[i] = (float)M_PI - angle_normalized_v3v3(vec[(i + 2) % 3], vec[i % 3]);
+ }
}
/********************************* Geometry **********************************/
@@ -630,10 +661,10 @@ void angle_poly_v3(float *angles, const float *verts[3], int len)
*/
void project_v2_v2v2(float out[2], const float p[2], const float v_proj[2])
{
- const float mul = dot_v2v2(p, v_proj) / dot_v2v2(v_proj, v_proj);
+ const float mul = dot_v2v2(p, v_proj) / dot_v2v2(v_proj, v_proj);
- out[0] = mul * v_proj[0];
- out[1] = mul * v_proj[1];
+ out[0] = mul * v_proj[0];
+ out[1] = mul * v_proj[1];
}
/**
@@ -641,11 +672,11 @@ void project_v2_v2v2(float out[2], const float p[2], const float v_proj[2])
*/
void project_v3_v3v3(float out[3], const float p[3], const float v_proj[3])
{
- const float mul = dot_v3v3(p, v_proj) / dot_v3v3(v_proj, v_proj);
+ const float mul = dot_v3v3(p, v_proj) / dot_v3v3(v_proj, v_proj);
- out[0] = mul * v_proj[0];
- out[1] = mul * v_proj[1];
- out[2] = mul * v_proj[2];
+ out[0] = mul * v_proj[0];
+ out[1] = mul * v_proj[1];
+ out[2] = mul * v_proj[2];
}
/**
@@ -653,11 +684,11 @@ void project_v3_v3v3(float out[3], const float p[3], const float v_proj[3])
*/
void project_v2_v2v2_normalized(float out[2], const float p[2], const float v_proj[2])
{
- BLI_ASSERT_UNIT_V2(v_proj);
- const float mul = dot_v2v2(p, v_proj);
+ BLI_ASSERT_UNIT_V2(v_proj);
+ const float mul = dot_v2v2(p, v_proj);
- out[0] = mul * v_proj[0];
- out[1] = mul * v_proj[1];
+ out[0] = mul * v_proj[0];
+ out[1] = mul * v_proj[1];
}
/**
@@ -665,12 +696,12 @@ void project_v2_v2v2_normalized(float out[2], const float p[2], const float v_pr
*/
void project_v3_v3v3_normalized(float out[3], const float p[3], const float v_proj[3])
{
- BLI_ASSERT_UNIT_V3(v_proj);
- const float mul = dot_v3v3(p, v_proj);
+ BLI_ASSERT_UNIT_V3(v_proj);
+ const float mul = dot_v3v3(p, v_proj);
- out[0] = mul * v_proj[0];
- out[1] = mul * v_proj[1];
- out[2] = mul * v_proj[2];
+ out[0] = mul * v_proj[0];
+ out[1] = mul * v_proj[1];
+ out[2] = mul * v_proj[2];
}
/**
@@ -688,64 +719,64 @@ void project_v3_v3v3_normalized(float out[3], const float p[3], const float v_pr
*/
void project_plane_v3_v3v3(float out[3], const float p[3], const float v_plane[3])
{
- const float mul = dot_v3v3(p, v_plane) / dot_v3v3(v_plane, v_plane);
+ const float mul = dot_v3v3(p, v_plane) / dot_v3v3(v_plane, v_plane);
- out[0] = p[0] - (mul * v_plane[0]);
- out[1] = p[1] - (mul * v_plane[1]);
- out[2] = p[2] - (mul * v_plane[2]);
+ out[0] = p[0] - (mul * v_plane[0]);
+ out[1] = p[1] - (mul * v_plane[1]);
+ out[2] = p[2] - (mul * v_plane[2]);
}
void project_plane_v2_v2v2(float out[2], const float p[2], const float v_plane[2])
{
- const float mul = dot_v2v2(p, v_plane) / dot_v2v2(v_plane, v_plane);
+ const float mul = dot_v2v2(p, v_plane) / dot_v2v2(v_plane, v_plane);
- out[0] = p[0] - (mul * v_plane[0]);
- out[1] = p[1] - (mul * v_plane[1]);
+ out[0] = p[0] - (mul * v_plane[0]);
+ out[1] = p[1] - (mul * v_plane[1]);
}
void project_plane_normalized_v3_v3v3(float out[3], const float p[3], const float v_plane[3])
{
- BLI_ASSERT_UNIT_V3(v_plane);
- const float mul = dot_v3v3(p, v_plane);
+ BLI_ASSERT_UNIT_V3(v_plane);
+ const float mul = dot_v3v3(p, v_plane);
- out[0] = p[0] - (mul * v_plane[0]);
- out[1] = p[1] - (mul * v_plane[1]);
- out[2] = p[2] - (mul * v_plane[2]);
+ out[0] = p[0] - (mul * v_plane[0]);
+ out[1] = p[1] - (mul * v_plane[1]);
+ out[2] = p[2] - (mul * v_plane[2]);
}
void project_plane_normalized_v2_v2v2(float out[2], const float p[2], const float v_plane[2])
{
- BLI_ASSERT_UNIT_V2(v_plane);
- const float mul = dot_v2v2(p, v_plane);
+ BLI_ASSERT_UNIT_V2(v_plane);
+ const float mul = dot_v2v2(p, v_plane);
- out[0] = p[0] - (mul * v_plane[0]);
- out[1] = p[1] - (mul * v_plane[1]);
+ out[0] = p[0] - (mul * v_plane[0]);
+ out[1] = p[1] - (mul * v_plane[1]);
}
/* project a vector on a plane defined by normal and a plane point p */
void project_v3_plane(float out[3], const float plane_no[3], const float plane_co[3])
{
- float vector[3];
- float mul;
+ float vector[3];
+ float mul;
- sub_v3_v3v3(vector, out, plane_co);
- mul = dot_v3v3(vector, plane_no) / len_squared_v3(plane_no);
+ sub_v3_v3v3(vector, out, plane_co);
+ mul = dot_v3v3(vector, plane_no) / len_squared_v3(plane_no);
- mul_v3_v3fl(vector, plane_no, mul);
+ mul_v3_v3fl(vector, plane_no, mul);
- sub_v3_v3(out, vector);
+ sub_v3_v3(out, vector);
}
/* Returns a vector bisecting the angle at v2 formed by v1, v2 and v3 */
void bisect_v3_v3v3v3(float out[3], const float v1[3], const float v2[3], const float v3[3])
{
- float d_12[3], d_23[3];
- sub_v3_v3v3(d_12, v2, v1);
- sub_v3_v3v3(d_23, v3, v2);
- normalize_v3(d_12);
- normalize_v3(d_23);
- add_v3_v3v3(out, d_12, d_23);
- normalize_v3(out);
+ float d_12[3], d_23[3];
+ sub_v3_v3v3(d_12, v2, v1);
+ sub_v3_v3v3(d_23, v3, v2);
+ normalize_v3(d_12);
+ normalize_v3(d_23);
+ add_v3_v3v3(out, d_12, d_23);
+ normalize_v3(out);
}
/**
@@ -766,13 +797,13 @@ void bisect_v3_v3v3v3(float out[3], const float v1[3], const float v2[3], const
*/
void reflect_v3_v3v3(float out[3], const float v[3], const float normal[3])
{
- const float dot2 = 2.0f * dot_v3v3(v, normal);
+ const float dot2 = 2.0f * dot_v3v3(v, normal);
- BLI_ASSERT_UNIT_V3(normal);
+ BLI_ASSERT_UNIT_V3(normal);
- out[0] = v[0] - (dot2 * normal[0]);
- out[1] = v[1] - (dot2 * normal[1]);
- out[2] = v[2] - (dot2 * normal[2]);
+ out[0] = v[0] - (dot2 * normal[0]);
+ out[1] = v[1] - (dot2 * normal[1]);
+ out[2] = v[2] - (dot2 * normal[2]);
}
/**
@@ -782,27 +813,27 @@ void reflect_v3_v3v3(float out[3], const float v[3], const float normal[3])
*/
void ortho_basis_v3v3_v3(float r_n1[3], float r_n2[3], const float n[3])
{
- const float eps = FLT_EPSILON;
- const float f = len_squared_v2(n);
+ const float eps = FLT_EPSILON;
+ const float f = len_squared_v2(n);
- if (f > eps) {
- const float d = 1.0f / sqrtf(f);
+ if (f > eps) {
+ const float d = 1.0f / sqrtf(f);
- BLI_assert(isfinite(d));
+ BLI_assert(isfinite(d));
- r_n1[0] = n[1] * d;
- r_n1[1] = -n[0] * d;
- r_n1[2] = 0.0f;
- r_n2[0] = -n[2] * r_n1[1];
- r_n2[1] = n[2] * r_n1[0];
- r_n2[2] = n[0] * r_n1[1] - n[1] * r_n1[0];
- }
- else {
- /* degenerate case */
- r_n1[0] = (n[2] < 0.0f) ? -1.0f : 1.0f;
- r_n1[1] = r_n1[2] = r_n2[0] = r_n2[2] = 0.0f;
- r_n2[1] = 1.0f;
- }
+ r_n1[0] = n[1] * d;
+ r_n1[1] = -n[0] * d;
+ r_n1[2] = 0.0f;
+ r_n2[0] = -n[2] * r_n1[1];
+ r_n2[1] = n[2] * r_n1[0];
+ r_n2[2] = n[0] * r_n1[1] - n[1] * r_n1[0];
+ }
+ else {
+ /* degenerate case */
+ r_n1[0] = (n[2] < 0.0f) ? -1.0f : 1.0f;
+ r_n1[1] = r_n1[2] = r_n2[0] = r_n2[2] = 0.0f;
+ r_n2[1] = 1.0f;
+ }
}
/**
@@ -812,27 +843,27 @@ void ortho_basis_v3v3_v3(float r_n1[3], float r_n2[3], const float n[3])
*/
void ortho_v3_v3(float out[3], const float v[3])
{
- const int axis = axis_dominant_v3_single(v);
-
- BLI_assert(out != v);
-
- switch (axis) {
- case 0:
- out[0] = -v[1] - v[2];
- out[1] = v[0];
- out[2] = v[0];
- break;
- case 1:
- out[0] = v[1];
- out[1] = -v[0] - v[2];
- out[2] = v[1];
- break;
- case 2:
- out[0] = v[2];
- out[1] = v[2];
- out[2] = -v[0] - v[1];
- break;
- }
+ const int axis = axis_dominant_v3_single(v);
+
+ BLI_assert(out != v);
+
+ switch (axis) {
+ case 0:
+ out[0] = -v[1] - v[2];
+ out[1] = v[0];
+ out[2] = v[0];
+ break;
+ case 1:
+ out[0] = v[1];
+ out[1] = -v[0] - v[2];
+ out[2] = v[1];
+ break;
+ case 2:
+ out[0] = v[2];
+ out[1] = v[2];
+ out[2] = -v[0] - v[1];
+ break;
+ }
}
/**
@@ -840,10 +871,10 @@ void ortho_v3_v3(float out[3], const float v[3])
*/
void ortho_v2_v2(float out[2], const float v[2])
{
- BLI_assert(out != v);
+ BLI_assert(out != v);
- out[0] = -v[1];
- out[1] = v[0];
+ out[0] = -v[1];
+ out[1] = v[0];
}
/**
@@ -851,146 +882,179 @@ void ortho_v2_v2(float out[2], const float v[2])
*/
void rotate_v2_v2fl(float r[2], const float p[2], const float angle)
{
- const float co = cosf(angle);
- const float si = sinf(angle);
+ const float co = cosf(angle);
+ const float si = sinf(angle);
- BLI_assert(r != p);
+ BLI_assert(r != p);
- r[0] = co * p[0] - si * p[1];
- r[1] = si * p[0] + co * p[1];
+ r[0] = co * p[0] - si * p[1];
+ r[1] = si * p[0] + co * p[1];
}
/**
* Rotate a point \a p by \a angle around an arbitrary unit length \a axis.
* http://local.wasp.uwa.edu.au/~pbourke/geometry/
*/
-void rotate_normalized_v3_v3v3fl(float out[3], const float p[3], const float axis[3], const float angle)
+void rotate_normalized_v3_v3v3fl(float out[3],
+ const float p[3],
+ const float axis[3],
+ const float angle)
{
- const float costheta = cosf(angle);
- const float sintheta = sinf(angle);
+ const float costheta = cosf(angle);
+ const float sintheta = sinf(angle);
- /* double check they are normalized */
- BLI_ASSERT_UNIT_V3(axis);
+ /* double check they are normalized */
+ BLI_ASSERT_UNIT_V3(axis);
- out[0] = ((costheta + (1 - costheta) * axis[0] * axis[0]) * p[0]) +
- (((1 - costheta) * axis[0] * axis[1] - axis[2] * sintheta) * p[1]) +
- (((1 - costheta) * axis[0] * axis[2] + axis[1] * sintheta) * p[2]);
+ out[0] = ((costheta + (1 - costheta) * axis[0] * axis[0]) * p[0]) +
+ (((1 - costheta) * axis[0] * axis[1] - axis[2] * sintheta) * p[1]) +
+ (((1 - costheta) * axis[0] * axis[2] + axis[1] * sintheta) * p[2]);
- out[1] = (((1 - costheta) * axis[0] * axis[1] + axis[2] * sintheta) * p[0]) +
- ((costheta + (1 - costheta) * axis[1] * axis[1]) * p[1]) +
- (((1 - costheta) * axis[1] * axis[2] - axis[0] * sintheta) * p[2]);
+ out[1] = (((1 - costheta) * axis[0] * axis[1] + axis[2] * sintheta) * p[0]) +
+ ((costheta + (1 - costheta) * axis[1] * axis[1]) * p[1]) +
+ (((1 - costheta) * axis[1] * axis[2] - axis[0] * sintheta) * p[2]);
- out[2] = (((1 - costheta) * axis[0] * axis[2] - axis[1] * sintheta) * p[0]) +
- (((1 - costheta) * axis[1] * axis[2] + axis[0] * sintheta) * p[1]) +
- ((costheta + (1 - costheta) * axis[2] * axis[2]) * p[2]);
+ out[2] = (((1 - costheta) * axis[0] * axis[2] - axis[1] * sintheta) * p[0]) +
+ (((1 - costheta) * axis[1] * axis[2] + axis[0] * sintheta) * p[1]) +
+ ((costheta + (1 - costheta) * axis[2] * axis[2]) * p[2]);
}
void rotate_v3_v3v3fl(float r[3], const float p[3], const float axis[3], const float angle)
{
- BLI_assert(r != p);
+ BLI_assert(r != p);
- float axis_n[3];
+ float axis_n[3];
- normalize_v3_v3(axis_n, axis);
+ normalize_v3_v3(axis_n, axis);
- rotate_normalized_v3_v3v3fl(r, p, axis_n, angle);
+ rotate_normalized_v3_v3v3fl(r, p, axis_n, angle);
}
/*********************************** Other ***********************************/
void print_v2(const char *str, const float v[2])
{
- printf("%s: %.8f %.8f\n", str, v[0], v[1]);
+ printf("%s: %.8f %.8f\n", str, v[0], v[1]);
}
void print_v3(const char *str, const float v[3])
{
- printf("%s: %.8f %.8f %.8f\n", str, v[0], v[1], v[2]);
+ printf("%s: %.8f %.8f %.8f\n", str, v[0], v[1], v[2]);
}
void print_v4(const char *str, const float v[4])
{
- printf("%s: %.8f %.8f %.8f %.8f\n", str, v[0], v[1], v[2], v[3]);
+ printf("%s: %.8f %.8f %.8f %.8f\n", str, v[0], v[1], v[2], v[3]);
}
void print_vn(const char *str, const float v[], const int n)
{
- int i = 0;
- printf("%s[%d]:", str, n);
- while (i < n) {
- printf(" %.8f", v[i++]);
- }
- printf("\n");
+ int i = 0;
+ printf("%s[%d]:", str, n);
+ while (i < n) {
+ printf(" %.8f", v[i++]);
+ }
+ printf("\n");
}
void minmax_v3v3_v3(float min[3], float max[3], const float vec[3])
{
- if (min[0] > vec[0]) { min[0] = vec[0]; }
- if (min[1] > vec[1]) { min[1] = vec[1]; }
- if (min[2] > vec[2]) { min[2] = vec[2]; }
-
- if (max[0] < vec[0]) { max[0] = vec[0]; }
- if (max[1] < vec[1]) { max[1] = vec[1]; }
- if (max[2] < vec[2]) { max[2] = vec[2]; }
+ if (min[0] > vec[0]) {
+ min[0] = vec[0];
+ }
+ if (min[1] > vec[1]) {
+ min[1] = vec[1];
+ }
+ if (min[2] > vec[2]) {
+ min[2] = vec[2];
+ }
+
+ if (max[0] < vec[0]) {
+ max[0] = vec[0];
+ }
+ if (max[1] < vec[1]) {
+ max[1] = vec[1];
+ }
+ if (max[2] < vec[2]) {
+ max[2] = vec[2];
+ }
}
void minmax_v2v2_v2(float min[2], float max[2], const float vec[2])
{
- if (min[0] > vec[0]) { min[0] = vec[0]; }
- if (min[1] > vec[1]) { min[1] = vec[1]; }
+ if (min[0] > vec[0]) {
+ min[0] = vec[0];
+ }
+ if (min[1] > vec[1]) {
+ min[1] = vec[1];
+ }
- if (max[0] < vec[0]) { max[0] = vec[0]; }
- if (max[1] < vec[1]) { max[1] = vec[1]; }
+ if (max[0] < vec[0]) {
+ max[0] = vec[0];
+ }
+ if (max[1] < vec[1]) {
+ max[1] = vec[1];
+ }
}
void minmax_v3v3_v3_array(float r_min[3], float r_max[3], const float (*vec_arr)[3], int nbr)
{
- while (nbr--) {
- minmax_v3v3_v3(r_min, r_max, *vec_arr++);
- }
+ while (nbr--) {
+ minmax_v3v3_v3(r_min, r_max, *vec_arr++);
+ }
}
/** ensure \a v1 is \a dist from \a v2 */
void dist_ensure_v3_v3fl(float v1[3], const float v2[3], const float dist)
{
- if (!equals_v3v3(v2, v1)) {
- float nor[3];
+ if (!equals_v3v3(v2, v1)) {
+ float nor[3];
- sub_v3_v3v3(nor, v1, v2);
- normalize_v3(nor);
- madd_v3_v3v3fl(v1, v2, nor, dist);
- }
+ sub_v3_v3v3(nor, v1, v2);
+ normalize_v3(nor);
+ madd_v3_v3v3fl(v1, v2, nor, dist);
+ }
}
void dist_ensure_v2_v2fl(float v1[2], const float v2[2], const float dist)
{
- if (!equals_v2v2(v2, v1)) {
- float nor[2];
+ if (!equals_v2v2(v2, v1)) {
+ float nor[2];
- sub_v2_v2v2(nor, v1, v2);
- normalize_v2(nor);
- madd_v2_v2v2fl(v1, v2, nor, dist);
- }
+ sub_v2_v2v2(nor, v1, v2);
+ normalize_v2(nor);
+ madd_v2_v2v2fl(v1, v2, nor, dist);
+ }
}
void axis_sort_v3(const float axis_values[3], int r_axis_order[3])
{
- float v[3];
- copy_v3_v3(v, axis_values);
-
-#define SWAP_AXIS(a, b) { \
- SWAP(float, v[a], v[b]); \
- SWAP(int, r_axis_order[a], r_axis_order[b]); \
-} (void)0
-
- if (v[0] < v[1]) {
- if (v[2] < v[0]) { SWAP_AXIS(0, 2); }
- }
- else {
- if (v[1] < v[2]) { SWAP_AXIS(0, 1); }
- else { SWAP_AXIS(0, 2); }
- }
- if (v[2] < v[1]) { SWAP_AXIS(1, 2); }
+ float v[3];
+ copy_v3_v3(v, axis_values);
+
+#define SWAP_AXIS(a, b) \
+ { \
+ SWAP(float, v[a], v[b]); \
+ SWAP(int, r_axis_order[a], r_axis_order[b]); \
+ } \
+ (void)0
+
+ if (v[0] < v[1]) {
+ if (v[2] < v[0]) {
+ SWAP_AXIS(0, 2);
+ }
+ }
+ else {
+ if (v[1] < v[2]) {
+ SWAP_AXIS(0, 1);
+ }
+ else {
+ SWAP_AXIS(0, 2);
+ }
+ }
+ if (v[2] < v[1]) {
+ SWAP_AXIS(1, 2);
+ }
#undef SWAP_AXIS
}
@@ -999,280 +1063,297 @@ void axis_sort_v3(const float axis_values[3], int r_axis_order[3])
MINLINE double sqr_db(double f)
{
- return f * f;
+ return f * f;
}
double dot_vn_vn(const float *array_src_a, const float *array_src_b, const int size)
{
- double d = 0.0f;
- const float *array_pt_a = array_src_a + (size - 1);
- const float *array_pt_b = array_src_b + (size - 1);
- int i = size;
- while (i--) {
- d += (double)(*(array_pt_a--) * *(array_pt_b--));
- }
- return d;
+ double d = 0.0f;
+ const float *array_pt_a = array_src_a + (size - 1);
+ const float *array_pt_b = array_src_b + (size - 1);
+ int i = size;
+ while (i--) {
+ d += (double)(*(array_pt_a--) * *(array_pt_b--));
+ }
+ return d;
}
double len_squared_vn(const float *array, const int size)
{
- double d = 0.0f;
- const float *array_pt = array + (size - 1);
- int i = size;
- while (i--) {
- d += sqr_db((double)(*(array_pt--)));
- }
- return d;
+ double d = 0.0f;
+ const float *array_pt = array + (size - 1);
+ int i = size;
+ while (i--) {
+ d += sqr_db((double)(*(array_pt--)));
+ }
+ return d;
}
float normalize_vn_vn(float *array_tar, const float *array_src, const int size)
{
- const double d = len_squared_vn(array_src, size);
- float d_sqrt;
- if (d > 1.0e-35) {
- d_sqrt = (float)sqrt(d);
- mul_vn_vn_fl(array_tar, array_src, size, 1.0f / d_sqrt);
- }
- else {
- copy_vn_fl(array_tar, size, 0.0f);
- d_sqrt = 0.0f;
- }
- return d_sqrt;
+ const double d = len_squared_vn(array_src, size);
+ float d_sqrt;
+ if (d > 1.0e-35) {
+ d_sqrt = (float)sqrt(d);
+ mul_vn_vn_fl(array_tar, array_src, size, 1.0f / d_sqrt);
+ }
+ else {
+ copy_vn_fl(array_tar, size, 0.0f);
+ d_sqrt = 0.0f;
+ }
+ return d_sqrt;
}
float normalize_vn(float *array_tar, const int size)
{
- return normalize_vn_vn(array_tar, array_tar, size);
+ return normalize_vn_vn(array_tar, array_tar, size);
}
void range_vn_i(int *array_tar, const int size, const int start)
{
- int *array_pt = array_tar + (size - 1);
- int j = start + (size - 1);
- int i = size;
- while (i--) {
- *(array_pt--) = j--;
- }
+ int *array_pt = array_tar + (size - 1);
+ int j = start + (size - 1);
+ int i = size;
+ while (i--) {
+ *(array_pt--) = j--;
+ }
}
void range_vn_u(unsigned int *array_tar, const int size, const unsigned int start)
{
- unsigned int *array_pt = array_tar + (size - 1);
- unsigned int j = start + (unsigned int)(size - 1);
- int i = size;
- while (i--) {
- *(array_pt--) = j--;
- }
+ unsigned int *array_pt = array_tar + (size - 1);
+ unsigned int j = start + (unsigned int)(size - 1);
+ int i = size;
+ while (i--) {
+ *(array_pt--) = j--;
+ }
}
void range_vn_fl(float *array_tar, const int size, const float start, const float step)
{
- float *array_pt = array_tar + (size - 1);
- int i = size;
- while (i--) {
- *(array_pt--) = start + step * (float)(i);
- }
+ float *array_pt = array_tar + (size - 1);
+ int i = size;
+ while (i--) {
+ *(array_pt--) = start + step * (float)(i);
+ }
}
void negate_vn(float *array_tar, const int size)
{
- float *array_pt = array_tar + (size - 1);
- int i = size;
- while (i--) {
- *(array_pt--) *= -1.0f;
- }
+ float *array_pt = array_tar + (size - 1);
+ int i = size;
+ while (i--) {
+ *(array_pt--) *= -1.0f;
+ }
}
void negate_vn_vn(float *array_tar, const float *array_src, const int size)
{
- float *tar = array_tar + (size - 1);
- const float *src = array_src + (size - 1);
- int i = size;
- while (i--) {
- *(tar--) = -*(src--);
- }
+ float *tar = array_tar + (size - 1);
+ const float *src = array_src + (size - 1);
+ int i = size;
+ while (i--) {
+ *(tar--) = -*(src--);
+ }
}
void mul_vn_vn(float *array_tar, const float *array_src, const int size)
{
- float *tar = array_tar + (size - 1);
- const float *src = array_src + (size - 1);
- int i = size;
- while (i--) {
- *(tar--) *= *(src--);
- }
+ float *tar = array_tar + (size - 1);
+ const float *src = array_src + (size - 1);
+ int i = size;
+ while (i--) {
+ *(tar--) *= *(src--);
+ }
}
-void mul_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, const int size)
+void mul_vn_vnvn(float *array_tar,
+ const float *array_src_a,
+ const float *array_src_b,
+ const int size)
{
- float *tar = array_tar + (size - 1);
- const float *src_a = array_src_a + (size - 1);
- const float *src_b = array_src_b + (size - 1);
- int i = size;
- while (i--) {
- *(tar--) = *(src_a--) * *(src_b--);
- }
+ float *tar = array_tar + (size - 1);
+ const float *src_a = array_src_a + (size - 1);
+ const float *src_b = array_src_b + (size - 1);
+ int i = size;
+ while (i--) {
+ *(tar--) = *(src_a--) * *(src_b--);
+ }
}
void mul_vn_fl(float *array_tar, const int size, const float f)
{
- float *array_pt = array_tar + (size - 1);
- int i = size;
- while (i--) {
- *(array_pt--) *= f;
- }
+ float *array_pt = array_tar + (size - 1);
+ int i = size;
+ while (i--) {
+ *(array_pt--) *= f;
+ }
}
void mul_vn_vn_fl(float *array_tar, const float *array_src, const int size, const float f)
{
- float *tar = array_tar + (size - 1);
- const float *src = array_src + (size - 1);
- int i = size;
- while (i--) {
- *(tar--) = *(src--) * f;
- }
+ float *tar = array_tar + (size - 1);
+ const float *src = array_src + (size - 1);
+ int i = size;
+ while (i--) {
+ *(tar--) = *(src--) * f;
+ }
}
void add_vn_vn(float *array_tar, const float *array_src, const int size)
{
- float *tar = array_tar + (size - 1);
- const float *src = array_src + (size - 1);
- int i = size;
- while (i--) {
- *(tar--) += *(src--);
- }
+ float *tar = array_tar + (size - 1);
+ const float *src = array_src + (size - 1);
+ int i = size;
+ while (i--) {
+ *(tar--) += *(src--);
+ }
}
-void add_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, const int size)
+void add_vn_vnvn(float *array_tar,
+ const float *array_src_a,
+ const float *array_src_b,
+ const int size)
{
- float *tar = array_tar + (size - 1);
- const float *src_a = array_src_a + (size - 1);
- const float *src_b = array_src_b + (size - 1);
- int i = size;
- while (i--) {
- *(tar--) = *(src_a--) + *(src_b--);
- }
+ float *tar = array_tar + (size - 1);
+ const float *src_a = array_src_a + (size - 1);
+ const float *src_b = array_src_b + (size - 1);
+ int i = size;
+ while (i--) {
+ *(tar--) = *(src_a--) + *(src_b--);
+ }
}
void madd_vn_vn(float *array_tar, const float *array_src, const float f, const int size)
{
- float *tar = array_tar + (size - 1);
- const float *src = array_src + (size - 1);
- int i = size;
- while (i--) {
- *(tar--) += *(src--) * f;
- }
+ float *tar = array_tar + (size - 1);
+ const float *src = array_src + (size - 1);
+ int i = size;
+ while (i--) {
+ *(tar--) += *(src--) * f;
+ }
}
-void madd_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, const float f, const int size)
+void madd_vn_vnvn(float *array_tar,
+ const float *array_src_a,
+ const float *array_src_b,
+ const float f,
+ const int size)
{
- float *tar = array_tar + (size - 1);
- const float *src_a = array_src_a + (size - 1);
- const float *src_b = array_src_b + (size - 1);
- int i = size;
- while (i--) {
- *(tar--) = *(src_a--) + (*(src_b--) * f);
- }
+ float *tar = array_tar + (size - 1);
+ const float *src_a = array_src_a + (size - 1);
+ const float *src_b = array_src_b + (size - 1);
+ int i = size;
+ while (i--) {
+ *(tar--) = *(src_a--) + (*(src_b--) * f);
+ }
}
void sub_vn_vn(float *array_tar, const float *array_src, const int size)
{
- float *tar = array_tar + (size - 1);
- const float *src = array_src + (size - 1);
- int i = size;
- while (i--) {
- *(tar--) -= *(src--);
- }
+ float *tar = array_tar + (size - 1);
+ const float *src = array_src + (size - 1);
+ int i = size;
+ while (i--) {
+ *(tar--) -= *(src--);
+ }
}
-void sub_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, const int size)
+void sub_vn_vnvn(float *array_tar,
+ const float *array_src_a,
+ const float *array_src_b,
+ const int size)
{
- float *tar = array_tar + (size - 1);
- const float *src_a = array_src_a + (size - 1);
- const float *src_b = array_src_b + (size - 1);
- int i = size;
- while (i--) {
- *(tar--) = *(src_a--) - *(src_b--);
- }
+ float *tar = array_tar + (size - 1);
+ const float *src_a = array_src_a + (size - 1);
+ const float *src_b = array_src_b + (size - 1);
+ int i = size;
+ while (i--) {
+ *(tar--) = *(src_a--) - *(src_b--);
+ }
}
void msub_vn_vn(float *array_tar, const float *array_src, const float f, const int size)
{
- float *tar = array_tar + (size - 1);
- const float *src = array_src + (size - 1);
- int i = size;
- while (i--) {
- *(tar--) -= *(src--) * f;
- }
+ float *tar = array_tar + (size - 1);
+ const float *src = array_src + (size - 1);
+ int i = size;
+ while (i--) {
+ *(tar--) -= *(src--) * f;
+ }
}
-void msub_vn_vnvn(float *array_tar, const float *array_src_a, const float *array_src_b, const float f, const int size)
+void msub_vn_vnvn(float *array_tar,
+ const float *array_src_a,
+ const float *array_src_b,
+ const float f,
+ const int size)
{
- float *tar = array_tar + (size - 1);
- const float *src_a = array_src_a + (size - 1);
- const float *src_b = array_src_b + (size - 1);
- int i = size;
- while (i--) {
- *(tar--) = *(src_a--) - (*(src_b--) * f);
- }
+ float *tar = array_tar + (size - 1);
+ const float *src_a = array_src_a + (size - 1);
+ const float *src_b = array_src_b + (size - 1);
+ int i = size;
+ while (i--) {
+ *(tar--) = *(src_a--) - (*(src_b--) * f);
+ }
}
void interp_vn_vn(float *array_tar, const float *array_src, const float t, const int size)
{
- const float s = 1.0f - t;
- float *tar = array_tar + (size - 1);
- const float *src = array_src + (size - 1);
- int i = size;
- while (i--) {
- *(tar) = (s * *(tar)) + (t * *(src));
- tar--;
- src--;
- }
+ const float s = 1.0f - t;
+ float *tar = array_tar + (size - 1);
+ const float *src = array_src + (size - 1);
+ int i = size;
+ while (i--) {
+ *(tar) = (s * *(tar)) + (t * *(src));
+ tar--;
+ src--;
+ }
}
void copy_vn_i(int *array_tar, const int size, const int val)
{
- int *tar = array_tar + (size - 1);
- int i = size;
- while (i--) {
- *(tar--) = val;
- }
+ int *tar = array_tar + (size - 1);
+ int i = size;
+ while (i--) {
+ *(tar--) = val;
+ }
}
void copy_vn_short(short *array_tar, const int size, const short val)
{
- short *tar = array_tar + (size - 1);
- int i = size;
- while (i--) {
- *(tar--) = val;
- }
+ short *tar = array_tar + (size - 1);
+ int i = size;
+ while (i--) {
+ *(tar--) = val;
+ }
}
void copy_vn_ushort(unsigned short *array_tar, const int size, const unsigned short val)
{
- unsigned short *tar = array_tar + (size - 1);
- int i = size;
- while (i--) {
- *(tar--) = val;
- }
+ unsigned short *tar = array_tar + (size - 1);
+ int i = size;
+ while (i--) {
+ *(tar--) = val;
+ }
}
void copy_vn_uchar(unsigned char *array_tar, const int size, const unsigned char val)
{
- unsigned char *tar = array_tar + (size - 1);
- int i = size;
- while (i--) {
- *(tar--) = val;
- }
+ unsigned char *tar = array_tar + (size - 1);
+ int i = size;
+ while (i--) {
+ *(tar--) = val;
+ }
}
void copy_vn_fl(float *array_tar, const int size, const float val)
{
- float *tar = array_tar + (size - 1);
- int i = size;
- while (i--) {
- *(tar--) = val;
- }
+ float *tar = array_tar + (size - 1);
+ int i = size;
+ while (i--) {
+ *(tar--) = val;
+ }
}
/** \name Double precision versions 'db'.
@@ -1280,32 +1361,35 @@ void copy_vn_fl(float *array_tar, const int size, const float val)
void add_vn_vn_d(double *array_tar, const double *array_src, const int size)
{
- double *tar = array_tar + (size - 1);
- const double *src = array_src + (size - 1);
- int i = size;
- while (i--) {
- *(tar--) += *(src--);
- }
+ double *tar = array_tar + (size - 1);
+ const double *src = array_src + (size - 1);
+ int i = size;
+ while (i--) {
+ *(tar--) += *(src--);
+ }
}
-void add_vn_vnvn_d(double *array_tar, const double *array_src_a, const double *array_src_b, const int size)
+void add_vn_vnvn_d(double *array_tar,
+ const double *array_src_a,
+ const double *array_src_b,
+ const int size)
{
- double *tar = array_tar + (size - 1);
- const double *src_a = array_src_a + (size - 1);
- const double *src_b = array_src_b + (size - 1);
- int i = size;
- while (i--) {
- *(tar--) = *(src_a--) + *(src_b--);
- }
+ double *tar = array_tar + (size - 1);
+ const double *src_a = array_src_a + (size - 1);
+ const double *src_b = array_src_b + (size - 1);
+ int i = size;
+ while (i--) {
+ *(tar--) = *(src_a--) + *(src_b--);
+ }
}
void mul_vn_db(double *array_tar, const int size, const double f)
{
- double *array_pt = array_tar + (size - 1);
- int i = size;
- while (i--) {
- *(array_pt--) *= f;
- }
+ double *array_pt = array_tar + (size - 1);
+ int i = size;
+ while (i--) {
+ *(array_pt--) *= f;
+ }
}
/** \} */
diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c
index f22b2a7a457..865c2f5dc25 100644
--- a/source/blender/blenlib/intern/math_vector_inline.c
+++ b/source/blender/blenlib/intern/math_vector_inline.c
@@ -33,508 +33,507 @@
MINLINE void zero_v2(float r[2])
{
- r[0] = 0.0f;
- r[1] = 0.0f;
+ r[0] = 0.0f;
+ r[1] = 0.0f;
}
MINLINE void zero_v3(float r[3])
{
- r[0] = 0.0f;
- r[1] = 0.0f;
- r[2] = 0.0f;
+ r[0] = 0.0f;
+ r[1] = 0.0f;
+ r[2] = 0.0f;
}
MINLINE void zero_v4(float r[4])
{
- r[0] = 0.0f;
- r[1] = 0.0f;
- r[2] = 0.0f;
- r[3] = 0.0f;
+ r[0] = 0.0f;
+ r[1] = 0.0f;
+ r[2] = 0.0f;
+ r[3] = 0.0f;
}
MINLINE void copy_v2_v2(float r[2], const float a[2])
{
- r[0] = a[0];
- r[1] = a[1];
+ r[0] = a[0];
+ r[1] = a[1];
}
MINLINE void copy_v3_v3(float r[3], const float a[3])
{
- r[0] = a[0];
- r[1] = a[1];
- r[2] = a[2];
+ r[0] = a[0];
+ r[1] = a[1];
+ r[2] = a[2];
}
MINLINE void copy_v3fl_v3s(float r[3], const short a[3])
{
- r[0] = (float)a[0];
- r[1] = (float)a[1];
- r[2] = (float)a[2];
+ r[0] = (float)a[0];
+ r[1] = (float)a[1];
+ r[2] = (float)a[2];
}
MINLINE void copy_v4_v4(float r[4], const float a[4])
{
- r[0] = a[0];
- r[1] = a[1];
- r[2] = a[2];
- r[3] = a[3];
+ r[0] = a[0];
+ r[1] = a[1];
+ r[2] = a[2];
+ r[3] = a[3];
}
MINLINE void copy_v2_fl(float r[2], float f)
{
- r[0] = f;
- r[1] = f;
+ r[0] = f;
+ r[1] = f;
}
MINLINE void copy_v3_fl(float r[3], float f)
{
- r[0] = f;
- r[1] = f;
- r[2] = f;
+ r[0] = f;
+ r[1] = f;
+ r[2] = f;
}
MINLINE void copy_v4_fl(float r[4], float f)
{
- r[0] = f;
- r[1] = f;
- r[2] = f;
- r[3] = f;
+ r[0] = f;
+ r[1] = f;
+ r[2] = f;
+ r[3] = f;
}
/* unsigned char */
MINLINE void copy_v2_v2_uchar(unsigned char r[2], const unsigned char a[2])
{
- r[0] = a[0];
- r[1] = a[1];
+ r[0] = a[0];
+ r[1] = a[1];
}
MINLINE void copy_v3_v3_uchar(unsigned char r[3], const unsigned char a[3])
{
- r[0] = a[0];
- r[1] = a[1];
- r[2] = a[2];
+ r[0] = a[0];
+ r[1] = a[1];
+ r[2] = a[2];
}
MINLINE void copy_v4_v4_uchar(unsigned char r[4], const unsigned char a[4])
{
- r[0] = a[0];
- r[1] = a[1];
- r[2] = a[2];
- r[3] = a[3];
+ r[0] = a[0];
+ r[1] = a[1];
+ r[2] = a[2];
+ r[3] = a[3];
}
/* char */
MINLINE void copy_v2_v2_char(char r[2], const char a[2])
{
- r[0] = a[0];
- r[1] = a[1];
+ r[0] = a[0];
+ r[1] = a[1];
}
MINLINE void copy_v3_v3_char(char r[3], const char a[3])
{
- r[0] = a[0];
- r[1] = a[1];
- r[2] = a[2];
+ r[0] = a[0];
+ r[1] = a[1];
+ r[2] = a[2];
}
MINLINE void copy_v4_v4_char(char r[4], const char a[4])
{
- r[0] = a[0];
- r[1] = a[1];
- r[2] = a[2];
- r[3] = a[3];
+ r[0] = a[0];
+ r[1] = a[1];
+ r[2] = a[2];
+ r[3] = a[3];
}
/* short */
MINLINE void copy_v2_v2_short(short r[2], const short a[2])
{
- r[0] = a[0];
- r[1] = a[1];
+ r[0] = a[0];
+ r[1] = a[1];
}
MINLINE void copy_v3_v3_short(short r[3], const short a[3])
{
- r[0] = a[0];
- r[1] = a[1];
- r[2] = a[2];
+ r[0] = a[0];
+ r[1] = a[1];
+ r[2] = a[2];
}
MINLINE void copy_v4_v4_short(short r[4], const short a[4])
{
- r[0] = a[0];
- r[1] = a[1];
- r[2] = a[2];
- r[3] = a[3];
+ r[0] = a[0];
+ r[1] = a[1];
+ r[2] = a[2];
+ r[3] = a[3];
}
/* int */
MINLINE void zero_v3_int(int r[3])
{
- r[0] = 0;
- r[1] = 0;
- r[2] = 0;
+ r[0] = 0;
+ r[1] = 0;
+ r[2] = 0;
}
MINLINE void copy_v2_v2_int(int r[2], const int a[2])
{
- r[0] = a[0];
- r[1] = a[1];
+ r[0] = a[0];
+ r[1] = a[1];
}
MINLINE void copy_v3_v3_int(int r[3], const int a[3])
{
- r[0] = a[0];
- r[1] = a[1];
- r[2] = a[2];
+ r[0] = a[0];
+ r[1] = a[1];
+ r[2] = a[2];
}
MINLINE void copy_v4_v4_int(int r[4], const int a[4])
{
- r[0] = a[0];
- r[1] = a[1];
- r[2] = a[2];
- r[3] = a[3];
+ r[0] = a[0];
+ r[1] = a[1];
+ r[2] = a[2];
+ r[3] = a[3];
}
/* double */
MINLINE void zero_v3_db(double r[3])
{
- r[0] = 0.0;
- r[1] = 0.0;
- r[2] = 0.0;
+ r[0] = 0.0;
+ r[1] = 0.0;
+ r[2] = 0.0;
}
MINLINE void copy_v2_v2_db(double r[2], const double a[2])
{
- r[0] = a[0];
- r[1] = a[1];
+ r[0] = a[0];
+ r[1] = a[1];
}
MINLINE void copy_v3_v3_db(double r[3], const double a[3])
{
- r[0] = a[0];
- r[1] = a[1];
- r[2] = a[2];
+ r[0] = a[0];
+ r[1] = a[1];
+ r[2] = a[2];
}
MINLINE void copy_v4_v4_db(double r[4], const double a[4])
{
- r[0] = a[0];
- r[1] = a[1];
- r[2] = a[2];
- r[3] = a[3];
+ r[0] = a[0];
+ r[1] = a[1];
+ r[2] = a[2];
+ r[3] = a[3];
}
/* int <-> float */
MINLINE void round_v2i_v2fl(int r[2], const float a[2])
{
- r[0] = (int)roundf(a[0]);
- r[1] = (int)roundf(a[1]);
+ r[0] = (int)roundf(a[0]);
+ r[1] = (int)roundf(a[1]);
}
MINLINE void copy_v2fl_v2i(float r[2], const int a[2])
{
- r[0] = (float)a[0];
- r[1] = (float)a[1];
+ r[0] = (float)a[0];
+ r[1] = (float)a[1];
}
/* double -> float */
MINLINE void copy_v2fl_v2db(float r[2], const double a[2])
{
- r[0] = (float)a[0];
- r[1] = (float)a[1];
+ r[0] = (float)a[0];
+ r[1] = (float)a[1];
}
MINLINE void copy_v3fl_v3db(float r[3], const double a[3])
{
- r[0] = (float)a[0];
- r[1] = (float)a[1];
- r[2] = (float)a[2];
+ r[0] = (float)a[0];
+ r[1] = (float)a[1];
+ r[2] = (float)a[2];
}
MINLINE void copy_v4fl_v4db(float r[4], const double a[4])
{
- r[0] = (float)a[0];
- r[1] = (float)a[1];
- r[2] = (float)a[2];
- r[3] = (float)a[3];
+ r[0] = (float)a[0];
+ r[1] = (float)a[1];
+ r[2] = (float)a[2];
+ r[3] = (float)a[3];
}
/* float -> double */
MINLINE void copy_v2db_v2fl(double r[2], const float a[2])
{
- r[0] = (double)a[0];
- r[1] = (double)a[1];
+ r[0] = (double)a[0];
+ r[1] = (double)a[1];
}
MINLINE void copy_v3db_v3fl(double r[3], const float a[3])
{
- r[0] = (double)a[0];
- r[1] = (double)a[1];
- r[2] = (double)a[2];
+ r[0] = (double)a[0];
+ r[1] = (double)a[1];
+ r[2] = (double)a[2];
}
MINLINE void copy_v4db_v4fl(double r[4], const float a[4])
{
- r[0] = (double)a[0];
- r[1] = (double)a[1];
- r[2] = (double)a[2];
- r[3] = (double)a[3];
+ r[0] = (double)a[0];
+ r[1] = (double)a[1];
+ r[2] = (double)a[2];
+ r[3] = (double)a[3];
}
MINLINE void swap_v2_v2(float a[2], float b[2])
{
- SWAP(float, a[0], b[0]);
- SWAP(float, a[1], b[1]);
+ SWAP(float, a[0], b[0]);
+ SWAP(float, a[1], b[1]);
}
MINLINE void swap_v3_v3(float a[3], float b[3])
{
- SWAP(float, a[0], b[0]);
- SWAP(float, a[1], b[1]);
- SWAP(float, a[2], b[2]);
+ SWAP(float, a[0], b[0]);
+ SWAP(float, a[1], b[1]);
+ SWAP(float, a[2], b[2]);
}
MINLINE void swap_v4_v4(float a[4], float b[4])
{
- SWAP(float, a[0], b[0]);
- SWAP(float, a[1], b[1]);
- SWAP(float, a[2], b[2]);
- SWAP(float, a[3], b[3]);
+ SWAP(float, a[0], b[0]);
+ SWAP(float, a[1], b[1]);
+ SWAP(float, a[2], b[2]);
+ SWAP(float, a[3], b[3]);
}
/* float args -> vec */
MINLINE void copy_v2_fl2(float v[2], float x, float y)
{
- v[0] = x;
- v[1] = y;
+ v[0] = x;
+ v[1] = y;
}
MINLINE void copy_v3_fl3(float v[3], float x, float y, float z)
{
- v[0] = x;
- v[1] = y;
- v[2] = z;
+ v[0] = x;
+ v[1] = y;
+ v[2] = z;
}
MINLINE void copy_v4_fl4(float v[4], float x, float y, float z, float w)
{
- v[0] = x;
- v[1] = y;
- v[2] = z;
- v[3] = w;
+ v[0] = x;
+ v[1] = y;
+ v[2] = z;
+ v[3] = w;
}
/********************************* Arithmetic ********************************/
MINLINE void add_v2_fl(float r[2], float f)
{
- r[0] += f;
- r[1] += f;
+ r[0] += f;
+ r[1] += f;
}
-
MINLINE void add_v3_fl(float r[3], float f)
{
- r[0] += f;
- r[1] += f;
- r[2] += f;
+ r[0] += f;
+ r[1] += f;
+ r[2] += f;
}
MINLINE void add_v4_fl(float r[4], float f)
{
- r[0] += f;
- r[1] += f;
- r[2] += f;
- r[3] += f;
+ r[0] += f;
+ r[1] += f;
+ r[2] += f;
+ r[3] += f;
}
MINLINE void add_v2_v2(float r[2], const float a[2])
{
- r[0] += a[0];
- r[1] += a[1];
+ r[0] += a[0];
+ r[1] += a[1];
}
MINLINE void add_v2_v2v2(float r[2], const float a[2], const float b[2])
{
- r[0] = a[0] + b[0];
- r[1] = a[1] + b[1];
+ r[0] = a[0] + b[0];
+ r[1] = a[1] + b[1];
}
MINLINE void add_v2_v2v2_int(int r[2], const int a[2], const int b[2])
{
- r[0] = a[0] + b[0];
- r[1] = a[1] + b[1];
+ r[0] = a[0] + b[0];
+ r[1] = a[1] + b[1];
}
MINLINE void add_v3_v3(float r[3], const float a[3])
{
- r[0] += a[0];
- r[1] += a[1];
- r[2] += a[2];
+ r[0] += a[0];
+ r[1] += a[1];
+ r[2] += a[2];
}
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
{
- r[0] = a[0] + b[0];
- r[1] = a[1] + b[1];
- r[2] = a[2] + b[2];
+ r[0] = a[0] + b[0];
+ r[1] = a[1] + b[1];
+ r[2] = a[2] + b[2];
}
MINLINE void add_v3fl_v3fl_v3i(float r[3], const float a[3], const int b[3])
{
- r[0] = a[0] + (float)b[0];
- r[1] = a[1] + (float)b[1];
- r[2] = a[2] + (float)b[2];
+ r[0] = a[0] + (float)b[0];
+ r[1] = a[1] + (float)b[1];
+ r[2] = a[2] + (float)b[2];
}
MINLINE void add_v3fl_v3fl_v3s(float r[3], const float a[3], const short b[3])
{
- r[0] = a[0] + (float)b[0];
- r[1] = a[1] + (float)b[1];
- r[2] = a[2] + (float)b[2];
+ r[0] = a[0] + (float)b[0];
+ r[1] = a[1] + (float)b[1];
+ r[2] = a[2] + (float)b[2];
}
MINLINE void add_v4_v4(float r[4], const float a[4])
{
- r[0] += a[0];
- r[1] += a[1];
- r[2] += a[2];
- r[3] += a[3];
+ r[0] += a[0];
+ r[1] += a[1];
+ r[2] += a[2];
+ r[3] += a[3];
}
MINLINE void add_v4_v4v4(float r[4], const float a[4], const float b[4])
{
- r[0] = a[0] + b[0];
- r[1] = a[1] + b[1];
- r[2] = a[2] + b[2];
- r[3] = a[3] + b[3];
+ r[0] = a[0] + b[0];
+ r[1] = a[1] + b[1];
+ r[2] = a[2] + b[2];
+ r[3] = a[3] + b[3];
}
MINLINE void sub_v2_v2(float r[2], const float a[2])
{
- r[0] -= a[0];
- r[1] -= a[1];
+ r[0] -= a[0];
+ r[1] -= a[1];
}
MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2])
{
- r[0] = a[0] - b[0];
- r[1] = a[1] - b[1];
+ r[0] = a[0] - b[0];
+ r[1] = a[1] - b[1];
}
MINLINE void sub_v2_v2v2_int(int r[2], const int a[2], const int b[2])
{
- r[0] = a[0] - b[0];
- r[1] = a[1] - b[1];
+ r[0] = a[0] - b[0];
+ r[1] = a[1] - b[1];
}
MINLINE void sub_v3_v3(float r[3], const float a[3])
{
- r[0] -= a[0];
- r[1] -= a[1];
- r[2] -= a[2];
+ r[0] -= a[0];
+ r[1] -= a[1];
+ r[2] -= a[2];
}
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
{
- r[0] = a[0] - b[0];
- r[1] = a[1] - b[1];
- r[2] = a[2] - b[2];
+ r[0] = a[0] - b[0];
+ r[1] = a[1] - b[1];
+ r[2] = a[2] - b[2];
}
MINLINE void sub_v3_v3v3_int(int r[3], const int a[3], const int b[3])
{
- r[0] = a[0] - b[0];
- r[1] = a[1] - b[1];
- r[2] = a[2] - b[2];
+ r[0] = a[0] - b[0];
+ r[1] = a[1] - b[1];
+ r[2] = a[2] - b[2];
}
MINLINE void sub_v3db_v3fl_v3fl(double r[3], const float a[3], const float b[3])
{
- r[0] = (double)a[0] - (double)b[0];
- r[1] = (double)a[1] - (double)b[1];
- r[2] = (double)a[2] - (double)b[2];
+ r[0] = (double)a[0] - (double)b[0];
+ r[1] = (double)a[1] - (double)b[1];
+ r[2] = (double)a[2] - (double)b[2];
}
MINLINE void sub_v4_v4(float r[4], const float a[4])
{
- r[0] -= a[0];
- r[1] -= a[1];
- r[2] -= a[2];
- r[3] -= a[3];
+ r[0] -= a[0];
+ r[1] -= a[1];
+ r[2] -= a[2];
+ r[3] -= a[3];
}
MINLINE void sub_v4_v4v4(float r[4], const float a[4], const float b[4])
{
- r[0] = a[0] - b[0];
- r[1] = a[1] - b[1];
- r[2] = a[2] - b[2];
- r[3] = a[3] - b[3];
+ r[0] = a[0] - b[0];
+ r[1] = a[1] - b[1];
+ r[2] = a[2] - b[2];
+ r[3] = a[3] - b[3];
}
MINLINE void mul_v2_fl(float r[2], float f)
{
- r[0] *= f;
- r[1] *= f;
+ r[0] *= f;
+ r[1] *= f;
}
MINLINE void mul_v2_v2fl(float r[2], const float a[2], float f)
{
- r[0] = a[0] * f;
- r[1] = a[1] * f;
+ r[0] = a[0] * f;
+ r[1] = a[1] * f;
}
MINLINE void mul_v3_fl(float r[3], float f)
{
- r[0] *= f;
- r[1] *= f;
- r[2] *= f;
+ r[0] *= f;
+ r[1] *= f;
+ r[2] *= f;
}
MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
{
- r[0] = a[0] * f;
- r[1] = a[1] * f;
- r[2] = a[2] * f;
+ r[0] = a[0] * f;
+ r[1] = a[1] * f;
+ r[2] = a[2] * f;
}
MINLINE void mul_v2_v2(float r[2], const float a[2])
{
- r[0] *= a[0];
- r[1] *= a[1];
+ r[0] *= a[0];
+ r[1] *= a[1];
}
MINLINE void mul_v3_v3(float r[3], const float a[3])
{
- r[0] *= a[0];
- r[1] *= a[1];
- r[2] *= a[2];
+ r[0] *= a[0];
+ r[1] *= a[1];
+ r[2] *= a[2];
}
MINLINE void mul_v4_fl(float r[4], float f)
{
- r[0] *= f;
- r[1] *= f;
- r[2] *= f;
- r[3] *= f;
+ r[0] *= f;
+ r[1] *= f;
+ r[2] *= f;
+ r[3] *= f;
}
MINLINE void mul_v4_v4(float r[4], const float a[4])
{
- r[0] *= a[0];
- r[1] *= a[1];
- r[2] *= a[2];
- r[3] *= a[3];
+ r[0] *= a[0];
+ r[1] *= a[1];
+ r[2] *= a[2];
+ r[3] *= a[3];
}
MINLINE void mul_v4_v4fl(float r[4], const float a[4], float f)
{
- r[0] = a[0] * f;
- r[1] = a[1] * f;
- r[2] = a[2] * f;
- r[3] = a[3] * f;
+ r[0] = a[0] * f;
+ r[1] = a[1] * f;
+ r[2] = a[2] * f;
+ r[3] = a[3] * f;
}
/**
@@ -548,18 +547,18 @@ MINLINE void mul_v4_v4fl(float r[4], const float a[4], float f)
MINLINE void mul_v2_v2_cw(float r[2], const float mat[2], const float vec[2])
{
- BLI_assert(r != vec);
+ BLI_assert(r != vec);
- r[0] = mat[0] * vec[0] + (+mat[1]) * vec[1];
- r[1] = mat[1] * vec[0] + (-mat[0]) * vec[1];
+ r[0] = mat[0] * vec[0] + (+mat[1]) * vec[1];
+ r[1] = mat[1] * vec[0] + (-mat[0]) * vec[1];
}
MINLINE void mul_v2_v2_ccw(float r[2], const float mat[2], const float vec[2])
{
- BLI_assert(r != vec);
+ BLI_assert(r != vec);
- r[0] = mat[0] * vec[0] + (-mat[1]) * vec[1];
- r[1] = mat[1] * vec[0] + (+mat[0]) * vec[1];
+ r[0] = mat[0] * vec[0] + (-mat[1]) * vec[1];
+ r[1] = mat[1] * vec[0] + (+mat[0]) * vec[1];
}
/**
@@ -576,9 +575,7 @@ MINLINE void mul_v2_v2_ccw(float r[2], const float mat[2], const float vec[2])
*/
MINLINE float mul_project_m4_v3_zfac(const float mat[4][4], const float co[3])
{
- return (mat[0][3] * co[0]) +
- (mat[1][3] * co[1]) +
- (mat[2][3] * co[2]) + mat[3][3];
+ return (mat[0][3] * co[0]) + (mat[1][3] * co[1]) + (mat[2][3] * co[2]) + mat[3][3];
}
/**
@@ -586,15 +583,15 @@ MINLINE float mul_project_m4_v3_zfac(const float mat[4][4], const float co[3])
*/
MINLINE float dot_m3_v3_row_x(const float M[3][3], const float a[3])
{
- return M[0][0] * a[0] + M[1][0] * a[1] + M[2][0] * a[2];
+ return M[0][0] * a[0] + M[1][0] * a[1] + M[2][0] * a[2];
}
MINLINE float dot_m3_v3_row_y(const float M[3][3], const float a[3])
{
- return M[0][1] * a[0] + M[1][1] * a[1] + M[2][1] * a[2];
+ return M[0][1] * a[0] + M[1][1] * a[1] + M[2][1] * a[2];
}
MINLINE float dot_m3_v3_row_z(const float M[3][3], const float a[3])
{
- return M[0][2] * a[0] + M[1][2] * a[1] + M[2][2] * a[2];
+ return M[0][2] * a[0] + M[1][2] * a[1] + M[2][2] * a[2];
}
/**
@@ -603,260 +600,263 @@ MINLINE float dot_m3_v3_row_z(const float M[3][3], const float a[3])
*/
MINLINE float dot_m4_v3_row_x(const float M[4][4], const float a[3])
{
- return M[0][0] * a[0] + M[1][0] * a[1] + M[2][0] * a[2];
+ return M[0][0] * a[0] + M[1][0] * a[1] + M[2][0] * a[2];
}
MINLINE float dot_m4_v3_row_y(const float M[4][4], const float a[3])
{
- return M[0][1] * a[0] + M[1][1] * a[1] + M[2][1] * a[2];
+ return M[0][1] * a[0] + M[1][1] * a[1] + M[2][1] * a[2];
}
MINLINE float dot_m4_v3_row_z(const float M[4][4], const float a[3])
{
- return M[0][2] * a[0] + M[1][2] * a[1] + M[2][2] * a[2];
+ return M[0][2] * a[0] + M[1][2] * a[1] + M[2][2] * a[2];
}
MINLINE void madd_v2_v2fl(float r[2], const float a[2], float f)
{
- r[0] += a[0] * f;
- r[1] += a[1] * f;
+ r[0] += a[0] * f;
+ r[1] += a[1] * f;
}
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
{
- r[0] += a[0] * f;
- r[1] += a[1] * f;
- r[2] += a[2] * f;
+ r[0] += a[0] * f;
+ r[1] += a[1] * f;
+ r[2] += a[2] * f;
}
MINLINE void madd_v3_v3v3(float r[3], const float a[3], const float b[3])
{
- r[0] += a[0] * b[0];
- r[1] += a[1] * b[1];
- r[2] += a[2] * b[2];
+ r[0] += a[0] * b[0];
+ r[1] += a[1] * b[1];
+ r[2] += a[2] * b[2];
}
MINLINE void madd_v2_v2v2fl(float r[2], const float a[2], const float b[2], float f)
{
- r[0] = a[0] + b[0] * f;
- r[1] = a[1] + b[1] * f;
+ r[0] = a[0] + b[0] * f;
+ r[1] = a[1] + b[1] * f;
}
MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], float f)
{
- r[0] = a[0] + b[0] * f;
- r[1] = a[1] + b[1] * f;
- r[2] = a[2] + b[2] * f;
+ r[0] = a[0] + b[0] * f;
+ r[1] = a[1] + b[1] * f;
+ r[2] = a[2] + b[2] * f;
}
MINLINE void madd_v3_v3v3v3(float r[3], const float a[3], const float b[3], const float c[3])
{
- r[0] = a[0] + b[0] * c[0];
- r[1] = a[1] + b[1] * c[1];
- r[2] = a[2] + b[2] * c[2];
+ r[0] = a[0] + b[0] * c[0];
+ r[1] = a[1] + b[1] * c[1];
+ r[2] = a[2] + b[2] * c[2];
}
-MINLINE void madd_v3fl_v3fl_v3fl_v3i(float r[3], const float a[3], const float b[3], const int c[3])
+MINLINE void madd_v3fl_v3fl_v3fl_v3i(float r[3],
+ const float a[3],
+ const float b[3],
+ const int c[3])
{
- r[0] = a[0] + b[0] * (float)c[0];
- r[1] = a[1] + b[1] * (float)c[1];
- r[2] = a[2] + b[2] * (float)c[2];
+ r[0] = a[0] + b[0] * (float)c[0];
+ r[1] = a[1] + b[1] * (float)c[1];
+ r[2] = a[2] + b[2] * (float)c[2];
}
MINLINE void madd_v4_v4fl(float r[4], const float a[4], float f)
{
- r[0] += a[0] * f;
- r[1] += a[1] * f;
- r[2] += a[2] * f;
- r[3] += a[3] * f;
+ r[0] += a[0] * f;
+ r[1] += a[1] * f;
+ r[2] += a[2] * f;
+ r[3] += a[3] * f;
}
MINLINE void madd_v4_v4v4(float r[4], const float a[4], const float b[4])
{
- r[0] += a[0] * b[0];
- r[1] += a[1] * b[1];
- r[2] += a[2] * b[2];
- r[3] += a[3] * b[3];
+ r[0] += a[0] * b[0];
+ r[1] += a[1] * b[1];
+ r[2] += a[2] * b[2];
+ r[3] += a[3] * b[3];
}
MINLINE void mul_v3_v3v3(float r[3], const float v1[3], const float v2[3])
{
- r[0] = v1[0] * v2[0];
- r[1] = v1[1] * v2[1];
- r[2] = v1[2] * v2[2];
+ r[0] = v1[0] * v2[0];
+ r[1] = v1[1] * v2[1];
+ r[2] = v1[2] * v2[2];
}
MINLINE void mul_v2_v2v2(float r[2], const float a[2], const float b[2])
{
- r[0] = a[0] * b[0];
- r[1] = a[1] * b[1];
+ r[0] = a[0] * b[0];
+ r[1] = a[1] * b[1];
}
MINLINE void negate_v2(float r[2])
{
- r[0] = -r[0];
- r[1] = -r[1];
+ r[0] = -r[0];
+ r[1] = -r[1];
}
MINLINE void negate_v2_v2(float r[2], const float a[2])
{
- r[0] = -a[0];
- r[1] = -a[1];
+ r[0] = -a[0];
+ r[1] = -a[1];
}
MINLINE void negate_v3(float r[3])
{
- r[0] = -r[0];
- r[1] = -r[1];
- r[2] = -r[2];
+ r[0] = -r[0];
+ r[1] = -r[1];
+ r[2] = -r[2];
}
MINLINE void negate_v3_v3(float r[3], const float a[3])
{
- r[0] = -a[0];
- r[1] = -a[1];
- r[2] = -a[2];
+ r[0] = -a[0];
+ r[1] = -a[1];
+ r[2] = -a[2];
}
MINLINE void negate_v4(float r[4])
{
- r[0] = -r[0];
- r[1] = -r[1];
- r[2] = -r[2];
- r[3] = -r[3];
+ r[0] = -r[0];
+ r[1] = -r[1];
+ r[2] = -r[2];
+ r[3] = -r[3];
}
MINLINE void negate_v4_v4(float r[4], const float a[4])
{
- r[0] = -a[0];
- r[1] = -a[1];
- r[2] = -a[2];
- r[3] = -a[3];
+ r[0] = -a[0];
+ r[1] = -a[1];
+ r[2] = -a[2];
+ r[3] = -a[3];
}
/* could add more... */
MINLINE void negate_v3_short(short r[3])
{
- r[0] = (short)-r[0];
- r[1] = (short)-r[1];
- r[2] = (short)-r[2];
+ r[0] = (short)-r[0];
+ r[1] = (short)-r[1];
+ r[2] = (short)-r[2];
}
MINLINE void negate_v3_db(double r[3])
{
- r[0] = -r[0];
- r[1] = -r[1];
- r[2] = -r[2];
+ r[0] = -r[0];
+ r[1] = -r[1];
+ r[2] = -r[2];
}
MINLINE void invert_v2(float r[2])
{
- BLI_assert(!ELEM(0.0f, r[0], r[1]));
- r[0] = 1.0f / r[0];
- r[1] = 1.0f / r[1];
+ BLI_assert(!ELEM(0.0f, r[0], r[1]));
+ r[0] = 1.0f / r[0];
+ r[1] = 1.0f / r[1];
}
MINLINE void invert_v3(float r[3])
{
- BLI_assert(!ELEM(0.0f, r[0], r[1], r[2]));
- r[0] = 1.0f / r[0];
- r[1] = 1.0f / r[1];
- r[2] = 1.0f / r[2];
+ BLI_assert(!ELEM(0.0f, r[0], r[1], r[2]));
+ r[0] = 1.0f / r[0];
+ r[1] = 1.0f / r[1];
+ r[2] = 1.0f / r[2];
}
MINLINE void abs_v2(float r[2])
{
- r[0] = fabsf(r[0]);
- r[1] = fabsf(r[1]);
+ r[0] = fabsf(r[0]);
+ r[1] = fabsf(r[1]);
}
MINLINE void abs_v2_v2(float r[2], const float a[2])
{
- r[0] = fabsf(a[0]);
- r[1] = fabsf(a[1]);
+ r[0] = fabsf(a[0]);
+ r[1] = fabsf(a[1]);
}
MINLINE void abs_v3(float r[3])
{
- r[0] = fabsf(r[0]);
- r[1] = fabsf(r[1]);
- r[2] = fabsf(r[2]);
+ r[0] = fabsf(r[0]);
+ r[1] = fabsf(r[1]);
+ r[2] = fabsf(r[2]);
}
MINLINE void abs_v3_v3(float r[3], const float a[3])
{
- r[0] = fabsf(a[0]);
- r[1] = fabsf(a[1]);
- r[2] = fabsf(a[2]);
+ r[0] = fabsf(a[0]);
+ r[1] = fabsf(a[1]);
+ r[2] = fabsf(a[2]);
}
MINLINE void abs_v4(float r[4])
{
- r[0] = fabsf(r[0]);
- r[1] = fabsf(r[1]);
- r[2] = fabsf(r[2]);
- r[3] = fabsf(r[3]);
+ r[0] = fabsf(r[0]);
+ r[1] = fabsf(r[1]);
+ r[2] = fabsf(r[2]);
+ r[3] = fabsf(r[3]);
}
MINLINE void abs_v4_v4(float r[4], const float a[4])
{
- r[0] = fabsf(a[0]);
- r[1] = fabsf(a[1]);
- r[2] = fabsf(a[2]);
- r[3] = fabsf(a[3]);
+ r[0] = fabsf(a[0]);
+ r[1] = fabsf(a[1]);
+ r[2] = fabsf(a[2]);
+ r[3] = fabsf(a[3]);
}
MINLINE float dot_v2v2(const float a[2], const float b[2])
{
- return a[0] * b[0] + a[1] * b[1];
+ return a[0] * b[0] + a[1] * b[1];
}
MINLINE float dot_v3v3(const float a[3], const float b[3])
{
- return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
+ return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
}
MINLINE float dot_v3v3v3(const float p[3], const float a[3], const float b[3])
{
- float vec1[3], vec2[3];
+ float vec1[3], vec2[3];
- sub_v3_v3v3(vec1, a, p);
- sub_v3_v3v3(vec2, b, p);
- if (is_zero_v3(vec1) || is_zero_v3(vec2)) {
- return 0.0f;
- }
- return dot_v3v3(vec1, vec2);
+ sub_v3_v3v3(vec1, a, p);
+ sub_v3_v3v3(vec2, b, p);
+ if (is_zero_v3(vec1) || is_zero_v3(vec2)) {
+ return 0.0f;
+ }
+ return dot_v3v3(vec1, vec2);
}
MINLINE float dot_v4v4(const float a[4], const float b[4])
{
- return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
+ return a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
}
MINLINE double dot_v3db_v3fl(const double a[3], const float b[3])
{
- return a[0] * (double)b[0] + a[1] * (double)b[1] + a[2] * (double)b[2];
+ return a[0] * (double)b[0] + a[1] * (double)b[1] + a[2] * (double)b[2];
}
MINLINE float cross_v2v2(const float a[2], const float b[2])
{
- return a[0] * b[1] - a[1] * b[0];
+ return a[0] * b[1] - a[1] * b[0];
}
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
{
- BLI_assert(r != a && r != b);
- r[0] = a[1] * b[2] - a[2] * b[1];
- r[1] = a[2] * b[0] - a[0] * b[2];
- r[2] = a[0] * b[1] - a[1] * b[0];
+ BLI_assert(r != a && r != b);
+ r[0] = a[1] * b[2] - a[2] * b[1];
+ r[1] = a[2] * b[0] - a[0] * b[2];
+ r[2] = a[0] * b[1] - a[1] * b[0];
}
/* cross product suffers from severe precision loss when vectors are
* nearly parallel or opposite; doing the computation in double helps a lot */
MINLINE void cross_v3_v3v3_hi_prec(float r[3], const float a[3], const float b[3])
{
- BLI_assert(r != a && r != b);
- r[0] = (float)((double)a[1] * (double)b[2] - (double)a[2] * (double)b[1]);
- r[1] = (float)((double)a[2] * (double)b[0] - (double)a[0] * (double)b[2]);
- r[2] = (float)((double)a[0] * (double)b[1] - (double)a[1] * (double)b[0]);
+ BLI_assert(r != a && r != b);
+ r[0] = (float)((double)a[1] * (double)b[2] - (double)a[2] * (double)b[1]);
+ r[1] = (float)((double)a[2] * (double)b[0] - (double)a[0] * (double)b[2]);
+ r[2] = (float)((double)a[0] * (double)b[1] - (double)a[1] * (double)b[0]);
}
/* Newell's Method */
@@ -865,276 +865,273 @@ MINLINE void cross_v3_v3v3_hi_prec(float r[3], const float a[3], const float b[3
* could use a better name */
MINLINE void add_newell_cross_v3_v3v3(float n[3], const float v_prev[3], const float v_curr[3])
{
- n[0] += (v_prev[1] - v_curr[1]) * (v_prev[2] + v_curr[2]);
- n[1] += (v_prev[2] - v_curr[2]) * (v_prev[0] + v_curr[0]);
- n[2] += (v_prev[0] - v_curr[0]) * (v_prev[1] + v_curr[1]);
+ n[0] += (v_prev[1] - v_curr[1]) * (v_prev[2] + v_curr[2]);
+ n[1] += (v_prev[2] - v_curr[2]) * (v_prev[0] + v_curr[0]);
+ n[2] += (v_prev[0] - v_curr[0]) * (v_prev[1] + v_curr[1]);
}
MINLINE void star_m3_v3(float rmat[3][3], float a[3])
{
- rmat[0][0] = rmat[1][1] = rmat[2][2] = 0.0;
- rmat[0][1] = -a[2];
- rmat[0][2] = a[1];
- rmat[1][0] = a[2];
- rmat[1][2] = -a[0];
- rmat[2][0] = -a[1];
- rmat[2][1] = a[0];
+ rmat[0][0] = rmat[1][1] = rmat[2][2] = 0.0;
+ rmat[0][1] = -a[2];
+ rmat[0][2] = a[1];
+ rmat[1][0] = a[2];
+ rmat[1][2] = -a[0];
+ rmat[2][0] = -a[1];
+ rmat[2][1] = a[0];
}
/*********************************** Length **********************************/
MINLINE float len_squared_v2(const float v[2])
{
- return v[0] * v[0] + v[1] * v[1];
+ return v[0] * v[0] + v[1] * v[1];
}
MINLINE float len_squared_v3(const float v[3])
{
- return v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
+ return v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
}
MINLINE float len_manhattan_v2(const float v[2])
{
- return fabsf(v[0]) + fabsf(v[1]);
+ return fabsf(v[0]) + fabsf(v[1]);
}
MINLINE int len_manhattan_v2_int(const int v[2])
{
- return abs(v[0]) + abs(v[1]);
+ return abs(v[0]) + abs(v[1]);
}
MINLINE float len_manhattan_v3(const float v[3])
{
- return fabsf(v[0]) + fabsf(v[1]) + fabsf(v[2]);
+ return fabsf(v[0]) + fabsf(v[1]) + fabsf(v[2]);
}
MINLINE float len_v2(const float v[2])
{
- return sqrtf(v[0] * v[0] + v[1] * v[1]);
+ return sqrtf(v[0] * v[0] + v[1] * v[1]);
}
MINLINE float len_v2v2(const float v1[2], const float v2[2])
{
- float x, y;
+ float x, y;
- x = v1[0] - v2[0];
- y = v1[1] - v2[1];
- return sqrtf(x * x + y * y);
+ x = v1[0] - v2[0];
+ y = v1[1] - v2[1];
+ return sqrtf(x * x + y * y);
}
MINLINE float len_v2v2_int(const int v1[2], const int v2[2])
{
- float x, y;
+ float x, y;
- x = (float)(v1[0] - v2[0]);
- y = (float)(v1[1] - v2[1]);
- return sqrtf(x * x + y * y);
+ x = (float)(v1[0] - v2[0]);
+ y = (float)(v1[1] - v2[1]);
+ return sqrtf(x * x + y * y);
}
MINLINE float len_v3(const float a[3])
{
- return sqrtf(dot_v3v3(a, a));
+ return sqrtf(dot_v3v3(a, a));
}
MINLINE float len_squared_v2v2(const float a[2], const float b[2])
{
- float d[2];
+ float d[2];
- sub_v2_v2v2(d, b, a);
- return dot_v2v2(d, d);
+ sub_v2_v2v2(d, b, a);
+ return dot_v2v2(d, d);
}
MINLINE float len_squared_v3v3(const float a[3], const float b[3])
{
- float d[3];
+ float d[3];
- sub_v3_v3v3(d, b, a);
- return dot_v3v3(d, d);
+ sub_v3_v3v3(d, b, a);
+ return dot_v3v3(d, d);
}
MINLINE float len_squared_v4v4(const float a[4], const float b[4])
{
- float d[4];
+ float d[4];
- sub_v4_v4v4(d, b, a);
- return dot_v4v4(d, d);
+ sub_v4_v4v4(d, b, a);
+ return dot_v4v4(d, d);
}
MINLINE float len_manhattan_v2v2(const float a[2], const float b[2])
{
- float d[2];
+ float d[2];
- sub_v2_v2v2(d, b, a);
- return len_manhattan_v2(d);
+ sub_v2_v2v2(d, b, a);
+ return len_manhattan_v2(d);
}
MINLINE int len_manhattan_v2v2_int(const int a[2], const int b[2])
{
- int d[2];
+ int d[2];
- sub_v2_v2v2_int(d, b, a);
- return len_manhattan_v2_int(d);
+ sub_v2_v2v2_int(d, b, a);
+ return len_manhattan_v2_int(d);
}
MINLINE float len_manhattan_v3v3(const float a[3], const float b[3])
{
- float d[3];
+ float d[3];
- sub_v3_v3v3(d, b, a);
- return len_manhattan_v3(d);
+ sub_v3_v3v3(d, b, a);
+ return len_manhattan_v3(d);
}
MINLINE float len_v3v3(const float a[3], const float b[3])
{
- float d[3];
+ float d[3];
- sub_v3_v3v3(d, b, a);
- return len_v3(d);
+ sub_v3_v3v3(d, b, a);
+ return len_v3(d);
}
MINLINE float normalize_v2_v2_length(float r[2], const float a[2], const float unit_length)
{
- float d = dot_v2v2(a, a);
+ float d = dot_v2v2(a, a);
- if (d > 1.0e-35f) {
- d = sqrtf(d);
- mul_v2_v2fl(r, a, unit_length / d);
- }
- else {
- zero_v2(r);
- d = 0.0f;
- }
+ if (d > 1.0e-35f) {
+ d = sqrtf(d);
+ mul_v2_v2fl(r, a, unit_length / d);
+ }
+ else {
+ zero_v2(r);
+ d = 0.0f;
+ }
- return d;
+ return d;
}
MINLINE float normalize_v2_v2(float r[2], const float a[2])
{
- return normalize_v2_v2_length(r, a, 1.0f);
+ return normalize_v2_v2_length(r, a, 1.0f);
}
MINLINE float normalize_v2(float n[2])
{
- return normalize_v2_v2(n, n);
+ return normalize_v2_v2(n, n);
}
MINLINE float normalize_v2_length(float n[2], const float unit_length)
{
- return normalize_v2_v2_length(n, n, unit_length);
+ return normalize_v2_v2_length(n, n, unit_length);
}
MINLINE float normalize_v3_v3_length(float r[3], const float a[3], const float unit_length)
{
- float d = dot_v3v3(a, a);
+ float d = dot_v3v3(a, a);
- /* a larger value causes normalize errors in a
- * scaled down models with camera extreme close */
- if (d > 1.0e-35f) {
- d = sqrtf(d);
- mul_v3_v3fl(r, a, unit_length / d);
- }
- else {
- zero_v3(r);
- d = 0.0f;
- }
+ /* a larger value causes normalize errors in a
+ * scaled down models with camera extreme close */
+ if (d > 1.0e-35f) {
+ d = sqrtf(d);
+ mul_v3_v3fl(r, a, unit_length / d);
+ }
+ else {
+ zero_v3(r);
+ d = 0.0f;
+ }
- return d;
+ return d;
}
MINLINE float normalize_v3_v3(float r[3], const float a[3])
{
- return normalize_v3_v3_length(r, a, 1.0f);
+ return normalize_v3_v3_length(r, a, 1.0f);
}
MINLINE double normalize_v3_length_d(double n[3], const double unit_length)
{
- double d = n[0] * n[0] + n[1] * n[1] + n[2] * n[2];
+ double d = n[0] * n[0] + n[1] * n[1] + n[2] * n[2];
- /* a larger value causes normalize errors in a
- * scaled down models with camera extreme close */
- if (d > 1.0e-35) {
- double mul;
+ /* a larger value causes normalize errors in a
+ * scaled down models with camera extreme close */
+ if (d > 1.0e-35) {
+ double mul;
- d = sqrt(d);
- mul = unit_length / d;
+ d = sqrt(d);
+ mul = unit_length / d;
- n[0] *= mul;
- n[1] *= mul;
- n[2] *= mul;
- }
- else {
- n[0] = n[1] = n[2] = 0;
- d = 0.0;
- }
+ n[0] *= mul;
+ n[1] *= mul;
+ n[2] *= mul;
+ }
+ else {
+ n[0] = n[1] = n[2] = 0;
+ d = 0.0;
+ }
- return d;
+ return d;
}
MINLINE double normalize_v3_d(double n[3])
{
- return normalize_v3_length_d(n, 1.0);
+ return normalize_v3_length_d(n, 1.0);
}
MINLINE float normalize_v3_length(float n[3], const float unit_length)
{
- return normalize_v3_v3_length(n, n, unit_length);
+ return normalize_v3_v3_length(n, n, unit_length);
}
MINLINE float normalize_v3(float n[3])
{
- return normalize_v3_v3(n, n);
+ return normalize_v3_v3(n, n);
}
MINLINE void normal_float_to_short_v2(short out[2], const float in[2])
{
- out[0] = (short) (in[0] * 32767.0f);
- out[1] = (short) (in[1] * 32767.0f);
+ out[0] = (short)(in[0] * 32767.0f);
+ out[1] = (short)(in[1] * 32767.0f);
}
MINLINE void normal_short_to_float_v3(float out[3], const short in[3])
{
- out[0] = in[0] * (1.0f / 32767.0f);
- out[1] = in[1] * (1.0f / 32767.0f);
- out[2] = in[2] * (1.0f / 32767.0f);
+ out[0] = in[0] * (1.0f / 32767.0f);
+ out[1] = in[1] * (1.0f / 32767.0f);
+ out[2] = in[2] * (1.0f / 32767.0f);
}
MINLINE void normal_float_to_short_v3(short out[3], const float in[3])
{
- out[0] = (short) (in[0] * 32767.0f);
- out[1] = (short) (in[1] * 32767.0f);
- out[2] = (short) (in[2] * 32767.0f);
+ out[0] = (short)(in[0] * 32767.0f);
+ out[1] = (short)(in[1] * 32767.0f);
+ out[2] = (short)(in[2] * 32767.0f);
}
MINLINE void normal_float_to_short_v4(short out[4], const float in[4])
{
- out[0] = (short) (in[0] * 32767.0f);
- out[1] = (short) (in[1] * 32767.0f);
- out[2] = (short) (in[2] * 32767.0f);
- out[3] = (short) (in[3] * 32767.0f);
+ out[0] = (short)(in[0] * 32767.0f);
+ out[1] = (short)(in[1] * 32767.0f);
+ out[2] = (short)(in[2] * 32767.0f);
+ out[3] = (short)(in[3] * 32767.0f);
}
-
/********************************* Comparison ********************************/
-
MINLINE bool is_zero_v2(const float v[2])
{
- return (v[0] == 0.0f && v[1] == 0.0f);
+ return (v[0] == 0.0f && v[1] == 0.0f);
}
MINLINE bool is_zero_v3(const float v[3])
{
- return (v[0] == 0.0f && v[1] == 0.0f && v[2] == 0.0f);
+ return (v[0] == 0.0f && v[1] == 0.0f && v[2] == 0.0f);
}
MINLINE bool is_zero_v4(const float v[4])
{
- return (v[0] == 0.0f && v[1] == 0.0f && v[2] == 0.0f && v[3] == 0.0f);
+ return (v[0] == 0.0f && v[1] == 0.0f && v[2] == 0.0f && v[3] == 0.0f);
}
MINLINE bool is_one_v3(const float v[3])
{
- return (v[0] == 1.0f && v[1] == 1.0f && v[2] == 1.0f);
+ return (v[0] == 1.0f && v[1] == 1.0f && v[2] == 1.0f);
}
-
/** \name Vector Comparison
*
* \note use ``value <= limit``, so a limit of zero doesn't fail on an exact match.
@@ -1142,67 +1139,71 @@ MINLINE bool is_one_v3(const float v[3])
MINLINE bool equals_v2v2(const float v1[2], const float v2[2])
{
- return ((v1[0] == v2[0]) && (v1[1] == v2[1]));
+ return ((v1[0] == v2[0]) && (v1[1] == v2[1]));
}
MINLINE bool equals_v3v3(const float v1[3], const float v2[3])
{
- return ((v1[0] == v2[0]) && (v1[1] == v2[1]) && (v1[2] == v2[2]));
+ return ((v1[0] == v2[0]) && (v1[1] == v2[1]) && (v1[2] == v2[2]));
}
MINLINE bool equals_v4v4(const float v1[4], const float v2[4])
{
- return ((v1[0] == v2[0]) && (v1[1] == v2[1]) && (v1[2] == v2[2]) && (v1[3] == v2[3]));
+ return ((v1[0] == v2[0]) && (v1[1] == v2[1]) && (v1[2] == v2[2]) && (v1[3] == v2[3]));
}
MINLINE bool compare_v2v2(const float v1[2], const float v2[2], const float limit)
{
- return (compare_ff(v1[0], v2[0], limit) &&
- compare_ff(v1[1], v2[1], limit));
+ return (compare_ff(v1[0], v2[0], limit) && compare_ff(v1[1], v2[1], limit));
}
MINLINE bool compare_v3v3(const float v1[3], const float v2[3], const float limit)
{
- return (compare_ff(v1[0], v2[0], limit) &&
- compare_ff(v1[1], v2[1], limit) &&
- compare_ff(v1[2], v2[2], limit));
+ return (compare_ff(v1[0], v2[0], limit) && compare_ff(v1[1], v2[1], limit) &&
+ compare_ff(v1[2], v2[2], limit));
}
MINLINE bool compare_v4v4(const float v1[4], const float v2[4], const float limit)
{
- return (compare_ff(v1[0], v2[0], limit) &&
- compare_ff(v1[1], v2[1], limit) &&
- compare_ff(v1[2], v2[2], limit) &&
- compare_ff(v1[3], v2[3], limit));
+ return (compare_ff(v1[0], v2[0], limit) && compare_ff(v1[1], v2[1], limit) &&
+ compare_ff(v1[2], v2[2], limit) && compare_ff(v1[3], v2[3], limit));
}
-MINLINE bool compare_v2v2_relative(const float v1[2], const float v2[2], const float limit, const int max_ulps)
+MINLINE bool compare_v2v2_relative(const float v1[2],
+ const float v2[2],
+ const float limit,
+ const int max_ulps)
{
- return (compare_ff_relative(v1[0], v2[0], limit, max_ulps) &&
- compare_ff_relative(v1[1], v2[1], limit, max_ulps));
+ return (compare_ff_relative(v1[0], v2[0], limit, max_ulps) &&
+ compare_ff_relative(v1[1], v2[1], limit, max_ulps));
}
-MINLINE bool compare_v3v3_relative(const float v1[3], const float v2[3], const float limit, const int max_ulps)
+MINLINE bool compare_v3v3_relative(const float v1[3],
+ const float v2[3],
+ const float limit,
+ const int max_ulps)
{
- return (compare_ff_relative(v1[0], v2[0], limit, max_ulps) &&
- compare_ff_relative(v1[1], v2[1], limit, max_ulps) &&
- compare_ff_relative(v1[2], v2[2], limit, max_ulps));
+ return (compare_ff_relative(v1[0], v2[0], limit, max_ulps) &&
+ compare_ff_relative(v1[1], v2[1], limit, max_ulps) &&
+ compare_ff_relative(v1[2], v2[2], limit, max_ulps));
}
-MINLINE bool compare_v4v4_relative(const float v1[4], const float v2[4], const float limit, const int max_ulps)
+MINLINE bool compare_v4v4_relative(const float v1[4],
+ const float v2[4],
+ const float limit,
+ const int max_ulps)
{
- return (compare_ff_relative(v1[0], v2[0], limit, max_ulps) &&
- compare_ff_relative(v1[1], v2[1], limit, max_ulps) &&
- compare_ff_relative(v1[2], v2[2], limit, max_ulps) &&
- compare_ff_relative(v1[3], v2[3], limit, max_ulps));
+ return (compare_ff_relative(v1[0], v2[0], limit, max_ulps) &&
+ compare_ff_relative(v1[1], v2[1], limit, max_ulps) &&
+ compare_ff_relative(v1[2], v2[2], limit, max_ulps) &&
+ compare_ff_relative(v1[3], v2[3], limit, max_ulps));
}
-
MINLINE bool compare_len_v3v3(const float v1[3], const float v2[3], const float limit)
{
- float d[3];
- sub_v3_v3v3(d, v1, v2);
- return (dot_v3v3(d, d) <= (limit * limit));
+ float d[3];
+ sub_v3_v3v3(d, v1, v2);
+ return (dot_v3v3(d, d) <= (limit * limit));
}
/**
@@ -1219,8 +1220,7 @@ MINLINE bool compare_len_v3v3(const float v1[3], const float v2[3], const float
*/
MINLINE float line_point_side_v2(const float l1[2], const float l2[2], const float pt[2])
{
- return (((l1[0] - pt[0]) * (l2[1] - pt[1])) -
- ((l2[0] - pt[0]) * (l1[1] - pt[1])));
+ return (((l1[0] - pt[0]) * (l2[1] - pt[1])) - ((l2[0] - pt[0]) * (l1[1] - pt[1])));
}
/** \} */
diff --git a/source/blender/blenlib/intern/memory_utils.c b/source/blender/blenlib/intern/memory_utils.c
index b0cfe709be8..91e75861dde 100644
--- a/source/blender/blenlib/intern/memory_utils.c
+++ b/source/blender/blenlib/intern/memory_utils.c
@@ -35,12 +35,12 @@
*/
bool BLI_memory_is_zero(const void *s, const size_t nbytes)
{
- const char *s_byte = s;
- const char *s_end = (const char *)s + nbytes;
+ const char *s_byte = s;
+ const char *s_end = (const char *)s + nbytes;
- while ((s_byte != s_end) && (*s_byte == 0)) {
- s_byte++;
- }
+ while ((s_byte != s_end) && (*s_byte == 0)) {
+ s_byte++;
+ }
- return (s_byte == s_end);
+ return (s_byte == s_end);
}
diff --git a/source/blender/blenlib/intern/noise.c b/source/blender/blenlib/intern/noise.c
index 241c5ec954c..2fbf64e1200 100644
--- a/source/blender/blenlib/intern/noise.c
+++ b/source/blender/blenlib/intern/noise.c
@@ -34,224 +34,230 @@ static float noise3_perlin(float vec[3]);
// #define HASHVEC(x, y, z) hashvectf + 3 * hash[(hash[(hash[(z) & 255] + (y)) & 255] + (x)) & 255]
/* needed for voronoi */
-#define HASHPNT(x, y, z) hashpntf + 3 * hash[(hash[(hash[(z) & 255] + (y)) & 255] + (x)) & 255]
+#define HASHPNT(x, y, z) hashpntf + 3 * hash[(hash[(hash[(z)&255] + (y)) & 255] + (x)) & 255]
static const float hashpntf[768] = {
- 0.536902, 0.020915, 0.501445, 0.216316, 0.517036, 0.822466, 0.965315,
- 0.377313, 0.678764, 0.744545, 0.097731, 0.396357, 0.247202, 0.520897,
- 0.613396, 0.542124, 0.146813, 0.255489, 0.810868, 0.638641, 0.980742,
- 0.292316, 0.357948, 0.114382, 0.861377, 0.629634, 0.722530, 0.714103,
- 0.048549, 0.075668, 0.564920, 0.162026, 0.054466, 0.411738, 0.156897,
- 0.887657, 0.599368, 0.074249, 0.170277, 0.225799, 0.393154, 0.301348,
- 0.057434, 0.293849, 0.442745, 0.150002, 0.398732, 0.184582, 0.915200,
- 0.630984, 0.974040, 0.117228, 0.795520, 0.763238, 0.158982, 0.616211,
- 0.250825, 0.906539, 0.316874, 0.676205, 0.234720, 0.667673, 0.792225,
- 0.273671, 0.119363, 0.199131, 0.856716, 0.828554, 0.900718, 0.705960,
- 0.635923, 0.989433, 0.027261, 0.283507, 0.113426, 0.388115, 0.900176,
- 0.637741, 0.438802, 0.715490, 0.043692, 0.202640, 0.378325, 0.450325,
- 0.471832, 0.147803, 0.906899, 0.524178, 0.784981, 0.051483, 0.893369,
- 0.596895, 0.275635, 0.391483, 0.844673, 0.103061, 0.257322, 0.708390,
- 0.504091, 0.199517, 0.660339, 0.376071, 0.038880, 0.531293, 0.216116,
- 0.138672, 0.907737, 0.807994, 0.659582, 0.915264, 0.449075, 0.627128,
- 0.480173, 0.380942, 0.018843, 0.211808, 0.569701, 0.082294, 0.689488,
- 0.573060, 0.593859, 0.216080, 0.373159, 0.108117, 0.595539, 0.021768,
- 0.380297, 0.948125, 0.377833, 0.319699, 0.315249, 0.972805, 0.792270,
- 0.445396, 0.845323, 0.372186, 0.096147, 0.689405, 0.423958, 0.055675,
- 0.117940, 0.328456, 0.605808, 0.631768, 0.372170, 0.213723, 0.032700,
- 0.447257, 0.440661, 0.728488, 0.299853, 0.148599, 0.649212, 0.498381,
- 0.049921, 0.496112, 0.607142, 0.562595, 0.990246, 0.739659, 0.108633,
- 0.978156, 0.209814, 0.258436, 0.876021, 0.309260, 0.600673, 0.713597,
- 0.576967, 0.641402, 0.853930, 0.029173, 0.418111, 0.581593, 0.008394,
- 0.589904, 0.661574, 0.979326, 0.275724, 0.111109, 0.440472, 0.120839,
- 0.521602, 0.648308, 0.284575, 0.204501, 0.153286, 0.822444, 0.300786,
- 0.303906, 0.364717, 0.209038, 0.916831, 0.900245, 0.600685, 0.890002,
- 0.581660, 0.431154, 0.705569, 0.551250, 0.417075, 0.403749, 0.696652,
- 0.292652, 0.911372, 0.690922, 0.323718, 0.036773, 0.258976, 0.274265,
- 0.225076, 0.628965, 0.351644, 0.065158, 0.080340, 0.467271, 0.130643,
- 0.385914, 0.919315, 0.253821, 0.966163, 0.017439, 0.392610, 0.478792,
- 0.978185, 0.072691, 0.982009, 0.097987, 0.731533, 0.401233, 0.107570,
- 0.349587, 0.479122, 0.700598, 0.481751, 0.788429, 0.706864, 0.120086,
- 0.562691, 0.981797, 0.001223, 0.192120, 0.451543, 0.173092, 0.108960,
- 0.549594, 0.587892, 0.657534, 0.396365, 0.125153, 0.666420, 0.385823,
- 0.890916, 0.436729, 0.128114, 0.369598, 0.759096, 0.044677, 0.904752,
- 0.088052, 0.621148, 0.005047, 0.452331, 0.162032, 0.494238, 0.523349,
- 0.741829, 0.698450, 0.452316, 0.563487, 0.819776, 0.492160, 0.004210,
- 0.647158, 0.551475, 0.362995, 0.177937, 0.814722, 0.727729, 0.867126,
- 0.997157, 0.108149, 0.085726, 0.796024, 0.665075, 0.362462, 0.323124,
- 0.043718, 0.042357, 0.315030, 0.328954, 0.870845, 0.683186, 0.467922,
- 0.514894, 0.809971, 0.631979, 0.176571, 0.366320, 0.850621, 0.505555,
- 0.749551, 0.750830, 0.401714, 0.481216, 0.438393, 0.508832, 0.867971,
- 0.654581, 0.058204, 0.566454, 0.084124, 0.548539, 0.902690, 0.779571,
- 0.562058, 0.048082, 0.863109, 0.079290, 0.713559, 0.783496, 0.265266,
- 0.672089, 0.786939, 0.143048, 0.086196, 0.876129, 0.408708, 0.229312,
- 0.629995, 0.206665, 0.207308, 0.710079, 0.341704, 0.264921, 0.028748,
- 0.629222, 0.470173, 0.726228, 0.125243, 0.328249, 0.794187, 0.741340,
- 0.489895, 0.189396, 0.724654, 0.092841, 0.039809, 0.860126, 0.247701,
- 0.655331, 0.964121, 0.672536, 0.044522, 0.690567, 0.837238, 0.631520,
- 0.953734, 0.352484, 0.289026, 0.034152, 0.852575, 0.098454, 0.795529,
- 0.452181, 0.826159, 0.186993, 0.820725, 0.440328, 0.922137, 0.704592,
- 0.915437, 0.738183, 0.733461, 0.193798, 0.929213, 0.161390, 0.318547,
- 0.888751, 0.430968, 0.740837, 0.193544, 0.872253, 0.563074, 0.274598,
- 0.347805, 0.666176, 0.449831, 0.800991, 0.588727, 0.052296, 0.714761,
- 0.420620, 0.570325, 0.057550, 0.210888, 0.407312, 0.662848, 0.924382,
- 0.895958, 0.775198, 0.688605, 0.025721, 0.301913, 0.791408, 0.500602,
- 0.831984, 0.828509, 0.642093, 0.494174, 0.525880, 0.446365, 0.440063,
- 0.763114, 0.630358, 0.223943, 0.333806, 0.906033, 0.498306, 0.241278,
- 0.427640, 0.772683, 0.198082, 0.225379, 0.503894, 0.436599, 0.016503,
- 0.803725, 0.189878, 0.291095, 0.499114, 0.151573, 0.079031, 0.904618,
- 0.708535, 0.273900, 0.067419, 0.317124, 0.936499, 0.716511, 0.543845,
- 0.939909, 0.826574, 0.715090, 0.154864, 0.750150, 0.845808, 0.648108,
- 0.556564, 0.644757, 0.140873, 0.799167, 0.632989, 0.444245, 0.471978,
- 0.435910, 0.359793, 0.216241, 0.007633, 0.337236, 0.857863, 0.380247,
- 0.092517, 0.799973, 0.919000, 0.296798, 0.096989, 0.854831, 0.165369,
- 0.568475, 0.216855, 0.020457, 0.835511, 0.538039, 0.999742, 0.620226,
- 0.244053, 0.060399, 0.323007, 0.294874, 0.988899, 0.384919, 0.735655,
- 0.773428, 0.549776, 0.292882, 0.660611, 0.593507, 0.621118, 0.175269,
- 0.682119, 0.794493, 0.868197, 0.632150, 0.807823, 0.509656, 0.482035,
- 0.001780, 0.259126, 0.358002, 0.280263, 0.192985, 0.290367, 0.208111,
- 0.917633, 0.114422, 0.925491, 0.981110, 0.255570, 0.974862, 0.016629,
- 0.552599, 0.575741, 0.612978, 0.615965, 0.803615, 0.772334, 0.089745,
- 0.838812, 0.634542, 0.113709, 0.755832, 0.577589, 0.667489, 0.529834,
- 0.325660, 0.817597, 0.316557, 0.335093, 0.737363, 0.260951, 0.737073,
- 0.049540, 0.735541, 0.988891, 0.299116, 0.147695, 0.417271, 0.940811,
- 0.524160, 0.857968, 0.176403, 0.244835, 0.485759, 0.033353, 0.280319,
- 0.750688, 0.755809, 0.924208, 0.095956, 0.962504, 0.275584, 0.173715,
- 0.942716, 0.706721, 0.078464, 0.576716, 0.804667, 0.559249, 0.900611,
- 0.646904, 0.432111, 0.927885, 0.383277, 0.269973, 0.114244, 0.574867,
- 0.150703, 0.241855, 0.272871, 0.199950, 0.079719, 0.868566, 0.962833,
- 0.789122, 0.320025, 0.905554, 0.234876, 0.991356, 0.061913, 0.732911,
- 0.785960, 0.874074, 0.069035, 0.658632, 0.309901, 0.023676, 0.791603,
- 0.764661, 0.661278, 0.319583, 0.829650, 0.117091, 0.903124, 0.982098,
- 0.161631, 0.193576, 0.670428, 0.857390, 0.003760, 0.572578, 0.222162,
- 0.114551, 0.420118, 0.530404, 0.470682, 0.525527, 0.764281, 0.040596,
- 0.443275, 0.501124, 0.816161, 0.417467, 0.332172, 0.447565, 0.614591,
- 0.559246, 0.805295, 0.226342, 0.155065, 0.714630, 0.160925, 0.760001,
- 0.453456, 0.093869, 0.406092, 0.264801, 0.720370, 0.743388, 0.373269,
- 0.403098, 0.911923, 0.897249, 0.147038, 0.753037, 0.516093, 0.739257,
- 0.175018, 0.045768, 0.735857, 0.801330, 0.927708, 0.240977, 0.591870,
- 0.921831, 0.540733, 0.149100, 0.423152, 0.806876, 0.397081, 0.061100,
- 0.811630, 0.044899, 0.460915, 0.961202, 0.822098, 0.971524, 0.867608,
- 0.773604, 0.226616, 0.686286, 0.926972, 0.411613, 0.267873, 0.081937,
- 0.226124, 0.295664, 0.374594, 0.533240, 0.237876, 0.669629, 0.599083,
- 0.513081, 0.878719, 0.201577, 0.721296, 0.495038, 0.079760, 0.965959,
- 0.233090, 0.052496, 0.714748, 0.887844, 0.308724, 0.972885, 0.723337,
- 0.453089, 0.914474, 0.704063, 0.823198, 0.834769, 0.906561, 0.919600,
- 0.100601, 0.307564, 0.901977, 0.468879, 0.265376, 0.885188, 0.683875,
- 0.868623, 0.081032, 0.466835, 0.199087, 0.663437, 0.812241, 0.311337,
- 0.821361, 0.356628, 0.898054, 0.160781, 0.222539, 0.714889, 0.490287,
- 0.984915, 0.951755, 0.964097, 0.641795, 0.815472, 0.852732, 0.862074,
- 0.051108, 0.440139, 0.323207, 0.517171, 0.562984, 0.115295, 0.743103,
- 0.977914, 0.337596, 0.440694, 0.535879, 0.959427, 0.351427, 0.704361,
- 0.010826, 0.131162, 0.577080, 0.349572, 0.774892, 0.425796, 0.072697,
- 0.500001, 0.267322, 0.909654, 0.206176, 0.223987, 0.937698, 0.323423,
- 0.117501, 0.490308, 0.474372, 0.689943, 0.168671, 0.719417, 0.188928,
- 0.330464, 0.265273, 0.446271, 0.171933, 0.176133, 0.474616, 0.140182,
- 0.114246, 0.905043, 0.713870, 0.555261, 0.951333,
+ 0.536902, 0.020915, 0.501445, 0.216316, 0.517036, 0.822466, 0.965315, 0.377313, 0.678764,
+ 0.744545, 0.097731, 0.396357, 0.247202, 0.520897, 0.613396, 0.542124, 0.146813, 0.255489,
+ 0.810868, 0.638641, 0.980742, 0.292316, 0.357948, 0.114382, 0.861377, 0.629634, 0.722530,
+ 0.714103, 0.048549, 0.075668, 0.564920, 0.162026, 0.054466, 0.411738, 0.156897, 0.887657,
+ 0.599368, 0.074249, 0.170277, 0.225799, 0.393154, 0.301348, 0.057434, 0.293849, 0.442745,
+ 0.150002, 0.398732, 0.184582, 0.915200, 0.630984, 0.974040, 0.117228, 0.795520, 0.763238,
+ 0.158982, 0.616211, 0.250825, 0.906539, 0.316874, 0.676205, 0.234720, 0.667673, 0.792225,
+ 0.273671, 0.119363, 0.199131, 0.856716, 0.828554, 0.900718, 0.705960, 0.635923, 0.989433,
+ 0.027261, 0.283507, 0.113426, 0.388115, 0.900176, 0.637741, 0.438802, 0.715490, 0.043692,
+ 0.202640, 0.378325, 0.450325, 0.471832, 0.147803, 0.906899, 0.524178, 0.784981, 0.051483,
+ 0.893369, 0.596895, 0.275635, 0.391483, 0.844673, 0.103061, 0.257322, 0.708390, 0.504091,
+ 0.199517, 0.660339, 0.376071, 0.038880, 0.531293, 0.216116, 0.138672, 0.907737, 0.807994,
+ 0.659582, 0.915264, 0.449075, 0.627128, 0.480173, 0.380942, 0.018843, 0.211808, 0.569701,
+ 0.082294, 0.689488, 0.573060, 0.593859, 0.216080, 0.373159, 0.108117, 0.595539, 0.021768,
+ 0.380297, 0.948125, 0.377833, 0.319699, 0.315249, 0.972805, 0.792270, 0.445396, 0.845323,
+ 0.372186, 0.096147, 0.689405, 0.423958, 0.055675, 0.117940, 0.328456, 0.605808, 0.631768,
+ 0.372170, 0.213723, 0.032700, 0.447257, 0.440661, 0.728488, 0.299853, 0.148599, 0.649212,
+ 0.498381, 0.049921, 0.496112, 0.607142, 0.562595, 0.990246, 0.739659, 0.108633, 0.978156,
+ 0.209814, 0.258436, 0.876021, 0.309260, 0.600673, 0.713597, 0.576967, 0.641402, 0.853930,
+ 0.029173, 0.418111, 0.581593, 0.008394, 0.589904, 0.661574, 0.979326, 0.275724, 0.111109,
+ 0.440472, 0.120839, 0.521602, 0.648308, 0.284575, 0.204501, 0.153286, 0.822444, 0.300786,
+ 0.303906, 0.364717, 0.209038, 0.916831, 0.900245, 0.600685, 0.890002, 0.581660, 0.431154,
+ 0.705569, 0.551250, 0.417075, 0.403749, 0.696652, 0.292652, 0.911372, 0.690922, 0.323718,
+ 0.036773, 0.258976, 0.274265, 0.225076, 0.628965, 0.351644, 0.065158, 0.080340, 0.467271,
+ 0.130643, 0.385914, 0.919315, 0.253821, 0.966163, 0.017439, 0.392610, 0.478792, 0.978185,
+ 0.072691, 0.982009, 0.097987, 0.731533, 0.401233, 0.107570, 0.349587, 0.479122, 0.700598,
+ 0.481751, 0.788429, 0.706864, 0.120086, 0.562691, 0.981797, 0.001223, 0.192120, 0.451543,
+ 0.173092, 0.108960, 0.549594, 0.587892, 0.657534, 0.396365, 0.125153, 0.666420, 0.385823,
+ 0.890916, 0.436729, 0.128114, 0.369598, 0.759096, 0.044677, 0.904752, 0.088052, 0.621148,
+ 0.005047, 0.452331, 0.162032, 0.494238, 0.523349, 0.741829, 0.698450, 0.452316, 0.563487,
+ 0.819776, 0.492160, 0.004210, 0.647158, 0.551475, 0.362995, 0.177937, 0.814722, 0.727729,
+ 0.867126, 0.997157, 0.108149, 0.085726, 0.796024, 0.665075, 0.362462, 0.323124, 0.043718,
+ 0.042357, 0.315030, 0.328954, 0.870845, 0.683186, 0.467922, 0.514894, 0.809971, 0.631979,
+ 0.176571, 0.366320, 0.850621, 0.505555, 0.749551, 0.750830, 0.401714, 0.481216, 0.438393,
+ 0.508832, 0.867971, 0.654581, 0.058204, 0.566454, 0.084124, 0.548539, 0.902690, 0.779571,
+ 0.562058, 0.048082, 0.863109, 0.079290, 0.713559, 0.783496, 0.265266, 0.672089, 0.786939,
+ 0.143048, 0.086196, 0.876129, 0.408708, 0.229312, 0.629995, 0.206665, 0.207308, 0.710079,
+ 0.341704, 0.264921, 0.028748, 0.629222, 0.470173, 0.726228, 0.125243, 0.328249, 0.794187,
+ 0.741340, 0.489895, 0.189396, 0.724654, 0.092841, 0.039809, 0.860126, 0.247701, 0.655331,
+ 0.964121, 0.672536, 0.044522, 0.690567, 0.837238, 0.631520, 0.953734, 0.352484, 0.289026,
+ 0.034152, 0.852575, 0.098454, 0.795529, 0.452181, 0.826159, 0.186993, 0.820725, 0.440328,
+ 0.922137, 0.704592, 0.915437, 0.738183, 0.733461, 0.193798, 0.929213, 0.161390, 0.318547,
+ 0.888751, 0.430968, 0.740837, 0.193544, 0.872253, 0.563074, 0.274598, 0.347805, 0.666176,
+ 0.449831, 0.800991, 0.588727, 0.052296, 0.714761, 0.420620, 0.570325, 0.057550, 0.210888,
+ 0.407312, 0.662848, 0.924382, 0.895958, 0.775198, 0.688605, 0.025721, 0.301913, 0.791408,
+ 0.500602, 0.831984, 0.828509, 0.642093, 0.494174, 0.525880, 0.446365, 0.440063, 0.763114,
+ 0.630358, 0.223943, 0.333806, 0.906033, 0.498306, 0.241278, 0.427640, 0.772683, 0.198082,
+ 0.225379, 0.503894, 0.436599, 0.016503, 0.803725, 0.189878, 0.291095, 0.499114, 0.151573,
+ 0.079031, 0.904618, 0.708535, 0.273900, 0.067419, 0.317124, 0.936499, 0.716511, 0.543845,
+ 0.939909, 0.826574, 0.715090, 0.154864, 0.750150, 0.845808, 0.648108, 0.556564, 0.644757,
+ 0.140873, 0.799167, 0.632989, 0.444245, 0.471978, 0.435910, 0.359793, 0.216241, 0.007633,
+ 0.337236, 0.857863, 0.380247, 0.092517, 0.799973, 0.919000, 0.296798, 0.096989, 0.854831,
+ 0.165369, 0.568475, 0.216855, 0.020457, 0.835511, 0.538039, 0.999742, 0.620226, 0.244053,
+ 0.060399, 0.323007, 0.294874, 0.988899, 0.384919, 0.735655, 0.773428, 0.549776, 0.292882,
+ 0.660611, 0.593507, 0.621118, 0.175269, 0.682119, 0.794493, 0.868197, 0.632150, 0.807823,
+ 0.509656, 0.482035, 0.001780, 0.259126, 0.358002, 0.280263, 0.192985, 0.290367, 0.208111,
+ 0.917633, 0.114422, 0.925491, 0.981110, 0.255570, 0.974862, 0.016629, 0.552599, 0.575741,
+ 0.612978, 0.615965, 0.803615, 0.772334, 0.089745, 0.838812, 0.634542, 0.113709, 0.755832,
+ 0.577589, 0.667489, 0.529834, 0.325660, 0.817597, 0.316557, 0.335093, 0.737363, 0.260951,
+ 0.737073, 0.049540, 0.735541, 0.988891, 0.299116, 0.147695, 0.417271, 0.940811, 0.524160,
+ 0.857968, 0.176403, 0.244835, 0.485759, 0.033353, 0.280319, 0.750688, 0.755809, 0.924208,
+ 0.095956, 0.962504, 0.275584, 0.173715, 0.942716, 0.706721, 0.078464, 0.576716, 0.804667,
+ 0.559249, 0.900611, 0.646904, 0.432111, 0.927885, 0.383277, 0.269973, 0.114244, 0.574867,
+ 0.150703, 0.241855, 0.272871, 0.199950, 0.079719, 0.868566, 0.962833, 0.789122, 0.320025,
+ 0.905554, 0.234876, 0.991356, 0.061913, 0.732911, 0.785960, 0.874074, 0.069035, 0.658632,
+ 0.309901, 0.023676, 0.791603, 0.764661, 0.661278, 0.319583, 0.829650, 0.117091, 0.903124,
+ 0.982098, 0.161631, 0.193576, 0.670428, 0.857390, 0.003760, 0.572578, 0.222162, 0.114551,
+ 0.420118, 0.530404, 0.470682, 0.525527, 0.764281, 0.040596, 0.443275, 0.501124, 0.816161,
+ 0.417467, 0.332172, 0.447565, 0.614591, 0.559246, 0.805295, 0.226342, 0.155065, 0.714630,
+ 0.160925, 0.760001, 0.453456, 0.093869, 0.406092, 0.264801, 0.720370, 0.743388, 0.373269,
+ 0.403098, 0.911923, 0.897249, 0.147038, 0.753037, 0.516093, 0.739257, 0.175018, 0.045768,
+ 0.735857, 0.801330, 0.927708, 0.240977, 0.591870, 0.921831, 0.540733, 0.149100, 0.423152,
+ 0.806876, 0.397081, 0.061100, 0.811630, 0.044899, 0.460915, 0.961202, 0.822098, 0.971524,
+ 0.867608, 0.773604, 0.226616, 0.686286, 0.926972, 0.411613, 0.267873, 0.081937, 0.226124,
+ 0.295664, 0.374594, 0.533240, 0.237876, 0.669629, 0.599083, 0.513081, 0.878719, 0.201577,
+ 0.721296, 0.495038, 0.079760, 0.965959, 0.233090, 0.052496, 0.714748, 0.887844, 0.308724,
+ 0.972885, 0.723337, 0.453089, 0.914474, 0.704063, 0.823198, 0.834769, 0.906561, 0.919600,
+ 0.100601, 0.307564, 0.901977, 0.468879, 0.265376, 0.885188, 0.683875, 0.868623, 0.081032,
+ 0.466835, 0.199087, 0.663437, 0.812241, 0.311337, 0.821361, 0.356628, 0.898054, 0.160781,
+ 0.222539, 0.714889, 0.490287, 0.984915, 0.951755, 0.964097, 0.641795, 0.815472, 0.852732,
+ 0.862074, 0.051108, 0.440139, 0.323207, 0.517171, 0.562984, 0.115295, 0.743103, 0.977914,
+ 0.337596, 0.440694, 0.535879, 0.959427, 0.351427, 0.704361, 0.010826, 0.131162, 0.577080,
+ 0.349572, 0.774892, 0.425796, 0.072697, 0.500001, 0.267322, 0.909654, 0.206176, 0.223987,
+ 0.937698, 0.323423, 0.117501, 0.490308, 0.474372, 0.689943, 0.168671, 0.719417, 0.188928,
+ 0.330464, 0.265273, 0.446271, 0.171933, 0.176133, 0.474616, 0.140182, 0.114246, 0.905043,
+ 0.713870, 0.555261, 0.951333,
};
-extern const unsigned char BLI_noise_hash_uchar_512[512]; /* Quiet warning. */
+extern const unsigned char BLI_noise_hash_uchar_512[512]; /* Quiet warning. */
const unsigned char BLI_noise_hash_uchar_512[512] = {
- 0xA2, 0xA0, 0x19, 0x3B, 0xF8, 0xEB, 0xAA, 0xEE, 0xF3, 0x1C, 0x67, 0x28, 0x1D, 0xED, 0x0, 0xDE, 0x95, 0x2E, 0xDC,
- 0x3F, 0x3A, 0x82, 0x35, 0x4D, 0x6C, 0xBA, 0x36, 0xD0, 0xF6, 0xC, 0x79, 0x32, 0xD1, 0x59, 0xF4, 0x8, 0x8B, 0x63,
- 0x89, 0x2F, 0xB8, 0xB4, 0x97, 0x83, 0xF2, 0x8F, 0x18, 0xC7, 0x51, 0x14, 0x65, 0x87, 0x48, 0x20, 0x42, 0xA8, 0x80,
- 0xB5, 0x40, 0x13, 0xB2, 0x22, 0x7E, 0x57, 0xBC, 0x7F, 0x6B, 0x9D, 0x86, 0x4C, 0xC8, 0xDB, 0x7C, 0xD5, 0x25, 0x4E,
- 0x5A, 0x55, 0x74, 0x50, 0xCD, 0xB3, 0x7A, 0xBB, 0xC3, 0xCB, 0xB6, 0xE2, 0xE4, 0xEC, 0xFD, 0x98, 0xB, 0x96, 0xD3,
- 0x9E, 0x5C, 0xA1, 0x64, 0xF1, 0x81, 0x61, 0xE1, 0xC4, 0x24, 0x72, 0x49, 0x8C, 0x90, 0x4B, 0x84, 0x34, 0x38, 0xAB,
- 0x78, 0xCA, 0x1F, 0x1, 0xD7, 0x93, 0x11, 0xC1, 0x58, 0xA9, 0x31, 0xF9, 0x44, 0x6D, 0xBF, 0x33, 0x9C, 0x5F, 0x9,
- 0x94, 0xA3, 0x85, 0x6, 0xC6, 0x9A, 0x1E, 0x7B, 0x46, 0x15, 0x30, 0x27, 0x2B, 0x1B, 0x71, 0x3C, 0x5B, 0xD6, 0x6F,
- 0x62, 0xAC, 0x4F, 0xC2, 0xC0, 0xE, 0xB1, 0x23, 0xA7, 0xDF, 0x47, 0xB0, 0x77, 0x69, 0x5, 0xE9, 0xE6, 0xE7, 0x76,
- 0x73, 0xF, 0xFE, 0x6E, 0x9B, 0x56, 0xEF, 0x12, 0xA5, 0x37, 0xFC, 0xAE, 0xD9, 0x3, 0x8E, 0xDD, 0x10, 0xB9, 0xCE,
- 0xC9, 0x8D, 0xDA, 0x2A, 0xBD, 0x68, 0x17, 0x9F, 0xBE, 0xD4, 0xA, 0xCC, 0xD2, 0xE8, 0x43, 0x3D, 0x70, 0xB7, 0x2,
- 0x7D, 0x99, 0xD8, 0xD, 0x60, 0x8A, 0x4, 0x2C, 0x3E, 0x92, 0xE5, 0xAF, 0x53, 0x7, 0xE0, 0x29, 0xA6, 0xC5, 0xE3,
- 0xF5, 0xF7, 0x4A, 0x41, 0x26, 0x6A, 0x16, 0x5E, 0x52, 0x2D, 0x21, 0xAD, 0xF0, 0x91, 0xFF, 0xEA, 0x54, 0xFA, 0x66,
- 0x1A, 0x45, 0x39, 0xCF, 0x75, 0xA4, 0x88, 0xFB, 0x5D, 0xA2, 0xA0, 0x19, 0x3B, 0xF8, 0xEB, 0xAA, 0xEE, 0xF3, 0x1C,
- 0x67, 0x28, 0x1D, 0xED, 0x0, 0xDE, 0x95, 0x2E, 0xDC, 0x3F, 0x3A, 0x82, 0x35, 0x4D, 0x6C, 0xBA, 0x36, 0xD0, 0xF6,
- 0xC, 0x79, 0x32, 0xD1, 0x59, 0xF4, 0x8, 0x8B, 0x63, 0x89, 0x2F, 0xB8, 0xB4, 0x97, 0x83, 0xF2, 0x8F, 0x18, 0xC7,
- 0x51, 0x14, 0x65, 0x87, 0x48, 0x20, 0x42, 0xA8, 0x80, 0xB5, 0x40, 0x13, 0xB2, 0x22, 0x7E, 0x57, 0xBC, 0x7F, 0x6B,
- 0x9D, 0x86, 0x4C, 0xC8, 0xDB, 0x7C, 0xD5, 0x25, 0x4E, 0x5A, 0x55, 0x74, 0x50, 0xCD, 0xB3, 0x7A, 0xBB, 0xC3, 0xCB,
- 0xB6, 0xE2, 0xE4, 0xEC, 0xFD, 0x98, 0xB, 0x96, 0xD3, 0x9E, 0x5C, 0xA1, 0x64, 0xF1, 0x81, 0x61, 0xE1, 0xC4, 0x24,
- 0x72, 0x49, 0x8C, 0x90, 0x4B, 0x84, 0x34, 0x38, 0xAB, 0x78, 0xCA, 0x1F, 0x1, 0xD7, 0x93, 0x11, 0xC1, 0x58, 0xA9,
- 0x31, 0xF9, 0x44, 0x6D, 0xBF, 0x33, 0x9C, 0x5F, 0x9, 0x94, 0xA3, 0x85, 0x6, 0xC6, 0x9A, 0x1E, 0x7B, 0x46, 0x15,
- 0x30, 0x27, 0x2B, 0x1B, 0x71, 0x3C, 0x5B, 0xD6, 0x6F, 0x62, 0xAC, 0x4F, 0xC2, 0xC0, 0xE, 0xB1, 0x23, 0xA7, 0xDF,
- 0x47, 0xB0, 0x77, 0x69, 0x5, 0xE9, 0xE6, 0xE7, 0x76, 0x73, 0xF, 0xFE, 0x6E, 0x9B, 0x56, 0xEF, 0x12, 0xA5, 0x37,
- 0xFC, 0xAE, 0xD9, 0x3, 0x8E, 0xDD, 0x10, 0xB9, 0xCE, 0xC9, 0x8D, 0xDA, 0x2A, 0xBD, 0x68, 0x17, 0x9F, 0xBE, 0xD4,
- 0xA, 0xCC, 0xD2, 0xE8, 0x43, 0x3D, 0x70, 0xB7, 0x2, 0x7D, 0x99, 0xD8, 0xD, 0x60, 0x8A, 0x4, 0x2C, 0x3E, 0x92,
- 0xE5, 0xAF, 0x53, 0x7, 0xE0, 0x29, 0xA6, 0xC5, 0xE3, 0xF5, 0xF7, 0x4A, 0x41, 0x26, 0x6A, 0x16, 0x5E, 0x52, 0x2D,
- 0x21, 0xAD, 0xF0, 0x91, 0xFF, 0xEA, 0x54, 0xFA, 0x66, 0x1A, 0x45, 0x39, 0xCF, 0x75, 0xA4, 0x88, 0xFB, 0x5D,
+ 0xA2, 0xA0, 0x19, 0x3B, 0xF8, 0xEB, 0xAA, 0xEE, 0xF3, 0x1C, 0x67, 0x28, 0x1D, 0xED, 0x0, 0xDE,
+ 0x95, 0x2E, 0xDC, 0x3F, 0x3A, 0x82, 0x35, 0x4D, 0x6C, 0xBA, 0x36, 0xD0, 0xF6, 0xC, 0x79, 0x32,
+ 0xD1, 0x59, 0xF4, 0x8, 0x8B, 0x63, 0x89, 0x2F, 0xB8, 0xB4, 0x97, 0x83, 0xF2, 0x8F, 0x18, 0xC7,
+ 0x51, 0x14, 0x65, 0x87, 0x48, 0x20, 0x42, 0xA8, 0x80, 0xB5, 0x40, 0x13, 0xB2, 0x22, 0x7E, 0x57,
+ 0xBC, 0x7F, 0x6B, 0x9D, 0x86, 0x4C, 0xC8, 0xDB, 0x7C, 0xD5, 0x25, 0x4E, 0x5A, 0x55, 0x74, 0x50,
+ 0xCD, 0xB3, 0x7A, 0xBB, 0xC3, 0xCB, 0xB6, 0xE2, 0xE4, 0xEC, 0xFD, 0x98, 0xB, 0x96, 0xD3, 0x9E,
+ 0x5C, 0xA1, 0x64, 0xF1, 0x81, 0x61, 0xE1, 0xC4, 0x24, 0x72, 0x49, 0x8C, 0x90, 0x4B, 0x84, 0x34,
+ 0x38, 0xAB, 0x78, 0xCA, 0x1F, 0x1, 0xD7, 0x93, 0x11, 0xC1, 0x58, 0xA9, 0x31, 0xF9, 0x44, 0x6D,
+ 0xBF, 0x33, 0x9C, 0x5F, 0x9, 0x94, 0xA3, 0x85, 0x6, 0xC6, 0x9A, 0x1E, 0x7B, 0x46, 0x15, 0x30,
+ 0x27, 0x2B, 0x1B, 0x71, 0x3C, 0x5B, 0xD6, 0x6F, 0x62, 0xAC, 0x4F, 0xC2, 0xC0, 0xE, 0xB1, 0x23,
+ 0xA7, 0xDF, 0x47, 0xB0, 0x77, 0x69, 0x5, 0xE9, 0xE6, 0xE7, 0x76, 0x73, 0xF, 0xFE, 0x6E, 0x9B,
+ 0x56, 0xEF, 0x12, 0xA5, 0x37, 0xFC, 0xAE, 0xD9, 0x3, 0x8E, 0xDD, 0x10, 0xB9, 0xCE, 0xC9, 0x8D,
+ 0xDA, 0x2A, 0xBD, 0x68, 0x17, 0x9F, 0xBE, 0xD4, 0xA, 0xCC, 0xD2, 0xE8, 0x43, 0x3D, 0x70, 0xB7,
+ 0x2, 0x7D, 0x99, 0xD8, 0xD, 0x60, 0x8A, 0x4, 0x2C, 0x3E, 0x92, 0xE5, 0xAF, 0x53, 0x7, 0xE0,
+ 0x29, 0xA6, 0xC5, 0xE3, 0xF5, 0xF7, 0x4A, 0x41, 0x26, 0x6A, 0x16, 0x5E, 0x52, 0x2D, 0x21, 0xAD,
+ 0xF0, 0x91, 0xFF, 0xEA, 0x54, 0xFA, 0x66, 0x1A, 0x45, 0x39, 0xCF, 0x75, 0xA4, 0x88, 0xFB, 0x5D,
+ 0xA2, 0xA0, 0x19, 0x3B, 0xF8, 0xEB, 0xAA, 0xEE, 0xF3, 0x1C, 0x67, 0x28, 0x1D, 0xED, 0x0, 0xDE,
+ 0x95, 0x2E, 0xDC, 0x3F, 0x3A, 0x82, 0x35, 0x4D, 0x6C, 0xBA, 0x36, 0xD0, 0xF6, 0xC, 0x79, 0x32,
+ 0xD1, 0x59, 0xF4, 0x8, 0x8B, 0x63, 0x89, 0x2F, 0xB8, 0xB4, 0x97, 0x83, 0xF2, 0x8F, 0x18, 0xC7,
+ 0x51, 0x14, 0x65, 0x87, 0x48, 0x20, 0x42, 0xA8, 0x80, 0xB5, 0x40, 0x13, 0xB2, 0x22, 0x7E, 0x57,
+ 0xBC, 0x7F, 0x6B, 0x9D, 0x86, 0x4C, 0xC8, 0xDB, 0x7C, 0xD5, 0x25, 0x4E, 0x5A, 0x55, 0x74, 0x50,
+ 0xCD, 0xB3, 0x7A, 0xBB, 0xC3, 0xCB, 0xB6, 0xE2, 0xE4, 0xEC, 0xFD, 0x98, 0xB, 0x96, 0xD3, 0x9E,
+ 0x5C, 0xA1, 0x64, 0xF1, 0x81, 0x61, 0xE1, 0xC4, 0x24, 0x72, 0x49, 0x8C, 0x90, 0x4B, 0x84, 0x34,
+ 0x38, 0xAB, 0x78, 0xCA, 0x1F, 0x1, 0xD7, 0x93, 0x11, 0xC1, 0x58, 0xA9, 0x31, 0xF9, 0x44, 0x6D,
+ 0xBF, 0x33, 0x9C, 0x5F, 0x9, 0x94, 0xA3, 0x85, 0x6, 0xC6, 0x9A, 0x1E, 0x7B, 0x46, 0x15, 0x30,
+ 0x27, 0x2B, 0x1B, 0x71, 0x3C, 0x5B, 0xD6, 0x6F, 0x62, 0xAC, 0x4F, 0xC2, 0xC0, 0xE, 0xB1, 0x23,
+ 0xA7, 0xDF, 0x47, 0xB0, 0x77, 0x69, 0x5, 0xE9, 0xE6, 0xE7, 0x76, 0x73, 0xF, 0xFE, 0x6E, 0x9B,
+ 0x56, 0xEF, 0x12, 0xA5, 0x37, 0xFC, 0xAE, 0xD9, 0x3, 0x8E, 0xDD, 0x10, 0xB9, 0xCE, 0xC9, 0x8D,
+ 0xDA, 0x2A, 0xBD, 0x68, 0x17, 0x9F, 0xBE, 0xD4, 0xA, 0xCC, 0xD2, 0xE8, 0x43, 0x3D, 0x70, 0xB7,
+ 0x2, 0x7D, 0x99, 0xD8, 0xD, 0x60, 0x8A, 0x4, 0x2C, 0x3E, 0x92, 0xE5, 0xAF, 0x53, 0x7, 0xE0,
+ 0x29, 0xA6, 0xC5, 0xE3, 0xF5, 0xF7, 0x4A, 0x41, 0x26, 0x6A, 0x16, 0x5E, 0x52, 0x2D, 0x21, 0xAD,
+ 0xF0, 0x91, 0xFF, 0xEA, 0x54, 0xFA, 0x66, 0x1A, 0x45, 0x39, 0xCF, 0x75, 0xA4, 0x88, 0xFB, 0x5D,
};
#define hash BLI_noise_hash_uchar_512
-
static const float hashvectf[768] = {
- 0.33783, 0.715698, -0.611206, -0.944031, -0.326599, -0.045624, -0.101074, -0.416443, -0.903503, 0.799286, 0.49411,
- -0.341949, -0.854645, 0.518036, 0.033936, 0.42514, -0.437866, -0.792114, -0.358948, 0.597046, 0.717377, -0.985413,
- 0.144714, 0.089294, -0.601776, -0.33728, -0.723907, -0.449921, 0.594513, 0.666382, 0.208313, -0.10791, 0.972076,
- 0.575317, 0.060425, 0.815643, 0.293365, -0.875702, -0.383453, 0.293762, 0.465759, 0.834686, -0.846008, -0.233398,
- -0.47934, -0.115814, 0.143036, -0.98291, 0.204681, -0.949036, -0.239532, 0.946716, -0.263947, 0.184326, -0.235596,
- 0.573822, 0.784332, 0.203705, -0.372253, -0.905487, 0.756989, -0.651031, 0.055298, 0.497803, 0.814697, -0.297363,
- -0.16214, 0.063995, -0.98468, -0.329254, 0.834381, 0.441925, 0.703827, -0.527039, -0.476227, 0.956421, 0.266113,
- 0.119781, 0.480133, 0.482849, 0.7323, -0.18631, 0.961212, -0.203125, -0.748474, -0.656921, -0.090393, -0.085052,
- -0.165253, 0.982544, -0.76947, 0.628174, -0.115234, 0.383148, 0.537659, 0.751068, 0.616486, -0.668488, -0.415924,
- -0.259979, -0.630005, 0.73175, 0.570953, -0.087952, 0.816223, -0.458008, 0.023254, 0.888611, -0.196167, 0.976563,
- -0.088287, -0.263885, -0.69812, -0.665527, 0.437134, -0.892273, -0.112793, -0.621674, -0.230438, 0.748566, 0.232422,
- 0.900574, -0.367249, 0.22229, -0.796143, 0.562744, -0.665497, -0.73764, 0.11377, 0.670135, 0.704803, 0.232605,
- 0.895599, 0.429749, -0.114655, -0.11557, -0.474243, 0.872742, 0.621826, 0.604004, -0.498444, -0.832214, 0.012756,
- 0.55426, -0.702484, 0.705994, -0.089661, -0.692017, 0.649292, 0.315399, -0.175995, -0.977997, 0.111877, 0.096954,
- -0.04953, 0.994019, 0.635284, -0.606689, -0.477783, -0.261261, -0.607422, -0.750153, 0.983276, 0.165436, 0.075958,
- -0.29837, 0.404083, -0.864655, -0.638672, 0.507721, 0.578156, 0.388214, 0.412079, 0.824249, 0.556183, -0.208832,
- 0.804352, 0.778442, 0.562012, 0.27951, -0.616577, 0.781921, -0.091522, 0.196289, 0.051056, 0.979187, -0.121216,
- 0.207153, -0.970734, -0.173401, -0.384735, 0.906555, 0.161499, -0.723236, -0.671387, 0.178497, -0.006226, -0.983887,
- -0.126038, 0.15799, 0.97934, 0.830475, -0.024811, 0.556458, -0.510132, -0.76944, 0.384247, 0.81424, 0.200104,
- -0.544891, -0.112549, -0.393311, -0.912445, 0.56189, 0.152222, -0.813049, 0.198914, -0.254517, -0.946381, -0.41217,
- 0.690979, -0.593811, -0.407257, 0.324524, 0.853668, -0.690186, 0.366119, -0.624115, -0.428345, 0.844147, -0.322296,
- -0.21228, -0.297546, -0.930756, -0.273071, 0.516113, 0.811798, 0.928314, 0.371643, 0.007233, 0.785828, -0.479218,
- -0.390778, -0.704895, 0.058929, 0.706818, 0.173248, 0.203583, 0.963562, 0.422211, -0.904297, -0.062469, -0.363312,
- -0.182465, 0.913605, 0.254028, -0.552307, -0.793945, -0.28891, -0.765747, -0.574554, 0.058319, 0.291382, 0.954803,
- 0.946136, -0.303925, 0.111267, -0.078156, 0.443695, -0.892731, 0.182098, 0.89389, 0.409515, -0.680298, -0.213318,
- 0.701141, 0.062469, 0.848389, -0.525635, -0.72879, -0.641846, 0.238342, -0.88089, 0.427673, 0.202637, -0.532501,
- -0.21405, 0.818878, 0.948975, -0.305084, 0.07962, 0.925446, 0.374664, 0.055817, 0.820923, 0.565491, 0.079102,
- 0.25882, 0.099792, -0.960724, -0.294617, 0.910522, 0.289978, 0.137115, 0.320038, -0.937408, -0.908386, 0.345276,
- -0.235718, -0.936218, 0.138763, 0.322754, 0.366577, 0.925934, -0.090637, 0.309296, -0.686829, -0.657684, 0.66983,
- 0.024445, 0.742065, -0.917999, -0.059113, -0.392059, 0.365509, 0.462158, -0.807922, 0.083374, 0.996399, -0.014801,
- 0.593842, 0.253143, -0.763672, 0.974976, -0.165466, 0.148285, 0.918976, 0.137299, 0.369537, 0.294952, 0.694977,
- 0.655731, 0.943085, 0.152618, -0.295319, 0.58783, -0.598236, 0.544495, 0.203796, 0.678223, 0.705994, -0.478821,
- -0.661011, 0.577667, 0.719055, -0.1698, -0.673828, -0.132172, -0.965332, 0.225006, -0.981873, -0.14502, 0.121979,
- 0.763458, 0.579742, 0.284546, -0.893188, 0.079681, 0.442474, -0.795776, -0.523804, 0.303802, 0.734955, 0.67804,
- -0.007446, 0.15506, 0.986267, -0.056183, 0.258026, 0.571503, -0.778931, -0.681549, -0.702087, -0.206116, -0.96286,
- -0.177185, 0.203613, -0.470978, -0.515106, 0.716095, -0.740326, 0.57135, 0.354095, -0.56012, -0.824982, -0.074982,
- -0.507874, 0.753204, 0.417969, -0.503113, 0.038147, 0.863342, 0.594025, 0.673553, -0.439758, -0.119873, -0.005524,
- -0.992737, 0.098267, -0.213776, 0.971893, -0.615631, 0.643951, 0.454163, 0.896851, -0.441071, 0.032166, -0.555023,
- 0.750763, -0.358093, 0.398773, 0.304688, 0.864929, -0.722961, 0.303589, 0.620544, -0.63559, -0.621948, -0.457306,
- -0.293243, 0.072327, 0.953278, -0.491638, 0.661041, -0.566772, -0.304199, -0.572083, -0.761688, 0.908081, -0.398956,
- 0.127014, -0.523621, -0.549683, -0.650848, -0.932922, -0.19986, 0.299408, 0.099426, 0.140869, 0.984985, -0.020325,
- -0.999756, -0.002319, 0.952667, 0.280853, -0.11615, -0.971893, 0.082581, 0.220337, 0.65921, 0.705292, -0.260651,
- 0.733063, -0.175537, 0.657043, -0.555206, 0.429504, -0.712189, 0.400421, -0.89859, 0.179352, 0.750885, -0.19696,
- 0.630341, 0.785675, -0.569336, 0.241821, -0.058899, -0.464111, 0.883789, 0.129608, -0.94519, 0.299622, -0.357819,
- 0.907654, 0.219238, -0.842133, -0.439117, -0.312927, -0.313477, 0.84433, 0.434479, -0.241211, 0.053253, 0.968994,
- 0.063873, 0.823273, 0.563965, 0.476288, 0.862152, -0.172516, 0.620941, -0.298126, 0.724915, 0.25238, -0.749359,
- -0.612122, -0.577545, 0.386566, 0.718994, -0.406342, -0.737976, 0.538696, 0.04718, 0.556305, 0.82959, -0.802856,
- 0.587463, 0.101166, -0.707733, -0.705963, 0.026428, 0.374908, 0.68457, 0.625092, 0.472137, 0.208405, -0.856506,
- -0.703064, -0.581085, -0.409821, -0.417206, -0.736328, 0.532623, -0.447876, -0.20285, -0.870728, 0.086945,
- -0.990417, 0.107086, 0.183685, 0.018341, -0.982788, 0.560638, -0.428864, 0.708282, 0.296722, -0.952576, -0.0672,
- 0.135773, 0.990265, 0.030243, -0.068787, 0.654724, 0.752686, 0.762604, -0.551758, 0.337585, -0.819611, -0.407684,
- 0.402466, -0.727844, -0.55072, -0.408539, -0.855774, -0.480011, 0.19281, 0.693176, -0.079285, 0.716339, 0.226013,
- 0.650116, -0.725433, 0.246704, 0.953369, -0.173553, -0.970398, -0.239227, -0.03244, 0.136383, -0.394318, 0.908752,
- 0.813232, 0.558167, 0.164368, 0.40451, 0.549042, -0.731323, -0.380249, -0.566711, 0.730865, 0.022156, 0.932739,
- 0.359741, 0.00824, 0.996552, -0.082306, 0.956635, -0.065338, -0.283722, -0.743561, 0.008209, 0.668579, -0.859589,
- -0.509674, 0.035767, -0.852234, 0.363678, -0.375977, -0.201965, -0.970795, -0.12915, 0.313477, 0.947327, 0.06546,
- -0.254028, -0.528259, 0.81015, 0.628052, 0.601105, 0.49411, -0.494385, 0.868378, 0.037933, 0.275635, -0.086426,
- 0.957336, -0.197937, 0.468903, -0.860748, 0.895599, 0.399384, 0.195801, 0.560791, 0.825012, -0.069214, 0.304199,
- -0.849487, 0.43103, 0.096375, 0.93576, 0.339111, -0.051422, 0.408966, -0.911072, 0.330444, 0.942841, -0.042389,
- -0.452362, -0.786407, 0.420563, 0.134308, -0.933472, -0.332489, 0.80191, -0.566711, -0.188934, -0.987946, -0.105988,
- 0.112518, -0.24408, 0.892242, -0.379791, -0.920502, 0.229095, -0.316376, 0.7789, 0.325958, 0.535706, -0.912872,
- 0.185211, -0.36377, -0.184784, 0.565369, -0.803833, -0.018463, 0.119537, 0.992615, -0.259247, -0.935608, 0.239532,
- -0.82373, -0.449127, -0.345947, -0.433105, 0.659515, 0.614349, -0.822754, 0.378845, -0.423676, 0.687195, -0.674835,
- -0.26889, -0.246582, -0.800842, 0.545715, -0.729187, -0.207794, 0.651978, 0.653534, -0.610443, -0.447388, 0.492584,
- -0.023346, 0.869934, 0.609039, 0.009094, -0.79306, 0.962494, -0.271088, -0.00885, 0.2659, -0.004913, 0.963959,
- 0.651245, 0.553619, -0.518951, 0.280548, -0.84314, 0.458618, -0.175293, -0.983215, 0.049805, 0.035339, -0.979919,
- 0.196045, -0.982941, 0.164307, -0.082245, 0.233734, -0.97226, -0.005005, -0.747253, -0.611328, 0.260437, 0.645599,
- 0.592773, 0.481384, 0.117706, -0.949524, -0.29068, -0.535004, -0.791901, -0.294312, -0.627167, -0.214447, 0.748718,
- -0.047974, -0.813477, -0.57959, -0.175537, 0.477264, -0.860992, 0.738556, -0.414246, -0.53183, 0.562561, -0.704071,
- 0.433289, -0.754944, 0.64801, -0.100586, 0.114716, 0.044525, -0.992371, 0.966003, 0.244873, -0.082764,
+ 0.33783, 0.715698, -0.611206, -0.944031, -0.326599, -0.045624, -0.101074, -0.416443,
+ -0.903503, 0.799286, 0.49411, -0.341949, -0.854645, 0.518036, 0.033936, 0.42514,
+ -0.437866, -0.792114, -0.358948, 0.597046, 0.717377, -0.985413, 0.144714, 0.089294,
+ -0.601776, -0.33728, -0.723907, -0.449921, 0.594513, 0.666382, 0.208313, -0.10791,
+ 0.972076, 0.575317, 0.060425, 0.815643, 0.293365, -0.875702, -0.383453, 0.293762,
+ 0.465759, 0.834686, -0.846008, -0.233398, -0.47934, -0.115814, 0.143036, -0.98291,
+ 0.204681, -0.949036, -0.239532, 0.946716, -0.263947, 0.184326, -0.235596, 0.573822,
+ 0.784332, 0.203705, -0.372253, -0.905487, 0.756989, -0.651031, 0.055298, 0.497803,
+ 0.814697, -0.297363, -0.16214, 0.063995, -0.98468, -0.329254, 0.834381, 0.441925,
+ 0.703827, -0.527039, -0.476227, 0.956421, 0.266113, 0.119781, 0.480133, 0.482849,
+ 0.7323, -0.18631, 0.961212, -0.203125, -0.748474, -0.656921, -0.090393, -0.085052,
+ -0.165253, 0.982544, -0.76947, 0.628174, -0.115234, 0.383148, 0.537659, 0.751068,
+ 0.616486, -0.668488, -0.415924, -0.259979, -0.630005, 0.73175, 0.570953, -0.087952,
+ 0.816223, -0.458008, 0.023254, 0.888611, -0.196167, 0.976563, -0.088287, -0.263885,
+ -0.69812, -0.665527, 0.437134, -0.892273, -0.112793, -0.621674, -0.230438, 0.748566,
+ 0.232422, 0.900574, -0.367249, 0.22229, -0.796143, 0.562744, -0.665497, -0.73764,
+ 0.11377, 0.670135, 0.704803, 0.232605, 0.895599, 0.429749, -0.114655, -0.11557,
+ -0.474243, 0.872742, 0.621826, 0.604004, -0.498444, -0.832214, 0.012756, 0.55426,
+ -0.702484, 0.705994, -0.089661, -0.692017, 0.649292, 0.315399, -0.175995, -0.977997,
+ 0.111877, 0.096954, -0.04953, 0.994019, 0.635284, -0.606689, -0.477783, -0.261261,
+ -0.607422, -0.750153, 0.983276, 0.165436, 0.075958, -0.29837, 0.404083, -0.864655,
+ -0.638672, 0.507721, 0.578156, 0.388214, 0.412079, 0.824249, 0.556183, -0.208832,
+ 0.804352, 0.778442, 0.562012, 0.27951, -0.616577, 0.781921, -0.091522, 0.196289,
+ 0.051056, 0.979187, -0.121216, 0.207153, -0.970734, -0.173401, -0.384735, 0.906555,
+ 0.161499, -0.723236, -0.671387, 0.178497, -0.006226, -0.983887, -0.126038, 0.15799,
+ 0.97934, 0.830475, -0.024811, 0.556458, -0.510132, -0.76944, 0.384247, 0.81424,
+ 0.200104, -0.544891, -0.112549, -0.393311, -0.912445, 0.56189, 0.152222, -0.813049,
+ 0.198914, -0.254517, -0.946381, -0.41217, 0.690979, -0.593811, -0.407257, 0.324524,
+ 0.853668, -0.690186, 0.366119, -0.624115, -0.428345, 0.844147, -0.322296, -0.21228,
+ -0.297546, -0.930756, -0.273071, 0.516113, 0.811798, 0.928314, 0.371643, 0.007233,
+ 0.785828, -0.479218, -0.390778, -0.704895, 0.058929, 0.706818, 0.173248, 0.203583,
+ 0.963562, 0.422211, -0.904297, -0.062469, -0.363312, -0.182465, 0.913605, 0.254028,
+ -0.552307, -0.793945, -0.28891, -0.765747, -0.574554, 0.058319, 0.291382, 0.954803,
+ 0.946136, -0.303925, 0.111267, -0.078156, 0.443695, -0.892731, 0.182098, 0.89389,
+ 0.409515, -0.680298, -0.213318, 0.701141, 0.062469, 0.848389, -0.525635, -0.72879,
+ -0.641846, 0.238342, -0.88089, 0.427673, 0.202637, -0.532501, -0.21405, 0.818878,
+ 0.948975, -0.305084, 0.07962, 0.925446, 0.374664, 0.055817, 0.820923, 0.565491,
+ 0.079102, 0.25882, 0.099792, -0.960724, -0.294617, 0.910522, 0.289978, 0.137115,
+ 0.320038, -0.937408, -0.908386, 0.345276, -0.235718, -0.936218, 0.138763, 0.322754,
+ 0.366577, 0.925934, -0.090637, 0.309296, -0.686829, -0.657684, 0.66983, 0.024445,
+ 0.742065, -0.917999, -0.059113, -0.392059, 0.365509, 0.462158, -0.807922, 0.083374,
+ 0.996399, -0.014801, 0.593842, 0.253143, -0.763672, 0.974976, -0.165466, 0.148285,
+ 0.918976, 0.137299, 0.369537, 0.294952, 0.694977, 0.655731, 0.943085, 0.152618,
+ -0.295319, 0.58783, -0.598236, 0.544495, 0.203796, 0.678223, 0.705994, -0.478821,
+ -0.661011, 0.577667, 0.719055, -0.1698, -0.673828, -0.132172, -0.965332, 0.225006,
+ -0.981873, -0.14502, 0.121979, 0.763458, 0.579742, 0.284546, -0.893188, 0.079681,
+ 0.442474, -0.795776, -0.523804, 0.303802, 0.734955, 0.67804, -0.007446, 0.15506,
+ 0.986267, -0.056183, 0.258026, 0.571503, -0.778931, -0.681549, -0.702087, -0.206116,
+ -0.96286, -0.177185, 0.203613, -0.470978, -0.515106, 0.716095, -0.740326, 0.57135,
+ 0.354095, -0.56012, -0.824982, -0.074982, -0.507874, 0.753204, 0.417969, -0.503113,
+ 0.038147, 0.863342, 0.594025, 0.673553, -0.439758, -0.119873, -0.005524, -0.992737,
+ 0.098267, -0.213776, 0.971893, -0.615631, 0.643951, 0.454163, 0.896851, -0.441071,
+ 0.032166, -0.555023, 0.750763, -0.358093, 0.398773, 0.304688, 0.864929, -0.722961,
+ 0.303589, 0.620544, -0.63559, -0.621948, -0.457306, -0.293243, 0.072327, 0.953278,
+ -0.491638, 0.661041, -0.566772, -0.304199, -0.572083, -0.761688, 0.908081, -0.398956,
+ 0.127014, -0.523621, -0.549683, -0.650848, -0.932922, -0.19986, 0.299408, 0.099426,
+ 0.140869, 0.984985, -0.020325, -0.999756, -0.002319, 0.952667, 0.280853, -0.11615,
+ -0.971893, 0.082581, 0.220337, 0.65921, 0.705292, -0.260651, 0.733063, -0.175537,
+ 0.657043, -0.555206, 0.429504, -0.712189, 0.400421, -0.89859, 0.179352, 0.750885,
+ -0.19696, 0.630341, 0.785675, -0.569336, 0.241821, -0.058899, -0.464111, 0.883789,
+ 0.129608, -0.94519, 0.299622, -0.357819, 0.907654, 0.219238, -0.842133, -0.439117,
+ -0.312927, -0.313477, 0.84433, 0.434479, -0.241211, 0.053253, 0.968994, 0.063873,
+ 0.823273, 0.563965, 0.476288, 0.862152, -0.172516, 0.620941, -0.298126, 0.724915,
+ 0.25238, -0.749359, -0.612122, -0.577545, 0.386566, 0.718994, -0.406342, -0.737976,
+ 0.538696, 0.04718, 0.556305, 0.82959, -0.802856, 0.587463, 0.101166, -0.707733,
+ -0.705963, 0.026428, 0.374908, 0.68457, 0.625092, 0.472137, 0.208405, -0.856506,
+ -0.703064, -0.581085, -0.409821, -0.417206, -0.736328, 0.532623, -0.447876, -0.20285,
+ -0.870728, 0.086945, -0.990417, 0.107086, 0.183685, 0.018341, -0.982788, 0.560638,
+ -0.428864, 0.708282, 0.296722, -0.952576, -0.0672, 0.135773, 0.990265, 0.030243,
+ -0.068787, 0.654724, 0.752686, 0.762604, -0.551758, 0.337585, -0.819611, -0.407684,
+ 0.402466, -0.727844, -0.55072, -0.408539, -0.855774, -0.480011, 0.19281, 0.693176,
+ -0.079285, 0.716339, 0.226013, 0.650116, -0.725433, 0.246704, 0.953369, -0.173553,
+ -0.970398, -0.239227, -0.03244, 0.136383, -0.394318, 0.908752, 0.813232, 0.558167,
+ 0.164368, 0.40451, 0.549042, -0.731323, -0.380249, -0.566711, 0.730865, 0.022156,
+ 0.932739, 0.359741, 0.00824, 0.996552, -0.082306, 0.956635, -0.065338, -0.283722,
+ -0.743561, 0.008209, 0.668579, -0.859589, -0.509674, 0.035767, -0.852234, 0.363678,
+ -0.375977, -0.201965, -0.970795, -0.12915, 0.313477, 0.947327, 0.06546, -0.254028,
+ -0.528259, 0.81015, 0.628052, 0.601105, 0.49411, -0.494385, 0.868378, 0.037933,
+ 0.275635, -0.086426, 0.957336, -0.197937, 0.468903, -0.860748, 0.895599, 0.399384,
+ 0.195801, 0.560791, 0.825012, -0.069214, 0.304199, -0.849487, 0.43103, 0.096375,
+ 0.93576, 0.339111, -0.051422, 0.408966, -0.911072, 0.330444, 0.942841, -0.042389,
+ -0.452362, -0.786407, 0.420563, 0.134308, -0.933472, -0.332489, 0.80191, -0.566711,
+ -0.188934, -0.987946, -0.105988, 0.112518, -0.24408, 0.892242, -0.379791, -0.920502,
+ 0.229095, -0.316376, 0.7789, 0.325958, 0.535706, -0.912872, 0.185211, -0.36377,
+ -0.184784, 0.565369, -0.803833, -0.018463, 0.119537, 0.992615, -0.259247, -0.935608,
+ 0.239532, -0.82373, -0.449127, -0.345947, -0.433105, 0.659515, 0.614349, -0.822754,
+ 0.378845, -0.423676, 0.687195, -0.674835, -0.26889, -0.246582, -0.800842, 0.545715,
+ -0.729187, -0.207794, 0.651978, 0.653534, -0.610443, -0.447388, 0.492584, -0.023346,
+ 0.869934, 0.609039, 0.009094, -0.79306, 0.962494, -0.271088, -0.00885, 0.2659,
+ -0.004913, 0.963959, 0.651245, 0.553619, -0.518951, 0.280548, -0.84314, 0.458618,
+ -0.175293, -0.983215, 0.049805, 0.035339, -0.979919, 0.196045, -0.982941, 0.164307,
+ -0.082245, 0.233734, -0.97226, -0.005005, -0.747253, -0.611328, 0.260437, 0.645599,
+ 0.592773, 0.481384, 0.117706, -0.949524, -0.29068, -0.535004, -0.791901, -0.294312,
+ -0.627167, -0.214447, 0.748718, -0.047974, -0.813477, -0.57959, -0.175537, 0.477264,
+ -0.860992, 0.738556, -0.414246, -0.53183, 0.562561, -0.704071, 0.433289, -0.754944,
+ 0.64801, -0.100586, 0.114716, 0.044525, -0.992371, 0.966003, 0.244873, -0.082764,
};
/**************************/
@@ -260,55 +266,64 @@ static const float hashvectf[768] = {
static float lerp(float t, float a, float b)
{
- return (a + t * (b - a));
+ return (a + t * (b - a));
}
static float npfade(float t)
{
- return (t * t * t * (t * (t * 6.0f - 15.0f) + 10.0f));
+ return (t * t * t * (t * (t * 6.0f - 15.0f) + 10.0f));
}
static float grad(int hash_val, float x, float y, float z)
{
- int h = hash_val & 15; /* CONVERT LO 4 BITS OF HASH CODE */
- float u = h < 8 ? x : y; /* INTO 12 GRADIENT DIRECTIONS. */
- float v = h < 4 ? y : h == 12 || h == 14 ? x : z;
- return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
+ int h = hash_val & 15; /* CONVERT LO 4 BITS OF HASH CODE */
+ float u = h < 8 ? x : y; /* INTO 12 GRADIENT DIRECTIONS. */
+ float v = h < 4 ? y : h == 12 || h == 14 ? x : z;
+ return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
}
/* instead of adding another permutation array, just use hash table defined above */
static float newPerlin(float x, float y, float z)
{
- int A, AA, AB, B, BA, BB;
- float u = floor(x), v = floor(y), w = floor(z);
- int X = ((int)u) & 255;
- int Y = ((int)v) & 255;
- int Z = ((int)w) & 255; /* FIND UNIT CUBE THAT CONTAINS POINT */
- x -= u; /* FIND RELATIVE X,Y,Z */
- y -= v; /* OF POINT IN CUBE. */
- z -= w;
- u = npfade(x); /* COMPUTE FADE CURVES */
- v = npfade(y); /* FOR EACH OF X,Y,Z. */
- w = npfade(z);
- A = hash[X ] + Y; AA = hash[A] + Z; AB = hash[A + 1] + Z; /* HASH COORDINATES OF */
- B = hash[X + 1] + Y; BA = hash[B] + Z; BB = hash[B + 1] + Z; /* THE 8 CUBE CORNERS, */
- return lerp(w, lerp(v, lerp(u, grad(hash[AA ], x, y, z ), /* AND ADD */
- grad(hash[BA ], x - 1, y, z )), /* BLENDED */
- lerp(u, grad(hash[AB ], x, y - 1, z ), /* RESULTS */
- grad(hash[BB ], x - 1, y - 1, z ))), /* FROM 8 */
- lerp(v, lerp(u, grad(hash[AA + 1], x, y, z - 1), /* CORNERS */
- grad(hash[BA + 1], x - 1, y, z - 1)), /* OF CUBE */
- lerp(u, grad(hash[AB + 1], x, y - 1, z - 1),
- grad(hash[BB + 1], x - 1, y - 1, z - 1))));
+ int A, AA, AB, B, BA, BB;
+ float u = floor(x), v = floor(y), w = floor(z);
+ int X = ((int)u) & 255;
+ int Y = ((int)v) & 255;
+ int Z = ((int)w) & 255; /* FIND UNIT CUBE THAT CONTAINS POINT */
+ x -= u; /* FIND RELATIVE X,Y,Z */
+ y -= v; /* OF POINT IN CUBE. */
+ z -= w;
+ u = npfade(x); /* COMPUTE FADE CURVES */
+ v = npfade(y); /* FOR EACH OF X,Y,Z. */
+ w = npfade(z);
+ A = hash[X] + Y;
+ AA = hash[A] + Z;
+ AB = hash[A + 1] + Z; /* HASH COORDINATES OF */
+ B = hash[X + 1] + Y;
+ BA = hash[B] + Z;
+ BB = hash[B + 1] + Z; /* THE 8 CUBE CORNERS, */
+ return lerp(
+ w,
+ lerp(v,
+ lerp(u,
+ grad(hash[AA], x, y, z), /* AND ADD */
+ grad(hash[BA], x - 1, y, z)), /* BLENDED */
+ lerp(u,
+ grad(hash[AB], x, y - 1, z), /* RESULTS */
+ grad(hash[BB], x - 1, y - 1, z))), /* FROM 8 */
+ lerp(v,
+ lerp(u,
+ grad(hash[AA + 1], x, y, z - 1), /* CORNERS */
+ grad(hash[BA + 1], x - 1, y, z - 1)), /* OF CUBE */
+ lerp(u, grad(hash[AB + 1], x, y - 1, z - 1), grad(hash[BB + 1], x - 1, y - 1, z - 1))));
}
/* for use with BLI_gNoise()/BLI_gTurbulence(), returns unsigned improved perlin noise */
static float newPerlinU(float x, float y, float z)
{
- return (0.5f + 0.5f * newPerlin(x, y, z));
+ return (0.5f + 0.5f * newPerlin(x, y, z));
}
-
/**************************/
/* END OF IMPROVED PERLIN */
/**************************/
@@ -316,774 +331,512 @@ static float newPerlinU(float x, float y, float z)
/* Was BLI_hnoise(), removed noisesize, so other functions can call it without scaling. */
static float orgBlenderNoise(float x, float y, float z)
{
- register float cn1, cn2, cn3, cn4, cn5, cn6, i;
- register const float *h;
- float fx, fy, fz, ox, oy, oz, jx, jy, jz;
- float n = 0.5;
- int ix, iy, iz, b00, b01, b10, b11, b20, b21;
-
- fx = floor(x);
- fy = floor(y);
- fz = floor(z);
-
- ox = x - fx;
- oy = y - fy;
- oz = z - fz;
-
- ix = (int)fx;
- iy = (int)fy;
- iz = (int)fz;
-
- jx = ox - 1;
- jy = oy - 1;
- jz = oz - 1;
-
- cn1 = ox * ox; cn2 = oy * oy; cn3 = oz * oz;
- cn4 = jx * jx; cn5 = jy * jy; cn6 = jz * jz;
-
- cn1 = 1.0f - 3.0f * cn1 + 2.0f * cn1 * ox;
- cn2 = 1.0f - 3.0f * cn2 + 2.0f * cn2 * oy;
- cn3 = 1.0f - 3.0f * cn3 + 2.0f * cn3 * oz;
- cn4 = 1.0f - 3.0f * cn4 - 2.0f * cn4 * jx;
- cn5 = 1.0f - 3.0f * cn5 - 2.0f * cn5 * jy;
- cn6 = 1.0f - 3.0f * cn6 - 2.0f * cn6 * jz;
-
- b00 = hash[hash[ix & 255] + (iy & 255)];
- b10 = hash[hash[(ix + 1) & 255] + (iy & 255)];
- b01 = hash[hash[ix & 255] + ((iy + 1) & 255)];
- b11 = hash[hash[(ix + 1) & 255] + ((iy + 1) & 255)];
-
- b20 = iz & 255; b21 = (iz + 1) & 255;
-
- /* 0 */
- i = (cn1 * cn2 * cn3);
- h = hashvectf + 3 * hash[b20 + b00];
- n += i * (h[0] * ox + h[1] * oy + h[2] * oz);
- /* 1 */
- i = (cn1 * cn2 * cn6);
- h = hashvectf + 3 * hash[b21 + b00];
- n += i * (h[0] * ox + h[1] * oy + h[2] * jz);
- /* 2 */
- i = (cn1 * cn5 * cn3);
- h = hashvectf + 3 * hash[b20 + b01];
- n += i * (h[0] * ox + h[1] * jy + h[2] * oz);
- /* 3 */
- i = (cn1 * cn5 * cn6);
- h = hashvectf + 3 * hash[b21 + b01];
- n += i * (h[0] * ox + h[1] * jy + h[2] * jz);
- /* 4 */
- i = cn4 * cn2 * cn3;
- h = hashvectf + 3 * hash[b20 + b10];
- n += i * (h[0] * jx + h[1] * oy + h[2] * oz);
- /* 5 */
- i = cn4 * cn2 * cn6;
- h = hashvectf + 3 * hash[b21 + b10];
- n += i * (h[0] * jx + h[1] * oy + h[2] * jz);
- /* 6 */
- i = cn4 * cn5 * cn3;
- h = hashvectf + 3 * hash[b20 + b11];
- n += i * (h[0] * jx + h[1] * jy + h[2] * oz);
- /* 7 */
- i = (cn4 * cn5 * cn6);
- h = hashvectf + 3 * hash[b21 + b11];
- n += i * (h[0] * jx + h[1] * jy + h[2] * jz);
-
- if (n < 0.0f) { n = 0.0f; }
- else if (n > 1.0f) { n = 1.0f; }
- return n;
+ register float cn1, cn2, cn3, cn4, cn5, cn6, i;
+ register const float *h;
+ float fx, fy, fz, ox, oy, oz, jx, jy, jz;
+ float n = 0.5;
+ int ix, iy, iz, b00, b01, b10, b11, b20, b21;
+
+ fx = floor(x);
+ fy = floor(y);
+ fz = floor(z);
+
+ ox = x - fx;
+ oy = y - fy;
+ oz = z - fz;
+
+ ix = (int)fx;
+ iy = (int)fy;
+ iz = (int)fz;
+
+ jx = ox - 1;
+ jy = oy - 1;
+ jz = oz - 1;
+
+ cn1 = ox * ox;
+ cn2 = oy * oy;
+ cn3 = oz * oz;
+ cn4 = jx * jx;
+ cn5 = jy * jy;
+ cn6 = jz * jz;
+
+ cn1 = 1.0f - 3.0f * cn1 + 2.0f * cn1 * ox;
+ cn2 = 1.0f - 3.0f * cn2 + 2.0f * cn2 * oy;
+ cn3 = 1.0f - 3.0f * cn3 + 2.0f * cn3 * oz;
+ cn4 = 1.0f - 3.0f * cn4 - 2.0f * cn4 * jx;
+ cn5 = 1.0f - 3.0f * cn5 - 2.0f * cn5 * jy;
+ cn6 = 1.0f - 3.0f * cn6 - 2.0f * cn6 * jz;
+
+ b00 = hash[hash[ix & 255] + (iy & 255)];
+ b10 = hash[hash[(ix + 1) & 255] + (iy & 255)];
+ b01 = hash[hash[ix & 255] + ((iy + 1) & 255)];
+ b11 = hash[hash[(ix + 1) & 255] + ((iy + 1) & 255)];
+
+ b20 = iz & 255;
+ b21 = (iz + 1) & 255;
+
+ /* 0 */
+ i = (cn1 * cn2 * cn3);
+ h = hashvectf + 3 * hash[b20 + b00];
+ n += i * (h[0] * ox + h[1] * oy + h[2] * oz);
+ /* 1 */
+ i = (cn1 * cn2 * cn6);
+ h = hashvectf + 3 * hash[b21 + b00];
+ n += i * (h[0] * ox + h[1] * oy + h[2] * jz);
+ /* 2 */
+ i = (cn1 * cn5 * cn3);
+ h = hashvectf + 3 * hash[b20 + b01];
+ n += i * (h[0] * ox + h[1] * jy + h[2] * oz);
+ /* 3 */
+ i = (cn1 * cn5 * cn6);
+ h = hashvectf + 3 * hash[b21 + b01];
+ n += i * (h[0] * ox + h[1] * jy + h[2] * jz);
+ /* 4 */
+ i = cn4 * cn2 * cn3;
+ h = hashvectf + 3 * hash[b20 + b10];
+ n += i * (h[0] * jx + h[1] * oy + h[2] * oz);
+ /* 5 */
+ i = cn4 * cn2 * cn6;
+ h = hashvectf + 3 * hash[b21 + b10];
+ n += i * (h[0] * jx + h[1] * oy + h[2] * jz);
+ /* 6 */
+ i = cn4 * cn5 * cn3;
+ h = hashvectf + 3 * hash[b20 + b11];
+ n += i * (h[0] * jx + h[1] * jy + h[2] * oz);
+ /* 7 */
+ i = (cn4 * cn5 * cn6);
+ h = hashvectf + 3 * hash[b21 + b11];
+ n += i * (h[0] * jx + h[1] * jy + h[2] * jz);
+
+ if (n < 0.0f) {
+ n = 0.0f;
+ }
+ else if (n > 1.0f) {
+ n = 1.0f;
+ }
+ return n;
}
/* as orgBlenderNoise(), returning signed noise */
static float orgBlenderNoiseS(float x, float y, float z)
{
- return (2.0f * orgBlenderNoise(x, y, z) - 1.0f);
+ return (2.0f * orgBlenderNoise(x, y, z) - 1.0f);
}
/* separated from orgBlenderNoise above, with scaling */
float BLI_hnoise(float noisesize, float x, float y, float z)
{
- if (noisesize == 0.0f) {
- return 0.0f;
- }
- x = (1.0f + x) / noisesize;
- y = (1.0f + y) / noisesize;
- z = (1.0f + z) / noisesize;
- return orgBlenderNoise(x, y, z);
+ if (noisesize == 0.0f) {
+ return 0.0f;
+ }
+ x = (1.0f + x) / noisesize;
+ y = (1.0f + y) / noisesize;
+ z = (1.0f + z) / noisesize;
+ return orgBlenderNoise(x, y, z);
}
-
/* original turbulence functions */
float BLI_turbulence(float noisesize, float x, float y, float z, int nr)
{
- float s, d = 0.5, div = 1.0;
+ float s, d = 0.5, div = 1.0;
- s = BLI_hnoise(noisesize, x, y, z);
+ s = BLI_hnoise(noisesize, x, y, z);
- while (nr > 0) {
+ while (nr > 0) {
- s += d * BLI_hnoise(noisesize * d, x, y, z);
- div += d;
- d *= 0.5f;
+ s += d * BLI_hnoise(noisesize * d, x, y, z);
+ div += d;
+ d *= 0.5f;
- nr--;
- }
- return s / div;
+ nr--;
+ }
+ return s / div;
}
float BLI_turbulence1(float noisesize, float x, float y, float z, int nr)
{
- float s, d = 0.5, div = 1.0;
+ float s, d = 0.5, div = 1.0;
- s = fabsf((-1.0f + 2.0f * BLI_hnoise(noisesize, x, y, z)));
+ s = fabsf((-1.0f + 2.0f * BLI_hnoise(noisesize, x, y, z)));
- while (nr > 0) {
+ while (nr > 0) {
- s += fabsf(d * (-1.0f + 2.0f * BLI_hnoise(noisesize * d, x, y, z)));
- div += d;
- d *= 0.5f;
+ s += fabsf(d * (-1.0f + 2.0f * BLI_hnoise(noisesize * d, x, y, z)));
+ div += d;
+ d *= 0.5f;
- nr--;
- }
- return s / div;
+ nr--;
+ }
+ return s / div;
}
/* ********************* FROM PERLIN HIMSELF: ******************** */
static const char g_perlin_data_ub[512 + 2] = {
- 0xA2, 0xA0, 0x19, 0x3B, 0xF8, 0xEB, 0xAA, 0xEE, 0xF3, 0x1C, 0x67, 0x28,
- 0x1D, 0xED, 0x0, 0xDE, 0x95, 0x2E, 0xDC, 0x3F, 0x3A, 0x82, 0x35, 0x4D,
- 0x6C, 0xBA, 0x36, 0xD0, 0xF6, 0xC, 0x79, 0x32, 0xD1, 0x59, 0xF4, 0x8,
- 0x8B, 0x63, 0x89, 0x2F, 0xB8, 0xB4, 0x97, 0x83, 0xF2, 0x8F, 0x18, 0xC7,
- 0x51, 0x14, 0x65, 0x87, 0x48, 0x20, 0x42, 0xA8, 0x80, 0xB5, 0x40, 0x13,
- 0xB2, 0x22, 0x7E, 0x57, 0xBC, 0x7F, 0x6B, 0x9D, 0x86, 0x4C, 0xC8, 0xDB,
- 0x7C, 0xD5, 0x25, 0x4E, 0x5A, 0x55, 0x74, 0x50, 0xCD, 0xB3, 0x7A, 0xBB,
- 0xC3, 0xCB, 0xB6, 0xE2, 0xE4, 0xEC, 0xFD, 0x98, 0xB, 0x96, 0xD3, 0x9E,
- 0x5C, 0xA1, 0x64, 0xF1, 0x81, 0x61, 0xE1, 0xC4, 0x24, 0x72, 0x49, 0x8C,
- 0x90, 0x4B, 0x84, 0x34, 0x38, 0xAB, 0x78, 0xCA, 0x1F, 0x1, 0xD7, 0x93,
- 0x11, 0xC1, 0x58, 0xA9, 0x31, 0xF9, 0x44, 0x6D, 0xBF, 0x33, 0x9C, 0x5F,
- 0x9, 0x94, 0xA3, 0x85, 0x6, 0xC6, 0x9A, 0x1E, 0x7B, 0x46, 0x15, 0x30,
- 0x27, 0x2B, 0x1B, 0x71, 0x3C, 0x5B, 0xD6, 0x6F, 0x62, 0xAC, 0x4F, 0xC2,
- 0xC0, 0xE, 0xB1, 0x23, 0xA7, 0xDF, 0x47, 0xB0, 0x77, 0x69, 0x5, 0xE9,
- 0xE6, 0xE7, 0x76, 0x73, 0xF, 0xFE, 0x6E, 0x9B, 0x56, 0xEF, 0x12, 0xA5,
- 0x37, 0xFC, 0xAE, 0xD9, 0x3, 0x8E, 0xDD, 0x10, 0xB9, 0xCE, 0xC9, 0x8D,
- 0xDA, 0x2A, 0xBD, 0x68, 0x17, 0x9F, 0xBE, 0xD4, 0xA, 0xCC, 0xD2, 0xE8,
- 0x43, 0x3D, 0x70, 0xB7, 0x2, 0x7D, 0x99, 0xD8, 0xD, 0x60, 0x8A, 0x4,
- 0x2C, 0x3E, 0x92, 0xE5, 0xAF, 0x53, 0x7, 0xE0, 0x29, 0xA6, 0xC5, 0xE3,
- 0xF5, 0xF7, 0x4A, 0x41, 0x26, 0x6A, 0x16, 0x5E, 0x52, 0x2D, 0x21, 0xAD,
- 0xF0, 0x91, 0xFF, 0xEA, 0x54, 0xFA, 0x66, 0x1A, 0x45, 0x39, 0xCF, 0x75,
- 0xA4, 0x88, 0xFB, 0x5D, 0xA2, 0xA0, 0x19, 0x3B, 0xF8, 0xEB, 0xAA, 0xEE,
- 0xF3, 0x1C, 0x67, 0x28, 0x1D, 0xED, 0x0, 0xDE, 0x95, 0x2E, 0xDC, 0x3F,
- 0x3A, 0x82, 0x35, 0x4D, 0x6C, 0xBA, 0x36, 0xD0, 0xF6, 0xC, 0x79, 0x32,
- 0xD1, 0x59, 0xF4, 0x8, 0x8B, 0x63, 0x89, 0x2F, 0xB8, 0xB4, 0x97, 0x83,
- 0xF2, 0x8F, 0x18, 0xC7, 0x51, 0x14, 0x65, 0x87, 0x48, 0x20, 0x42, 0xA8,
- 0x80, 0xB5, 0x40, 0x13, 0xB2, 0x22, 0x7E, 0x57, 0xBC, 0x7F, 0x6B, 0x9D,
- 0x86, 0x4C, 0xC8, 0xDB, 0x7C, 0xD5, 0x25, 0x4E, 0x5A, 0x55, 0x74, 0x50,
- 0xCD, 0xB3, 0x7A, 0xBB, 0xC3, 0xCB, 0xB6, 0xE2, 0xE4, 0xEC, 0xFD, 0x98,
- 0xB, 0x96, 0xD3, 0x9E, 0x5C, 0xA1, 0x64, 0xF1, 0x81, 0x61, 0xE1, 0xC4,
- 0x24, 0x72, 0x49, 0x8C, 0x90, 0x4B, 0x84, 0x34, 0x38, 0xAB, 0x78, 0xCA,
- 0x1F, 0x1, 0xD7, 0x93, 0x11, 0xC1, 0x58, 0xA9, 0x31, 0xF9, 0x44, 0x6D,
- 0xBF, 0x33, 0x9C, 0x5F, 0x9, 0x94, 0xA3, 0x85, 0x6, 0xC6, 0x9A, 0x1E,
- 0x7B, 0x46, 0x15, 0x30, 0x27, 0x2B, 0x1B, 0x71, 0x3C, 0x5B, 0xD6, 0x6F,
- 0x62, 0xAC, 0x4F, 0xC2, 0xC0, 0xE, 0xB1, 0x23, 0xA7, 0xDF, 0x47, 0xB0,
- 0x77, 0x69, 0x5, 0xE9, 0xE6, 0xE7, 0x76, 0x73, 0xF, 0xFE, 0x6E, 0x9B,
- 0x56, 0xEF, 0x12, 0xA5, 0x37, 0xFC, 0xAE, 0xD9, 0x3, 0x8E, 0xDD, 0x10,
- 0xB9, 0xCE, 0xC9, 0x8D, 0xDA, 0x2A, 0xBD, 0x68, 0x17, 0x9F, 0xBE, 0xD4,
- 0xA, 0xCC, 0xD2, 0xE8, 0x43, 0x3D, 0x70, 0xB7, 0x2, 0x7D, 0x99, 0xD8,
- 0xD, 0x60, 0x8A, 0x4, 0x2C, 0x3E, 0x92, 0xE5, 0xAF, 0x53, 0x7, 0xE0,
- 0x29, 0xA6, 0xC5, 0xE3, 0xF5, 0xF7, 0x4A, 0x41, 0x26, 0x6A, 0x16, 0x5E,
- 0x52, 0x2D, 0x21, 0xAD, 0xF0, 0x91, 0xFF, 0xEA, 0x54, 0xFA, 0x66, 0x1A,
- 0x45, 0x39, 0xCF, 0x75, 0xA4, 0x88, 0xFB, 0x5D, 0xA2, 0xA0,
+ 0xA2, 0xA0, 0x19, 0x3B, 0xF8, 0xEB, 0xAA, 0xEE, 0xF3, 0x1C, 0x67, 0x28, 0x1D, 0xED, 0x0, 0xDE,
+ 0x95, 0x2E, 0xDC, 0x3F, 0x3A, 0x82, 0x35, 0x4D, 0x6C, 0xBA, 0x36, 0xD0, 0xF6, 0xC, 0x79, 0x32,
+ 0xD1, 0x59, 0xF4, 0x8, 0x8B, 0x63, 0x89, 0x2F, 0xB8, 0xB4, 0x97, 0x83, 0xF2, 0x8F, 0x18, 0xC7,
+ 0x51, 0x14, 0x65, 0x87, 0x48, 0x20, 0x42, 0xA8, 0x80, 0xB5, 0x40, 0x13, 0xB2, 0x22, 0x7E, 0x57,
+ 0xBC, 0x7F, 0x6B, 0x9D, 0x86, 0x4C, 0xC8, 0xDB, 0x7C, 0xD5, 0x25, 0x4E, 0x5A, 0x55, 0x74, 0x50,
+ 0xCD, 0xB3, 0x7A, 0xBB, 0xC3, 0xCB, 0xB6, 0xE2, 0xE4, 0xEC, 0xFD, 0x98, 0xB, 0x96, 0xD3, 0x9E,
+ 0x5C, 0xA1, 0x64, 0xF1, 0x81, 0x61, 0xE1, 0xC4, 0x24, 0x72, 0x49, 0x8C, 0x90, 0x4B, 0x84, 0x34,
+ 0x38, 0xAB, 0x78, 0xCA, 0x1F, 0x1, 0xD7, 0x93, 0x11, 0xC1, 0x58, 0xA9, 0x31, 0xF9, 0x44, 0x6D,
+ 0xBF, 0x33, 0x9C, 0x5F, 0x9, 0x94, 0xA3, 0x85, 0x6, 0xC6, 0x9A, 0x1E, 0x7B, 0x46, 0x15, 0x30,
+ 0x27, 0x2B, 0x1B, 0x71, 0x3C, 0x5B, 0xD6, 0x6F, 0x62, 0xAC, 0x4F, 0xC2, 0xC0, 0xE, 0xB1, 0x23,
+ 0xA7, 0xDF, 0x47, 0xB0, 0x77, 0x69, 0x5, 0xE9, 0xE6, 0xE7, 0x76, 0x73, 0xF, 0xFE, 0x6E, 0x9B,
+ 0x56, 0xEF, 0x12, 0xA5, 0x37, 0xFC, 0xAE, 0xD9, 0x3, 0x8E, 0xDD, 0x10, 0xB9, 0xCE, 0xC9, 0x8D,
+ 0xDA, 0x2A, 0xBD, 0x68, 0x17, 0x9F, 0xBE, 0xD4, 0xA, 0xCC, 0xD2, 0xE8, 0x43, 0x3D, 0x70, 0xB7,
+ 0x2, 0x7D, 0x99, 0xD8, 0xD, 0x60, 0x8A, 0x4, 0x2C, 0x3E, 0x92, 0xE5, 0xAF, 0x53, 0x7, 0xE0,
+ 0x29, 0xA6, 0xC5, 0xE3, 0xF5, 0xF7, 0x4A, 0x41, 0x26, 0x6A, 0x16, 0x5E, 0x52, 0x2D, 0x21, 0xAD,
+ 0xF0, 0x91, 0xFF, 0xEA, 0x54, 0xFA, 0x66, 0x1A, 0x45, 0x39, 0xCF, 0x75, 0xA4, 0x88, 0xFB, 0x5D,
+ 0xA2, 0xA0, 0x19, 0x3B, 0xF8, 0xEB, 0xAA, 0xEE, 0xF3, 0x1C, 0x67, 0x28, 0x1D, 0xED, 0x0, 0xDE,
+ 0x95, 0x2E, 0xDC, 0x3F, 0x3A, 0x82, 0x35, 0x4D, 0x6C, 0xBA, 0x36, 0xD0, 0xF6, 0xC, 0x79, 0x32,
+ 0xD1, 0x59, 0xF4, 0x8, 0x8B, 0x63, 0x89, 0x2F, 0xB8, 0xB4, 0x97, 0x83, 0xF2, 0x8F, 0x18, 0xC7,
+ 0x51, 0x14, 0x65, 0x87, 0x48, 0x20, 0x42, 0xA8, 0x80, 0xB5, 0x40, 0x13, 0xB2, 0x22, 0x7E, 0x57,
+ 0xBC, 0x7F, 0x6B, 0x9D, 0x86, 0x4C, 0xC8, 0xDB, 0x7C, 0xD5, 0x25, 0x4E, 0x5A, 0x55, 0x74, 0x50,
+ 0xCD, 0xB3, 0x7A, 0xBB, 0xC3, 0xCB, 0xB6, 0xE2, 0xE4, 0xEC, 0xFD, 0x98, 0xB, 0x96, 0xD3, 0x9E,
+ 0x5C, 0xA1, 0x64, 0xF1, 0x81, 0x61, 0xE1, 0xC4, 0x24, 0x72, 0x49, 0x8C, 0x90, 0x4B, 0x84, 0x34,
+ 0x38, 0xAB, 0x78, 0xCA, 0x1F, 0x1, 0xD7, 0x93, 0x11, 0xC1, 0x58, 0xA9, 0x31, 0xF9, 0x44, 0x6D,
+ 0xBF, 0x33, 0x9C, 0x5F, 0x9, 0x94, 0xA3, 0x85, 0x6, 0xC6, 0x9A, 0x1E, 0x7B, 0x46, 0x15, 0x30,
+ 0x27, 0x2B, 0x1B, 0x71, 0x3C, 0x5B, 0xD6, 0x6F, 0x62, 0xAC, 0x4F, 0xC2, 0xC0, 0xE, 0xB1, 0x23,
+ 0xA7, 0xDF, 0x47, 0xB0, 0x77, 0x69, 0x5, 0xE9, 0xE6, 0xE7, 0x76, 0x73, 0xF, 0xFE, 0x6E, 0x9B,
+ 0x56, 0xEF, 0x12, 0xA5, 0x37, 0xFC, 0xAE, 0xD9, 0x3, 0x8E, 0xDD, 0x10, 0xB9, 0xCE, 0xC9, 0x8D,
+ 0xDA, 0x2A, 0xBD, 0x68, 0x17, 0x9F, 0xBE, 0xD4, 0xA, 0xCC, 0xD2, 0xE8, 0x43, 0x3D, 0x70, 0xB7,
+ 0x2, 0x7D, 0x99, 0xD8, 0xD, 0x60, 0x8A, 0x4, 0x2C, 0x3E, 0x92, 0xE5, 0xAF, 0x53, 0x7, 0xE0,
+ 0x29, 0xA6, 0xC5, 0xE3, 0xF5, 0xF7, 0x4A, 0x41, 0x26, 0x6A, 0x16, 0x5E, 0x52, 0x2D, 0x21, 0xAD,
+ 0xF0, 0x91, 0xFF, 0xEA, 0x54, 0xFA, 0x66, 0x1A, 0x45, 0x39, 0xCF, 0x75, 0xA4, 0x88, 0xFB, 0x5D,
+ 0xA2, 0xA0,
};
-
static const float g_perlin_data_v3[512 + 2][3] = {
- {0.33783, 0.715698, -0.611206},
- {-0.944031, -0.326599, -0.045624},
- {-0.101074, -0.416443, -0.903503},
- {0.799286, 0.49411, -0.341949},
- {-0.854645, 0.518036, 0.033936},
- {0.42514, -0.437866, -0.792114},
- {-0.358948, 0.597046, 0.717377},
- {-0.985413, 0.144714, 0.089294},
- {-0.601776, -0.33728, -0.723907},
- {-0.449921, 0.594513, 0.666382},
- {0.208313, -0.10791, 0.972076},
- {0.575317, 0.060425, 0.815643},
- {0.293365, -0.875702, -0.383453},
- {0.293762, 0.465759, 0.834686},
- {-0.846008, -0.233398, -0.47934},
- {-0.115814, 0.143036, -0.98291},
- {0.204681, -0.949036, -0.239532},
- {0.946716, -0.263947, 0.184326},
- {-0.235596, 0.573822, 0.784332},
- {0.203705, -0.372253, -0.905487},
- {0.756989, -0.651031, 0.055298},
- {0.497803, 0.814697, -0.297363},
- {-0.16214, 0.063995, -0.98468},
- {-0.329254, 0.834381, 0.441925},
- {0.703827, -0.527039, -0.476227},
- {0.956421, 0.266113, 0.119781},
- {0.480133, 0.482849, 0.7323},
- {-0.18631, 0.961212, -0.203125},
- {-0.748474, -0.656921, -0.090393},
- {-0.085052, -0.165253, 0.982544},
- {-0.76947, 0.628174, -0.115234},
- {0.383148, 0.537659, 0.751068},
- {0.616486, -0.668488, -0.415924},
- {-0.259979, -0.630005, 0.73175},
- {0.570953, -0.087952, 0.816223},
- {-0.458008, 0.023254, 0.888611},
- {-0.196167, 0.976563, -0.088287},
- {-0.263885, -0.69812, -0.665527},
- {0.437134, -0.892273, -0.112793},
- {-0.621674, -0.230438, 0.748566},
- {0.232422, 0.900574, -0.367249},
- {0.22229, -0.796143, 0.562744},
- {-0.665497, -0.73764, 0.11377},
- {0.670135, 0.704803, 0.232605},
- {0.895599, 0.429749, -0.114655},
- {-0.11557, -0.474243, 0.872742},
- {0.621826, 0.604004, -0.498444},
- {-0.832214, 0.012756, 0.55426},
- {-0.702484, 0.705994, -0.089661},
- {-0.692017, 0.649292, 0.315399},
- {-0.175995, -0.977997, 0.111877},
- {0.096954, -0.04953, 0.994019},
- {0.635284, -0.606689, -0.477783},
- {-0.261261, -0.607422, -0.750153},
- {0.983276, 0.165436, 0.075958},
- {-0.29837, 0.404083, -0.864655},
- {-0.638672, 0.507721, 0.578156},
- {0.388214, 0.412079, 0.824249},
- {0.556183, -0.208832, 0.804352},
- {0.778442, 0.562012, 0.27951},
- {-0.616577, 0.781921, -0.091522},
- {0.196289, 0.051056, 0.979187},
- {-0.121216, 0.207153, -0.970734},
- {-0.173401, -0.384735, 0.906555},
- {0.161499, -0.723236, -0.671387},
- {0.178497, -0.006226, -0.983887},
- {-0.126038, 0.15799, 0.97934},
- {0.830475, -0.024811, 0.556458},
- {-0.510132, -0.76944, 0.384247},
- {0.81424, 0.200104, -0.544891},
- {-0.112549, -0.393311, -0.912445},
- {0.56189, 0.152222, -0.813049},
- {0.198914, -0.254517, -0.946381},
- {-0.41217, 0.690979, -0.593811},
- {-0.407257, 0.324524, 0.853668},
- {-0.690186, 0.366119, -0.624115},
- {-0.428345, 0.844147, -0.322296},
- {-0.21228, -0.297546, -0.930756},
- {-0.273071, 0.516113, 0.811798},
- {0.928314, 0.371643, 0.007233},
- {0.785828, -0.479218, -0.390778},
- {-0.704895, 0.058929, 0.706818},
- {0.173248, 0.203583, 0.963562},
- {0.422211, -0.904297, -0.062469},
- {-0.363312, -0.182465, 0.913605},
- {0.254028, -0.552307, -0.793945},
- {-0.28891, -0.765747, -0.574554},
- {0.058319, 0.291382, 0.954803},
- {0.946136, -0.303925, 0.111267},
- {-0.078156, 0.443695, -0.892731},
- {0.182098, 0.89389, 0.409515},
- {-0.680298, -0.213318, 0.701141},
- {0.062469, 0.848389, -0.525635},
- {-0.72879, -0.641846, 0.238342},
- {-0.88089, 0.427673, 0.202637},
- {-0.532501, -0.21405, 0.818878},
- {0.948975, -0.305084, 0.07962},
- {0.925446, 0.374664, 0.055817},
- {0.820923, 0.565491, 0.079102},
- {0.25882, 0.099792, -0.960724},
- {-0.294617, 0.910522, 0.289978},
- {0.137115, 0.320038, -0.937408},
- {-0.908386, 0.345276, -0.235718},
- {-0.936218, 0.138763, 0.322754},
- {0.366577, 0.925934, -0.090637},
- {0.309296, -0.686829, -0.657684},
- {0.66983, 0.024445, 0.742065},
- {-0.917999, -0.059113, -0.392059},
- {0.365509, 0.462158, -0.807922},
- {0.083374, 0.996399, -0.014801},
- {0.593842, 0.253143, -0.763672},
- {0.974976, -0.165466, 0.148285},
- {0.918976, 0.137299, 0.369537},
- {0.294952, 0.694977, 0.655731},
- {0.943085, 0.152618, -0.295319},
- {0.58783, -0.598236, 0.544495},
- {0.203796, 0.678223, 0.705994},
- {-0.478821, -0.661011, 0.577667},
- {0.719055, -0.1698, -0.673828},
- {-0.132172, -0.965332, 0.225006},
- {-0.981873, -0.14502, 0.121979},
- {0.763458, 0.579742, 0.284546},
- {-0.893188, 0.079681, 0.442474},
- {-0.795776, -0.523804, 0.303802},
- {0.734955, 0.67804, -0.007446},
- {0.15506, 0.986267, -0.056183},
- {0.258026, 0.571503, -0.778931},
- {-0.681549, -0.702087, -0.206116},
- {-0.96286, -0.177185, 0.203613},
- {-0.470978, -0.515106, 0.716095},
- {-0.740326, 0.57135, 0.354095},
- {-0.56012, -0.824982, -0.074982},
- {-0.507874, 0.753204, 0.417969},
- {-0.503113, 0.038147, 0.863342},
- {0.594025, 0.673553, -0.439758},
- {-0.119873, -0.005524, -0.992737},
- {0.098267, -0.213776, 0.971893},
- {-0.615631, 0.643951, 0.454163},
- {0.896851, -0.441071, 0.032166},
- {-0.555023, 0.750763, -0.358093},
- {0.398773, 0.304688, 0.864929},
- {-0.722961, 0.303589, 0.620544},
- {-0.63559, -0.621948, -0.457306},
- {-0.293243, 0.072327, 0.953278},
- {-0.491638, 0.661041, -0.566772},
- {-0.304199, -0.572083, -0.761688},
- {0.908081, -0.398956, 0.127014},
- {-0.523621, -0.549683, -0.650848},
- {-0.932922, -0.19986, 0.299408},
- {0.099426, 0.140869, 0.984985},
- {-0.020325, -0.999756, -0.002319},
- {0.952667, 0.280853, -0.11615},
- {-0.971893, 0.082581, 0.220337},
- {0.65921, 0.705292, -0.260651},
- {0.733063, -0.175537, 0.657043},
- {-0.555206, 0.429504, -0.712189},
- {0.400421, -0.89859, 0.179352},
- {0.750885, -0.19696, 0.630341},
- {0.785675, -0.569336, 0.241821},
- {-0.058899, -0.464111, 0.883789},
- {0.129608, -0.94519, 0.299622},
- {-0.357819, 0.907654, 0.219238},
- {-0.842133, -0.439117, -0.312927},
- {-0.313477, 0.84433, 0.434479},
- {-0.241211, 0.053253, 0.968994},
- {0.063873, 0.823273, 0.563965},
- {0.476288, 0.862152, -0.172516},
- {0.620941, -0.298126, 0.724915},
- {0.25238, -0.749359, -0.612122},
- {-0.577545, 0.386566, 0.718994},
- {-0.406342, -0.737976, 0.538696},
- {0.04718, 0.556305, 0.82959},
- {-0.802856, 0.587463, 0.101166},
- {-0.707733, -0.705963, 0.026428},
- {0.374908, 0.68457, 0.625092},
- {0.472137, 0.208405, -0.856506},
- {-0.703064, -0.581085, -0.409821},
- {-0.417206, -0.736328, 0.532623},
- {-0.447876, -0.20285, -0.870728},
- {0.086945, -0.990417, 0.107086},
- {0.183685, 0.018341, -0.982788},
- {0.560638, -0.428864, 0.708282},
- {0.296722, -0.952576, -0.0672},
- {0.135773, 0.990265, 0.030243},
- {-0.068787, 0.654724, 0.752686},
- {0.762604, -0.551758, 0.337585},
- {-0.819611, -0.407684, 0.402466},
- {-0.727844, -0.55072, -0.408539},
- {-0.855774, -0.480011, 0.19281},
- {0.693176, -0.079285, 0.716339},
- {0.226013, 0.650116, -0.725433},
- {0.246704, 0.953369, -0.173553},
- {-0.970398, -0.239227, -0.03244},
- {0.136383, -0.394318, 0.908752},
- {0.813232, 0.558167, 0.164368},
- {0.40451, 0.549042, -0.731323},
- {-0.380249, -0.566711, 0.730865},
- {0.022156, 0.932739, 0.359741},
- {0.00824, 0.996552, -0.082306},
- {0.956635, -0.065338, -0.283722},
- {-0.743561, 0.008209, 0.668579},
- {-0.859589, -0.509674, 0.035767},
- {-0.852234, 0.363678, -0.375977},
- {-0.201965, -0.970795, -0.12915},
- {0.313477, 0.947327, 0.06546},
- {-0.254028, -0.528259, 0.81015},
- {0.628052, 0.601105, 0.49411},
- {-0.494385, 0.868378, 0.037933},
- {0.275635, -0.086426, 0.957336},
- {-0.197937, 0.468903, -0.860748},
- {0.895599, 0.399384, 0.195801},
- {0.560791, 0.825012, -0.069214},
- {0.304199, -0.849487, 0.43103},
- {0.096375, 0.93576, 0.339111},
- {-0.051422, 0.408966, -0.911072},
- {0.330444, 0.942841, -0.042389},
- {-0.452362, -0.786407, 0.420563},
- {0.134308, -0.933472, -0.332489},
- {0.80191, -0.566711, -0.188934},
- {-0.987946, -0.105988, 0.112518},
- {-0.24408, 0.892242, -0.379791},
- {-0.920502, 0.229095, -0.316376},
- {0.7789, 0.325958, 0.535706},
- {-0.912872, 0.185211, -0.36377},
- {-0.184784, 0.565369, -0.803833},
- {-0.018463, 0.119537, 0.992615},
- {-0.259247, -0.935608, 0.239532},
- {-0.82373, -0.449127, -0.345947},
- {-0.433105, 0.659515, 0.614349},
- {-0.822754, 0.378845, -0.423676},
- {0.687195, -0.674835, -0.26889},
- {-0.246582, -0.800842, 0.545715},
- {-0.729187, -0.207794, 0.651978},
- {0.653534, -0.610443, -0.447388},
- {0.492584, -0.023346, 0.869934},
- {0.609039, 0.009094, -0.79306},
- {0.962494, -0.271088, -0.00885},
- {0.2659, -0.004913, 0.963959},
- {0.651245, 0.553619, -0.518951},
- {0.280548, -0.84314, 0.458618},
- {-0.175293, -0.983215, 0.049805},
- {0.035339, -0.979919, 0.196045},
- {-0.982941, 0.164307, -0.082245},
- {0.233734, -0.97226, -0.005005},
- {-0.747253, -0.611328, 0.260437},
- {0.645599, 0.592773, 0.481384},
- {0.117706, -0.949524, -0.29068},
- {-0.535004, -0.791901, -0.294312},
- {-0.627167, -0.214447, 0.748718},
- {-0.047974, -0.813477, -0.57959},
- {-0.175537, 0.477264, -0.860992},
- {0.738556, -0.414246, -0.53183},
- {0.562561, -0.704071, 0.433289},
- {-0.754944, 0.64801, -0.100586},
- {0.114716, 0.044525, -0.992371},
- {0.966003, 0.244873, -0.082764},
- {0.33783, 0.715698, -0.611206},
- {-0.944031, -0.326599, -0.045624},
- {-0.101074, -0.416443, -0.903503},
- {0.799286, 0.49411, -0.341949},
- {-0.854645, 0.518036, 0.033936},
- {0.42514, -0.437866, -0.792114},
- {-0.358948, 0.597046, 0.717377},
- {-0.985413, 0.144714, 0.089294},
- {-0.601776, -0.33728, -0.723907},
- {-0.449921, 0.594513, 0.666382},
- {0.208313, -0.10791, 0.972076},
- {0.575317, 0.060425, 0.815643},
- {0.293365, -0.875702, -0.383453},
- {0.293762, 0.465759, 0.834686},
- {-0.846008, -0.233398, -0.47934},
- {-0.115814, 0.143036, -0.98291},
- {0.204681, -0.949036, -0.239532},
- {0.946716, -0.263947, 0.184326},
- {-0.235596, 0.573822, 0.784332},
- {0.203705, -0.372253, -0.905487},
- {0.756989, -0.651031, 0.055298},
- {0.497803, 0.814697, -0.297363},
- {-0.16214, 0.063995, -0.98468},
- {-0.329254, 0.834381, 0.441925},
- {0.703827, -0.527039, -0.476227},
- {0.956421, 0.266113, 0.119781},
- {0.480133, 0.482849, 0.7323},
- {-0.18631, 0.961212, -0.203125},
- {-0.748474, -0.656921, -0.090393},
- {-0.085052, -0.165253, 0.982544},
- {-0.76947, 0.628174, -0.115234},
- {0.383148, 0.537659, 0.751068},
- {0.616486, -0.668488, -0.415924},
- {-0.259979, -0.630005, 0.73175},
- {0.570953, -0.087952, 0.816223},
- {-0.458008, 0.023254, 0.888611},
- {-0.196167, 0.976563, -0.088287},
- {-0.263885, -0.69812, -0.665527},
- {0.437134, -0.892273, -0.112793},
- {-0.621674, -0.230438, 0.748566},
- {0.232422, 0.900574, -0.367249},
- {0.22229, -0.796143, 0.562744},
- {-0.665497, -0.73764, 0.11377},
- {0.670135, 0.704803, 0.232605},
- {0.895599, 0.429749, -0.114655},
- {-0.11557, -0.474243, 0.872742},
- {0.621826, 0.604004, -0.498444},
- {-0.832214, 0.012756, 0.55426},
- {-0.702484, 0.705994, -0.089661},
- {-0.692017, 0.649292, 0.315399},
- {-0.175995, -0.977997, 0.111877},
- {0.096954, -0.04953, 0.994019},
- {0.635284, -0.606689, -0.477783},
- {-0.261261, -0.607422, -0.750153},
- {0.983276, 0.165436, 0.075958},
- {-0.29837, 0.404083, -0.864655},
- {-0.638672, 0.507721, 0.578156},
- {0.388214, 0.412079, 0.824249},
- {0.556183, -0.208832, 0.804352},
- {0.778442, 0.562012, 0.27951},
- {-0.616577, 0.781921, -0.091522},
- {0.196289, 0.051056, 0.979187},
- {-0.121216, 0.207153, -0.970734},
- {-0.173401, -0.384735, 0.906555},
- {0.161499, -0.723236, -0.671387},
- {0.178497, -0.006226, -0.983887},
- {-0.126038, 0.15799, 0.97934},
- {0.830475, -0.024811, 0.556458},
- {-0.510132, -0.76944, 0.384247},
- {0.81424, 0.200104, -0.544891},
- {-0.112549, -0.393311, -0.912445},
- {0.56189, 0.152222, -0.813049},
- {0.198914, -0.254517, -0.946381},
- {-0.41217, 0.690979, -0.593811},
- {-0.407257, 0.324524, 0.853668},
- {-0.690186, 0.366119, -0.624115},
- {-0.428345, 0.844147, -0.322296},
- {-0.21228, -0.297546, -0.930756},
- {-0.273071, 0.516113, 0.811798},
- {0.928314, 0.371643, 0.007233},
- {0.785828, -0.479218, -0.390778},
- {-0.704895, 0.058929, 0.706818},
- {0.173248, 0.203583, 0.963562},
- {0.422211, -0.904297, -0.062469},
- {-0.363312, -0.182465, 0.913605},
- {0.254028, -0.552307, -0.793945},
- {-0.28891, -0.765747, -0.574554},
- {0.058319, 0.291382, 0.954803},
- {0.946136, -0.303925, 0.111267},
- {-0.078156, 0.443695, -0.892731},
- {0.182098, 0.89389, 0.409515},
- {-0.680298, -0.213318, 0.701141},
- {0.062469, 0.848389, -0.525635},
- {-0.72879, -0.641846, 0.238342},
- {-0.88089, 0.427673, 0.202637},
- {-0.532501, -0.21405, 0.818878},
- {0.948975, -0.305084, 0.07962},
- {0.925446, 0.374664, 0.055817},
- {0.820923, 0.565491, 0.079102},
- {0.25882, 0.099792, -0.960724},
- {-0.294617, 0.910522, 0.289978},
- {0.137115, 0.320038, -0.937408},
- {-0.908386, 0.345276, -0.235718},
- {-0.936218, 0.138763, 0.322754},
- {0.366577, 0.925934, -0.090637},
- {0.309296, -0.686829, -0.657684},
- {0.66983, 0.024445, 0.742065},
- {-0.917999, -0.059113, -0.392059},
- {0.365509, 0.462158, -0.807922},
- {0.083374, 0.996399, -0.014801},
- {0.593842, 0.253143, -0.763672},
- {0.974976, -0.165466, 0.148285},
- {0.918976, 0.137299, 0.369537},
- {0.294952, 0.694977, 0.655731},
- {0.943085, 0.152618, -0.295319},
- {0.58783, -0.598236, 0.544495},
- {0.203796, 0.678223, 0.705994},
- {-0.478821, -0.661011, 0.577667},
- {0.719055, -0.1698, -0.673828},
- {-0.132172, -0.965332, 0.225006},
- {-0.981873, -0.14502, 0.121979},
- {0.763458, 0.579742, 0.284546},
- {-0.893188, 0.079681, 0.442474},
- {-0.795776, -0.523804, 0.303802},
- {0.734955, 0.67804, -0.007446},
- {0.15506, 0.986267, -0.056183},
- {0.258026, 0.571503, -0.778931},
- {-0.681549, -0.702087, -0.206116},
- {-0.96286, -0.177185, 0.203613},
- {-0.470978, -0.515106, 0.716095},
- {-0.740326, 0.57135, 0.354095},
- {-0.56012, -0.824982, -0.074982},
- {-0.507874, 0.753204, 0.417969},
- {-0.503113, 0.038147, 0.863342},
- {0.594025, 0.673553, -0.439758},
- {-0.119873, -0.005524, -0.992737},
- {0.098267, -0.213776, 0.971893},
- {-0.615631, 0.643951, 0.454163},
- {0.896851, -0.441071, 0.032166},
- {-0.555023, 0.750763, -0.358093},
- {0.398773, 0.304688, 0.864929},
- {-0.722961, 0.303589, 0.620544},
- {-0.63559, -0.621948, -0.457306},
- {-0.293243, 0.072327, 0.953278},
- {-0.491638, 0.661041, -0.566772},
- {-0.304199, -0.572083, -0.761688},
- {0.908081, -0.398956, 0.127014},
- {-0.523621, -0.549683, -0.650848},
- {-0.932922, -0.19986, 0.299408},
- {0.099426, 0.140869, 0.984985},
- {-0.020325, -0.999756, -0.002319},
- {0.952667, 0.280853, -0.11615},
- {-0.971893, 0.082581, 0.220337},
- {0.65921, 0.705292, -0.260651},
- {0.733063, -0.175537, 0.657043},
- {-0.555206, 0.429504, -0.712189},
- {0.400421, -0.89859, 0.179352},
- {0.750885, -0.19696, 0.630341},
- {0.785675, -0.569336, 0.241821},
- {-0.058899, -0.464111, 0.883789},
- {0.129608, -0.94519, 0.299622},
- {-0.357819, 0.907654, 0.219238},
- {-0.842133, -0.439117, -0.312927},
- {-0.313477, 0.84433, 0.434479},
- {-0.241211, 0.053253, 0.968994},
- {0.063873, 0.823273, 0.563965},
- {0.476288, 0.862152, -0.172516},
- {0.620941, -0.298126, 0.724915},
- {0.25238, -0.749359, -0.612122},
- {-0.577545, 0.386566, 0.718994},
- {-0.406342, -0.737976, 0.538696},
- {0.04718, 0.556305, 0.82959},
- {-0.802856, 0.587463, 0.101166},
- {-0.707733, -0.705963, 0.026428},
- {0.374908, 0.68457, 0.625092},
- {0.472137, 0.208405, -0.856506},
- {-0.703064, -0.581085, -0.409821},
- {-0.417206, -0.736328, 0.532623},
- {-0.447876, -0.20285, -0.870728},
- {0.086945, -0.990417, 0.107086},
- {0.183685, 0.018341, -0.982788},
- {0.560638, -0.428864, 0.708282},
- {0.296722, -0.952576, -0.0672},
- {0.135773, 0.990265, 0.030243},
- {-0.068787, 0.654724, 0.752686},
- {0.762604, -0.551758, 0.337585},
- {-0.819611, -0.407684, 0.402466},
- {-0.727844, -0.55072, -0.408539},
- {-0.855774, -0.480011, 0.19281},
- {0.693176, -0.079285, 0.716339},
- {0.226013, 0.650116, -0.725433},
- {0.246704, 0.953369, -0.173553},
- {-0.970398, -0.239227, -0.03244},
- {0.136383, -0.394318, 0.908752},
- {0.813232, 0.558167, 0.164368},
- {0.40451, 0.549042, -0.731323},
- {-0.380249, -0.566711, 0.730865},
- {0.022156, 0.932739, 0.359741},
- {0.00824, 0.996552, -0.082306},
- {0.956635, -0.065338, -0.283722},
- {-0.743561, 0.008209, 0.668579},
- {-0.859589, -0.509674, 0.035767},
- {-0.852234, 0.363678, -0.375977},
- {-0.201965, -0.970795, -0.12915},
- {0.313477, 0.947327, 0.06546},
- {-0.254028, -0.528259, 0.81015},
- {0.628052, 0.601105, 0.49411},
- {-0.494385, 0.868378, 0.037933},
- {0.275635, -0.086426, 0.957336},
- {-0.197937, 0.468903, -0.860748},
- {0.895599, 0.399384, 0.195801},
- {0.560791, 0.825012, -0.069214},
- {0.304199, -0.849487, 0.43103},
- {0.096375, 0.93576, 0.339111},
- {-0.051422, 0.408966, -0.911072},
- {0.330444, 0.942841, -0.042389},
- {-0.452362, -0.786407, 0.420563},
- {0.134308, -0.933472, -0.332489},
- {0.80191, -0.566711, -0.188934},
- {-0.987946, -0.105988, 0.112518},
- {-0.24408, 0.892242, -0.379791},
- {-0.920502, 0.229095, -0.316376},
- {0.7789, 0.325958, 0.535706},
- {-0.912872, 0.185211, -0.36377},
- {-0.184784, 0.565369, -0.803833},
- {-0.018463, 0.119537, 0.992615},
- {-0.259247, -0.935608, 0.239532},
- {-0.82373, -0.449127, -0.345947},
- {-0.433105, 0.659515, 0.614349},
- {-0.822754, 0.378845, -0.423676},
- {0.687195, -0.674835, -0.26889},
- {-0.246582, -0.800842, 0.545715},
- {-0.729187, -0.207794, 0.651978},
- {0.653534, -0.610443, -0.447388},
- {0.492584, -0.023346, 0.869934},
- {0.609039, 0.009094, -0.79306},
- {0.962494, -0.271088, -0.00885},
- {0.2659, -0.004913, 0.963959},
- {0.651245, 0.553619, -0.518951},
- {0.280548, -0.84314, 0.458618},
- {-0.175293, -0.983215, 0.049805},
- {0.035339, -0.979919, 0.196045},
- {-0.982941, 0.164307, -0.082245},
- {0.233734, -0.97226, -0.005005},
- {-0.747253, -0.611328, 0.260437},
- {0.645599, 0.592773, 0.481384},
- {0.117706, -0.949524, -0.29068},
- {-0.535004, -0.791901, -0.294312},
- {-0.627167, -0.214447, 0.748718},
- {-0.047974, -0.813477, -0.57959},
- {-0.175537, 0.477264, -0.860992},
- {0.738556, -0.414246, -0.53183},
- {0.562561, -0.704071, 0.433289},
- {-0.754944, 0.64801, -0.100586},
- {0.114716, 0.044525, -0.992371},
- {0.966003, 0.244873, -0.082764},
- {0.33783, 0.715698, -0.611206},
- {-0.944031, -0.326599, -0.045624},
+ {0.33783, 0.715698, -0.611206}, {-0.944031, -0.326599, -0.045624},
+ {-0.101074, -0.416443, -0.903503}, {0.799286, 0.49411, -0.341949},
+ {-0.854645, 0.518036, 0.033936}, {0.42514, -0.437866, -0.792114},
+ {-0.358948, 0.597046, 0.717377}, {-0.985413, 0.144714, 0.089294},
+ {-0.601776, -0.33728, -0.723907}, {-0.449921, 0.594513, 0.666382},
+ {0.208313, -0.10791, 0.972076}, {0.575317, 0.060425, 0.815643},
+ {0.293365, -0.875702, -0.383453}, {0.293762, 0.465759, 0.834686},
+ {-0.846008, -0.233398, -0.47934}, {-0.115814, 0.143036, -0.98291},
+ {0.204681, -0.949036, -0.239532}, {0.946716, -0.263947, 0.184326},
+ {-0.235596, 0.573822, 0.784332}, {0.203705, -0.372253, -0.905487},
+ {0.756989, -0.651031, 0.055298}, {0.497803, 0.814697, -0.297363},
+ {-0.16214, 0.063995, -0.98468}, {-0.329254, 0.834381, 0.441925},
+ {0.703827, -0.527039, -0.476227}, {0.956421, 0.266113, 0.119781},
+ {0.480133, 0.482849, 0.7323}, {-0.18631, 0.961212, -0.203125},
+ {-0.748474, -0.656921, -0.090393}, {-0.085052, -0.165253, 0.982544},
+ {-0.76947, 0.628174, -0.115234}, {0.383148, 0.537659, 0.751068},
+ {0.616486, -0.668488, -0.415924}, {-0.259979, -0.630005, 0.73175},
+ {0.570953, -0.087952, 0.816223}, {-0.458008, 0.023254, 0.888611},
+ {-0.196167, 0.976563, -0.088287}, {-0.263885, -0.69812, -0.665527},
+ {0.437134, -0.892273, -0.112793}, {-0.621674, -0.230438, 0.748566},
+ {0.232422, 0.900574, -0.367249}, {0.22229, -0.796143, 0.562744},
+ {-0.665497, -0.73764, 0.11377}, {0.670135, 0.704803, 0.232605},
+ {0.895599, 0.429749, -0.114655}, {-0.11557, -0.474243, 0.872742},
+ {0.621826, 0.604004, -0.498444}, {-0.832214, 0.012756, 0.55426},
+ {-0.702484, 0.705994, -0.089661}, {-0.692017, 0.649292, 0.315399},
+ {-0.175995, -0.977997, 0.111877}, {0.096954, -0.04953, 0.994019},
+ {0.635284, -0.606689, -0.477783}, {-0.261261, -0.607422, -0.750153},
+ {0.983276, 0.165436, 0.075958}, {-0.29837, 0.404083, -0.864655},
+ {-0.638672, 0.507721, 0.578156}, {0.388214, 0.412079, 0.824249},
+ {0.556183, -0.208832, 0.804352}, {0.778442, 0.562012, 0.27951},
+ {-0.616577, 0.781921, -0.091522}, {0.196289, 0.051056, 0.979187},
+ {-0.121216, 0.207153, -0.970734}, {-0.173401, -0.384735, 0.906555},
+ {0.161499, -0.723236, -0.671387}, {0.178497, -0.006226, -0.983887},
+ {-0.126038, 0.15799, 0.97934}, {0.830475, -0.024811, 0.556458},
+ {-0.510132, -0.76944, 0.384247}, {0.81424, 0.200104, -0.544891},
+ {-0.112549, -0.393311, -0.912445}, {0.56189, 0.152222, -0.813049},
+ {0.198914, -0.254517, -0.946381}, {-0.41217, 0.690979, -0.593811},
+ {-0.407257, 0.324524, 0.853668}, {-0.690186, 0.366119, -0.624115},
+ {-0.428345, 0.844147, -0.322296}, {-0.21228, -0.297546, -0.930756},
+ {-0.273071, 0.516113, 0.811798}, {0.928314, 0.371643, 0.007233},
+ {0.785828, -0.479218, -0.390778}, {-0.704895, 0.058929, 0.706818},
+ {0.173248, 0.203583, 0.963562}, {0.422211, -0.904297, -0.062469},
+ {-0.363312, -0.182465, 0.913605}, {0.254028, -0.552307, -0.793945},
+ {-0.28891, -0.765747, -0.574554}, {0.058319, 0.291382, 0.954803},
+ {0.946136, -0.303925, 0.111267}, {-0.078156, 0.443695, -0.892731},
+ {0.182098, 0.89389, 0.409515}, {-0.680298, -0.213318, 0.701141},
+ {0.062469, 0.848389, -0.525635}, {-0.72879, -0.641846, 0.238342},
+ {-0.88089, 0.427673, 0.202637}, {-0.532501, -0.21405, 0.818878},
+ {0.948975, -0.305084, 0.07962}, {0.925446, 0.374664, 0.055817},
+ {0.820923, 0.565491, 0.079102}, {0.25882, 0.099792, -0.960724},
+ {-0.294617, 0.910522, 0.289978}, {0.137115, 0.320038, -0.937408},
+ {-0.908386, 0.345276, -0.235718}, {-0.936218, 0.138763, 0.322754},
+ {0.366577, 0.925934, -0.090637}, {0.309296, -0.686829, -0.657684},
+ {0.66983, 0.024445, 0.742065}, {-0.917999, -0.059113, -0.392059},
+ {0.365509, 0.462158, -0.807922}, {0.083374, 0.996399, -0.014801},
+ {0.593842, 0.253143, -0.763672}, {0.974976, -0.165466, 0.148285},
+ {0.918976, 0.137299, 0.369537}, {0.294952, 0.694977, 0.655731},
+ {0.943085, 0.152618, -0.295319}, {0.58783, -0.598236, 0.544495},
+ {0.203796, 0.678223, 0.705994}, {-0.478821, -0.661011, 0.577667},
+ {0.719055, -0.1698, -0.673828}, {-0.132172, -0.965332, 0.225006},
+ {-0.981873, -0.14502, 0.121979}, {0.763458, 0.579742, 0.284546},
+ {-0.893188, 0.079681, 0.442474}, {-0.795776, -0.523804, 0.303802},
+ {0.734955, 0.67804, -0.007446}, {0.15506, 0.986267, -0.056183},
+ {0.258026, 0.571503, -0.778931}, {-0.681549, -0.702087, -0.206116},
+ {-0.96286, -0.177185, 0.203613}, {-0.470978, -0.515106, 0.716095},
+ {-0.740326, 0.57135, 0.354095}, {-0.56012, -0.824982, -0.074982},
+ {-0.507874, 0.753204, 0.417969}, {-0.503113, 0.038147, 0.863342},
+ {0.594025, 0.673553, -0.439758}, {-0.119873, -0.005524, -0.992737},
+ {0.098267, -0.213776, 0.971893}, {-0.615631, 0.643951, 0.454163},
+ {0.896851, -0.441071, 0.032166}, {-0.555023, 0.750763, -0.358093},
+ {0.398773, 0.304688, 0.864929}, {-0.722961, 0.303589, 0.620544},
+ {-0.63559, -0.621948, -0.457306}, {-0.293243, 0.072327, 0.953278},
+ {-0.491638, 0.661041, -0.566772}, {-0.304199, -0.572083, -0.761688},
+ {0.908081, -0.398956, 0.127014}, {-0.523621, -0.549683, -0.650848},
+ {-0.932922, -0.19986, 0.299408}, {0.099426, 0.140869, 0.984985},
+ {-0.020325, -0.999756, -0.002319}, {0.952667, 0.280853, -0.11615},
+ {-0.971893, 0.082581, 0.220337}, {0.65921, 0.705292, -0.260651},
+ {0.733063, -0.175537, 0.657043}, {-0.555206, 0.429504, -0.712189},
+ {0.400421, -0.89859, 0.179352}, {0.750885, -0.19696, 0.630341},
+ {0.785675, -0.569336, 0.241821}, {-0.058899, -0.464111, 0.883789},
+ {0.129608, -0.94519, 0.299622}, {-0.357819, 0.907654, 0.219238},
+ {-0.842133, -0.439117, -0.312927}, {-0.313477, 0.84433, 0.434479},
+ {-0.241211, 0.053253, 0.968994}, {0.063873, 0.823273, 0.563965},
+ {0.476288, 0.862152, -0.172516}, {0.620941, -0.298126, 0.724915},
+ {0.25238, -0.749359, -0.612122}, {-0.577545, 0.386566, 0.718994},
+ {-0.406342, -0.737976, 0.538696}, {0.04718, 0.556305, 0.82959},
+ {-0.802856, 0.587463, 0.101166}, {-0.707733, -0.705963, 0.026428},
+ {0.374908, 0.68457, 0.625092}, {0.472137, 0.208405, -0.856506},
+ {-0.703064, -0.581085, -0.409821}, {-0.417206, -0.736328, 0.532623},
+ {-0.447876, -0.20285, -0.870728}, {0.086945, -0.990417, 0.107086},
+ {0.183685, 0.018341, -0.982788}, {0.560638, -0.428864, 0.708282},
+ {0.296722, -0.952576, -0.0672}, {0.135773, 0.990265, 0.030243},
+ {-0.068787, 0.654724, 0.752686}, {0.762604, -0.551758, 0.337585},
+ {-0.819611, -0.407684, 0.402466}, {-0.727844, -0.55072, -0.408539},
+ {-0.855774, -0.480011, 0.19281}, {0.693176, -0.079285, 0.716339},
+ {0.226013, 0.650116, -0.725433}, {0.246704, 0.953369, -0.173553},
+ {-0.970398, -0.239227, -0.03244}, {0.136383, -0.394318, 0.908752},
+ {0.813232, 0.558167, 0.164368}, {0.40451, 0.549042, -0.731323},
+ {-0.380249, -0.566711, 0.730865}, {0.022156, 0.932739, 0.359741},
+ {0.00824, 0.996552, -0.082306}, {0.956635, -0.065338, -0.283722},
+ {-0.743561, 0.008209, 0.668579}, {-0.859589, -0.509674, 0.035767},
+ {-0.852234, 0.363678, -0.375977}, {-0.201965, -0.970795, -0.12915},
+ {0.313477, 0.947327, 0.06546}, {-0.254028, -0.528259, 0.81015},
+ {0.628052, 0.601105, 0.49411}, {-0.494385, 0.868378, 0.037933},
+ {0.275635, -0.086426, 0.957336}, {-0.197937, 0.468903, -0.860748},
+ {0.895599, 0.399384, 0.195801}, {0.560791, 0.825012, -0.069214},
+ {0.304199, -0.849487, 0.43103}, {0.096375, 0.93576, 0.339111},
+ {-0.051422, 0.408966, -0.911072}, {0.330444, 0.942841, -0.042389},
+ {-0.452362, -0.786407, 0.420563}, {0.134308, -0.933472, -0.332489},
+ {0.80191, -0.566711, -0.188934}, {-0.987946, -0.105988, 0.112518},
+ {-0.24408, 0.892242, -0.379791}, {-0.920502, 0.229095, -0.316376},
+ {0.7789, 0.325958, 0.535706}, {-0.912872, 0.185211, -0.36377},
+ {-0.184784, 0.565369, -0.803833}, {-0.018463, 0.119537, 0.992615},
+ {-0.259247, -0.935608, 0.239532}, {-0.82373, -0.449127, -0.345947},
+ {-0.433105, 0.659515, 0.614349}, {-0.822754, 0.378845, -0.423676},
+ {0.687195, -0.674835, -0.26889}, {-0.246582, -0.800842, 0.545715},
+ {-0.729187, -0.207794, 0.651978}, {0.653534, -0.610443, -0.447388},
+ {0.492584, -0.023346, 0.869934}, {0.609039, 0.009094, -0.79306},
+ {0.962494, -0.271088, -0.00885}, {0.2659, -0.004913, 0.963959},
+ {0.651245, 0.553619, -0.518951}, {0.280548, -0.84314, 0.458618},
+ {-0.175293, -0.983215, 0.049805}, {0.035339, -0.979919, 0.196045},
+ {-0.982941, 0.164307, -0.082245}, {0.233734, -0.97226, -0.005005},
+ {-0.747253, -0.611328, 0.260437}, {0.645599, 0.592773, 0.481384},
+ {0.117706, -0.949524, -0.29068}, {-0.535004, -0.791901, -0.294312},
+ {-0.627167, -0.214447, 0.748718}, {-0.047974, -0.813477, -0.57959},
+ {-0.175537, 0.477264, -0.860992}, {0.738556, -0.414246, -0.53183},
+ {0.562561, -0.704071, 0.433289}, {-0.754944, 0.64801, -0.100586},
+ {0.114716, 0.044525, -0.992371}, {0.966003, 0.244873, -0.082764},
+ {0.33783, 0.715698, -0.611206}, {-0.944031, -0.326599, -0.045624},
+ {-0.101074, -0.416443, -0.903503}, {0.799286, 0.49411, -0.341949},
+ {-0.854645, 0.518036, 0.033936}, {0.42514, -0.437866, -0.792114},
+ {-0.358948, 0.597046, 0.717377}, {-0.985413, 0.144714, 0.089294},
+ {-0.601776, -0.33728, -0.723907}, {-0.449921, 0.594513, 0.666382},
+ {0.208313, -0.10791, 0.972076}, {0.575317, 0.060425, 0.815643},
+ {0.293365, -0.875702, -0.383453}, {0.293762, 0.465759, 0.834686},
+ {-0.846008, -0.233398, -0.47934}, {-0.115814, 0.143036, -0.98291},
+ {0.204681, -0.949036, -0.239532}, {0.946716, -0.263947, 0.184326},
+ {-0.235596, 0.573822, 0.784332}, {0.203705, -0.372253, -0.905487},
+ {0.756989, -0.651031, 0.055298}, {0.497803, 0.814697, -0.297363},
+ {-0.16214, 0.063995, -0.98468}, {-0.329254, 0.834381, 0.441925},
+ {0.703827, -0.527039, -0.476227}, {0.956421, 0.266113, 0.119781},
+ {0.480133, 0.482849, 0.7323}, {-0.18631, 0.961212, -0.203125},
+ {-0.748474, -0.656921, -0.090393}, {-0.085052, -0.165253, 0.982544},
+ {-0.76947, 0.628174, -0.115234}, {0.383148, 0.537659, 0.751068},
+ {0.616486, -0.668488, -0.415924}, {-0.259979, -0.630005, 0.73175},
+ {0.570953, -0.087952, 0.816223}, {-0.458008, 0.023254, 0.888611},
+ {-0.196167, 0.976563, -0.088287}, {-0.263885, -0.69812, -0.665527},
+ {0.437134, -0.892273, -0.112793}, {-0.621674, -0.230438, 0.748566},
+ {0.232422, 0.900574, -0.367249}, {0.22229, -0.796143, 0.562744},
+ {-0.665497, -0.73764, 0.11377}, {0.670135, 0.704803, 0.232605},
+ {0.895599, 0.429749, -0.114655}, {-0.11557, -0.474243, 0.872742},
+ {0.621826, 0.604004, -0.498444}, {-0.832214, 0.012756, 0.55426},
+ {-0.702484, 0.705994, -0.089661}, {-0.692017, 0.649292, 0.315399},
+ {-0.175995, -0.977997, 0.111877}, {0.096954, -0.04953, 0.994019},
+ {0.635284, -0.606689, -0.477783}, {-0.261261, -0.607422, -0.750153},
+ {0.983276, 0.165436, 0.075958}, {-0.29837, 0.404083, -0.864655},
+ {-0.638672, 0.507721, 0.578156}, {0.388214, 0.412079, 0.824249},
+ {0.556183, -0.208832, 0.804352}, {0.778442, 0.562012, 0.27951},
+ {-0.616577, 0.781921, -0.091522}, {0.196289, 0.051056, 0.979187},
+ {-0.121216, 0.207153, -0.970734}, {-0.173401, -0.384735, 0.906555},
+ {0.161499, -0.723236, -0.671387}, {0.178497, -0.006226, -0.983887},
+ {-0.126038, 0.15799, 0.97934}, {0.830475, -0.024811, 0.556458},
+ {-0.510132, -0.76944, 0.384247}, {0.81424, 0.200104, -0.544891},
+ {-0.112549, -0.393311, -0.912445}, {0.56189, 0.152222, -0.813049},
+ {0.198914, -0.254517, -0.946381}, {-0.41217, 0.690979, -0.593811},
+ {-0.407257, 0.324524, 0.853668}, {-0.690186, 0.366119, -0.624115},
+ {-0.428345, 0.844147, -0.322296}, {-0.21228, -0.297546, -0.930756},
+ {-0.273071, 0.516113, 0.811798}, {0.928314, 0.371643, 0.007233},
+ {0.785828, -0.479218, -0.390778}, {-0.704895, 0.058929, 0.706818},
+ {0.173248, 0.203583, 0.963562}, {0.422211, -0.904297, -0.062469},
+ {-0.363312, -0.182465, 0.913605}, {0.254028, -0.552307, -0.793945},
+ {-0.28891, -0.765747, -0.574554}, {0.058319, 0.291382, 0.954803},
+ {0.946136, -0.303925, 0.111267}, {-0.078156, 0.443695, -0.892731},
+ {0.182098, 0.89389, 0.409515}, {-0.680298, -0.213318, 0.701141},
+ {0.062469, 0.848389, -0.525635}, {-0.72879, -0.641846, 0.238342},
+ {-0.88089, 0.427673, 0.202637}, {-0.532501, -0.21405, 0.818878},
+ {0.948975, -0.305084, 0.07962}, {0.925446, 0.374664, 0.055817},
+ {0.820923, 0.565491, 0.079102}, {0.25882, 0.099792, -0.960724},
+ {-0.294617, 0.910522, 0.289978}, {0.137115, 0.320038, -0.937408},
+ {-0.908386, 0.345276, -0.235718}, {-0.936218, 0.138763, 0.322754},
+ {0.366577, 0.925934, -0.090637}, {0.309296, -0.686829, -0.657684},
+ {0.66983, 0.024445, 0.742065}, {-0.917999, -0.059113, -0.392059},
+ {0.365509, 0.462158, -0.807922}, {0.083374, 0.996399, -0.014801},
+ {0.593842, 0.253143, -0.763672}, {0.974976, -0.165466, 0.148285},
+ {0.918976, 0.137299, 0.369537}, {0.294952, 0.694977, 0.655731},
+ {0.943085, 0.152618, -0.295319}, {0.58783, -0.598236, 0.544495},
+ {0.203796, 0.678223, 0.705994}, {-0.478821, -0.661011, 0.577667},
+ {0.719055, -0.1698, -0.673828}, {-0.132172, -0.965332, 0.225006},
+ {-0.981873, -0.14502, 0.121979}, {0.763458, 0.579742, 0.284546},
+ {-0.893188, 0.079681, 0.442474}, {-0.795776, -0.523804, 0.303802},
+ {0.734955, 0.67804, -0.007446}, {0.15506, 0.986267, -0.056183},
+ {0.258026, 0.571503, -0.778931}, {-0.681549, -0.702087, -0.206116},
+ {-0.96286, -0.177185, 0.203613}, {-0.470978, -0.515106, 0.716095},
+ {-0.740326, 0.57135, 0.354095}, {-0.56012, -0.824982, -0.074982},
+ {-0.507874, 0.753204, 0.417969}, {-0.503113, 0.038147, 0.863342},
+ {0.594025, 0.673553, -0.439758}, {-0.119873, -0.005524, -0.992737},
+ {0.098267, -0.213776, 0.971893}, {-0.615631, 0.643951, 0.454163},
+ {0.896851, -0.441071, 0.032166}, {-0.555023, 0.750763, -0.358093},
+ {0.398773, 0.304688, 0.864929}, {-0.722961, 0.303589, 0.620544},
+ {-0.63559, -0.621948, -0.457306}, {-0.293243, 0.072327, 0.953278},
+ {-0.491638, 0.661041, -0.566772}, {-0.304199, -0.572083, -0.761688},
+ {0.908081, -0.398956, 0.127014}, {-0.523621, -0.549683, -0.650848},
+ {-0.932922, -0.19986, 0.299408}, {0.099426, 0.140869, 0.984985},
+ {-0.020325, -0.999756, -0.002319}, {0.952667, 0.280853, -0.11615},
+ {-0.971893, 0.082581, 0.220337}, {0.65921, 0.705292, -0.260651},
+ {0.733063, -0.175537, 0.657043}, {-0.555206, 0.429504, -0.712189},
+ {0.400421, -0.89859, 0.179352}, {0.750885, -0.19696, 0.630341},
+ {0.785675, -0.569336, 0.241821}, {-0.058899, -0.464111, 0.883789},
+ {0.129608, -0.94519, 0.299622}, {-0.357819, 0.907654, 0.219238},
+ {-0.842133, -0.439117, -0.312927}, {-0.313477, 0.84433, 0.434479},
+ {-0.241211, 0.053253, 0.968994}, {0.063873, 0.823273, 0.563965},
+ {0.476288, 0.862152, -0.172516}, {0.620941, -0.298126, 0.724915},
+ {0.25238, -0.749359, -0.612122}, {-0.577545, 0.386566, 0.718994},
+ {-0.406342, -0.737976, 0.538696}, {0.04718, 0.556305, 0.82959},
+ {-0.802856, 0.587463, 0.101166}, {-0.707733, -0.705963, 0.026428},
+ {0.374908, 0.68457, 0.625092}, {0.472137, 0.208405, -0.856506},
+ {-0.703064, -0.581085, -0.409821}, {-0.417206, -0.736328, 0.532623},
+ {-0.447876, -0.20285, -0.870728}, {0.086945, -0.990417, 0.107086},
+ {0.183685, 0.018341, -0.982788}, {0.560638, -0.428864, 0.708282},
+ {0.296722, -0.952576, -0.0672}, {0.135773, 0.990265, 0.030243},
+ {-0.068787, 0.654724, 0.752686}, {0.762604, -0.551758, 0.337585},
+ {-0.819611, -0.407684, 0.402466}, {-0.727844, -0.55072, -0.408539},
+ {-0.855774, -0.480011, 0.19281}, {0.693176, -0.079285, 0.716339},
+ {0.226013, 0.650116, -0.725433}, {0.246704, 0.953369, -0.173553},
+ {-0.970398, -0.239227, -0.03244}, {0.136383, -0.394318, 0.908752},
+ {0.813232, 0.558167, 0.164368}, {0.40451, 0.549042, -0.731323},
+ {-0.380249, -0.566711, 0.730865}, {0.022156, 0.932739, 0.359741},
+ {0.00824, 0.996552, -0.082306}, {0.956635, -0.065338, -0.283722},
+ {-0.743561, 0.008209, 0.668579}, {-0.859589, -0.509674, 0.035767},
+ {-0.852234, 0.363678, -0.375977}, {-0.201965, -0.970795, -0.12915},
+ {0.313477, 0.947327, 0.06546}, {-0.254028, -0.528259, 0.81015},
+ {0.628052, 0.601105, 0.49411}, {-0.494385, 0.868378, 0.037933},
+ {0.275635, -0.086426, 0.957336}, {-0.197937, 0.468903, -0.860748},
+ {0.895599, 0.399384, 0.195801}, {0.560791, 0.825012, -0.069214},
+ {0.304199, -0.849487, 0.43103}, {0.096375, 0.93576, 0.339111},
+ {-0.051422, 0.408966, -0.911072}, {0.330444, 0.942841, -0.042389},
+ {-0.452362, -0.786407, 0.420563}, {0.134308, -0.933472, -0.332489},
+ {0.80191, -0.566711, -0.188934}, {-0.987946, -0.105988, 0.112518},
+ {-0.24408, 0.892242, -0.379791}, {-0.920502, 0.229095, -0.316376},
+ {0.7789, 0.325958, 0.535706}, {-0.912872, 0.185211, -0.36377},
+ {-0.184784, 0.565369, -0.803833}, {-0.018463, 0.119537, 0.992615},
+ {-0.259247, -0.935608, 0.239532}, {-0.82373, -0.449127, -0.345947},
+ {-0.433105, 0.659515, 0.614349}, {-0.822754, 0.378845, -0.423676},
+ {0.687195, -0.674835, -0.26889}, {-0.246582, -0.800842, 0.545715},
+ {-0.729187, -0.207794, 0.651978}, {0.653534, -0.610443, -0.447388},
+ {0.492584, -0.023346, 0.869934}, {0.609039, 0.009094, -0.79306},
+ {0.962494, -0.271088, -0.00885}, {0.2659, -0.004913, 0.963959},
+ {0.651245, 0.553619, -0.518951}, {0.280548, -0.84314, 0.458618},
+ {-0.175293, -0.983215, 0.049805}, {0.035339, -0.979919, 0.196045},
+ {-0.982941, 0.164307, -0.082245}, {0.233734, -0.97226, -0.005005},
+ {-0.747253, -0.611328, 0.260437}, {0.645599, 0.592773, 0.481384},
+ {0.117706, -0.949524, -0.29068}, {-0.535004, -0.791901, -0.294312},
+ {-0.627167, -0.214447, 0.748718}, {-0.047974, -0.813477, -0.57959},
+ {-0.175537, 0.477264, -0.860992}, {0.738556, -0.414246, -0.53183},
+ {0.562561, -0.704071, 0.433289}, {-0.754944, 0.64801, -0.100586},
+ {0.114716, 0.044525, -0.992371}, {0.966003, 0.244873, -0.082764},
+ {0.33783, 0.715698, -0.611206}, {-0.944031, -0.326599, -0.045624},
};
-#define SETUP(val, b0, b1, r0, r1) \
- { \
- t = val + 10000.0f; \
- b0 = ((int)t) & 255; \
- b1 = (b0 + 1) & 255; \
- r0 = t - floorf(t); \
- r1 = r0 - 1.0f; \
- } (void)0
-
+#define SETUP(val, b0, b1, r0, r1) \
+ { \
+ t = val + 10000.0f; \
+ b0 = ((int)t) & 255; \
+ b1 = (b0 + 1) & 255; \
+ r0 = t - floorf(t); \
+ r1 = r0 - 1.0f; \
+ } \
+ (void)0
static float noise3_perlin(float vec[3])
{
- const char *p = g_perlin_data_ub;
- const float (*g)[3] = g_perlin_data_v3;
- int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
- float rx0, rx1, ry0, ry1, rz0, rz1, sx, sy, sz, a, b, c, d, t, u, v;
- const float *q;
- register int i, j;
-
-
- SETUP(vec[0], bx0, bx1, rx0, rx1);
- SETUP(vec[1], by0, by1, ry0, ry1);
- SETUP(vec[2], bz0, bz1, rz0, rz1);
-
- i = p[bx0];
- j = p[bx1];
-
- b00 = p[i + by0];
- b10 = p[j + by0];
- b01 = p[i + by1];
- b11 = p[j + by1];
-
-#define VALUE_AT(rx, ry, rz) ((rx) * q[0] + (ry) * q[1] + (rz) * q[2])
+ const char *p = g_perlin_data_ub;
+ const float(*g)[3] = g_perlin_data_v3;
+ int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
+ float rx0, rx1, ry0, ry1, rz0, rz1, sx, sy, sz, a, b, c, d, t, u, v;
+ const float *q;
+ register int i, j;
+
+ SETUP(vec[0], bx0, bx1, rx0, rx1);
+ SETUP(vec[1], by0, by1, ry0, ry1);
+ SETUP(vec[2], bz0, bz1, rz0, rz1);
+
+ i = p[bx0];
+ j = p[bx1];
+
+ b00 = p[i + by0];
+ b10 = p[j + by0];
+ b01 = p[i + by1];
+ b11 = p[j + by1];
+
+#define VALUE_AT(rx, ry, rz) ((rx)*q[0] + (ry)*q[1] + (rz)*q[2])
#define SURVE(t) ((t) * (t) * (3.0f - 2.0f * (t)))
-/* lerp moved to improved perlin above */
+ /* lerp moved to improved perlin above */
- sx = SURVE(rx0);
- sy = SURVE(ry0);
- sz = SURVE(rz0);
+ sx = SURVE(rx0);
+ sy = SURVE(ry0);
+ sz = SURVE(rz0);
+ q = g[b00 + bz0];
+ u = VALUE_AT(rx0, ry0, rz0);
+ q = g[b10 + bz0];
+ v = VALUE_AT(rx1, ry0, rz0);
+ a = lerp(sx, u, v);
- q = g[b00 + bz0];
- u = VALUE_AT(rx0, ry0, rz0);
- q = g[b10 + bz0];
- v = VALUE_AT(rx1, ry0, rz0);
- a = lerp(sx, u, v);
+ q = g[b01 + bz0];
+ u = VALUE_AT(rx0, ry1, rz0);
+ q = g[b11 + bz0];
+ v = VALUE_AT(rx1, ry1, rz0);
+ b = lerp(sx, u, v);
- q = g[b01 + bz0];
- u = VALUE_AT(rx0, ry1, rz0);
- q = g[b11 + bz0];
- v = VALUE_AT(rx1, ry1, rz0);
- b = lerp(sx, u, v);
+ c = lerp(sy, a, b); /* interpolate in y at lo x */
- c = lerp(sy, a, b); /* interpolate in y at lo x */
+ q = g[b00 + bz1];
+ u = VALUE_AT(rx0, ry0, rz1);
+ q = g[b10 + bz1];
+ v = VALUE_AT(rx1, ry0, rz1);
+ a = lerp(sx, u, v);
- q = g[b00 + bz1];
- u = VALUE_AT(rx0, ry0, rz1);
- q = g[b10 + bz1];
- v = VALUE_AT(rx1, ry0, rz1);
- a = lerp(sx, u, v);
+ q = g[b01 + bz1];
+ u = VALUE_AT(rx0, ry1, rz1);
+ q = g[b11 + bz1];
+ v = VALUE_AT(rx1, ry1, rz1);
+ b = lerp(sx, u, v);
- q = g[b01 + bz1];
- u = VALUE_AT(rx0, ry1, rz1);
- q = g[b11 + bz1];
- v = VALUE_AT(rx1, ry1, rz1);
- b = lerp(sx, u, v);
+ d = lerp(sy, a, b); /* interpolate in y at hi x */
- d = lerp(sy, a, b); /* interpolate in y at hi x */
-
- return 1.5f * lerp(sz, c, d); /* interpolate in z */
+ return 1.5f * lerp(sz, c, d); /* interpolate in z */
#undef VALUE_AT
#undef SURVE
@@ -1092,36 +845,36 @@ static float noise3_perlin(float vec[3])
/* for use with BLI_gNoise/gTurbulence, returns signed noise */
static float orgPerlinNoise(float x, float y, float z)
{
- float v[3];
+ float v[3];
- v[0] = x;
- v[1] = y;
- v[2] = z;
- return noise3_perlin(v);
+ v[0] = x;
+ v[1] = y;
+ v[2] = z;
+ return noise3_perlin(v);
}
/* for use with BLI_gNoise/gTurbulence, returns unsigned noise */
static float orgPerlinNoiseU(float x, float y, float z)
{
- float v[3];
+ float v[3];
- v[0] = x;
- v[1] = y;
- v[2] = z;
- return (0.5f + 0.5f * noise3_perlin(v));
+ v[0] = x;
+ v[1] = y;
+ v[2] = z;
+ return (0.5f + 0.5f * noise3_perlin(v));
}
/* *************** CALL AS: *************** */
float BLI_hnoisep(float noisesize, float x, float y, float z)
{
- float vec[3];
+ float vec[3];
- vec[0] = x / noisesize;
- vec[1] = y / noisesize;
- vec[2] = z / noisesize;
+ vec[0] = x / noisesize;
+ vec[1] = y / noisesize;
+ vec[2] = z / noisesize;
- return noise3_perlin(vec);
+ return noise3_perlin(vec);
}
/******************/
@@ -1134,224 +887,250 @@ float BLI_hnoisep(float noisesize, float x, float y, float z)
/* distance squared */
static float dist_Squared(float x, float y, float z, float e)
{
- (void)e; return (x * x + y * y + z * z);
+ (void)e;
+ return (x * x + y * y + z * z);
}
/* real distance */
static float dist_Real(float x, float y, float z, float e)
{
- (void)e; return sqrtf(x * x + y * y + z * z);
+ (void)e;
+ return sqrtf(x * x + y * y + z * z);
}
/* manhattan/taxicab/cityblock distance */
static float dist_Manhattan(float x, float y, float z, float e)
{
- (void)e; return (fabsf(x) + fabsf(y) + fabsf(z));
+ (void)e;
+ return (fabsf(x) + fabsf(y) + fabsf(z));
}
/* Chebychev */
static float dist_Chebychev(float x, float y, float z, float e)
{
- float t;
- (void)e;
-
- x = fabsf(x);
- y = fabsf(y);
- z = fabsf(z);
- t = (x > y) ? x : y;
- return ((z > t) ? z : t);
+ float t;
+ (void)e;
+
+ x = fabsf(x);
+ y = fabsf(y);
+ z = fabsf(z);
+ t = (x > y) ? x : y;
+ return ((z > t) ? z : t);
}
/* minkowski preset exponent 0.5 */
static float dist_MinkovskyH(float x, float y, float z, float e)
{
- float d = sqrtf(fabsf(x)) + sqrtf(fabsf(y)) + sqrtf(fabsf(z));
- (void)e;
- return (d * d);
+ float d = sqrtf(fabsf(x)) + sqrtf(fabsf(y)) + sqrtf(fabsf(z));
+ (void)e;
+ return (d * d);
}
/* minkowski preset exponent 4 */
static float dist_Minkovsky4(float x, float y, float z, float e)
{
- (void)e;
- x *= x;
- y *= y;
- z *= z;
- return sqrtf(sqrtf(x * x + y * y + z * z));
+ (void)e;
+ x *= x;
+ y *= y;
+ z *= z;
+ return sqrtf(sqrtf(x * x + y * y + z * z));
}
/* Minkowski, general case, slow, maybe too slow to be useful */
static float dist_Minkovsky(float x, float y, float z, float e)
{
- return powf(powf(fabsf(x), e) + powf(fabsf(y), e) + powf(fabsf(z), e), 1.0f / e);
+ return powf(powf(fabsf(x), e) + powf(fabsf(y), e) + powf(fabsf(z), e), 1.0f / e);
}
-
/* Not 'pure' Worley, but the results are virtually the same.
* Returns distances in da and point coords in pa */
void voronoi(float x, float y, float z, float *da, float *pa, float me, int dtype)
{
- int xx, yy, zz, xi, yi, zi;
- float xd, yd, zd, d;
-
- float (*distfunc)(float, float, float, float);
- switch (dtype) {
- case 1:
- distfunc = dist_Squared;
- break;
- case 2:
- distfunc = dist_Manhattan;
- break;
- case 3:
- distfunc = dist_Chebychev;
- break;
- case 4:
- distfunc = dist_MinkovskyH;
- break;
- case 5:
- distfunc = dist_Minkovsky4;
- break;
- case 6:
- distfunc = dist_Minkovsky;
- break;
- case 0:
- default:
- distfunc = dist_Real;
- break;
- }
-
- xi = (int)(floor(x));
- yi = (int)(floor(y));
- zi = (int)(floor(z));
- da[0] = da[1] = da[2] = da[3] = 1e10f;
- for (xx = xi - 1; xx <= xi + 1; xx++) {
- for (yy = yi - 1; yy <= yi + 1; yy++) {
- for (zz = zi - 1; zz <= zi + 1; zz++) {
- const float *p = HASHPNT(xx, yy, zz);
- xd = x - (p[0] + xx);
- yd = y - (p[1] + yy);
- zd = z - (p[2] + zz);
- d = distfunc(xd, yd, zd, me);
- if (d < da[0]) {
- da[3] = da[2]; da[2] = da[1]; da[1] = da[0]; da[0] = d;
- pa[9] = pa[6]; pa[10] = pa[7]; pa[11] = pa[8];
- pa[6] = pa[3]; pa[7] = pa[4]; pa[8] = pa[5];
- pa[3] = pa[0]; pa[4] = pa[1]; pa[5] = pa[2];
- pa[0] = p[0] + xx; pa[1] = p[1] + yy; pa[2] = p[2] + zz;
- }
- else if (d < da[1]) {
- da[3] = da[2]; da[2] = da[1]; da[1] = d;
- pa[9] = pa[6]; pa[10] = pa[7]; pa[11] = pa[8];
- pa[6] = pa[3]; pa[7] = pa[4]; pa[8] = pa[5];
- pa[3] = p[0] + xx; pa[4] = p[1] + yy; pa[5] = p[2] + zz;
- }
- else if (d < da[2]) {
- da[3] = da[2]; da[2] = d;
- pa[9] = pa[6]; pa[10] = pa[7]; pa[11] = pa[8];
- pa[6] = p[0] + xx; pa[7] = p[1] + yy; pa[8] = p[2] + zz;
- }
- else if (d < da[3]) {
- da[3] = d;
- pa[9] = p[0] + xx; pa[10] = p[1] + yy; pa[11] = p[2] + zz;
- }
- }
- }
- }
+ int xx, yy, zz, xi, yi, zi;
+ float xd, yd, zd, d;
+
+ float (*distfunc)(float, float, float, float);
+ switch (dtype) {
+ case 1:
+ distfunc = dist_Squared;
+ break;
+ case 2:
+ distfunc = dist_Manhattan;
+ break;
+ case 3:
+ distfunc = dist_Chebychev;
+ break;
+ case 4:
+ distfunc = dist_MinkovskyH;
+ break;
+ case 5:
+ distfunc = dist_Minkovsky4;
+ break;
+ case 6:
+ distfunc = dist_Minkovsky;
+ break;
+ case 0:
+ default:
+ distfunc = dist_Real;
+ break;
+ }
+
+ xi = (int)(floor(x));
+ yi = (int)(floor(y));
+ zi = (int)(floor(z));
+ da[0] = da[1] = da[2] = da[3] = 1e10f;
+ for (xx = xi - 1; xx <= xi + 1; xx++) {
+ for (yy = yi - 1; yy <= yi + 1; yy++) {
+ for (zz = zi - 1; zz <= zi + 1; zz++) {
+ const float *p = HASHPNT(xx, yy, zz);
+ xd = x - (p[0] + xx);
+ yd = y - (p[1] + yy);
+ zd = z - (p[2] + zz);
+ d = distfunc(xd, yd, zd, me);
+ if (d < da[0]) {
+ da[3] = da[2];
+ da[2] = da[1];
+ da[1] = da[0];
+ da[0] = d;
+ pa[9] = pa[6];
+ pa[10] = pa[7];
+ pa[11] = pa[8];
+ pa[6] = pa[3];
+ pa[7] = pa[4];
+ pa[8] = pa[5];
+ pa[3] = pa[0];
+ pa[4] = pa[1];
+ pa[5] = pa[2];
+ pa[0] = p[0] + xx;
+ pa[1] = p[1] + yy;
+ pa[2] = p[2] + zz;
+ }
+ else if (d < da[1]) {
+ da[3] = da[2];
+ da[2] = da[1];
+ da[1] = d;
+ pa[9] = pa[6];
+ pa[10] = pa[7];
+ pa[11] = pa[8];
+ pa[6] = pa[3];
+ pa[7] = pa[4];
+ pa[8] = pa[5];
+ pa[3] = p[0] + xx;
+ pa[4] = p[1] + yy;
+ pa[5] = p[2] + zz;
+ }
+ else if (d < da[2]) {
+ da[3] = da[2];
+ da[2] = d;
+ pa[9] = pa[6];
+ pa[10] = pa[7];
+ pa[11] = pa[8];
+ pa[6] = p[0] + xx;
+ pa[7] = p[1] + yy;
+ pa[8] = p[2] + zz;
+ }
+ else if (d < da[3]) {
+ da[3] = d;
+ pa[9] = p[0] + xx;
+ pa[10] = p[1] + yy;
+ pa[11] = p[2] + zz;
+ }
+ }
+ }
+ }
}
/* returns different feature points for use in BLI_gNoise() */
static float voronoi_F1(float x, float y, float z)
{
- float da[4], pa[12];
- voronoi(x, y, z, da, pa, 1, 0);
- return da[0];
+ float da[4], pa[12];
+ voronoi(x, y, z, da, pa, 1, 0);
+ return da[0];
}
static float voronoi_F2(float x, float y, float z)
{
- float da[4], pa[12];
- voronoi(x, y, z, da, pa, 1, 0);
- return da[1];
+ float da[4], pa[12];
+ voronoi(x, y, z, da, pa, 1, 0);
+ return da[1];
}
static float voronoi_F3(float x, float y, float z)
{
- float da[4], pa[12];
- voronoi(x, y, z, da, pa, 1, 0);
- return da[2];
+ float da[4], pa[12];
+ voronoi(x, y, z, da, pa, 1, 0);
+ return da[2];
}
static float voronoi_F4(float x, float y, float z)
{
- float da[4], pa[12];
- voronoi(x, y, z, da, pa, 1, 0);
- return da[3];
+ float da[4], pa[12];
+ voronoi(x, y, z, da, pa, 1, 0);
+ return da[3];
}
static float voronoi_F1F2(float x, float y, float z)
{
- float da[4], pa[12];
- voronoi(x, y, z, da, pa, 1, 0);
- return (da[1] - da[0]);
+ float da[4], pa[12];
+ voronoi(x, y, z, da, pa, 1, 0);
+ return (da[1] - da[0]);
}
/* Crackle type pattern, just a scale/clamp of F2-F1 */
static float voronoi_Cr(float x, float y, float z)
{
- float t = 10 * voronoi_F1F2(x, y, z);
- if (t > 1.f) {
- return 1.f;
- }
- return t;
+ float t = 10 * voronoi_F1F2(x, y, z);
+ if (t > 1.f) {
+ return 1.f;
+ }
+ return t;
}
-
/* Signed version of all 6 of the above, just 2x-1, not really correct though
* (range is potentially (0, sqrt(6)).
* Used in the musgrave functions */
static float voronoi_F1S(float x, float y, float z)
{
- float da[4], pa[12];
- voronoi(x, y, z, da, pa, 1, 0);
- return (2.0f * da[0] - 1.0f);
+ float da[4], pa[12];
+ voronoi(x, y, z, da, pa, 1, 0);
+ return (2.0f * da[0] - 1.0f);
}
static float voronoi_F2S(float x, float y, float z)
{
- float da[4], pa[12];
- voronoi(x, y, z, da, pa, 1, 0);
- return (2.0f * da[1] - 1.0f);
+ float da[4], pa[12];
+ voronoi(x, y, z, da, pa, 1, 0);
+ return (2.0f * da[1] - 1.0f);
}
static float voronoi_F3S(float x, float y, float z)
{
- float da[4], pa[12];
- voronoi(x, y, z, da, pa, 1, 0);
- return (2.0f * da[2] - 1.0f);
+ float da[4], pa[12];
+ voronoi(x, y, z, da, pa, 1, 0);
+ return (2.0f * da[2] - 1.0f);
}
static float voronoi_F4S(float x, float y, float z)
{
- float da[4], pa[12];
- voronoi(x, y, z, da, pa, 1, 0);
- return (2.0f * da[3] - 1.0f);
+ float da[4], pa[12];
+ voronoi(x, y, z, da, pa, 1, 0);
+ return (2.0f * da[3] - 1.0f);
}
static float voronoi_F1F2S(float x, float y, float z)
{
- float da[4], pa[12];
- voronoi(x, y, z, da, pa, 1, 0);
- return (2.0f * (da[1] - da[0]) - 1.0f);
+ float da[4], pa[12];
+ voronoi(x, y, z, da, pa, 1, 0);
+ return (2.0f * (da[1] - da[0]) - 1.0f);
}
/* Crackle type pattern, just a scale/clamp of F2-F1 */
static float voronoi_CrS(float x, float y, float z)
{
- float t = 10 * voronoi_F1F2(x, y, z);
- if (t > 1.f) {
- return 1.f;
- }
- return (2.0f * t - 1.0f);
+ float t = 10 * voronoi_F1F2(x, y, z);
+ if (t > 1.f) {
+ return 1.f;
+ }
+ return (2.0f * t - 1.0f);
}
-
/***************/
/* voronoi end */
/***************/
@@ -1363,43 +1142,42 @@ static float voronoi_CrS(float x, float y, float z)
/* returns unsigned cellnoise */
static float cellNoiseU(float x, float y, float z)
{
- /* avoid precision issues on unit coordinates */
- x = (x + 0.000001f) * 1.00001f;
- y = (y + 0.000001f) * 1.00001f;
- z = (z + 0.000001f) * 1.00001f;
-
- int xi = (int)(floor(x));
- int yi = (int)(floor(y));
- int zi = (int)(floor(z));
- unsigned int n = xi + yi * 1301 + zi * 314159;
- n ^= (n << 13);
- return ((float)(n * (n * n * 15731 + 789221) + 1376312589) / 4294967296.0f);
+ /* avoid precision issues on unit coordinates */
+ x = (x + 0.000001f) * 1.00001f;
+ y = (y + 0.000001f) * 1.00001f;
+ z = (z + 0.000001f) * 1.00001f;
+
+ int xi = (int)(floor(x));
+ int yi = (int)(floor(y));
+ int zi = (int)(floor(z));
+ unsigned int n = xi + yi * 1301 + zi * 314159;
+ n ^= (n << 13);
+ return ((float)(n * (n * n * 15731 + 789221) + 1376312589) / 4294967296.0f);
}
/* idem, signed */
float cellNoise(float x, float y, float z)
{
- return (2.0f * cellNoiseU(x, y, z) - 1.0f);
+ return (2.0f * cellNoiseU(x, y, z) - 1.0f);
}
/* returns a vector/point/color in ca, using point hasharray directly */
void cellNoiseV(float x, float y, float z, float ca[3])
{
- /* avoid precision issues on unit coordinates */
- x = (x + 0.000001f) * 1.00001f;
- y = (y + 0.000001f) * 1.00001f;
- z = (z + 0.000001f) * 1.00001f;
-
- int xi = (int)(floor(x));
- int yi = (int)(floor(y));
- int zi = (int)(floor(z));
- const float *p = HASHPNT(xi, yi, zi);
- ca[0] = p[0];
- ca[1] = p[1];
- ca[2] = p[2];
+ /* avoid precision issues on unit coordinates */
+ x = (x + 0.000001f) * 1.00001f;
+ y = (y + 0.000001f) * 1.00001f;
+ z = (z + 0.000001f) * 1.00001f;
+
+ int xi = (int)(floor(x));
+ int yi = (int)(floor(y));
+ int zi = (int)(floor(z));
+ const float *p = HASHPNT(xi, yi, zi);
+ ca[0] = p[0];
+ ca[1] = p[1];
+ ca[2] = p[2];
}
-
/*****************/
/* end cellnoise */
/*****************/
@@ -1407,128 +1185,126 @@ void cellNoiseV(float x, float y, float z, float ca[3])
/* newnoise: generic noise function for use with different noisebases */
float BLI_gNoise(float noisesize, float x, float y, float z, int hard, int noisebasis)
{
- float (*noisefunc)(float, float, float);
-
- switch (noisebasis) {
- case 1:
- noisefunc = orgPerlinNoiseU;
- break;
- case 2:
- noisefunc = newPerlinU;
- break;
- case 3:
- noisefunc = voronoi_F1;
- break;
- case 4:
- noisefunc = voronoi_F2;
- break;
- case 5:
- noisefunc = voronoi_F3;
- break;
- case 6:
- noisefunc = voronoi_F4;
- break;
- case 7:
- noisefunc = voronoi_F1F2;
- break;
- case 8:
- noisefunc = voronoi_Cr;
- break;
- case 14:
- noisefunc = cellNoiseU;
- break;
- case 0:
- default:
- {
- noisefunc = orgBlenderNoise;
- /* add one to make return value same as BLI_hnoise */
- x += 1;
- y += 1;
- z += 1;
- break;
- }
- }
-
- if (noisesize != 0.0f) {
- noisesize = 1.0f / noisesize;
- x *= noisesize;
- y *= noisesize;
- z *= noisesize;
- }
-
- if (hard) {
- return fabsf(2.0f * noisefunc(x, y, z) - 1.0f);
- }
- return noisefunc(x, y, z);
+ float (*noisefunc)(float, float, float);
+
+ switch (noisebasis) {
+ case 1:
+ noisefunc = orgPerlinNoiseU;
+ break;
+ case 2:
+ noisefunc = newPerlinU;
+ break;
+ case 3:
+ noisefunc = voronoi_F1;
+ break;
+ case 4:
+ noisefunc = voronoi_F2;
+ break;
+ case 5:
+ noisefunc = voronoi_F3;
+ break;
+ case 6:
+ noisefunc = voronoi_F4;
+ break;
+ case 7:
+ noisefunc = voronoi_F1F2;
+ break;
+ case 8:
+ noisefunc = voronoi_Cr;
+ break;
+ case 14:
+ noisefunc = cellNoiseU;
+ break;
+ case 0:
+ default: {
+ noisefunc = orgBlenderNoise;
+ /* add one to make return value same as BLI_hnoise */
+ x += 1;
+ y += 1;
+ z += 1;
+ break;
+ }
+ }
+
+ if (noisesize != 0.0f) {
+ noisesize = 1.0f / noisesize;
+ x *= noisesize;
+ y *= noisesize;
+ z *= noisesize;
+ }
+
+ if (hard) {
+ return fabsf(2.0f * noisefunc(x, y, z) - 1.0f);
+ }
+ return noisefunc(x, y, z);
}
/* newnoise: generic turbulence function for use with different noisebasis */
-float BLI_gTurbulence(float noisesize, float x, float y, float z, int oct, int hard, int noisebasis)
+float BLI_gTurbulence(
+ float noisesize, float x, float y, float z, int oct, int hard, int noisebasis)
{
- float (*noisefunc)(float, float, float);
- float sum, t, amp = 1, fscale = 1;
- int i;
-
- switch (noisebasis) {
- case 1:
- noisefunc = orgPerlinNoiseU;
- break;
- case 2:
- noisefunc = newPerlinU;
- break;
- case 3:
- noisefunc = voronoi_F1;
- break;
- case 4:
- noisefunc = voronoi_F2;
- break;
- case 5:
- noisefunc = voronoi_F3;
- break;
- case 6:
- noisefunc = voronoi_F4;
- break;
- case 7:
- noisefunc = voronoi_F1F2;
- break;
- case 8:
- noisefunc = voronoi_Cr;
- break;
- case 14:
- noisefunc = cellNoiseU;
- break;
- case 0:
- default:
- noisefunc = orgBlenderNoise;
- x += 1;
- y += 1;
- z += 1;
- break;
- }
-
- if (noisesize != 0.0f) {
- noisesize = 1.0f / noisesize;
- x *= noisesize;
- y *= noisesize;
- z *= noisesize;
- }
-
- sum = 0;
- for (i = 0; i <= oct; i++, amp *= 0.5f, fscale *= 2.0f) {
- t = noisefunc(fscale * x, fscale * y, fscale * z);
- if (hard) {
- t = fabsf(2.0f * t - 1.0f);
- }
- sum += t * amp;
- }
-
- sum *= ((float)(1 << oct) / (float)((1 << (oct + 1)) - 1));
-
- return sum;
-
+ float (*noisefunc)(float, float, float);
+ float sum, t, amp = 1, fscale = 1;
+ int i;
+
+ switch (noisebasis) {
+ case 1:
+ noisefunc = orgPerlinNoiseU;
+ break;
+ case 2:
+ noisefunc = newPerlinU;
+ break;
+ case 3:
+ noisefunc = voronoi_F1;
+ break;
+ case 4:
+ noisefunc = voronoi_F2;
+ break;
+ case 5:
+ noisefunc = voronoi_F3;
+ break;
+ case 6:
+ noisefunc = voronoi_F4;
+ break;
+ case 7:
+ noisefunc = voronoi_F1F2;
+ break;
+ case 8:
+ noisefunc = voronoi_Cr;
+ break;
+ case 14:
+ noisefunc = cellNoiseU;
+ break;
+ case 0:
+ default:
+ noisefunc = orgBlenderNoise;
+ x += 1;
+ y += 1;
+ z += 1;
+ break;
+ }
+
+ if (noisesize != 0.0f) {
+ noisesize = 1.0f / noisesize;
+ x *= noisesize;
+ y *= noisesize;
+ z *= noisesize;
+ }
+
+ sum = 0;
+ for (i = 0; i <= oct; i++, amp *= 0.5f, fscale *= 2.0f) {
+ t = noisefunc(fscale * x, fscale * y, fscale * z);
+ if (hard) {
+ t = fabsf(2.0f * t - 1.0f);
+ }
+ sum += t * amp;
+ }
+
+ sum *= ((float)(1 << oct) / (float)((1 << (oct + 1)) - 1));
+
+ return sum;
}
-
/*
* The following code is based on Ken Musgrave's explanations and sample
* source code in the book "Texturing and Modeling: A procedural approach"
@@ -1544,64 +1320,62 @@ float BLI_gTurbulence(float noisesize, float x, float y, float z, int oct, int h
*/
float mg_fBm(float x, float y, float z, float H, float lacunarity, float octaves, int noisebasis)
{
- float rmd, value = 0.0, pwr = 1.0, pwHL = powf(lacunarity, -H);
- int i;
-
- float (*noisefunc)(float, float, float);
- switch (noisebasis) {
- case 1:
- noisefunc = orgPerlinNoise;
- break;
- case 2:
- noisefunc = newPerlin;
- break;
- case 3:
- noisefunc = voronoi_F1S;
- break;
- case 4:
- noisefunc = voronoi_F2S;
- break;
- case 5:
- noisefunc = voronoi_F3S;
- break;
- case 6:
- noisefunc = voronoi_F4S;
- break;
- case 7:
- noisefunc = voronoi_F1F2S;
- break;
- case 8:
- noisefunc = voronoi_CrS;
- break;
- case 14:
- noisefunc = cellNoise;
- break;
- case 0:
- default:
- {
- noisefunc = orgBlenderNoiseS;
- break;
- }
- }
-
- for (i = 0; i < (int)octaves; i++) {
- value += noisefunc(x, y, z) * pwr;
- pwr *= pwHL;
- x *= lacunarity;
- y *= lacunarity;
- z *= lacunarity;
- }
-
- rmd = octaves - floorf(octaves);
- if (rmd != 0.0f) {
- value += rmd * noisefunc(x, y, z) * pwr;
- }
-
- return value;
+ float rmd, value = 0.0, pwr = 1.0, pwHL = powf(lacunarity, -H);
+ int i;
+
+ float (*noisefunc)(float, float, float);
+ switch (noisebasis) {
+ case 1:
+ noisefunc = orgPerlinNoise;
+ break;
+ case 2:
+ noisefunc = newPerlin;
+ break;
+ case 3:
+ noisefunc = voronoi_F1S;
+ break;
+ case 4:
+ noisefunc = voronoi_F2S;
+ break;
+ case 5:
+ noisefunc = voronoi_F3S;
+ break;
+ case 6:
+ noisefunc = voronoi_F4S;
+ break;
+ case 7:
+ noisefunc = voronoi_F1F2S;
+ break;
+ case 8:
+ noisefunc = voronoi_CrS;
+ break;
+ case 14:
+ noisefunc = cellNoise;
+ break;
+ case 0:
+ default: {
+ noisefunc = orgBlenderNoiseS;
+ break;
+ }
+ }
+
+ for (i = 0; i < (int)octaves; i++) {
+ value += noisefunc(x, y, z) * pwr;
+ pwr *= pwHL;
+ x *= lacunarity;
+ y *= lacunarity;
+ z *= lacunarity;
+ }
+
+ rmd = octaves - floorf(octaves);
+ if (rmd != 0.0f) {
+ value += rmd * noisefunc(x, y, z) * pwr;
+ }
+
+ return value;
} /* fBm() */
-
/*
* Procedural multifractal evaluated at "point";
* returns value stored in "value".
@@ -1616,61 +1390,61 @@ float mg_fBm(float x, float y, float z, float H, float lacunarity, float octaves
/* this one is in fact rather confusing,
* there seem to be errors in the original source code (in all three versions of proc.text&mod),
* I modified it to something that made sense to me, so it might be wrong... */
-float mg_MultiFractal(float x, float y, float z, float H, float lacunarity, float octaves, int noisebasis)
+float mg_MultiFractal(
+ float x, float y, float z, float H, float lacunarity, float octaves, int noisebasis)
{
- float rmd, value = 1.0, pwr = 1.0, pwHL = powf(lacunarity, -H);
- int i;
-
- float (*noisefunc)(float, float, float);
- switch (noisebasis) {
- case 1:
- noisefunc = orgPerlinNoise;
- break;
- case 2:
- noisefunc = newPerlin;
- break;
- case 3:
- noisefunc = voronoi_F1S;
- break;
- case 4:
- noisefunc = voronoi_F2S;
- break;
- case 5:
- noisefunc = voronoi_F3S;
- break;
- case 6:
- noisefunc = voronoi_F4S;
- break;
- case 7:
- noisefunc = voronoi_F1F2S;
- break;
- case 8:
- noisefunc = voronoi_CrS;
- break;
- case 14:
- noisefunc = cellNoise;
- break;
- case 0:
- default:
- {
- noisefunc = orgBlenderNoiseS;
- break;
- }
- }
-
- for (i = 0; i < (int)octaves; i++) {
- value *= (pwr * noisefunc(x, y, z) + 1.0f);
- pwr *= pwHL;
- x *= lacunarity;
- y *= lacunarity;
- z *= lacunarity;
- }
- rmd = octaves - floorf(octaves);
- if (rmd != 0.0f) {
- value *= (rmd * noisefunc(x, y, z) * pwr + 1.0f);
- }
-
- return value;
+ float rmd, value = 1.0, pwr = 1.0, pwHL = powf(lacunarity, -H);
+ int i;
+
+ float (*noisefunc)(float, float, float);
+ switch (noisebasis) {
+ case 1:
+ noisefunc = orgPerlinNoise;
+ break;
+ case 2:
+ noisefunc = newPerlin;
+ break;
+ case 3:
+ noisefunc = voronoi_F1S;
+ break;
+ case 4:
+ noisefunc = voronoi_F2S;
+ break;
+ case 5:
+ noisefunc = voronoi_F3S;
+ break;
+ case 6:
+ noisefunc = voronoi_F4S;
+ break;
+ case 7:
+ noisefunc = voronoi_F1F2S;
+ break;
+ case 8:
+ noisefunc = voronoi_CrS;
+ break;
+ case 14:
+ noisefunc = cellNoise;
+ break;
+ case 0:
+ default: {
+ noisefunc = orgBlenderNoiseS;
+ break;
+ }
+ }
+
+ for (i = 0; i < (int)octaves; i++) {
+ value *= (pwr * noisefunc(x, y, z) + 1.0f);
+ pwr *= pwHL;
+ x *= lacunarity;
+ y *= lacunarity;
+ z *= lacunarity;
+ }
+ rmd = octaves - floorf(octaves);
+ if (rmd != 0.0f) {
+ value *= (rmd * noisefunc(x, y, z) * pwr + 1.0f);
+ }
+
+ return value;
} /* multifractal() */
@@ -1684,74 +1458,79 @@ float mg_MultiFractal(float x, float y, float z, float H, float lacunarity, floa
* ``octaves'' is the number of frequencies in the fBm
* ``offset'' raises the terrain from `sea level'
*/
-float mg_HeteroTerrain(float x, float y, float z, float H, float lacunarity, float octaves, float offset, int noisebasis)
+float mg_HeteroTerrain(float x,
+ float y,
+ float z,
+ float H,
+ float lacunarity,
+ float octaves,
+ float offset,
+ int noisebasis)
{
- float value, increment, rmd;
- int i;
- float pwHL = powf(lacunarity, -H);
- float pwr = pwHL; /* starts with i=1 instead of 0 */
-
- float (*noisefunc)(float, float, float);
- switch (noisebasis) {
- case 1:
- noisefunc = orgPerlinNoise;
- break;
- case 2:
- noisefunc = newPerlin;
- break;
- case 3:
- noisefunc = voronoi_F1S;
- break;
- case 4:
- noisefunc = voronoi_F2S;
- break;
- case 5:
- noisefunc = voronoi_F3S;
- break;
- case 6:
- noisefunc = voronoi_F4S;
- break;
- case 7:
- noisefunc = voronoi_F1F2S;
- break;
- case 8:
- noisefunc = voronoi_CrS;
- break;
- case 14:
- noisefunc = cellNoise;
- break;
- case 0:
- default:
- {
- noisefunc = orgBlenderNoiseS;
- break;
- }
- }
-
- /* first unscaled octave of function; later octaves are scaled */
- value = offset + noisefunc(x, y, z);
- x *= lacunarity;
- y *= lacunarity;
- z *= lacunarity;
-
- for (i = 1; i < (int)octaves; i++) {
- increment = (noisefunc(x, y, z) + offset) * pwr * value;
- value += increment;
- pwr *= pwHL;
- x *= lacunarity;
- y *= lacunarity;
- z *= lacunarity;
- }
-
- rmd = octaves - floorf(octaves);
- if (rmd != 0.0f) {
- increment = (noisefunc(x, y, z) + offset) * pwr * value;
- value += rmd * increment;
- }
- return value;
+ float value, increment, rmd;
+ int i;
+ float pwHL = powf(lacunarity, -H);
+ float pwr = pwHL; /* starts with i=1 instead of 0 */
+
+ float (*noisefunc)(float, float, float);
+ switch (noisebasis) {
+ case 1:
+ noisefunc = orgPerlinNoise;
+ break;
+ case 2:
+ noisefunc = newPerlin;
+ break;
+ case 3:
+ noisefunc = voronoi_F1S;
+ break;
+ case 4:
+ noisefunc = voronoi_F2S;
+ break;
+ case 5:
+ noisefunc = voronoi_F3S;
+ break;
+ case 6:
+ noisefunc = voronoi_F4S;
+ break;
+ case 7:
+ noisefunc = voronoi_F1F2S;
+ break;
+ case 8:
+ noisefunc = voronoi_CrS;
+ break;
+ case 14:
+ noisefunc = cellNoise;
+ break;
+ case 0:
+ default: {
+ noisefunc = orgBlenderNoiseS;
+ break;
+ }
+ }
+
+ /* first unscaled octave of function; later octaves are scaled */
+ value = offset + noisefunc(x, y, z);
+ x *= lacunarity;
+ y *= lacunarity;
+ z *= lacunarity;
+
+ for (i = 1; i < (int)octaves; i++) {
+ increment = (noisefunc(x, y, z) + offset) * pwr * value;
+ value += increment;
+ pwr *= pwHL;
+ x *= lacunarity;
+ y *= lacunarity;
+ z *= lacunarity;
+ }
+
+ rmd = octaves - floorf(octaves);
+ if (rmd != 0.0f) {
+ increment = (noisefunc(x, y, z) + offset) * pwr * value;
+ value += rmd * increment;
+ }
+ return value;
}
-
/* Hybrid additive/multiplicative multifractal terrain model.
*
* Some good parameter values to start with:
@@ -1759,79 +1538,85 @@ float mg_HeteroTerrain(float x, float y, float z, float H, float lacunarity, flo
* H: 0.25
* offset: 0.7
*/
-float mg_HybridMultiFractal(float x, float y, float z, float H, float lacunarity, float octaves, float offset, float gain, int noisebasis)
+float mg_HybridMultiFractal(float x,
+ float y,
+ float z,
+ float H,
+ float lacunarity,
+ float octaves,
+ float offset,
+ float gain,
+ int noisebasis)
{
- float result, signal, weight, rmd;
- int i;
- float pwHL = powf(lacunarity, -H);
- float pwr = pwHL; /* starts with i=1 instead of 0 */
- float (*noisefunc)(float, float, float);
-
- switch (noisebasis) {
- case 1:
- noisefunc = orgPerlinNoise;
- break;
- case 2:
- noisefunc = newPerlin;
- break;
- case 3:
- noisefunc = voronoi_F1S;
- break;
- case 4:
- noisefunc = voronoi_F2S;
- break;
- case 5:
- noisefunc = voronoi_F3S;
- break;
- case 6:
- noisefunc = voronoi_F4S;
- break;
- case 7:
- noisefunc = voronoi_F1F2S;
- break;
- case 8:
- noisefunc = voronoi_CrS;
- break;
- case 14:
- noisefunc = cellNoise;
- break;
- case 0:
- default:
- {
- noisefunc = orgBlenderNoiseS;
- break;
- }
- }
-
- result = noisefunc(x, y, z) + offset;
- weight = gain * result;
- x *= lacunarity;
- y *= lacunarity;
- z *= lacunarity;
-
- for (i = 1; (weight > 0.001f) && (i < (int)octaves); i++) {
- if (weight > 1.0f) {
- weight = 1.0f;
- }
- signal = (noisefunc(x, y, z) + offset) * pwr;
- pwr *= pwHL;
- result += weight * signal;
- weight *= gain * signal;
- x *= lacunarity;
- y *= lacunarity;
- z *= lacunarity;
- }
-
- rmd = octaves - floorf(octaves);
- if (rmd != 0.f) {
- result += rmd * ((noisefunc(x, y, z) + offset) * pwr);
- }
-
- return result;
+ float result, signal, weight, rmd;
+ int i;
+ float pwHL = powf(lacunarity, -H);
+ float pwr = pwHL; /* starts with i=1 instead of 0 */
+ float (*noisefunc)(float, float, float);
+
+ switch (noisebasis) {
+ case 1:
+ noisefunc = orgPerlinNoise;
+ break;
+ case 2:
+ noisefunc = newPerlin;
+ break;
+ case 3:
+ noisefunc = voronoi_F1S;
+ break;
+ case 4:
+ noisefunc = voronoi_F2S;
+ break;
+ case 5:
+ noisefunc = voronoi_F3S;
+ break;
+ case 6:
+ noisefunc = voronoi_F4S;
+ break;
+ case 7:
+ noisefunc = voronoi_F1F2S;
+ break;
+ case 8:
+ noisefunc = voronoi_CrS;
+ break;
+ case 14:
+ noisefunc = cellNoise;
+ break;
+ case 0:
+ default: {
+ noisefunc = orgBlenderNoiseS;
+ break;
+ }
+ }
+
+ result = noisefunc(x, y, z) + offset;
+ weight = gain * result;
+ x *= lacunarity;
+ y *= lacunarity;
+ z *= lacunarity;
+
+ for (i = 1; (weight > 0.001f) && (i < (int)octaves); i++) {
+ if (weight > 1.0f) {
+ weight = 1.0f;
+ }
+ signal = (noisefunc(x, y, z) + offset) * pwr;
+ pwr *= pwHL;
+ result += weight * signal;
+ weight *= gain * signal;
+ x *= lacunarity;
+ y *= lacunarity;
+ z *= lacunarity;
+ }
+
+ rmd = octaves - floorf(octaves);
+ if (rmd != 0.f) {
+ result += rmd * ((noisefunc(x, y, z) + offset) * pwr);
+ }
+
+ return result;
} /* HybridMultifractal() */
-
/* Ridged multifractal terrain model.
*
* Some good parameter values to start with:
@@ -1840,70 +1625,80 @@ float mg_HybridMultiFractal(float x, float y, float z, float H, float lacunarity
* offset: 1.0
* gain: 2.0
*/
-float mg_RidgedMultiFractal(float x, float y, float z, float H, float lacunarity, float octaves, float offset, float gain, int noisebasis)
+float mg_RidgedMultiFractal(float x,
+ float y,
+ float z,
+ float H,
+ float lacunarity,
+ float octaves,
+ float offset,
+ float gain,
+ int noisebasis)
{
- float result, signal, weight;
- int i;
- float pwHL = powf(lacunarity, -H);
- float pwr = pwHL; /* starts with i=1 instead of 0 */
-
- float (*noisefunc)(float, float, float);
- switch (noisebasis) {
- case 1:
- noisefunc = orgPerlinNoise;
- break;
- case 2:
- noisefunc = newPerlin;
- break;
- case 3:
- noisefunc = voronoi_F1S;
- break;
- case 4:
- noisefunc = voronoi_F2S;
- break;
- case 5:
- noisefunc = voronoi_F3S;
- break;
- case 6:
- noisefunc = voronoi_F4S;
- break;
- case 7:
- noisefunc = voronoi_F1F2S;
- break;
- case 8:
- noisefunc = voronoi_CrS;
- break;
- case 14:
- noisefunc = cellNoise;
- break;
- case 0:
- default:
- {
- noisefunc = orgBlenderNoiseS;
- break;
- }
- }
-
- signal = offset - fabsf(noisefunc(x, y, z));
- signal *= signal;
- result = signal;
-
-
- for (i = 1; i < (int)octaves; i++) {
- x *= lacunarity;
- y *= lacunarity;
- z *= lacunarity;
- weight = signal * gain;
- if (weight > 1.0f) { weight = 1.0f; }
- else if (weight < 0.0f) { weight = 0.0f; }
- signal = offset - fabsf(noisefunc(x, y, z));
- signal *= signal;
- signal *= weight;
- result += signal * pwr;
- pwr *= pwHL;
- }
-
- return result;
+ float result, signal, weight;
+ int i;
+ float pwHL = powf(lacunarity, -H);
+ float pwr = pwHL; /* starts with i=1 instead of 0 */
+
+ float (*noisefunc)(float, float, float);
+ switch (noisebasis) {
+ case 1:
+ noisefunc = orgPerlinNoise;
+ break;
+ case 2:
+ noisefunc = newPerlin;
+ break;
+ case 3:
+ noisefunc = voronoi_F1S;
+ break;
+ case 4:
+ noisefunc = voronoi_F2S;
+ break;
+ case 5:
+ noisefunc = voronoi_F3S;
+ break;
+ case 6:
+ noisefunc = voronoi_F4S;
+ break;
+ case 7:
+ noisefunc = voronoi_F1F2S;
+ break;
+ case 8:
+ noisefunc = voronoi_CrS;
+ break;
+ case 14:
+ noisefunc = cellNoise;
+ break;
+ case 0:
+ default: {
+ noisefunc = orgBlenderNoiseS;
+ break;
+ }
+ }
+
+ signal = offset - fabsf(noisefunc(x, y, z));
+ signal *= signal;
+ result = signal;
+
+ for (i = 1; i < (int)octaves; i++) {
+ x *= lacunarity;
+ y *= lacunarity;
+ z *= lacunarity;
+ weight = signal * gain;
+ if (weight > 1.0f) {
+ weight = 1.0f;
+ }
+ else if (weight < 0.0f) {
+ weight = 0.0f;
+ }
+ signal = offset - fabsf(noisefunc(x, y, z));
+ signal *= signal;
+ signal *= weight;
+ result += signal * pwr;
+ pwr *= pwHL;
+ }
+
+ return result;
} /* RidgedMultifractal() */
/* "Variable Lacunarity Noise"
@@ -1911,87 +1706,85 @@ float mg_RidgedMultiFractal(float x, float y, float z, float H, float lacunarity
*/
float mg_VLNoise(float x, float y, float z, float distortion, int nbas1, int nbas2)
{
- float rv[3];
- float (*noisefunc1)(float, float, float);
- float (*noisefunc2)(float, float, float);
-
- switch (nbas1) {
- case 1:
- noisefunc1 = orgPerlinNoise;
- break;
- case 2:
- noisefunc1 = newPerlin;
- break;
- case 3:
- noisefunc1 = voronoi_F1S;
- break;
- case 4:
- noisefunc1 = voronoi_F2S;
- break;
- case 5:
- noisefunc1 = voronoi_F3S;
- break;
- case 6:
- noisefunc1 = voronoi_F4S;
- break;
- case 7:
- noisefunc1 = voronoi_F1F2S;
- break;
- case 8:
- noisefunc1 = voronoi_CrS;
- break;
- case 14:
- noisefunc1 = cellNoise;
- break;
- case 0:
- default:
- {
- noisefunc1 = orgBlenderNoiseS;
- break;
- }
- }
-
- switch (nbas2) {
- case 1:
- noisefunc2 = orgPerlinNoise;
- break;
- case 2:
- noisefunc2 = newPerlin;
- break;
- case 3:
- noisefunc2 = voronoi_F1S;
- break;
- case 4:
- noisefunc2 = voronoi_F2S;
- break;
- case 5:
- noisefunc2 = voronoi_F3S;
- break;
- case 6:
- noisefunc2 = voronoi_F4S;
- break;
- case 7:
- noisefunc2 = voronoi_F1F2S;
- break;
- case 8:
- noisefunc2 = voronoi_CrS;
- break;
- case 14:
- noisefunc2 = cellNoise;
- break;
- case 0:
- default:
- {
- noisefunc2 = orgBlenderNoiseS;
- break;
- }
- }
-
- /* get a random vector and scale the randomization */
- rv[0] = noisefunc1(x + 13.5f, y + 13.5f, z + 13.5f) * distortion;
- rv[1] = noisefunc1(x, y, z) * distortion;
- rv[2] = noisefunc1(x - 13.5f, y - 13.5f, z - 13.5f) * distortion;
- return noisefunc2(x + rv[0], y + rv[1], z + rv[2]); /* distorted-domain noise */
+ float rv[3];
+ float (*noisefunc1)(float, float, float);
+ float (*noisefunc2)(float, float, float);
+
+ switch (nbas1) {
+ case 1:
+ noisefunc1 = orgPerlinNoise;
+ break;
+ case 2:
+ noisefunc1 = newPerlin;
+ break;
+ case 3:
+ noisefunc1 = voronoi_F1S;
+ break;
+ case 4:
+ noisefunc1 = voronoi_F2S;
+ break;
+ case 5:
+ noisefunc1 = voronoi_F3S;
+ break;
+ case 6:
+ noisefunc1 = voronoi_F4S;
+ break;
+ case 7:
+ noisefunc1 = voronoi_F1F2S;
+ break;
+ case 8:
+ noisefunc1 = voronoi_CrS;
+ break;
+ case 14:
+ noisefunc1 = cellNoise;
+ break;
+ case 0:
+ default: {
+ noisefunc1 = orgBlenderNoiseS;
+ break;
+ }
+ }
+
+ switch (nbas2) {
+ case 1:
+ noisefunc2 = orgPerlinNoise;
+ break;
+ case 2:
+ noisefunc2 = newPerlin;
+ break;
+ case 3:
+ noisefunc2 = voronoi_F1S;
+ break;
+ case 4:
+ noisefunc2 = voronoi_F2S;
+ break;
+ case 5:
+ noisefunc2 = voronoi_F3S;
+ break;
+ case 6:
+ noisefunc2 = voronoi_F4S;
+ break;
+ case 7:
+ noisefunc2 = voronoi_F1F2S;
+ break;
+ case 8:
+ noisefunc2 = voronoi_CrS;
+ break;
+ case 14:
+ noisefunc2 = cellNoise;
+ break;
+ case 0:
+ default: {
+ noisefunc2 = orgBlenderNoiseS;
+ break;
+ }
+ }
+
+ /* get a random vector and scale the randomization */
+ rv[0] = noisefunc1(x + 13.5f, y + 13.5f, z + 13.5f) * distortion;
+ rv[1] = noisefunc1(x, y, z) * distortion;
+ rv[2] = noisefunc1(x - 13.5f, y - 13.5f, z - 13.5f) * distortion;
+ return noisefunc2(x + rv[0], y + rv[1], z + rv[2]); /* distorted-domain noise */
}
/****************/
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index 33cd844f851..64872e881f5 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -60,7 +60,7 @@
/* return true if the path is absolute ie starts with a drive specifier (eg A:\) or is a UNC path */
static bool BLI_path_is_abs(const char *name);
-#endif /* WIN32 */
+#endif /* WIN32 */
// #define DEBUG_STRSIZE
@@ -77,79 +77,79 @@ static bool BLI_path_is_abs(const char *name);
*/
int BLI_stringdec(const char *string, char *head, char *tail, ushort *r_num_len)
{
- uint nums = 0, nume = 0;
- int i;
- bool found_digit = false;
- const char * const lslash = BLI_last_slash(string);
- const uint string_len = strlen(string);
- const uint lslash_len = lslash != NULL ? (int)(lslash - string) : 0;
- uint name_end = string_len;
-
- while (name_end > lslash_len && string[--name_end] != '.') {
- /* name ends at dot if present */
- }
- if (name_end == lslash_len && string[name_end] != '.') {
- name_end = string_len;
- }
-
- for (i = name_end - 1; i >= (int)lslash_len; i--) {
- if (isdigit(string[i])) {
- if (found_digit) {
- nums = i;
- }
- else {
- nume = i;
- nums = i;
- found_digit = true;
- }
- }
- else {
- if (found_digit) {
- break;
- }
- }
- }
-
- if (found_digit) {
- const long long int ret = strtoll(&(string[nums]), NULL, 10);
- if (ret >= INT_MIN && ret <= INT_MAX) {
- if (tail) {
- strcpy(tail, &string[nume + 1]);
- }
- if (head) {
- strcpy(head, string);
- head[nums] = 0;
- }
- if (r_num_len) {
- *r_num_len = nume - nums + 1;
- }
- return (int)ret;
- }
- }
-
- if (tail) {
- strcpy(tail, string + name_end);
- }
- if (head) {
- /* name_end points to last character of head,
- * make it +1 so null-terminator is nicely placed
- */
- BLI_strncpy(head, string, name_end + 1);
- }
- if (r_num_len) {
- *r_num_len = 0;
- }
- return 0;
+ uint nums = 0, nume = 0;
+ int i;
+ bool found_digit = false;
+ const char *const lslash = BLI_last_slash(string);
+ const uint string_len = strlen(string);
+ const uint lslash_len = lslash != NULL ? (int)(lslash - string) : 0;
+ uint name_end = string_len;
+
+ while (name_end > lslash_len && string[--name_end] != '.') {
+ /* name ends at dot if present */
+ }
+ if (name_end == lslash_len && string[name_end] != '.') {
+ name_end = string_len;
+ }
+
+ for (i = name_end - 1; i >= (int)lslash_len; i--) {
+ if (isdigit(string[i])) {
+ if (found_digit) {
+ nums = i;
+ }
+ else {
+ nume = i;
+ nums = i;
+ found_digit = true;
+ }
+ }
+ else {
+ if (found_digit) {
+ break;
+ }
+ }
+ }
+
+ if (found_digit) {
+ const long long int ret = strtoll(&(string[nums]), NULL, 10);
+ if (ret >= INT_MIN && ret <= INT_MAX) {
+ if (tail) {
+ strcpy(tail, &string[nume + 1]);
+ }
+ if (head) {
+ strcpy(head, string);
+ head[nums] = 0;
+ }
+ if (r_num_len) {
+ *r_num_len = nume - nums + 1;
+ }
+ return (int)ret;
+ }
+ }
+
+ if (tail) {
+ strcpy(tail, string + name_end);
+ }
+ if (head) {
+ /* name_end points to last character of head,
+ * make it +1 so null-terminator is nicely placed
+ */
+ BLI_strncpy(head, string, name_end + 1);
+ }
+ if (r_num_len) {
+ *r_num_len = 0;
+ }
+ return 0;
}
-
/**
* Returns in area pointed to by string a string of the form "<head><pic><tail>", where pic
* is formatted as numlen digits with leading zeroes.
*/
-void BLI_stringenc(char *string, const char *head, const char *tail, unsigned short numlen, int pic)
+void BLI_stringenc(
+ char *string, const char *head, const char *tail, unsigned short numlen, int pic)
{
- sprintf(string, "%s%.*d%s", head, numlen, MAX2(0, pic), tail);
+ sprintf(string, "%s%.*d%s", head, numlen, MAX2(0, pic), tail);
}
static int BLI_path_unc_prefix_len(const char *path); /* defined below in same file */
@@ -167,91 +167,91 @@ static int BLI_path_unc_prefix_len(const char *path); /* defined below in same f
*/
void BLI_cleanup_path(const char *relabase, char *path)
{
- ptrdiff_t a;
- char *start, *eind;
- if (relabase) {
- BLI_path_abs(path, relabase);
- }
- else {
- if (path[0] == '/' && path[1] == '/') {
- if (path[2] == '\0') {
- return; /* path is "//" - cant clean it */
- }
- path = path + 2; /* leave the initial "//" untouched */
- }
- }
-
- /* Note
- * memmove(start, eind, strlen(eind) + 1);
- * is the same as
- * strcpy(start, eind);
- * except strcpy should not be used because there is overlap,
- * so use memmove's slightly more obscure syntax - Campbell
- */
+ ptrdiff_t a;
+ char *start, *eind;
+ if (relabase) {
+ BLI_path_abs(path, relabase);
+ }
+ else {
+ if (path[0] == '/' && path[1] == '/') {
+ if (path[2] == '\0') {
+ return; /* path is "//" - cant clean it */
+ }
+ path = path + 2; /* leave the initial "//" untouched */
+ }
+ }
+
+ /* Note
+ * memmove(start, eind, strlen(eind) + 1);
+ * is the same as
+ * strcpy(start, eind);
+ * except strcpy should not be used because there is overlap,
+ * so use memmove's slightly more obscure syntax - Campbell
+ */
#ifdef WIN32
- while ( (start = strstr(path, "\\..\\")) ) {
- eind = start + strlen("\\..\\") - 1;
- a = start - path - 1;
- while (a > 0) {
- if (path[a] == '\\') {
- break;
- }
- a--;
- }
- if (a < 0) {
- break;
- }
- else {
- memmove(path + a, eind, strlen(eind) + 1);
- }
- }
-
- while ( (start = strstr(path, "\\.\\")) ) {
- eind = start + strlen("\\.\\") - 1;
- memmove(start, eind, strlen(eind) + 1);
- }
-
- /* remove two consecutive backslashes, but skip the UNC prefix,
- * which needs to be preserved */
- while ( (start = strstr(path + BLI_path_unc_prefix_len(path), "\\\\")) ) {
- eind = start + strlen("\\\\") - 1;
- memmove(start, eind, strlen(eind) + 1);
- }
+ while ((start = strstr(path, "\\..\\"))) {
+ eind = start + strlen("\\..\\") - 1;
+ a = start - path - 1;
+ while (a > 0) {
+ if (path[a] == '\\') {
+ break;
+ }
+ a--;
+ }
+ if (a < 0) {
+ break;
+ }
+ else {
+ memmove(path + a, eind, strlen(eind) + 1);
+ }
+ }
+
+ while ((start = strstr(path, "\\.\\"))) {
+ eind = start + strlen("\\.\\") - 1;
+ memmove(start, eind, strlen(eind) + 1);
+ }
+
+ /* remove two consecutive backslashes, but skip the UNC prefix,
+ * which needs to be preserved */
+ while ((start = strstr(path + BLI_path_unc_prefix_len(path), "\\\\"))) {
+ eind = start + strlen("\\\\") - 1;
+ memmove(start, eind, strlen(eind) + 1);
+ }
#else
- while ( (start = strstr(path, "/../")) ) {
- a = start - path - 1;
- if (a > 0) {
- /* <prefix>/<parent>/../<postfix> => <prefix>/<postfix> */
- eind = start + (4 - 1) /* strlen("/../") - 1 */; /* strip "/.." and keep last "/" */
- while (a > 0 && path[a] != '/') { /* find start of <parent> */
- a--;
- }
- memmove(path + a, eind, strlen(eind) + 1);
- }
- else {
- /* support for odd paths: eg /../home/me --> /home/me
- * this is a valid path in blender but we cant handle this the usual way below
- * simply strip this prefix then evaluate the path as usual.
- * pythons os.path.normpath() does this */
-
- /* Note: previous version of following call used an offset of 3 instead of 4,
- * which meant that the "/../home/me" example actually became "home/me".
- * Using offset of 3 gives behavior consistent with the abovementioned
- * Python routine. */
- memmove(path, path + 3, strlen(path + 3) + 1);
- }
- }
-
- while ( (start = strstr(path, "/./")) ) {
- eind = start + (3 - 1) /* strlen("/./") - 1 */;
- memmove(start, eind, strlen(eind) + 1);
- }
-
- while ( (start = strstr(path, "//")) ) {
- eind = start + (2 - 1) /* strlen("//") - 1 */;
- memmove(start, eind, strlen(eind) + 1);
- }
+ while ((start = strstr(path, "/../"))) {
+ a = start - path - 1;
+ if (a > 0) {
+ /* <prefix>/<parent>/../<postfix> => <prefix>/<postfix> */
+ eind = start + (4 - 1) /* strlen("/../") - 1 */; /* strip "/.." and keep last "/" */
+ while (a > 0 && path[a] != '/') { /* find start of <parent> */
+ a--;
+ }
+ memmove(path + a, eind, strlen(eind) + 1);
+ }
+ else {
+ /* support for odd paths: eg /../home/me --> /home/me
+ * this is a valid path in blender but we cant handle this the usual way below
+ * simply strip this prefix then evaluate the path as usual.
+ * pythons os.path.normpath() does this */
+
+ /* Note: previous version of following call used an offset of 3 instead of 4,
+ * which meant that the "/../home/me" example actually became "home/me".
+ * Using offset of 3 gives behavior consistent with the abovementioned
+ * Python routine. */
+ memmove(path, path + 3, strlen(path + 3) + 1);
+ }
+ }
+
+ while ((start = strstr(path, "/./"))) {
+ eind = start + (3 - 1) /* strlen("/./") - 1 */;
+ memmove(start, eind, strlen(eind) + 1);
+ }
+
+ while ((start = strstr(path, "//"))) {
+ eind = start + (2 - 1) /* strlen("//") - 1 */;
+ memmove(start, eind, strlen(eind) + 1);
+ }
#endif
}
@@ -260,9 +260,8 @@ void BLI_cleanup_path(const char *relabase, char *path)
*/
void BLI_cleanup_dir(const char *relabase, char *dir)
{
- BLI_cleanup_path(relabase, dir);
- BLI_add_slash(dir);
-
+ BLI_cleanup_path(relabase, dir);
+ BLI_add_slash(dir);
}
/**
@@ -270,11 +269,10 @@ void BLI_cleanup_dir(const char *relabase, char *dir)
*/
void BLI_cleanup_file(const char *relabase, char *path)
{
- BLI_cleanup_path(relabase, path);
- BLI_del_slash(path);
+ BLI_cleanup_path(relabase, path);
+ BLI_del_slash(path);
}
-
/**
* Make given name safe to be used in paths.
*
@@ -296,72 +294,72 @@ void BLI_cleanup_file(const char *relabase, char *path)
*/
bool BLI_filename_make_safe(char *fname)
{
- const char *invalid = "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
- "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
- "/\\?*:|\"<>";
- char *fn;
- bool changed = false;
-
- if (*fname == '\0') {
- return changed;
- }
-
- for (fn = fname; *fn && (fn = strpbrk(fn, invalid)); fn++) {
- *fn = '_';
- changed = true;
- }
-
- /* Forbid only dots. */
- for (fn = fname; *fn == '.'; fn++) {
- /* pass */
- }
- if (*fn == '\0') {
- *fname = '_';
- changed = true;
- }
+ const char *invalid =
+ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+ "/\\?*:|\"<>";
+ char *fn;
+ bool changed = false;
+
+ if (*fname == '\0') {
+ return changed;
+ }
+
+ for (fn = fname; *fn && (fn = strpbrk(fn, invalid)); fn++) {
+ *fn = '_';
+ changed = true;
+ }
+
+ /* Forbid only dots. */
+ for (fn = fname; *fn == '.'; fn++) {
+ /* pass */
+ }
+ if (*fn == '\0') {
+ *fname = '_';
+ changed = true;
+ }
#ifdef WIN32
- {
- const size_t len = strlen(fname);
- const char *invalid_names[] = {
- "con", "prn", "aux", "null",
- "com1", "com2", "com3", "com4", "com5", "com6", "com7", "com8", "com9",
- "lpt1", "lpt2", "lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9",
- NULL,
- };
- char *lower_fname = BLI_strdup(fname);
- const char **iname;
-
- /* Forbid trailing dot (trailing space has already been replaced above). */
- if (fname[len - 1] == '.') {
- fname[len - 1] = '_';
- changed = true;
- }
-
- /* Check for forbidden names - not we have to check all combination
- * of upper and lower cases, hence the usage of lower_fname
- * (more efficient than using BLI_strcasestr repeatedly). */
- BLI_str_tolower_ascii(lower_fname, len);
- for (iname = invalid_names; *iname; iname++) {
- if (strstr(lower_fname, *iname) == lower_fname) {
- const size_t iname_len = strlen(*iname);
- /* Only invalid if the whole name is made of the invalid chunk, or it has an
- * (assumed extension) dot just after. This means it will also catch 'valid'
- * names like 'aux.foo.bar', but should be
- * good enough for us! */
- if ((iname_len == len) || (lower_fname[iname_len] == '.')) {
- *fname = '_';
- changed = true;
- break;
- }
- }
- }
-
- MEM_freeN(lower_fname);
- }
+ {
+ const size_t len = strlen(fname);
+ const char *invalid_names[] = {
+ "con", "prn", "aux", "null", "com1", "com2", "com3", "com4",
+ "com5", "com6", "com7", "com8", "com9", "lpt1", "lpt2", "lpt3",
+ "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9", NULL,
+ };
+ char *lower_fname = BLI_strdup(fname);
+ const char **iname;
+
+ /* Forbid trailing dot (trailing space has already been replaced above). */
+ if (fname[len - 1] == '.') {
+ fname[len - 1] = '_';
+ changed = true;
+ }
+
+ /* Check for forbidden names - not we have to check all combination
+ * of upper and lower cases, hence the usage of lower_fname
+ * (more efficient than using BLI_strcasestr repeatedly). */
+ BLI_str_tolower_ascii(lower_fname, len);
+ for (iname = invalid_names; *iname; iname++) {
+ if (strstr(lower_fname, *iname) == lower_fname) {
+ const size_t iname_len = strlen(*iname);
+ /* Only invalid if the whole name is made of the invalid chunk, or it has an
+ * (assumed extension) dot just after. This means it will also catch 'valid'
+ * names like 'aux.foo.bar', but should be
+ * good enough for us! */
+ if ((iname_len == len) || (lower_fname[iname_len] == '.')) {
+ *fname = '_';
+ changed = true;
+ break;
+ }
+ }
+ }
+
+ MEM_freeN(lower_fname);
+ }
#endif
- return changed;
+ return changed;
}
/**
@@ -371,34 +369,35 @@ bool BLI_filename_make_safe(char *fname)
*/
bool BLI_path_make_safe(char *path)
{
- /* Simply apply BLI_filename_make_safe() over each component of the path.
- * Luckily enough, same 'safe' rules applies to filenames and dirnames. */
- char *curr_slash, *curr_path = path;
- bool changed = false;
- bool skip_first = false;
+ /* Simply apply BLI_filename_make_safe() over each component of the path.
+ * Luckily enough, same 'safe' rules applies to filenames and dirnames. */
+ char *curr_slash, *curr_path = path;
+ bool changed = false;
+ bool skip_first = false;
#ifdef WIN32
- if (BLI_path_is_abs(path)) {
- /* Do not make safe 'C:' in 'C:\foo\bar'... */
- skip_first = true;
- }
+ if (BLI_path_is_abs(path)) {
+ /* Do not make safe 'C:' in 'C:\foo\bar'... */
+ skip_first = true;
+ }
#endif
- for (curr_slash = (char *)BLI_first_slash(curr_path); curr_slash; curr_slash = (char *)BLI_first_slash(curr_path)) {
- const char backup = *curr_slash;
- *curr_slash = '\0';
- if (!skip_first && (*curr_path != '\0') && BLI_filename_make_safe(curr_path)) {
- changed = true;
- }
- skip_first = false;
- curr_path = curr_slash + 1;
- *curr_slash = backup;
- }
- if (BLI_filename_make_safe(curr_path)) {
- changed = true;
- }
-
- return changed;
+ for (curr_slash = (char *)BLI_first_slash(curr_path); curr_slash;
+ curr_slash = (char *)BLI_first_slash(curr_path)) {
+ const char backup = *curr_slash;
+ *curr_slash = '\0';
+ if (!skip_first && (*curr_path != '\0') && BLI_filename_make_safe(curr_path)) {
+ changed = true;
+ }
+ skip_first = false;
+ curr_path = curr_slash + 1;
+ *curr_slash = backup;
+ }
+ if (BLI_filename_make_safe(curr_path)) {
+ changed = true;
+ }
+
+ return changed;
}
/**
@@ -407,13 +406,13 @@ bool BLI_path_make_safe(char *path)
*/
bool BLI_path_is_rel(const char *path)
{
- return path[0] == '/' && path[1] == '/';
+ return path[0] == '/' && path[1] == '/';
}
/* return true if the path is a UNC share */
bool BLI_path_is_unc(const char *name)
{
- return name[0] == '\\' && name[1] == '\\';
+ return name[0] == '\\' && name[1] == '\\';
}
/**
@@ -424,17 +423,17 @@ bool BLI_path_is_unc(const char *name)
*/
static int BLI_path_unc_prefix_len(const char *path)
{
- if (BLI_path_is_unc(path)) {
- if ((path[2] == '?') && (path[3] == '\\') ) {
- /* we assume long UNC path like \\?\server\share\folder etc... */
- return 4;
- }
- else {
- return 2;
- }
- }
-
- return 0;
+ if (BLI_path_is_unc(path)) {
+ if ((path[2] == '?') && (path[3] == '\\')) {
+ /* we assume long UNC path like \\?\server\share\folder etc... */
+ return 4;
+ }
+ else {
+ return 2;
+ }
+ }
+
+ return 0;
}
#if defined(WIN32)
@@ -442,74 +441,69 @@ static int BLI_path_unc_prefix_len(const char *path)
/* return true if the path is absolute ie starts with a drive specifier (eg A:\) or is a UNC path */
static bool BLI_path_is_abs(const char *name)
{
- return (name[1] == ':' && (name[2] == '\\' || name[2] == '/') ) || BLI_path_is_unc(name);
+ return (name[1] == ':' && (name[2] == '\\' || name[2] == '/')) || BLI_path_is_unc(name);
}
static wchar_t *next_slash(wchar_t *path)
{
- wchar_t *slash = path;
- while (*slash && *slash != L'\\') {
- slash++;
- }
- return slash;
+ wchar_t *slash = path;
+ while (*slash && *slash != L'\\') {
+ slash++;
+ }
+ return slash;
}
/* adds a slash if the unc path points sto a share */
static void BLI_path_add_slash_to_share(wchar_t *uncpath)
{
- wchar_t *slash_after_server = next_slash(uncpath + 2);
- if (*slash_after_server) {
- wchar_t *slash_after_share = next_slash(slash_after_server + 1);
- if (!(*slash_after_share)) {
- slash_after_share[0] = L'\\';
- slash_after_share[1] = L'\0';
- }
- }
+ wchar_t *slash_after_server = next_slash(uncpath + 2);
+ if (*slash_after_server) {
+ wchar_t *slash_after_share = next_slash(slash_after_server + 1);
+ if (!(*slash_after_share)) {
+ slash_after_share[0] = L'\\';
+ slash_after_share[1] = L'\0';
+ }
+ }
}
static void BLI_path_unc_to_short(wchar_t *unc)
{
- wchar_t tmp[PATH_MAX];
-
- int len = wcslen(unc);
- /* convert:
- * \\?\UNC\server\share\folder\... to \\server\share\folder\...
- * \\?\C:\ to C:\ and \\?\C:\folder\... to C:\folder\...
- */
- if ((len > 3) &&
- (unc[0] == L'\\') &&
- (unc[1] == L'\\') &&
- (unc[2] == L'?') &&
- ((unc[3] == L'\\') || (unc[3] == L'/')))
- {
- if ((len > 5) && (unc[5] == L':')) {
- wcsncpy(tmp, unc + 4, len - 4);
- tmp[len - 4] = L'\0';
- wcscpy(unc, tmp);
- }
- else if ((len > 7) && (wcsncmp(&unc[4], L"UNC", 3) == 0) &&
- ((unc[7] == L'\\') || (unc[7] == L'/')))
- {
- tmp[0] = L'\\';
- tmp[1] = L'\\';
- wcsncpy(tmp + 2, unc + 8, len - 8);
- tmp[len - 6] = L'\0';
- wcscpy(unc, tmp);
- }
- }
+ wchar_t tmp[PATH_MAX];
+
+ int len = wcslen(unc);
+ /* convert:
+ * \\?\UNC\server\share\folder\... to \\server\share\folder\...
+ * \\?\C:\ to C:\ and \\?\C:\folder\... to C:\folder\...
+ */
+ if ((len > 3) && (unc[0] == L'\\') && (unc[1] == L'\\') && (unc[2] == L'?') &&
+ ((unc[3] == L'\\') || (unc[3] == L'/'))) {
+ if ((len > 5) && (unc[5] == L':')) {
+ wcsncpy(tmp, unc + 4, len - 4);
+ tmp[len - 4] = L'\0';
+ wcscpy(unc, tmp);
+ }
+ else if ((len > 7) && (wcsncmp(&unc[4], L"UNC", 3) == 0) &&
+ ((unc[7] == L'\\') || (unc[7] == L'/'))) {
+ tmp[0] = L'\\';
+ tmp[1] = L'\\';
+ wcsncpy(tmp + 2, unc + 8, len - 8);
+ tmp[len - 6] = L'\0';
+ wcscpy(unc, tmp);
+ }
+ }
}
void BLI_cleanup_unc(char *path, int maxlen)
{
- wchar_t *tmp_16 = alloc_utf16_from_8(path, 1);
- BLI_cleanup_unc_16(tmp_16);
- conv_utf_16_to_8(tmp_16, path, maxlen);
+ wchar_t *tmp_16 = alloc_utf16_from_8(path, 1);
+ BLI_cleanup_unc_16(tmp_16);
+ conv_utf_16_to_8(tmp_16, path, maxlen);
}
void BLI_cleanup_unc_16(wchar_t *path_16)
{
- BLI_path_unc_to_short(path_16);
- BLI_path_add_slash_to_share(path_16);
+ BLI_path_unc_to_short(path_16);
+ BLI_path_add_slash_to_share(path_16);
}
#endif
@@ -519,134 +513,140 @@ void BLI_cleanup_unc_16(wchar_t *path_16)
*/
void BLI_path_rel(char *file, const char *relfile)
{
- const char *lslash;
- char temp[FILE_MAX];
- char res[FILE_MAX];
+ const char *lslash;
+ char temp[FILE_MAX];
+ char res[FILE_MAX];
- /* if file is already relative, bail out */
- if (BLI_path_is_rel(file)) {
- return;
- }
+ /* if file is already relative, bail out */
+ if (BLI_path_is_rel(file)) {
+ return;
+ }
- /* also bail out if relative path is not set */
- if (relfile[0] == '\0') {
- return;
- }
+ /* also bail out if relative path is not set */
+ if (relfile[0] == '\0') {
+ return;
+ }
#ifdef WIN32
- if (BLI_strnlen(relfile, 3) > 2 && !BLI_path_is_abs(relfile)) {
- char *ptemp;
- /* fix missing volume name in relative base,
- * can happen with old recent-files.txt files */
- get_default_root(temp);
- ptemp = &temp[2];
- if (relfile[0] != '\\' && relfile[0] != '/') {
- ptemp++;
- }
- BLI_strncpy(ptemp, relfile, FILE_MAX - 3);
- }
- else {
- BLI_strncpy(temp, relfile, FILE_MAX);
- }
-
- if (BLI_strnlen(file, 3) > 2) {
- bool is_unc = BLI_path_is_unc(file);
-
- /* Ensure paths are both UNC paths or are both drives */
- if (BLI_path_is_unc(temp) != is_unc) {
- return;
- }
-
- /* Ensure both UNC paths are on the same share */
- if (is_unc) {
- int off;
- int slash = 0;
- for (off = 0; temp[off] && slash < 4; off++) {
- if (temp[off] != file[off]) {
- return;
- }
-
- if (temp[off] == '\\') {
- slash++;
- }
- }
- }
- else if (temp[1] == ':' && file[1] == ':' && temp[0] != file[0]) {
- return;
- }
- }
+ if (BLI_strnlen(relfile, 3) > 2 && !BLI_path_is_abs(relfile)) {
+ char *ptemp;
+ /* fix missing volume name in relative base,
+ * can happen with old recent-files.txt files */
+ get_default_root(temp);
+ ptemp = &temp[2];
+ if (relfile[0] != '\\' && relfile[0] != '/') {
+ ptemp++;
+ }
+ BLI_strncpy(ptemp, relfile, FILE_MAX - 3);
+ }
+ else {
+ BLI_strncpy(temp, relfile, FILE_MAX);
+ }
+
+ if (BLI_strnlen(file, 3) > 2) {
+ bool is_unc = BLI_path_is_unc(file);
+
+ /* Ensure paths are both UNC paths or are both drives */
+ if (BLI_path_is_unc(temp) != is_unc) {
+ return;
+ }
+
+ /* Ensure both UNC paths are on the same share */
+ if (is_unc) {
+ int off;
+ int slash = 0;
+ for (off = 0; temp[off] && slash < 4; off++) {
+ if (temp[off] != file[off]) {
+ return;
+ }
+
+ if (temp[off] == '\\') {
+ slash++;
+ }
+ }
+ }
+ else if (temp[1] == ':' && file[1] == ':' && temp[0] != file[0]) {
+ return;
+ }
+ }
#else
- BLI_strncpy(temp, relfile, FILE_MAX);
+ BLI_strncpy(temp, relfile, FILE_MAX);
#endif
- BLI_str_replace_char(temp + BLI_path_unc_prefix_len(temp), '\\', '/');
- BLI_str_replace_char(file + BLI_path_unc_prefix_len(file), '\\', '/');
+ BLI_str_replace_char(temp + BLI_path_unc_prefix_len(temp), '\\', '/');
+ BLI_str_replace_char(file + BLI_path_unc_prefix_len(file), '\\', '/');
- /* remove /./ which confuse the following slash counting... */
- BLI_cleanup_path(NULL, file);
- BLI_cleanup_path(NULL, temp);
+ /* remove /./ which confuse the following slash counting... */
+ BLI_cleanup_path(NULL, file);
+ BLI_cleanup_path(NULL, temp);
- /* the last slash in the file indicates where the path part ends */
- lslash = BLI_last_slash(temp);
+ /* the last slash in the file indicates where the path part ends */
+ lslash = BLI_last_slash(temp);
- if (lslash) {
- /* find the prefix of the filename that is equal for both filenames.
- * This is replaced by the two slashes at the beginning */
- const char *p = temp;
- const char *q = file;
- char *r = res;
+ if (lslash) {
+ /* find the prefix of the filename that is equal for both filenames.
+ * This is replaced by the two slashes at the beginning */
+ const char *p = temp;
+ const char *q = file;
+ char *r = res;
#ifdef WIN32
- while (tolower(*p) == tolower(*q))
+ while (tolower(*p) == tolower(*q))
#else
- while (*p == *q)
+ while (*p == *q)
#endif
- {
- p++;
- q++;
-
- /* don't search beyond the end of the string
- * in the rare case they match */
- if ((*p == '\0') || (*q == '\0')) {
- break;
- }
- }
-
- /* we might have passed the slash when the beginning of a dir matches
- * so we rewind. Only check on the actual filename
- */
- if (*q != '/') {
- while ( (q >= file) && (*q != '/') ) { --q; --p; }
- }
- else if (*p != '/') {
- while ( (p >= temp) && (*p != '/') ) { --p; --q; }
- }
-
- r += BLI_strcpy_rlen(r, "//");
-
- /* p now points to the slash that is at the beginning of the part
- * where the path is different from the relative path.
- * We count the number of directories we need to go up in the
- * hierarchy to arrive at the common 'prefix' of the path
- */
- if (p < temp) {
- p = temp;
- }
- while (p && p < lslash) {
- if (*p == '/') {
- r += BLI_strcpy_rlen(r, "../");
- }
- p++;
- }
-
- /* don't copy the slash at the beginning */
- r += BLI_strcpy_rlen(r, q + 1);
-
-#ifdef WIN32
- BLI_str_replace_char(res + 2, '/', '\\');
+ {
+ p++;
+ q++;
+
+ /* don't search beyond the end of the string
+ * in the rare case they match */
+ if ((*p == '\0') || (*q == '\0')) {
+ break;
+ }
+ }
+
+ /* we might have passed the slash when the beginning of a dir matches
+ * so we rewind. Only check on the actual filename
+ */
+ if (*q != '/') {
+ while ((q >= file) && (*q != '/')) {
+ --q;
+ --p;
+ }
+ }
+ else if (*p != '/') {
+ while ((p >= temp) && (*p != '/')) {
+ --p;
+ --q;
+ }
+ }
+
+ r += BLI_strcpy_rlen(r, "//");
+
+ /* p now points to the slash that is at the beginning of the part
+ * where the path is different from the relative path.
+ * We count the number of directories we need to go up in the
+ * hierarchy to arrive at the common 'prefix' of the path
+ */
+ if (p < temp) {
+ p = temp;
+ }
+ while (p && p < lslash) {
+ if (*p == '/') {
+ r += BLI_strcpy_rlen(r, "../");
+ }
+ p++;
+ }
+
+ /* don't copy the slash at the beginning */
+ r += BLI_strcpy_rlen(r, q + 1);
+
+#ifdef WIN32
+ BLI_str_replace_char(res + 2, '/', '\\');
#endif
- strcpy(file, res);
- }
+ strcpy(file, res);
+ }
}
/**
@@ -664,36 +664,36 @@ void BLI_path_rel(char *file, const char *relfile)
bool BLI_path_suffix(char *string, size_t maxlen, const char *suffix, const char *sep)
{
#ifdef DEBUG_STRSIZE
- memset(string, 0xff, sizeof(*string) * maxlen);
+ memset(string, 0xff, sizeof(*string) * maxlen);
#endif
- const size_t string_len = strlen(string);
- const size_t suffix_len = strlen(suffix);
- const size_t sep_len = strlen(sep);
- ssize_t a;
- char extension[FILE_MAX];
- bool has_extension = false;
-
- if (string_len + sep_len + suffix_len >= maxlen) {
- return false;
- }
-
- for (a = string_len - 1; a >= 0; a--) {
- if (string[a] == '.') {
- has_extension = true;
- break;
- }
- else if (ELEM(string[a], '/', '\\')) {
- break;
- }
- }
-
- if (!has_extension) {
- a = string_len;
- }
-
- BLI_strncpy(extension, string + a, sizeof(extension));
- sprintf(string + a, "%s%s%s", sep, suffix, extension);
- return true;
+ const size_t string_len = strlen(string);
+ const size_t suffix_len = strlen(suffix);
+ const size_t sep_len = strlen(sep);
+ ssize_t a;
+ char extension[FILE_MAX];
+ bool has_extension = false;
+
+ if (string_len + sep_len + suffix_len >= maxlen) {
+ return false;
+ }
+
+ for (a = string_len - 1; a >= 0; a--) {
+ if (string[a] == '.') {
+ has_extension = true;
+ break;
+ }
+ else if (ELEM(string[a], '/', '\\')) {
+ break;
+ }
+ }
+
+ if (!has_extension) {
+ a = string_len;
+ }
+
+ BLI_strncpy(extension, string + a, sizeof(extension));
+ sprintf(string + a, "%s%s%s", sep, suffix, extension);
+ return true;
}
/**
@@ -702,19 +702,19 @@ bool BLI_path_suffix(char *string, size_t maxlen, const char *suffix, const char
*/
bool BLI_parent_dir(char *path)
{
- const char parent_dir[] = {'.', '.', SEP, '\0'}; /* "../" or "..\\" */
- char tmp[FILE_MAX + 4];
-
- BLI_join_dirfile(tmp, sizeof(tmp), path, parent_dir);
- BLI_cleanup_dir(NULL, tmp); /* does all the work of normalizing the path for us */
-
- if (!BLI_path_extension_check(tmp, parent_dir)) {
- strcpy(path, tmp); /* We assume pardir is always shorter... */
- return true;
- }
- else {
- return false;
- }
+ const char parent_dir[] = {'.', '.', SEP, '\0'}; /* "../" or "..\\" */
+ char tmp[FILE_MAX + 4];
+
+ BLI_join_dirfile(tmp, sizeof(tmp), path, parent_dir);
+ BLI_cleanup_dir(NULL, tmp); /* does all the work of normalizing the path for us */
+
+ if (!BLI_path_extension_check(tmp, parent_dir)) {
+ strcpy(path, tmp); /* We assume pardir is always shorter... */
+ return true;
+ }
+ else {
+ return false;
+ }
}
/**
@@ -724,35 +724,35 @@ bool BLI_parent_dir(char *path)
*/
static bool stringframe_chars(const char *path, int *char_start, int *char_end)
{
- uint ch_sta, ch_end, i;
- /* Insert current frame: file### -> file001 */
- ch_sta = ch_end = 0;
- for (i = 0; path[i] != '\0'; i++) {
- if (path[i] == '\\' || path[i] == '/') {
- ch_end = 0; /* this is a directory name, don't use any hashes we found */
- }
- else if (path[i] == '#') {
- ch_sta = i;
- ch_end = ch_sta + 1;
- while (path[ch_end] == '#') {
- ch_end++;
- }
- i = ch_end - 1; /* keep searching */
-
- /* don't break, there may be a slash after this that invalidates the previous #'s */
- }
- }
-
- if (ch_end) {
- *char_start = ch_sta;
- *char_end = ch_end;
- return true;
- }
- else {
- *char_start = -1;
- *char_end = -1;
- return false;
- }
+ uint ch_sta, ch_end, i;
+ /* Insert current frame: file### -> file001 */
+ ch_sta = ch_end = 0;
+ for (i = 0; path[i] != '\0'; i++) {
+ if (path[i] == '\\' || path[i] == '/') {
+ ch_end = 0; /* this is a directory name, don't use any hashes we found */
+ }
+ else if (path[i] == '#') {
+ ch_sta = i;
+ ch_end = ch_sta + 1;
+ while (path[ch_end] == '#') {
+ ch_end++;
+ }
+ i = ch_end - 1; /* keep searching */
+
+ /* don't break, there may be a slash after this that invalidates the previous #'s */
+ }
+ }
+
+ if (ch_end) {
+ *char_start = ch_sta;
+ *char_end = ch_end;
+ return true;
+ }
+ else {
+ *char_start = -1;
+ *char_end = -1;
+ return false;
+ }
}
/**
@@ -761,20 +761,20 @@ static bool stringframe_chars(const char *path, int *char_start, int *char_end)
*/
static void ensure_digits(char *path, int digits)
{
- char *file = (char *)BLI_last_slash(path);
+ char *file = (char *)BLI_last_slash(path);
- if (file == NULL) {
- file = path;
- }
+ if (file == NULL) {
+ file = path;
+ }
- if (strrchr(file, '#') == NULL) {
- int len = strlen(file);
+ if (strrchr(file, '#') == NULL) {
+ int len = strlen(file);
- while (digits--) {
- file[len++] = '#';
- }
- file[len] = '\0';
- }
+ while (digits--) {
+ file[len++] = '#';
+ }
+ file[len] = '\0';
+ }
}
/**
@@ -783,21 +783,20 @@ static void ensure_digits(char *path, int digits)
*/
bool BLI_path_frame(char *path, int frame, int digits)
{
- int ch_sta, ch_end;
-
- if (digits) {
- ensure_digits(path, digits);
- }
-
- if (stringframe_chars(path, &ch_sta, &ch_end)) { /* warning, ch_end is the last # +1 */
- char tmp[FILE_MAX];
- BLI_snprintf(tmp, sizeof(tmp),
- "%.*s%.*d%s",
- ch_sta, path, ch_end - ch_sta, frame, path + ch_end);
- BLI_strncpy(path, tmp, FILE_MAX);
- return true;
- }
- return false;
+ int ch_sta, ch_end;
+
+ if (digits) {
+ ensure_digits(path, digits);
+ }
+
+ if (stringframe_chars(path, &ch_sta, &ch_end)) { /* warning, ch_end is the last # +1 */
+ char tmp[FILE_MAX];
+ BLI_snprintf(
+ tmp, sizeof(tmp), "%.*s%.*d%s", ch_sta, path, ch_end - ch_sta, frame, path + ch_end);
+ BLI_strncpy(path, tmp, FILE_MAX);
+ return true;
+ }
+ return false;
}
/**
@@ -807,21 +806,28 @@ bool BLI_path_frame(char *path, int frame, int digits)
*/
bool BLI_path_frame_range(char *path, int sta, int end, int digits)
{
- int ch_sta, ch_end;
-
- if (digits) {
- ensure_digits(path, digits);
- }
-
- if (stringframe_chars(path, &ch_sta, &ch_end)) { /* warning, ch_end is the last # +1 */
- char tmp[FILE_MAX];
- BLI_snprintf(tmp, sizeof(tmp),
- "%.*s%.*d-%.*d%s",
- ch_sta, path, ch_end - ch_sta, sta, ch_end - ch_sta, end, path + ch_end);
- BLI_strncpy(path, tmp, FILE_MAX);
- return true;
- }
- return false;
+ int ch_sta, ch_end;
+
+ if (digits) {
+ ensure_digits(path, digits);
+ }
+
+ if (stringframe_chars(path, &ch_sta, &ch_end)) { /* warning, ch_end is the last # +1 */
+ char tmp[FILE_MAX];
+ BLI_snprintf(tmp,
+ sizeof(tmp),
+ "%.*s%.*d-%.*d%s",
+ ch_sta,
+ path,
+ ch_end - ch_sta,
+ sta,
+ ch_end - ch_sta,
+ end,
+ path + ch_end);
+ BLI_strncpy(path, tmp, FILE_MAX);
+ return true;
+ }
+ return false;
}
/**
@@ -829,113 +835,112 @@ bool BLI_path_frame_range(char *path, int sta, int end, int digits)
*/
bool BLI_path_frame_get(char *path, int *r_frame, int *r_numdigits)
{
- if (*path) {
- char *file = (char *)BLI_last_slash(path);
- char *c;
- int len, numdigits;
+ if (*path) {
+ char *file = (char *)BLI_last_slash(path);
+ char *c;
+ int len, numdigits;
- numdigits = *r_numdigits = 0;
+ numdigits = *r_numdigits = 0;
- if (file == NULL) {
- file = path;
- }
+ if (file == NULL) {
+ file = path;
+ }
- /* first get the extension part */
- len = strlen(file);
+ /* first get the extension part */
+ len = strlen(file);
- c = file + len;
+ c = file + len;
- /* isolate extension */
- while (--c != file) {
- if (*c == '.') {
- c--;
- break;
- }
- }
+ /* isolate extension */
+ while (--c != file) {
+ if (*c == '.') {
+ c--;
+ break;
+ }
+ }
- /* find start of number */
- while (c != (file - 1) && isdigit(*c)) {
- c--;
- numdigits++;
- }
+ /* find start of number */
+ while (c != (file - 1) && isdigit(*c)) {
+ c--;
+ numdigits++;
+ }
- if (numdigits) {
- char prevchar;
+ if (numdigits) {
+ char prevchar;
- c++;
- prevchar = c[numdigits];
- c[numdigits] = 0;
+ c++;
+ prevchar = c[numdigits];
+ c[numdigits] = 0;
- /* was the number really an extension? */
- *r_frame = atoi(c);
- c[numdigits] = prevchar;
+ /* was the number really an extension? */
+ *r_frame = atoi(c);
+ c[numdigits] = prevchar;
- *r_numdigits = numdigits;
+ *r_numdigits = numdigits;
- return true;
- }
- }
+ return true;
+ }
+ }
- return false;
+ return false;
}
void BLI_path_frame_strip(char *path, char *r_ext)
{
- *r_ext = '\0';
- if (*path == '\0') {
- return;
- }
-
- char *file = (char *)BLI_last_slash(path);
- char *c, *suffix;
- int len;
- int numdigits = 0;
-
- if (file == NULL) {
- file = path;
- }
-
- /* first get the extension part */
- len = strlen(file);
-
- c = file + len;
-
- /* isolate extension */
- while (--c != file) {
- if (*c == '.') {
- c--;
- break;
- }
- }
-
- suffix = c + 1;
-
- /* find start of number */
- while (c != (file - 1) && isdigit(*c)) {
- c--;
- numdigits++;
- }
-
- c++;
-
- int suffix_length = len - (suffix - file);
- BLI_strncpy(r_ext, suffix, suffix_length + 1);
-
- /* replace the number with the suffix and terminate the string */
- while (numdigits--) {
- *c++ = '#';
- }
- *c = '\0';
+ *r_ext = '\0';
+ if (*path == '\0') {
+ return;
+ }
+
+ char *file = (char *)BLI_last_slash(path);
+ char *c, *suffix;
+ int len;
+ int numdigits = 0;
+
+ if (file == NULL) {
+ file = path;
+ }
+
+ /* first get the extension part */
+ len = strlen(file);
+
+ c = file + len;
+
+ /* isolate extension */
+ while (--c != file) {
+ if (*c == '.') {
+ c--;
+ break;
+ }
+ }
+
+ suffix = c + 1;
+
+ /* find start of number */
+ while (c != (file - 1) && isdigit(*c)) {
+ c--;
+ numdigits++;
+ }
+
+ c++;
+
+ int suffix_length = len - (suffix - file);
+ BLI_strncpy(r_ext, suffix, suffix_length + 1);
+
+ /* replace the number with the suffix and terminate the string */
+ while (numdigits--) {
+ *c++ = '#';
+ }
+ *c = '\0';
}
-
/**
* Check if we have '#' chars, usable for #BLI_path_frame, #BLI_path_frame_range
*/
bool BLI_path_frame_check_chars(const char *path)
{
- int ch_sta, ch_end; /* dummy args */
- return stringframe_chars(path, &ch_sta, &ch_end);
+ int ch_sta, ch_end; /* dummy args */
+ return stringframe_chars(path, &ch_sta, &ch_end);
}
/**
@@ -944,40 +949,40 @@ bool BLI_path_frame_check_chars(const char *path)
*/
void BLI_path_to_display_name(char *display_name, int maxlen, const char *name)
{
- /* Strip leading underscores and spaces. */
- int strip_offset = 0;
- while (ELEM(name[strip_offset], '_', ' ')) {
- strip_offset++;
- }
-
- BLI_strncpy(display_name, name + strip_offset, maxlen);
-
- /* Replace underscores with spaces. */
- BLI_str_replace_char(display_name, '_', ' ');
-
- /* Strip extension. */
- BLI_path_extension_replace(display_name, maxlen, "");
-
- /* Test if string has any upper case characters. */
- bool all_lower = true;
- for (int i = 0; display_name[i]; i++) {
- if (isupper(display_name[i])) {
- all_lower = false;
- break;
- }
- }
-
- if (all_lower) {
- /* For full lowercase string, use title case. */
- bool prevspace = true;
- for (int i = 0; display_name[i]; i++) {
- if (prevspace) {
- display_name[i] = toupper(display_name[i]);
- }
-
- prevspace = isspace(display_name[i]);
- }
- }
+ /* Strip leading underscores and spaces. */
+ int strip_offset = 0;
+ while (ELEM(name[strip_offset], '_', ' ')) {
+ strip_offset++;
+ }
+
+ BLI_strncpy(display_name, name + strip_offset, maxlen);
+
+ /* Replace underscores with spaces. */
+ BLI_str_replace_char(display_name, '_', ' ');
+
+ /* Strip extension. */
+ BLI_path_extension_replace(display_name, maxlen, "");
+
+ /* Test if string has any upper case characters. */
+ bool all_lower = true;
+ for (int i = 0; display_name[i]; i++) {
+ if (isupper(display_name[i])) {
+ all_lower = false;
+ break;
+ }
+ }
+
+ if (all_lower) {
+ /* For full lowercase string, use title case. */
+ bool prevspace = true;
+ for (int i = 0; display_name[i]; i++) {
+ if (prevspace) {
+ display_name[i] = toupper(display_name[i]);
+ }
+
+ prevspace = isspace(display_name[i]);
+ }
+ }
}
/**
@@ -992,109 +997,108 @@ void BLI_path_to_display_name(char *display_name, int maxlen, const char *name)
*/
bool BLI_path_abs(char *path, const char *basepath)
{
- const bool wasrelative = BLI_path_is_rel(path);
- char tmp[FILE_MAX];
- char base[FILE_MAX];
+ const bool wasrelative = BLI_path_is_rel(path);
+ char tmp[FILE_MAX];
+ char base[FILE_MAX];
#ifdef WIN32
- /* without this: "" --> "C:\" */
- if (*path == '\0') {
- return wasrelative;
- }
-
- /* we are checking here if we have an absolute path that is not in the current
- * blend file as a lib main - we are basically checking for the case that a
- * UNIX root '/' is passed.
- */
- if (!wasrelative && !BLI_path_is_abs(path)) {
- char *p = path;
- get_default_root(tmp);
- // get rid of the slashes at the beginning of the path
- while (*p == '\\' || *p == '/') {
- p++;
- }
- strcat(tmp, p);
- }
- else {
- BLI_strncpy(tmp, path, FILE_MAX);
- }
+ /* without this: "" --> "C:\" */
+ if (*path == '\0') {
+ return wasrelative;
+ }
+
+ /* we are checking here if we have an absolute path that is not in the current
+ * blend file as a lib main - we are basically checking for the case that a
+ * UNIX root '/' is passed.
+ */
+ if (!wasrelative && !BLI_path_is_abs(path)) {
+ char *p = path;
+ get_default_root(tmp);
+ // get rid of the slashes at the beginning of the path
+ while (*p == '\\' || *p == '/') {
+ p++;
+ }
+ strcat(tmp, p);
+ }
+ else {
+ BLI_strncpy(tmp, path, FILE_MAX);
+ }
#else
- BLI_strncpy(tmp, path, sizeof(tmp));
+ BLI_strncpy(tmp, path, sizeof(tmp));
- /* Check for loading a windows path on a posix system
- * in this case, there is no use in trying C:/ since it
- * will never exist on a unix os.
- *
- * Add a / prefix and lowercase the driveletter, remove the :
- * C:\foo.JPG -> /c/foo.JPG */
+ /* Check for loading a windows path on a posix system
+ * in this case, there is no use in trying C:/ since it
+ * will never exist on a unix os.
+ *
+ * Add a / prefix and lowercase the driveletter, remove the :
+ * C:\foo.JPG -> /c/foo.JPG */
- if (isalpha(tmp[0]) && tmp[1] == ':' && (tmp[2] == '\\' || tmp[2] == '/') ) {
- tmp[1] = tolower(tmp[0]); /* replace ':' with driveletter */
- tmp[0] = '/';
- /* '\' the slash will be converted later */
- }
+ if (isalpha(tmp[0]) && tmp[1] == ':' && (tmp[2] == '\\' || tmp[2] == '/')) {
+ tmp[1] = tolower(tmp[0]); /* replace ':' with driveletter */
+ tmp[0] = '/';
+ /* '\' the slash will be converted later */
+ }
#endif
- /* push slashes into unix mode - strings entering this part are
- * potentially messed up: having both back- and forward slashes.
- * Here we push into one conform direction, and at the end we
- * push them into the system specific dir. This ensures uniformity
- * of paths and solving some problems (and prevent potential future
- * ones) -jesterKing.
- * For UNC paths the first characters containing the UNC prefix
- * shouldn't be switched as we need to distinguish them from
- * paths relative to the .blend file -elubie */
- BLI_str_replace_char(tmp + BLI_path_unc_prefix_len(tmp), '\\', '/');
-
- /* Paths starting with // will get the blend file as their base,
- * this isn't standard in any os but is used in blender all over the place */
- if (wasrelative) {
- const char *lslash;
- BLI_strncpy(base, basepath, sizeof(base));
-
- /* file component is ignored, so don't bother with the trailing slash */
- BLI_cleanup_path(NULL, base);
- lslash = BLI_last_slash(base);
- BLI_str_replace_char(base + BLI_path_unc_prefix_len(base), '\\', '/');
-
- if (lslash) {
- /* length up to and including last "/" */
- const int baselen = (int) (lslash - base) + 1;
- /* use path for temp storage here, we copy back over it right away */
- BLI_strncpy(path, tmp + 2, FILE_MAX); /* strip "//" */
-
- memcpy(tmp, base, baselen); /* prefix with base up to last "/" */
- BLI_strncpy(tmp + baselen, path, sizeof(tmp) - baselen); /* append path after "//" */
- BLI_strncpy(path, tmp, FILE_MAX); /* return as result */
- }
- else {
- /* base doesn't seem to be a directory--ignore it and just strip "//" prefix on path */
- BLI_strncpy(path, tmp + 2, FILE_MAX);
- }
- }
- else {
- /* base ignored */
- BLI_strncpy(path, tmp, FILE_MAX);
- }
+ /* push slashes into unix mode - strings entering this part are
+ * potentially messed up: having both back- and forward slashes.
+ * Here we push into one conform direction, and at the end we
+ * push them into the system specific dir. This ensures uniformity
+ * of paths and solving some problems (and prevent potential future
+ * ones) -jesterKing.
+ * For UNC paths the first characters containing the UNC prefix
+ * shouldn't be switched as we need to distinguish them from
+ * paths relative to the .blend file -elubie */
+ BLI_str_replace_char(tmp + BLI_path_unc_prefix_len(tmp), '\\', '/');
+
+ /* Paths starting with // will get the blend file as their base,
+ * this isn't standard in any os but is used in blender all over the place */
+ if (wasrelative) {
+ const char *lslash;
+ BLI_strncpy(base, basepath, sizeof(base));
+
+ /* file component is ignored, so don't bother with the trailing slash */
+ BLI_cleanup_path(NULL, base);
+ lslash = BLI_last_slash(base);
+ BLI_str_replace_char(base + BLI_path_unc_prefix_len(base), '\\', '/');
+
+ if (lslash) {
+ /* length up to and including last "/" */
+ const int baselen = (int)(lslash - base) + 1;
+ /* use path for temp storage here, we copy back over it right away */
+ BLI_strncpy(path, tmp + 2, FILE_MAX); /* strip "//" */
+
+ memcpy(tmp, base, baselen); /* prefix with base up to last "/" */
+ BLI_strncpy(tmp + baselen, path, sizeof(tmp) - baselen); /* append path after "//" */
+ BLI_strncpy(path, tmp, FILE_MAX); /* return as result */
+ }
+ else {
+ /* base doesn't seem to be a directory--ignore it and just strip "//" prefix on path */
+ BLI_strncpy(path, tmp + 2, FILE_MAX);
+ }
+ }
+ else {
+ /* base ignored */
+ BLI_strncpy(path, tmp, FILE_MAX);
+ }
#ifdef WIN32
- /* skip first two chars, which in case of
- * absolute path will be drive:/blabla and
- * in case of relpath //blabla/. So relpath
- * // will be retained, rest will be nice and
- * shiny win32 backward slashes :) -jesterKing
- */
- BLI_str_replace_char(path + 2, '/', '\\');
+ /* skip first two chars, which in case of
+ * absolute path will be drive:/blabla and
+ * in case of relpath //blabla/. So relpath
+ * // will be retained, rest will be nice and
+ * shiny win32 backward slashes :) -jesterKing
+ */
+ BLI_str_replace_char(path + 2, '/', '\\');
#endif
- /* ensure this is after correcting for path switch */
- BLI_cleanup_path(NULL, path);
+ /* ensure this is after correcting for path switch */
+ BLI_cleanup_path(NULL, path);
- return wasrelative;
+ return wasrelative;
}
-
/**
* Expands path relative to the current working directory, if it was relative.
* Returns true if such expansion was done.
@@ -1105,35 +1109,35 @@ bool BLI_path_abs(char *path, const char *basepath)
bool BLI_path_cwd(char *path, const size_t maxlen)
{
#ifdef DEBUG_STRSIZE
- memset(path, 0xff, sizeof(*path) * maxlen);
+ memset(path, 0xff, sizeof(*path) * maxlen);
#endif
- bool wasrelative = true;
- const int filelen = strlen(path);
+ bool wasrelative = true;
+ const int filelen = strlen(path);
#ifdef WIN32
- if ((filelen >= 3 && BLI_path_is_abs(path)) || BLI_path_is_unc(path)) {
- wasrelative = false;
- }
+ if ((filelen >= 3 && BLI_path_is_abs(path)) || BLI_path_is_unc(path)) {
+ wasrelative = false;
+ }
#else
- if (filelen >= 2 && path[0] == '/') {
- wasrelative = false;
- }
+ if (filelen >= 2 && path[0] == '/') {
+ wasrelative = false;
+ }
#endif
- if (wasrelative) {
- char cwd[FILE_MAX];
- /* in case the full path to the blend isn't used */
- if (BLI_current_working_dir(cwd, sizeof(cwd))) {
- char origpath[FILE_MAX];
- BLI_strncpy(origpath, path, FILE_MAX);
- BLI_join_dirfile(path, maxlen, cwd, origpath);
- }
- else {
- printf("Could not get the current working directory - $PWD for an unknown reason.\n");
- }
- }
-
- return wasrelative;
+ if (wasrelative) {
+ char cwd[FILE_MAX];
+ /* in case the full path to the blend isn't used */
+ if (BLI_current_working_dir(cwd, sizeof(cwd))) {
+ char origpath[FILE_MAX];
+ BLI_strncpy(origpath, path, FILE_MAX);
+ BLI_join_dirfile(path, maxlen, cwd, origpath);
+ }
+ else {
+ printf("Could not get the current working directory - $PWD for an unknown reason.\n");
+ }
+ }
+
+ return wasrelative;
}
#ifdef _WIN32
@@ -1144,107 +1148,104 @@ bool BLI_path_cwd(char *path, const size_t maxlen)
*/
bool BLI_path_program_extensions_add_win32(char *name, const size_t maxlen)
{
- bool retval = false;
- int type;
-
- type = BLI_exists(name);
- if ((type == 0) || S_ISDIR(type)) {
- /* typically 3-5, ".EXE", ".BAT"... etc */
- const int ext_max = 12;
- const char *ext = BLI_getenv("PATHEXT");
- if (ext) {
- const int name_len = strlen(name);
- char *filename = alloca(name_len + ext_max);
- char *filename_ext;
- const char *ext_next;
-
- /* null terminated in the loop */
- memcpy(filename, name, name_len);
- filename_ext = filename + name_len;
-
- do {
- int ext_len;
- ext_next = strchr(ext, ';');
- ext_len = ext_next ? ((ext_next++) - ext) : strlen(ext);
-
- if (LIKELY(ext_len < ext_max)) {
- memcpy(filename_ext, ext, ext_len);
- filename_ext[ext_len] = '\0';
-
- type = BLI_exists(filename);
- if (type && (!S_ISDIR(type))) {
- retval = true;
- BLI_strncpy(name, filename, maxlen);
- break;
- }
- }
- } while ((ext = ext_next));
- }
- }
- else {
- retval = true;
- }
-
- return retval;
+ bool retval = false;
+ int type;
+
+ type = BLI_exists(name);
+ if ((type == 0) || S_ISDIR(type)) {
+ /* typically 3-5, ".EXE", ".BAT"... etc */
+ const int ext_max = 12;
+ const char *ext = BLI_getenv("PATHEXT");
+ if (ext) {
+ const int name_len = strlen(name);
+ char *filename = alloca(name_len + ext_max);
+ char *filename_ext;
+ const char *ext_next;
+
+ /* null terminated in the loop */
+ memcpy(filename, name, name_len);
+ filename_ext = filename + name_len;
+
+ do {
+ int ext_len;
+ ext_next = strchr(ext, ';');
+ ext_len = ext_next ? ((ext_next++) - ext) : strlen(ext);
+
+ if (LIKELY(ext_len < ext_max)) {
+ memcpy(filename_ext, ext, ext_len);
+ filename_ext[ext_len] = '\0';
+
+ type = BLI_exists(filename);
+ if (type && (!S_ISDIR(type))) {
+ retval = true;
+ BLI_strncpy(name, filename, maxlen);
+ break;
+ }
+ }
+ } while ((ext = ext_next));
+ }
+ }
+ else {
+ retval = true;
+ }
+
+ return retval;
}
-#endif /* WIN32 */
+#endif /* WIN32 */
/**
* Search for a binary (executable)
*/
-bool BLI_path_program_search(
- char *fullname, const size_t maxlen,
- const char *name)
+bool BLI_path_program_search(char *fullname, const size_t maxlen, const char *name)
{
#ifdef DEBUG_STRSIZE
- memset(fullname, 0xff, sizeof(*fullname) * maxlen);
+ memset(fullname, 0xff, sizeof(*fullname) * maxlen);
#endif
- const char *path;
- bool retval = false;
+ const char *path;
+ bool retval = false;
#ifdef _WIN32
- const char separator = ';';
+ const char separator = ';';
#else
- const char separator = ':';
+ const char separator = ':';
#endif
- path = BLI_getenv("PATH");
- if (path) {
- char filename[FILE_MAX];
- const char *temp;
-
- do {
- temp = strchr(path, separator);
- if (temp) {
- memcpy(filename, path, temp - path);
- filename[temp - path] = 0;
- path = temp + 1;
- }
- else {
- BLI_strncpy(filename, path, sizeof(filename));
- }
-
- BLI_path_append(filename, maxlen, name);
- if (
+ path = BLI_getenv("PATH");
+ if (path) {
+ char filename[FILE_MAX];
+ const char *temp;
+
+ do {
+ temp = strchr(path, separator);
+ if (temp) {
+ memcpy(filename, path, temp - path);
+ filename[temp - path] = 0;
+ path = temp + 1;
+ }
+ else {
+ BLI_strncpy(filename, path, sizeof(filename));
+ }
+
+ BLI_path_append(filename, maxlen, name);
+ if (
#ifdef _WIN32
- BLI_path_program_extensions_add_win32(filename, maxlen)
+ BLI_path_program_extensions_add_win32(filename, maxlen)
#else
- BLI_exists(filename)
+ BLI_exists(filename)
#endif
- )
- {
- BLI_strncpy(fullname, filename, maxlen);
- retval = true;
- break;
- }
- } while (temp);
- }
-
- if (retval == false) {
- *fullname = '\0';
- }
-
- return retval;
+ ) {
+ BLI_strncpy(fullname, filename, maxlen);
+ retval = true;
+ break;
+ }
+ } while (temp);
+ }
+
+ if (retval == false) {
+ *fullname = '\0';
+ }
+
+ return retval;
}
/**
@@ -1253,23 +1254,22 @@ bool BLI_path_program_search(
*/
void BLI_setenv(const char *env, const char *val)
{
- /* free windows */
+ /* free windows */
#if (defined(WIN32) || defined(WIN64))
- uputenv(env, val);
+ uputenv(env, val);
#else
- /* linux/osx/bsd */
- if (val) {
- setenv(env, val, 1);
- }
- else {
- unsetenv(env);
- }
+ /* linux/osx/bsd */
+ if (val) {
+ setenv(env, val, 1);
+ }
+ else {
+ unsetenv(env);
+ }
#endif
}
-
/**
* Only set an env var if already not there.
* Like Unix setenv(env, val, 0);
@@ -1278,9 +1278,9 @@ void BLI_setenv(const char *env, const char *val)
*/
void BLI_setenv_if_new(const char *env, const char *val)
{
- if (BLI_getenv(env) == NULL) {
- BLI_setenv(env, val);
- }
+ if (BLI_getenv(env) == NULL) {
+ BLI_setenv(env, val);
+ }
}
/**
@@ -1289,40 +1289,39 @@ void BLI_setenv_if_new(const char *env, const char *val)
const char *BLI_getenv(const char *env)
{
#ifdef _MSC_VER
- static char buffer[32767]; /* 32767 is the total size of the environment block on windows*/
- if (GetEnvironmentVariableA(env, buffer, sizeof(buffer))) {
- return buffer;
- }
- else {
- return NULL;
- }
+ static char buffer[32767]; /* 32767 is the total size of the environment block on windows*/
+ if (GetEnvironmentVariableA(env, buffer, sizeof(buffer))) {
+ return buffer;
+ }
+ else {
+ return NULL;
+ }
#else
- return getenv(env);
+ return getenv(env);
#endif
}
-
/**
* Strips off nonexistent (or non-accessible) subdirectories from the end of *dir, leaving the path of
* the lowest-level directory that does exist and we can read.
*/
void BLI_make_exist(char *dir)
{
- bool valid_path = true;
+ bool valid_path = true;
- /* Loop as long as cur path is not a dir, and we can get a parent path. */
- while ((BLI_access(dir, R_OK) != 0) && (valid_path = BLI_parent_dir(dir))) {
- /* pass */
- }
+ /* Loop as long as cur path is not a dir, and we can get a parent path. */
+ while ((BLI_access(dir, R_OK) != 0) && (valid_path = BLI_parent_dir(dir))) {
+ /* pass */
+ }
- /* If we could not find an existing dir, use default root... */
- if (!valid_path || !dir[0]) {
+ /* If we could not find an existing dir, use default root... */
+ if (!valid_path || !dir[0]) {
#ifdef WIN32
- get_default_root(dir);
+ get_default_root(dir);
#else
- strcpy(dir, "/");
+ strcpy(dir, "/");
#endif
- }
+ }
}
/**
@@ -1332,11 +1331,11 @@ void BLI_make_exist(char *dir)
*/
bool BLI_make_existing_file(const char *name)
{
- char di[FILE_MAX];
- BLI_split_dir_part(name, di, sizeof(di));
+ char di[FILE_MAX];
+ BLI_split_dir_part(name, di, sizeof(di));
- /* make if the dir doesn't exist */
- return BLI_dir_create_recursive(di);
+ /* make if the dir doesn't exist */
+ return BLI_dir_create_recursive(di);
}
/**
@@ -1350,137 +1349,139 @@ bool BLI_make_existing_file(const char *name)
*/
void BLI_make_file_string(const char *relabase, char *string, const char *dir, const char *file)
{
- int sl;
-
- if (string) {
- /* ensure this is always set even if dir/file are NULL */
- string[0] = '\0';
-
- if (ELEM(NULL, dir, file)) {
- return; /* We don't want any NULLs */
- }
- }
- else {
- return; /* string is NULL, probably shouldnt happen but return anyway */
- }
-
- /* Resolve relative references */
- if (relabase && dir[0] == '/' && dir[1] == '/') {
- char *lslash;
-
- /* Get the file name, chop everything past the last slash (ie. the filename) */
- strcpy(string, relabase);
-
- lslash = (char *)BLI_last_slash(string);
- if (lslash) {
- *(lslash + 1) = 0;
- }
-
- dir += 2; /* Skip over the relative reference */
- }
+ int sl;
+
+ if (string) {
+ /* ensure this is always set even if dir/file are NULL */
+ string[0] = '\0';
+
+ if (ELEM(NULL, dir, file)) {
+ return; /* We don't want any NULLs */
+ }
+ }
+ else {
+ return; /* string is NULL, probably shouldnt happen but return anyway */
+ }
+
+ /* Resolve relative references */
+ if (relabase && dir[0] == '/' && dir[1] == '/') {
+ char *lslash;
+
+ /* Get the file name, chop everything past the last slash (ie. the filename) */
+ strcpy(string, relabase);
+
+ lslash = (char *)BLI_last_slash(string);
+ if (lslash) {
+ *(lslash + 1) = 0;
+ }
+
+ dir += 2; /* Skip over the relative reference */
+ }
#ifdef WIN32
- else {
- if (BLI_strnlen(dir, 3) >= 2 && dir[1] == ':') {
- BLI_strncpy(string, dir, 3);
- dir += 2;
- }
- else if (BLI_strnlen(dir, 3) >= 2 && BLI_path_is_unc(dir)) {
- string[0] = 0;
- }
- else { /* no drive specified */
- /* first option: get the drive from the relabase if it has one */
- if (relabase && BLI_strnlen(relabase, 3) >= 2 && relabase[1] == ':') {
- BLI_strncpy(string, relabase, 3);
- string[2] = '\\';
- string[3] = '\0';
- }
- else { /* we're out of luck here, guessing the first valid drive, usually c:\ */
- get_default_root(string);
- }
-
- /* ignore leading slashes */
- while (*dir == '/' || *dir == '\\') {
- dir++;
- }
- }
- }
+ else {
+ if (BLI_strnlen(dir, 3) >= 2 && dir[1] == ':') {
+ BLI_strncpy(string, dir, 3);
+ dir += 2;
+ }
+ else if (BLI_strnlen(dir, 3) >= 2 && BLI_path_is_unc(dir)) {
+ string[0] = 0;
+ }
+ else { /* no drive specified */
+ /* first option: get the drive from the relabase if it has one */
+ if (relabase && BLI_strnlen(relabase, 3) >= 2 && relabase[1] == ':') {
+ BLI_strncpy(string, relabase, 3);
+ string[2] = '\\';
+ string[3] = '\0';
+ }
+ else { /* we're out of luck here, guessing the first valid drive, usually c:\ */
+ get_default_root(string);
+ }
+
+ /* ignore leading slashes */
+ while (*dir == '/' || *dir == '\\') {
+ dir++;
+ }
+ }
+ }
#endif
- strcat(string, dir);
+ strcat(string, dir);
- /* Make sure string ends in one (and only one) slash */
- /* first trim all slashes from the end of the string */
- sl = strlen(string);
- while (sl > 0 && (string[sl - 1] == '/' || string[sl - 1] == '\\') ) {
- string[sl - 1] = '\0';
- sl--;
- }
- /* since we've now removed all slashes, put back one slash at the end. */
- strcat(string, "/");
+ /* Make sure string ends in one (and only one) slash */
+ /* first trim all slashes from the end of the string */
+ sl = strlen(string);
+ while (sl > 0 && (string[sl - 1] == '/' || string[sl - 1] == '\\')) {
+ string[sl - 1] = '\0';
+ sl--;
+ }
+ /* since we've now removed all slashes, put back one slash at the end. */
+ strcat(string, "/");
- while (*file && (*file == '/' || *file == '\\')) {
- /* Trim slashes from the front of file */
- file++;
- }
+ while (*file && (*file == '/' || *file == '\\')) {
+ /* Trim slashes from the front of file */
+ file++;
+ }
- strcat(string, file);
+ strcat(string, file);
- /* Push all slashes to the system preferred direction */
- BLI_path_native_slash(string);
+ /* Push all slashes to the system preferred direction */
+ BLI_path_native_slash(string);
}
-static bool path_extension_check_ex(const char *str, const size_t str_len,
- const char *ext, const size_t ext_len)
+static bool path_extension_check_ex(const char *str,
+ const size_t str_len,
+ const char *ext,
+ const size_t ext_len)
{
- BLI_assert(strlen(str) == str_len);
- BLI_assert(strlen(ext) == ext_len);
+ BLI_assert(strlen(str) == str_len);
+ BLI_assert(strlen(ext) == ext_len);
- return (((str_len == 0 || ext_len == 0 || ext_len >= str_len) == 0) &&
- (BLI_strcasecmp(ext, str + str_len - ext_len) == 0));
+ return (((str_len == 0 || ext_len == 0 || ext_len >= str_len) == 0) &&
+ (BLI_strcasecmp(ext, str + str_len - ext_len) == 0));
}
/* does str end with ext. */
bool BLI_path_extension_check(const char *str, const char *ext)
{
- return path_extension_check_ex(str, strlen(str), ext, strlen(ext));
+ return path_extension_check_ex(str, strlen(str), ext, strlen(ext));
}
bool BLI_path_extension_check_n(const char *str, ...)
{
- const size_t str_len = strlen(str);
+ const size_t str_len = strlen(str);
- va_list args;
- const char *ext;
- bool ret = false;
+ va_list args;
+ const char *ext;
+ bool ret = false;
- va_start(args, str);
+ va_start(args, str);
- while ((ext = (const char *) va_arg(args, void *))) {
- if (path_extension_check_ex(str, str_len, ext, strlen(ext))) {
- ret = true;
- break;
- }
- }
+ while ((ext = (const char *)va_arg(args, void *))) {
+ if (path_extension_check_ex(str, str_len, ext, strlen(ext))) {
+ ret = true;
+ break;
+ }
+ }
- va_end(args);
+ va_end(args);
- return ret;
+ return ret;
}
/* does str end with any of the suffixes in *ext_array. */
bool BLI_path_extension_check_array(const char *str, const char **ext_array)
{
- const size_t str_len = strlen(str);
- int i = 0;
+ const size_t str_len = strlen(str);
+ int i = 0;
- while (ext_array[i]) {
- if (path_extension_check_ex(str, str_len, ext_array[i], strlen(ext_array[i]))) {
- return true;
- }
+ while (ext_array[i]) {
+ if (path_extension_check_ex(str, str_len, ext_array[i], strlen(ext_array[i]))) {
+ return true;
+ }
- i++;
- }
- return false;
+ i++;
+ }
+ return false;
}
/**
@@ -1490,28 +1491,28 @@ bool BLI_path_extension_check_array(const char *str, const char **ext_array)
*/
bool BLI_path_extension_check_glob(const char *str, const char *ext_fnmatch)
{
- const char *ext_step = ext_fnmatch;
- char pattern[16];
-
- while (ext_step[0]) {
- const char *ext_next;
- size_t len_ext;
-
- if ((ext_next = strchr(ext_step, ';'))) {
- len_ext = ext_next - ext_step + 1;
- BLI_strncpy(pattern, ext_step, (len_ext > sizeof(pattern)) ? sizeof(pattern) : len_ext);
- }
- else {
- len_ext = BLI_strncpy_rlen(pattern, ext_step, sizeof(pattern));
- }
-
- if (fnmatch(pattern, str, FNM_CASEFOLD) == 0) {
- return true;
- }
- ext_step += len_ext;
- }
-
- return false;
+ const char *ext_step = ext_fnmatch;
+ char pattern[16];
+
+ while (ext_step[0]) {
+ const char *ext_next;
+ size_t len_ext;
+
+ if ((ext_next = strchr(ext_step, ';'))) {
+ len_ext = ext_next - ext_step + 1;
+ BLI_strncpy(pattern, ext_step, (len_ext > sizeof(pattern)) ? sizeof(pattern) : len_ext);
+ }
+ else {
+ len_ext = BLI_strncpy_rlen(pattern, ext_step, sizeof(pattern));
+ }
+
+ if (fnmatch(pattern, str, FNM_CASEFOLD) == 0) {
+ return true;
+ }
+ ext_step += len_ext;
+ }
+
+ return false;
}
/**
@@ -1524,28 +1525,28 @@ bool BLI_path_extension_check_glob(const char *str, const char *ext_fnmatch)
*/
bool BLI_path_extension_glob_validate(char *ext_fnmatch)
{
- bool only_wildcards = false;
-
- for (size_t i = strlen(ext_fnmatch); i-- > 0; ) {
- if (ext_fnmatch[i] == ';') {
- /* Group separator, we truncate here if we only had wildcards so far.
- * Otherwise, all is sound and fine. */
- if (only_wildcards) {
- ext_fnmatch[i] = '\0';
- return true;
- }
- return false;
- }
- if (!ELEM(ext_fnmatch[i], '?', '*')) {
- /* Non-wildcard char, we can break here and consider the pattern valid. */
- return false;
- }
- /* So far, only wildcards in last group of the pattern... */
- only_wildcards = true;
- }
- /* Only one group in the pattern, so even if its only made of wildcard(s),
- * it is assumed vaid. */
- return false;
+ bool only_wildcards = false;
+
+ for (size_t i = strlen(ext_fnmatch); i-- > 0;) {
+ if (ext_fnmatch[i] == ';') {
+ /* Group separator, we truncate here if we only had wildcards so far.
+ * Otherwise, all is sound and fine. */
+ if (only_wildcards) {
+ ext_fnmatch[i] = '\0';
+ return true;
+ }
+ return false;
+ }
+ if (!ELEM(ext_fnmatch[i], '?', '*')) {
+ /* Non-wildcard char, we can break here and consider the pattern valid. */
+ return false;
+ }
+ /* So far, only wildcards in last group of the pattern... */
+ only_wildcards = true;
+ }
+ /* Only one group in the pattern, so even if its only made of wildcard(s),
+ * it is assumed vaid. */
+ return false;
}
/**
@@ -1555,28 +1556,28 @@ bool BLI_path_extension_glob_validate(char *ext_fnmatch)
bool BLI_path_extension_replace(char *path, size_t maxlen, const char *ext)
{
#ifdef DEBUG_STRSIZE
- memset(path, 0xff, sizeof(*path) * maxlen);
+ memset(path, 0xff, sizeof(*path) * maxlen);
#endif
- const size_t path_len = strlen(path);
- const size_t ext_len = strlen(ext);
- ssize_t a;
-
- for (a = path_len - 1; a >= 0; a--) {
- if (ELEM(path[a], '.', '/', '\\')) {
- break;
- }
- }
-
- if ((a < 0) || (path[a] != '.')) {
- a = path_len;
- }
-
- if (a + ext_len >= maxlen) {
- return false;
- }
-
- memcpy(path + a, ext, ext_len + 1);
- return true;
+ const size_t path_len = strlen(path);
+ const size_t ext_len = strlen(ext);
+ ssize_t a;
+
+ for (a = path_len - 1; a >= 0; a--) {
+ if (ELEM(path[a], '.', '/', '\\')) {
+ break;
+ }
+ }
+
+ if ((a < 0) || (path[a] != '.')) {
+ a = path_len;
+ }
+
+ if (a + ext_len >= maxlen) {
+ return false;
+ }
+
+ memcpy(path + a, ext, ext_len + 1);
+ return true;
}
/**
@@ -1585,46 +1586,46 @@ bool BLI_path_extension_replace(char *path, size_t maxlen, const char *ext)
bool BLI_path_extension_ensure(char *path, size_t maxlen, const char *ext)
{
#ifdef DEBUG_STRSIZE
- memset(path, 0xff, sizeof(*path) * maxlen);
+ memset(path, 0xff, sizeof(*path) * maxlen);
#endif
- const size_t path_len = strlen(path);
- const size_t ext_len = strlen(ext);
- ssize_t a;
-
- /* first check the extension is already there */
- if ((ext_len <= path_len) && (STREQ(path + (path_len - ext_len), ext))) {
- return true;
- }
-
- for (a = path_len - 1; a >= 0; a--) {
- if (path[a] == '.') {
- path[a] = '\0';
- }
- else {
- break;
- }
- }
- a++;
-
- if (a + ext_len >= maxlen) {
- return false;
- }
-
- memcpy(path + a, ext, ext_len + 1);
- return true;
+ const size_t path_len = strlen(path);
+ const size_t ext_len = strlen(ext);
+ ssize_t a;
+
+ /* first check the extension is already there */
+ if ((ext_len <= path_len) && (STREQ(path + (path_len - ext_len), ext))) {
+ return true;
+ }
+
+ for (a = path_len - 1; a >= 0; a--) {
+ if (path[a] == '.') {
+ path[a] = '\0';
+ }
+ else {
+ break;
+ }
+ }
+ a++;
+
+ if (a + ext_len >= maxlen) {
+ return false;
+ }
+
+ memcpy(path + a, ext, ext_len + 1);
+ return true;
}
bool BLI_ensure_filename(char *filepath, size_t maxlen, const char *filename)
{
#ifdef DEBUG_STRSIZE
- memset(filepath, 0xff, sizeof(*filepath) * maxlen);
+ memset(filepath, 0xff, sizeof(*filepath) * maxlen);
#endif
- char *c = (char *)BLI_last_slash(filepath);
- if (!c || ((c - filepath) < maxlen - (strlen(filename) + 1))) {
- strcpy(c ? &c[1] : filepath, filename);
- return true;
- }
- return false;
+ char *c = (char *)BLI_last_slash(filepath);
+ if (!c || ((c - filepath) < maxlen - (strlen(filename) + 1))) {
+ strcpy(c ? &c[1] : filepath, filename);
+ return true;
+ }
+ return false;
}
/**
@@ -1635,28 +1636,29 @@ bool BLI_ensure_filename(char *filepath, size_t maxlen, const char *filename)
* - Doesn't use CWD, or deal with relative paths.
* - Only fill's in \a dir and \a file when they are non NULL.
* */
-void BLI_split_dirfile(const char *string, char *dir, char *file, const size_t dirlen, const size_t filelen)
+void BLI_split_dirfile(
+ const char *string, char *dir, char *file, const size_t dirlen, const size_t filelen)
{
#ifdef DEBUG_STRSIZE
- memset(dir, 0xff, sizeof(*dir) * dirlen);
- memset(file, 0xff, sizeof(*file) * filelen);
+ memset(dir, 0xff, sizeof(*dir) * dirlen);
+ memset(file, 0xff, sizeof(*file) * filelen);
#endif
- const char *lslash_str = BLI_last_slash(string);
- const size_t lslash = lslash_str ? (size_t)(lslash_str - string) + 1 : 0;
-
- if (dir) {
- if (lslash) {
- /* +1 to include the slash and the last char */
- BLI_strncpy(dir, string, MIN2(dirlen, lslash + 1));
- }
- else {
- dir[0] = '\0';
- }
- }
-
- if (file) {
- BLI_strncpy(file, string + lslash, filelen);
- }
+ const char *lslash_str = BLI_last_slash(string);
+ const size_t lslash = lslash_str ? (size_t)(lslash_str - string) + 1 : 0;
+
+ if (dir) {
+ if (lslash) {
+ /* +1 to include the slash and the last char */
+ BLI_strncpy(dir, string, MIN2(dirlen, lslash + 1));
+ }
+ else {
+ dir[0] = '\0';
+ }
+ }
+
+ if (file) {
+ BLI_strncpy(file, string + lslash, filelen);
+ }
}
/**
@@ -1664,7 +1666,7 @@ void BLI_split_dirfile(const char *string, char *dir, char *file, const size_t d
*/
void BLI_split_dir_part(const char *string, char *dir, const size_t dirlen)
{
- BLI_split_dirfile(string, dir, NULL, dirlen, 0);
+ BLI_split_dirfile(string, dir, NULL, dirlen, 0);
}
/**
@@ -1672,7 +1674,7 @@ void BLI_split_dir_part(const char *string, char *dir, const size_t dirlen)
*/
void BLI_split_file_part(const char *string, char *file, const size_t filelen)
{
- BLI_split_dirfile(string, NULL, file, 0, filelen);
+ BLI_split_dirfile(string, NULL, file, 0, filelen);
}
/**
@@ -1680,59 +1682,62 @@ void BLI_split_file_part(const char *string, char *file, const size_t filelen)
*/
void BLI_path_append(char *__restrict dst, const size_t maxlen, const char *__restrict file)
{
- size_t dirlen = BLI_strnlen(dst, maxlen);
+ size_t dirlen = BLI_strnlen(dst, maxlen);
- /* inline BLI_add_slash */
- if ((dirlen > 0) && (dst[dirlen - 1] != SEP)) {
- dst[dirlen++] = SEP;
- dst[dirlen] = '\0';
- }
+ /* inline BLI_add_slash */
+ if ((dirlen > 0) && (dst[dirlen - 1] != SEP)) {
+ dst[dirlen++] = SEP;
+ dst[dirlen] = '\0';
+ }
- if (dirlen >= maxlen) {
- return; /* fills the path */
- }
+ if (dirlen >= maxlen) {
+ return; /* fills the path */
+ }
- BLI_strncpy(dst + dirlen, file, maxlen - dirlen);
+ BLI_strncpy(dst + dirlen, file, maxlen - dirlen);
}
/**
* Simple appending of filename to dir, does not check for valid path!
* Puts result into *dst, which may be same area as *dir.
*/
-void BLI_join_dirfile(char *__restrict dst, const size_t maxlen, const char *__restrict dir, const char *__restrict file)
+void BLI_join_dirfile(char *__restrict dst,
+ const size_t maxlen,
+ const char *__restrict dir,
+ const char *__restrict file)
{
#ifdef DEBUG_STRSIZE
- memset(dst, 0xff, sizeof(*dst) * maxlen);
+ memset(dst, 0xff, sizeof(*dst) * maxlen);
#endif
- size_t dirlen = BLI_strnlen(dir, maxlen);
-
- /* args can't match */
- BLI_assert(!ELEM(dst, dir, file));
-
- if (dirlen == maxlen) {
- memcpy(dst, dir, dirlen);
- dst[dirlen - 1] = '\0';
- return; /* dir fills the path */
- }
- else {
- memcpy(dst, dir, dirlen + 1);
- }
-
- if (dirlen + 1 >= maxlen) {
- return; /* fills the path */
- }
-
- /* inline BLI_add_slash */
- if ((dirlen > 0) && !ELEM(dst[dirlen - 1], SEP, ALTSEP)) {
- dst[dirlen++] = SEP;
- dst[dirlen] = '\0';
- }
-
- if (dirlen >= maxlen) {
- return; /* fills the path */
- }
-
- BLI_strncpy(dst + dirlen, file, maxlen - dirlen);
+ size_t dirlen = BLI_strnlen(dir, maxlen);
+
+ /* args can't match */
+ BLI_assert(!ELEM(dst, dir, file));
+
+ if (dirlen == maxlen) {
+ memcpy(dst, dir, dirlen);
+ dst[dirlen - 1] = '\0';
+ return; /* dir fills the path */
+ }
+ else {
+ memcpy(dst, dir, dirlen + 1);
+ }
+
+ if (dirlen + 1 >= maxlen) {
+ return; /* fills the path */
+ }
+
+ /* inline BLI_add_slash */
+ if ((dirlen > 0) && !ELEM(dst[dirlen - 1], SEP, ALTSEP)) {
+ dst[dirlen++] = SEP;
+ dst[dirlen] = '\0';
+ }
+
+ if (dirlen >= maxlen) {
+ return; /* fills the path */
+ }
+
+ BLI_strncpy(dst + dirlen, file, maxlen - dirlen);
}
/**
@@ -1745,81 +1750,81 @@ void BLI_join_dirfile(char *__restrict dst, const size_t maxlen, const char *__r
size_t BLI_path_join(char *__restrict dst, const size_t dst_len, const char *path, ...)
{
#ifdef DEBUG_STRSIZE
- memset(dst, 0xff, sizeof(*dst) * dst_len);
+ memset(dst, 0xff, sizeof(*dst) * dst_len);
#endif
- if (UNLIKELY(dst_len == 0)) {
- return 0;
- }
- const size_t dst_last = dst_len - 1;
- size_t ofs = BLI_strncpy_rlen(dst, path, dst_len);
-
- if (ofs == dst_last) {
- return ofs;
- }
-
- /* remove trailing slashes, unless there are _only_ trailing slashes
- * (allow "//" as the first argument). */
- bool has_trailing_slash = false;
- if (ofs != 0) {
- size_t len = ofs;
- while ((len != 0) && ELEM(path[len - 1], SEP, ALTSEP)) {
- len -= 1;
- }
- if (len != 0) {
- ofs = len;
- }
- has_trailing_slash = (path[len] != '\0');
- }
-
- va_list args;
- va_start(args, path);
- while ((path = (const char *) va_arg(args, const char *))) {
- has_trailing_slash = false;
- const char *path_init = path;
- while (ELEM(path[0], SEP, ALTSEP)) {
- path++;
- }
- size_t len = strlen(path);
- if (len != 0) {
- while ((len != 0) && ELEM(path[len - 1], SEP, ALTSEP)) {
- len -= 1;
- }
-
- if (len != 0) {
- /* the very first path may have a slash at the end */
- if (ofs && !ELEM(dst[ofs - 1], SEP, ALTSEP)) {
- dst[ofs++] = SEP;
- if (ofs == dst_last) {
- break;
- }
- }
- has_trailing_slash = (path[len] != '\0');
- if (ofs + len >= dst_last) {
- len = dst_last - ofs;
- }
- memcpy(&dst[ofs], path, len);
- ofs += len;
- if (ofs == dst_last) {
- break;
- }
- }
- }
- else {
- has_trailing_slash = (path_init != path);
- }
- }
- va_end(args);
-
- if (has_trailing_slash) {
- if ((ofs != dst_last) && (ofs != 0) && (ELEM(dst[ofs - 1], SEP, ALTSEP) == 0)) {
- dst[ofs++] = SEP;
- }
- }
-
- BLI_assert(ofs <= dst_last);
- dst[ofs] = '\0';
-
- return ofs;
+ if (UNLIKELY(dst_len == 0)) {
+ return 0;
+ }
+ const size_t dst_last = dst_len - 1;
+ size_t ofs = BLI_strncpy_rlen(dst, path, dst_len);
+
+ if (ofs == dst_last) {
+ return ofs;
+ }
+
+ /* remove trailing slashes, unless there are _only_ trailing slashes
+ * (allow "//" as the first argument). */
+ bool has_trailing_slash = false;
+ if (ofs != 0) {
+ size_t len = ofs;
+ while ((len != 0) && ELEM(path[len - 1], SEP, ALTSEP)) {
+ len -= 1;
+ }
+ if (len != 0) {
+ ofs = len;
+ }
+ has_trailing_slash = (path[len] != '\0');
+ }
+
+ va_list args;
+ va_start(args, path);
+ while ((path = (const char *)va_arg(args, const char *))) {
+ has_trailing_slash = false;
+ const char *path_init = path;
+ while (ELEM(path[0], SEP, ALTSEP)) {
+ path++;
+ }
+ size_t len = strlen(path);
+ if (len != 0) {
+ while ((len != 0) && ELEM(path[len - 1], SEP, ALTSEP)) {
+ len -= 1;
+ }
+
+ if (len != 0) {
+ /* the very first path may have a slash at the end */
+ if (ofs && !ELEM(dst[ofs - 1], SEP, ALTSEP)) {
+ dst[ofs++] = SEP;
+ if (ofs == dst_last) {
+ break;
+ }
+ }
+ has_trailing_slash = (path[len] != '\0');
+ if (ofs + len >= dst_last) {
+ len = dst_last - ofs;
+ }
+ memcpy(&dst[ofs], path, len);
+ ofs += len;
+ if (ofs == dst_last) {
+ break;
+ }
+ }
+ }
+ else {
+ has_trailing_slash = (path_init != path);
+ }
+ }
+ va_end(args);
+
+ if (has_trailing_slash) {
+ if ((ofs != dst_last) && (ofs != 0) && (ELEM(dst[ofs - 1], SEP, ALTSEP) == 0)) {
+ dst[ofs++] = SEP;
+ }
+ }
+
+ BLI_assert(ofs <= dst_last);
+ dst[ofs] = '\0';
+
+ return ofs;
}
/**
@@ -1830,8 +1835,8 @@ size_t BLI_path_join(char *__restrict dst, const size_t dst_len, const char *pat
*/
const char *BLI_path_basename(const char *path)
{
- const char * const filename = BLI_last_slash(path);
- return filename ? filename + 1 : path;
+ const char *const filename = BLI_last_slash(path);
+ return filename ? filename + 1 : path;
}
/**
@@ -1845,58 +1850,58 @@ const char *BLI_path_basename(const char *path)
*/
bool BLI_path_name_at_index(const char *path, const int index, int *r_offset, int *r_len)
{
- if (index >= 0) {
- int index_step = 0;
- int prev = -1;
- int i = 0;
- while (true) {
- const char c = path[i];
- if (ELEM(c, SEP, ALTSEP, '\0')) {
- if (prev + 1 != i) {
- prev += 1;
- if (index_step == index) {
- *r_offset = prev;
- *r_len = i - prev;
- /* printf("!!! %d %d\n", start, end); */
- return true;
- }
- index_step += 1;
- }
- if (c == '\0') {
- break;
- }
- prev = i;
- }
- i += 1;
- }
- return false;
- }
- else {
- /* negative number, reverse where -1 is the last element */
- int index_step = -1;
- int prev = strlen(path);
- int i = prev - 1;
- while (true) {
- const char c = i >= 0 ? path[i] : '\0';
- if (ELEM(c, SEP, ALTSEP, '\0')) {
- if (prev - 1 != i) {
- i += 1;
- if (index_step == index) {
- *r_offset = i;
- *r_len = prev - i;
- return true;
- }
- index_step -= 1;
- }
- if (c == '\0') {
- break;
- }
- prev = i;
- }
- i -= 1;
- }
- return false;
- }
+ if (index >= 0) {
+ int index_step = 0;
+ int prev = -1;
+ int i = 0;
+ while (true) {
+ const char c = path[i];
+ if (ELEM(c, SEP, ALTSEP, '\0')) {
+ if (prev + 1 != i) {
+ prev += 1;
+ if (index_step == index) {
+ *r_offset = prev;
+ *r_len = i - prev;
+ /* printf("!!! %d %d\n", start, end); */
+ return true;
+ }
+ index_step += 1;
+ }
+ if (c == '\0') {
+ break;
+ }
+ prev = i;
+ }
+ i += 1;
+ }
+ return false;
+ }
+ else {
+ /* negative number, reverse where -1 is the last element */
+ int index_step = -1;
+ int prev = strlen(path);
+ int i = prev - 1;
+ while (true) {
+ const char c = i >= 0 ? path[i] : '\0';
+ if (ELEM(c, SEP, ALTSEP, '\0')) {
+ if (prev - 1 != i) {
+ i += 1;
+ if (index_step == index) {
+ *r_offset = i;
+ *r_len = prev - i;
+ return true;
+ }
+ index_step -= 1;
+ }
+ if (c == '\0') {
+ break;
+ }
+ prev = i;
+ }
+ i -= 1;
+ }
+ return false;
+ }
}
/**
@@ -1904,17 +1909,17 @@ bool BLI_path_name_at_index(const char *path, const int index, int *r_offset, in
*/
const char *BLI_first_slash(const char *string)
{
- const char * const ffslash = strchr(string, '/');
- const char * const fbslash = strchr(string, '\\');
+ const char *const ffslash = strchr(string, '/');
+ const char *const fbslash = strchr(string, '\\');
- if (!ffslash) {
- return fbslash;
- }
- else if (!fbslash) {
- return ffslash;
- }
+ if (!ffslash) {
+ return fbslash;
+ }
+ else if (!fbslash) {
+ return ffslash;
+ }
- return (ffslash < fbslash) ? ffslash : fbslash;
+ return (ffslash < fbslash) ? ffslash : fbslash;
}
/**
@@ -1922,17 +1927,17 @@ const char *BLI_first_slash(const char *string)
*/
const char *BLI_last_slash(const char *string)
{
- const char * const lfslash = strrchr(string, '/');
- const char * const lbslash = strrchr(string, '\\');
+ const char *const lfslash = strrchr(string, '/');
+ const char *const lbslash = strrchr(string, '\\');
- if (!lfslash) {
- return lbslash;
- }
- else if (!lbslash) {
- return lfslash;
- }
+ if (!lfslash) {
+ return lbslash;
+ }
+ else if (!lbslash) {
+ return lfslash;
+ }
- return (lfslash > lbslash) ? lfslash : lbslash;
+ return (lfslash > lbslash) ? lfslash : lbslash;
}
/**
@@ -1941,13 +1946,13 @@ const char *BLI_last_slash(const char *string)
*/
int BLI_add_slash(char *string)
{
- int len = strlen(string);
- if (len == 0 || string[len - 1] != SEP) {
- string[len] = SEP;
- string[len + 1] = '\0';
- return len + 1;
- }
- return len;
+ int len = strlen(string);
+ if (len == 0 || string[len - 1] != SEP) {
+ string[len] = SEP;
+ string[len + 1] = '\0';
+ return len + 1;
+ }
+ return len;
}
/**
@@ -1955,16 +1960,16 @@ int BLI_add_slash(char *string)
*/
void BLI_del_slash(char *string)
{
- int len = strlen(string);
- while (len) {
- if (string[len - 1] == SEP) {
- string[len - 1] = '\0';
- len--;
- }
- else {
- break;
- }
- }
+ int len = strlen(string);
+ while (len) {
+ if (string[len - 1] == SEP) {
+ string[len - 1] = '\0';
+ len--;
+ }
+ else {
+ break;
+ }
+ }
}
/**
@@ -1973,10 +1978,10 @@ void BLI_del_slash(char *string)
void BLI_path_native_slash(char *path)
{
#ifdef WIN32
- if (path && BLI_strnlen(path, 3) > 2) {
- BLI_str_replace_char(path + 2, '/', '\\');
- }
+ if (path && BLI_strnlen(path, 3) > 2) {
+ BLI_str_replace_char(path + 2, '/', '\\');
+ }
#else
- BLI_str_replace_char(path + BLI_path_unc_prefix_len(path), '\\', '/');
+ BLI_str_replace_char(path + BLI_path_unc_prefix_len(path), '\\', '/');
#endif
}
diff --git a/source/blender/blenlib/intern/polyfill_2d.c b/source/blender/blenlib/intern/polyfill_2d.c
index 4044ebad56b..1538b5922b1 100644
--- a/source/blender/blenlib/intern/polyfill_2d.c
+++ b/source/blender/blenlib/intern/polyfill_2d.c
@@ -49,7 +49,7 @@
#include "BLI_memarena.h"
#include "BLI_alloca.h"
-#include "BLI_polyfill_2d.h" /* own include */
+#include "BLI_polyfill_2d.h" /* own include */
#include "BLI_strict_flags.h"
@@ -72,7 +72,6 @@
# include "PIL_time_utildefines.h"
#endif
-
typedef signed char eSign;
#ifdef USE_KDTREE
@@ -99,93 +98,91 @@ typedef bool axis_t;
/* use for sorting */
typedef struct KDTreeNode2D_head {
- uint neg, pos;
- uint index;
+ uint neg, pos;
+ uint index;
} KDTreeNode2D_head;
typedef struct KDTreeNode2D {
- uint neg, pos;
- uint index;
- axis_t axis; /* range is only (0-1) */
- ushort flag;
- uint parent;
+ uint neg, pos;
+ uint index;
+ axis_t axis; /* range is only (0-1) */
+ ushort flag;
+ uint parent;
} KDTreeNode2D;
struct KDTree2D {
- KDTreeNode2D *nodes;
- const float (*coords)[2];
- uint root;
- uint totnode;
- uint *nodes_map; /* index -> node lookup */
+ KDTreeNode2D *nodes;
+ const float (*coords)[2];
+ uint root;
+ uint totnode;
+ uint *nodes_map; /* index -> node lookup */
};
struct KDRange2D {
- float min, max;
+ float min, max;
};
-#endif /* USE_KDTREE */
+#endif /* USE_KDTREE */
enum {
- CONCAVE = -1,
- TANGENTIAL = 0,
- CONVEX = 1,
+ CONCAVE = -1,
+ TANGENTIAL = 0,
+ CONVEX = 1,
};
typedef struct PolyFill {
- struct PolyIndex *indices; /* vertex aligned */
+ struct PolyIndex *indices; /* vertex aligned */
- const float (*coords)[2];
- uint coords_tot;
+ const float (*coords)[2];
+ uint coords_tot;
#ifdef USE_CONVEX_SKIP
- uint coords_tot_concave;
+ uint coords_tot_concave;
#endif
- /* A polygon with n vertices has a triangulation of n-2 triangles. */
- uint (*tris)[3];
- uint tris_tot;
+ /* A polygon with n vertices has a triangulation of n-2 triangles. */
+ uint (*tris)[3];
+ uint tris_tot;
#ifdef USE_KDTREE
- struct KDTree2D kdtree;
+ struct KDTree2D kdtree;
#endif
} PolyFill;
-
/* circular linklist */
typedef struct PolyIndex {
- struct PolyIndex *next, *prev;
- uint index;
- eSign sign;
+ struct PolyIndex *next, *prev;
+ uint index;
+ eSign sign;
} PolyIndex;
-
/* based on libgdx 2013-11-28, apache 2.0 licensed */
static void pf_coord_sign_calc(PolyFill *pf, PolyIndex *pi);
-static PolyIndex *pf_ear_tip_find(
- PolyFill *pf
+static PolyIndex *pf_ear_tip_find(PolyFill *pf
#ifdef USE_CLIP_EVEN
- , PolyIndex *pi_ear_init
+ ,
+ PolyIndex *pi_ear_init
#endif
#ifdef USE_CLIP_SWEEP
- , bool reverse
+ ,
+ bool reverse
#endif
- );
-
-static bool pf_ear_tip_check(PolyFill *pf, PolyIndex *pi_ear_tip);
-static void pf_ear_tip_cut(PolyFill *pf, PolyIndex *pi_ear_tip);
+);
+static bool pf_ear_tip_check(PolyFill *pf, PolyIndex *pi_ear_tip);
+static void pf_ear_tip_cut(PolyFill *pf, PolyIndex *pi_ear_tip);
BLI_INLINE eSign signum_enum(float a)
{
- if (UNLIKELY(a == 0.0f)) {
- return 0;
- }
- else if (a > 0.0f) {
- return 1;
- }
- else {
- return -1;
- }
+ if (UNLIKELY(a == 0.0f)) {
+ return 0;
+ }
+ else if (a > 0.0f) {
+ return 1;
+ }
+ else {
+ return -1;
+ }
}
/**
@@ -196,407 +193,386 @@ BLI_INLINE eSign signum_enum(float a)
*/
BLI_INLINE float area_tri_signed_v2_alt_2x(const float v1[2], const float v2[2], const float v3[2])
{
- return ((v1[0] * (v2[1] - v3[1])) +
- (v2[0] * (v3[1] - v1[1])) +
- (v3[0] * (v1[1] - v2[1])));
+ return ((v1[0] * (v2[1] - v3[1])) + (v2[0] * (v3[1] - v1[1])) + (v3[0] * (v1[1] - v2[1])));
}
-
static eSign span_tri_v2_sign(const float v1[2], const float v2[2], const float v3[2])
{
- return signum_enum(area_tri_signed_v2_alt_2x(v3, v2, v1));
+ return signum_enum(area_tri_signed_v2_alt_2x(v3, v2, v1));
}
-
#ifdef USE_KDTREE
-#define KDNODE_UNSET ((uint)-1)
+# define KDNODE_UNSET ((uint)-1)
enum {
- KDNODE_FLAG_REMOVED = (1 << 0),
+ KDNODE_FLAG_REMOVED = (1 << 0),
};
-static void kdtree2d_new(
- struct KDTree2D *tree,
- uint tot,
- const float (*coords)[2])
+static void kdtree2d_new(struct KDTree2D *tree, uint tot, const float (*coords)[2])
{
- /* set by caller */
- // tree->nodes = nodes;
- tree->coords = coords;
- tree->root = KDNODE_UNSET;
- tree->totnode = tot;
+ /* set by caller */
+ // tree->nodes = nodes;
+ tree->coords = coords;
+ tree->root = KDNODE_UNSET;
+ tree->totnode = tot;
}
/**
* no need for kdtree2d_insert, since we know the coords array.
*/
-static void kdtree2d_init(
- struct KDTree2D *tree,
- const uint coords_tot,
- const PolyIndex *indices)
+static void kdtree2d_init(struct KDTree2D *tree, const uint coords_tot, const PolyIndex *indices)
{
- KDTreeNode2D *node;
- uint i;
-
- for (i = 0, node = tree->nodes; i < coords_tot; i++) {
- if (indices[i].sign != CONVEX) {
- node->neg = node->pos = KDNODE_UNSET;
- node->index = indices[i].index;
- node->axis = 0;
- node->flag = 0;
- node++;
- }
- }
-
- BLI_assert(tree->totnode == (uint)(node - tree->nodes));
+ KDTreeNode2D *node;
+ uint i;
+
+ for (i = 0, node = tree->nodes; i < coords_tot; i++) {
+ if (indices[i].sign != CONVEX) {
+ node->neg = node->pos = KDNODE_UNSET;
+ node->index = indices[i].index;
+ node->axis = 0;
+ node->flag = 0;
+ node++;
+ }
+ }
+
+ BLI_assert(tree->totnode == (uint)(node - tree->nodes));
}
static uint kdtree2d_balance_recursive(
- KDTreeNode2D *nodes, uint totnode, axis_t axis,
- const float (*coords)[2], const uint ofs)
+ KDTreeNode2D *nodes, uint totnode, axis_t axis, const float (*coords)[2], const uint ofs)
{
- KDTreeNode2D *node;
- uint neg, pos, median, i, j;
-
- if (totnode <= 0) {
- return KDNODE_UNSET;
- }
- else if (totnode == 1) {
- return 0 + ofs;
- }
-
- /* quicksort style sorting around median */
- neg = 0;
- pos = totnode - 1;
- median = totnode / 2;
-
- while (pos > neg) {
- const float co = coords[nodes[pos].index][axis];
- i = neg - 1;
- j = pos;
-
- while (1) {
- while (coords[nodes[++i].index][axis] < co) { /* pass */ }
- while (coords[nodes[--j].index][axis] > co && j > neg) { /* pass */ }
-
- if (i >= j) {
- break;
- }
- SWAP(KDTreeNode2D_head, *(KDTreeNode2D_head *)&nodes[i], *(KDTreeNode2D_head *)&nodes[j]);
- }
-
- SWAP(KDTreeNode2D_head, *(KDTreeNode2D_head *)&nodes[i], *(KDTreeNode2D_head *)&nodes[pos]);
- if (i >= median) {
- pos = i - 1;
- }
- if (i <= median) {
- neg = i + 1;
- }
- }
-
- /* set node and sort subnodes */
- node = &nodes[median];
- node->axis = axis;
- axis = !axis;
- node->neg = kdtree2d_balance_recursive(nodes, median, axis, coords, ofs);
- node->pos = kdtree2d_balance_recursive(&nodes[median + 1], (totnode - (median + 1)), axis, coords, (median + 1) + ofs);
-
- return median + ofs;
+ KDTreeNode2D *node;
+ uint neg, pos, median, i, j;
+
+ if (totnode <= 0) {
+ return KDNODE_UNSET;
+ }
+ else if (totnode == 1) {
+ return 0 + ofs;
+ }
+
+ /* quicksort style sorting around median */
+ neg = 0;
+ pos = totnode - 1;
+ median = totnode / 2;
+
+ while (pos > neg) {
+ const float co = coords[nodes[pos].index][axis];
+ i = neg - 1;
+ j = pos;
+
+ while (1) {
+ while (coords[nodes[++i].index][axis] < co) { /* pass */
+ }
+ while (coords[nodes[--j].index][axis] > co && j > neg) { /* pass */
+ }
+
+ if (i >= j) {
+ break;
+ }
+ SWAP(KDTreeNode2D_head, *(KDTreeNode2D_head *)&nodes[i], *(KDTreeNode2D_head *)&nodes[j]);
+ }
+
+ SWAP(KDTreeNode2D_head, *(KDTreeNode2D_head *)&nodes[i], *(KDTreeNode2D_head *)&nodes[pos]);
+ if (i >= median) {
+ pos = i - 1;
+ }
+ if (i <= median) {
+ neg = i + 1;
+ }
+ }
+
+ /* set node and sort subnodes */
+ node = &nodes[median];
+ node->axis = axis;
+ axis = !axis;
+ node->neg = kdtree2d_balance_recursive(nodes, median, axis, coords, ofs);
+ node->pos = kdtree2d_balance_recursive(
+ &nodes[median + 1], (totnode - (median + 1)), axis, coords, (median + 1) + ofs);
+
+ return median + ofs;
}
-static void kdtree2d_balance(
- struct KDTree2D *tree)
+static void kdtree2d_balance(struct KDTree2D *tree)
{
- tree->root = kdtree2d_balance_recursive(tree->nodes, tree->totnode, 0, tree->coords, 0);
+ tree->root = kdtree2d_balance_recursive(tree->nodes, tree->totnode, 0, tree->coords, 0);
}
-
-static void kdtree2d_init_mapping(
- struct KDTree2D *tree)
+static void kdtree2d_init_mapping(struct KDTree2D *tree)
{
- uint i;
- KDTreeNode2D *node;
-
- for (i = 0, node = tree->nodes; i < tree->totnode; i++, node++) {
- if (node->neg != KDNODE_UNSET) {
- tree->nodes[node->neg].parent = i;
- }
- if (node->pos != KDNODE_UNSET) {
- tree->nodes[node->pos].parent = i;
- }
-
- /* build map */
- BLI_assert(tree->nodes_map[node->index] == KDNODE_UNSET);
- tree->nodes_map[node->index] = i;
- }
-
- tree->nodes[tree->root].parent = KDNODE_UNSET;
+ uint i;
+ KDTreeNode2D *node;
+
+ for (i = 0, node = tree->nodes; i < tree->totnode; i++, node++) {
+ if (node->neg != KDNODE_UNSET) {
+ tree->nodes[node->neg].parent = i;
+ }
+ if (node->pos != KDNODE_UNSET) {
+ tree->nodes[node->pos].parent = i;
+ }
+
+ /* build map */
+ BLI_assert(tree->nodes_map[node->index] == KDNODE_UNSET);
+ tree->nodes_map[node->index] = i;
+ }
+
+ tree->nodes[tree->root].parent = KDNODE_UNSET;
}
-static void kdtree2d_node_remove(
- struct KDTree2D *tree,
- uint index)
+static void kdtree2d_node_remove(struct KDTree2D *tree, uint index)
{
- uint node_index = tree->nodes_map[index];
- KDTreeNode2D *node;
-
- if (node_index == KDNODE_UNSET) {
- return;
- }
- else {
- tree->nodes_map[index] = KDNODE_UNSET;
- }
-
- node = &tree->nodes[node_index];
- tree->totnode -= 1;
-
- BLI_assert((node->flag & KDNODE_FLAG_REMOVED) == 0);
- node->flag |= KDNODE_FLAG_REMOVED;
-
- while ((node->neg == KDNODE_UNSET) &&
- (node->pos == KDNODE_UNSET) &&
- (node->parent != KDNODE_UNSET))
- {
- KDTreeNode2D *node_parent = &tree->nodes[node->parent];
-
- BLI_assert((uint)(node - tree->nodes) == node_index);
- if (node_parent->neg == node_index) {
- node_parent->neg = KDNODE_UNSET;
- }
- else {
- BLI_assert(node_parent->pos == node_index);
- node_parent->pos = KDNODE_UNSET;
- }
-
- if (node_parent->flag & KDNODE_FLAG_REMOVED) {
- node_index = node->parent;
- node = node_parent;
- }
- else {
- break;
- }
- }
+ uint node_index = tree->nodes_map[index];
+ KDTreeNode2D *node;
+
+ if (node_index == KDNODE_UNSET) {
+ return;
+ }
+ else {
+ tree->nodes_map[index] = KDNODE_UNSET;
+ }
+
+ node = &tree->nodes[node_index];
+ tree->totnode -= 1;
+
+ BLI_assert((node->flag & KDNODE_FLAG_REMOVED) == 0);
+ node->flag |= KDNODE_FLAG_REMOVED;
+
+ while ((node->neg == KDNODE_UNSET) && (node->pos == KDNODE_UNSET) &&
+ (node->parent != KDNODE_UNSET)) {
+ KDTreeNode2D *node_parent = &tree->nodes[node->parent];
+
+ BLI_assert((uint)(node - tree->nodes) == node_index);
+ if (node_parent->neg == node_index) {
+ node_parent->neg = KDNODE_UNSET;
+ }
+ else {
+ BLI_assert(node_parent->pos == node_index);
+ node_parent->pos = KDNODE_UNSET;
+ }
+
+ if (node_parent->flag & KDNODE_FLAG_REMOVED) {
+ node_index = node->parent;
+ node = node_parent;
+ }
+ else {
+ break;
+ }
+ }
}
-static bool kdtree2d_isect_tri_recursive(
- const struct KDTree2D *tree,
- const uint tri_index[3],
- const float *tri_coords[3],
- const float tri_center[2],
- const struct KDRange2D bounds[2],
- const KDTreeNode2D *node)
+static bool kdtree2d_isect_tri_recursive(const struct KDTree2D *tree,
+ const uint tri_index[3],
+ const float *tri_coords[3],
+ const float tri_center[2],
+ const struct KDRange2D bounds[2],
+ const KDTreeNode2D *node)
{
- const float *co = tree->coords[node->index];
-
- /* bounds then triangle intersect */
- if ((node->flag & KDNODE_FLAG_REMOVED) == 0) {
- /* bounding box test first */
- if ((co[0] >= bounds[0].min) &&
- (co[0] <= bounds[0].max) &&
- (co[1] >= bounds[1].min) &&
- (co[1] <= bounds[1].max))
- {
- if ((span_tri_v2_sign(tri_coords[0], tri_coords[1], co) != CONCAVE) &&
- (span_tri_v2_sign(tri_coords[1], tri_coords[2], co) != CONCAVE) &&
- (span_tri_v2_sign(tri_coords[2], tri_coords[0], co) != CONCAVE))
- {
- if (!ELEM(node->index, tri_index[0], tri_index[1], tri_index[2])) {
- return true;
- }
- }
- }
- }
-
-#define KDTREE2D_ISECT_TRI_RECURSE_NEG \
- (((node->neg != KDNODE_UNSET) && (co[node->axis] >= bounds[node->axis].min)) && \
- (kdtree2d_isect_tri_recursive(tree, tri_index, tri_coords, tri_center, bounds, \
- &tree->nodes[node->neg])))
-#define KDTREE2D_ISECT_TRI_RECURSE_POS \
- (((node->pos != KDNODE_UNSET) && (co[node->axis] <= bounds[node->axis].max)) && \
- (kdtree2d_isect_tri_recursive(tree, tri_index, tri_coords, tri_center, bounds, \
- &tree->nodes[node->pos])))
-
- if (tri_center[node->axis] > co[node->axis]) {
- if (KDTREE2D_ISECT_TRI_RECURSE_POS) {
- return true;
- }
- if (KDTREE2D_ISECT_TRI_RECURSE_NEG) {
- return true;
- }
- }
- else {
- if (KDTREE2D_ISECT_TRI_RECURSE_NEG) {
- return true;
- }
- if (KDTREE2D_ISECT_TRI_RECURSE_POS) {
- return true;
- }
- }
-
-#undef KDTREE2D_ISECT_TRI_RECURSE_NEG
-#undef KDTREE2D_ISECT_TRI_RECURSE_POS
-
- BLI_assert(node->index != KDNODE_UNSET);
-
- return false;
+ const float *co = tree->coords[node->index];
+
+ /* bounds then triangle intersect */
+ if ((node->flag & KDNODE_FLAG_REMOVED) == 0) {
+ /* bounding box test first */
+ if ((co[0] >= bounds[0].min) && (co[0] <= bounds[0].max) && (co[1] >= bounds[1].min) &&
+ (co[1] <= bounds[1].max)) {
+ if ((span_tri_v2_sign(tri_coords[0], tri_coords[1], co) != CONCAVE) &&
+ (span_tri_v2_sign(tri_coords[1], tri_coords[2], co) != CONCAVE) &&
+ (span_tri_v2_sign(tri_coords[2], tri_coords[0], co) != CONCAVE)) {
+ if (!ELEM(node->index, tri_index[0], tri_index[1], tri_index[2])) {
+ return true;
+ }
+ }
+ }
+ }
+
+# define KDTREE2D_ISECT_TRI_RECURSE_NEG \
+ (((node->neg != KDNODE_UNSET) && (co[node->axis] >= bounds[node->axis].min)) && \
+ (kdtree2d_isect_tri_recursive( \
+ tree, tri_index, tri_coords, tri_center, bounds, &tree->nodes[node->neg])))
+# define KDTREE2D_ISECT_TRI_RECURSE_POS \
+ (((node->pos != KDNODE_UNSET) && (co[node->axis] <= bounds[node->axis].max)) && \
+ (kdtree2d_isect_tri_recursive( \
+ tree, tri_index, tri_coords, tri_center, bounds, &tree->nodes[node->pos])))
+
+ if (tri_center[node->axis] > co[node->axis]) {
+ if (KDTREE2D_ISECT_TRI_RECURSE_POS) {
+ return true;
+ }
+ if (KDTREE2D_ISECT_TRI_RECURSE_NEG) {
+ return true;
+ }
+ }
+ else {
+ if (KDTREE2D_ISECT_TRI_RECURSE_NEG) {
+ return true;
+ }
+ if (KDTREE2D_ISECT_TRI_RECURSE_POS) {
+ return true;
+ }
+ }
+
+# undef KDTREE2D_ISECT_TRI_RECURSE_NEG
+# undef KDTREE2D_ISECT_TRI_RECURSE_POS
+
+ BLI_assert(node->index != KDNODE_UNSET);
+
+ return false;
}
-static bool kdtree2d_isect_tri(
- struct KDTree2D *tree,
- const uint ind[3])
+static bool kdtree2d_isect_tri(struct KDTree2D *tree, const uint ind[3])
{
- const float *vs[3];
- uint i;
- struct KDRange2D bounds[2] = {
- {FLT_MAX, -FLT_MAX},
- {FLT_MAX, -FLT_MAX},
- };
- float tri_center[2] = {0.0f, 0.0f};
+ const float *vs[3];
+ uint i;
+ struct KDRange2D bounds[2] = {
+ {FLT_MAX, -FLT_MAX},
+ {FLT_MAX, -FLT_MAX},
+ };
+ float tri_center[2] = {0.0f, 0.0f};
- for (i = 0; i < 3; i++) {
- vs[i] = tree->coords[ind[i]];
+ for (i = 0; i < 3; i++) {
+ vs[i] = tree->coords[ind[i]];
- add_v2_v2(tri_center, vs[i]);
+ add_v2_v2(tri_center, vs[i]);
- CLAMP_MAX(bounds[0].min, vs[i][0]);
- CLAMP_MIN(bounds[0].max, vs[i][0]);
- CLAMP_MAX(bounds[1].min, vs[i][1]);
- CLAMP_MIN(bounds[1].max, vs[i][1]);
- }
+ CLAMP_MAX(bounds[0].min, vs[i][0]);
+ CLAMP_MIN(bounds[0].max, vs[i][0]);
+ CLAMP_MAX(bounds[1].min, vs[i][1]);
+ CLAMP_MIN(bounds[1].max, vs[i][1]);
+ }
- mul_v2_fl(tri_center, 1.0f / 3.0f);
+ mul_v2_fl(tri_center, 1.0f / 3.0f);
- return kdtree2d_isect_tri_recursive(tree, ind, vs, tri_center, bounds, &tree->nodes[tree->root]);
+ return kdtree2d_isect_tri_recursive(tree, ind, vs, tri_center, bounds, &tree->nodes[tree->root]);
}
-#endif /* USE_KDTREE */
-
+#endif /* USE_KDTREE */
static uint *pf_tri_add(PolyFill *pf)
{
- return pf->tris[pf->tris_tot++];
+ return pf->tris[pf->tris_tot++];
}
static void pf_coord_remove(PolyFill *pf, PolyIndex *pi)
{
#ifdef USE_KDTREE
- /* avoid double lookups, since convex coords are ignored when testing intersections */
- if (pf->kdtree.totnode) {
- kdtree2d_node_remove(&pf->kdtree, pi->index);
- }
+ /* avoid double lookups, since convex coords are ignored when testing intersections */
+ if (pf->kdtree.totnode) {
+ kdtree2d_node_remove(&pf->kdtree, pi->index);
+ }
#endif
- pi->next->prev = pi->prev;
- pi->prev->next = pi->next;
+ pi->next->prev = pi->prev;
+ pi->prev->next = pi->next;
- if (UNLIKELY(pf->indices == pi)) {
- pf->indices = pi->next;
- }
+ if (UNLIKELY(pf->indices == pi)) {
+ pf->indices = pi->next;
+ }
#ifdef DEBUG
- pi->index = (uint)-1;
- pi->next = pi->prev = NULL;
+ pi->index = (uint)-1;
+ pi->next = pi->prev = NULL;
#endif
- pf->coords_tot -= 1;
+ pf->coords_tot -= 1;
}
static void pf_triangulate(PolyFill *pf)
{
- /* localize */
- PolyIndex *pi_ear;
+ /* localize */
+ PolyIndex *pi_ear;
#ifdef USE_CLIP_EVEN
- PolyIndex *pi_ear_init = pf->indices;
+ PolyIndex *pi_ear_init = pf->indices;
#endif
#ifdef USE_CLIP_SWEEP
- bool reverse = false;
+ bool reverse = false;
#endif
- while (pf->coords_tot > 3) {
- PolyIndex *pi_prev, *pi_next;
- eSign sign_orig_prev, sign_orig_next;
+ while (pf->coords_tot > 3) {
+ PolyIndex *pi_prev, *pi_next;
+ eSign sign_orig_prev, sign_orig_next;
- pi_ear = pf_ear_tip_find(
- pf
+ pi_ear = pf_ear_tip_find(pf
#ifdef USE_CLIP_EVEN
- , pi_ear_init
+ ,
+ pi_ear_init
#endif
#ifdef USE_CLIP_SWEEP
- , reverse
+ ,
+ reverse
#endif
- );
+ );
#ifdef USE_CONVEX_SKIP
- if (pi_ear->sign != CONVEX) {
- pf->coords_tot_concave -= 1;
- }
+ if (pi_ear->sign != CONVEX) {
+ pf->coords_tot_concave -= 1;
+ }
#endif
- pi_prev = pi_ear->prev;
- pi_next = pi_ear->next;
+ pi_prev = pi_ear->prev;
+ pi_next = pi_ear->next;
- pf_ear_tip_cut(pf, pi_ear);
+ pf_ear_tip_cut(pf, pi_ear);
- /* The type of the two vertices adjacent to the clipped vertex may have changed. */
- sign_orig_prev = pi_prev->sign;
- sign_orig_next = pi_next->sign;
+ /* The type of the two vertices adjacent to the clipped vertex may have changed. */
+ sign_orig_prev = pi_prev->sign;
+ sign_orig_next = pi_next->sign;
- /* check if any verts became convex the (else if)
- * case is highly unlikely but may happen with degenerate polygons */
- if (sign_orig_prev != CONVEX) {
- pf_coord_sign_calc(pf, pi_prev);
+ /* check if any verts became convex the (else if)
+ * case is highly unlikely but may happen with degenerate polygons */
+ if (sign_orig_prev != CONVEX) {
+ pf_coord_sign_calc(pf, pi_prev);
#ifdef USE_CONVEX_SKIP
- if (pi_prev->sign == CONVEX) {
- pf->coords_tot_concave -= 1;
-#ifdef USE_KDTREE
- kdtree2d_node_remove(&pf->kdtree, pi_prev->index);
-#endif
- }
-#endif
- }
- if (sign_orig_next != CONVEX) {
- pf_coord_sign_calc(pf, pi_next);
+ if (pi_prev->sign == CONVEX) {
+ pf->coords_tot_concave -= 1;
+# ifdef USE_KDTREE
+ kdtree2d_node_remove(&pf->kdtree, pi_prev->index);
+# endif
+ }
+#endif
+ }
+ if (sign_orig_next != CONVEX) {
+ pf_coord_sign_calc(pf, pi_next);
#ifdef USE_CONVEX_SKIP
- if (pi_next->sign == CONVEX) {
- pf->coords_tot_concave -= 1;
-#ifdef USE_KDTREE
- kdtree2d_node_remove(&pf->kdtree, pi_next->index);
+ if (pi_next->sign == CONVEX) {
+ pf->coords_tot_concave -= 1;
+# ifdef USE_KDTREE
+ kdtree2d_node_remove(&pf->kdtree, pi_next->index);
+# endif
+ }
#endif
- }
-#endif
- }
+ }
#ifdef USE_CLIP_EVEN
-#ifdef USE_CLIP_SWEEP
- pi_ear_init = reverse ? pi_prev->prev : pi_next->next;
-#else
- pi_ear_init = pi_next->next;
-#endif
+# ifdef USE_CLIP_SWEEP
+ pi_ear_init = reverse ? pi_prev->prev : pi_next->next;
+# else
+ pi_ear_init = pi_next->next;
+# endif
#endif
#ifdef USE_CLIP_EVEN
-#ifdef USE_CLIP_SWEEP
- if (pi_ear_init->sign != CONVEX) {
- /* take the extra step since this ear isn't a good candidate */
- pi_ear_init = reverse ? pi_ear_init->prev : pi_ear_init->next;
- reverse = !reverse;
- }
-#endif
+# ifdef USE_CLIP_SWEEP
+ if (pi_ear_init->sign != CONVEX) {
+ /* take the extra step since this ear isn't a good candidate */
+ pi_ear_init = reverse ? pi_ear_init->prev : pi_ear_init->next;
+ reverse = !reverse;
+ }
+# endif
#else
- if ((reverse ? pi_prev->prev : pi_next->next)->sign != CONVEX) {
- reverse = !reverse;
- }
-#endif
-
- }
-
- if (pf->coords_tot == 3) {
- uint *tri = pf_tri_add(pf);
- pi_ear = pf->indices;
- tri[0] = pi_ear->index; pi_ear = pi_ear->next;
- tri[1] = pi_ear->index; pi_ear = pi_ear->next;
- tri[2] = pi_ear->index;
- }
+ if ((reverse ? pi_prev->prev : pi_next->next)->sign != CONVEX) {
+ reverse = !reverse;
+ }
+#endif
+ }
+
+ if (pf->coords_tot == 3) {
+ uint *tri = pf_tri_add(pf);
+ pi_ear = pf->indices;
+ tri[0] = pi_ear->index;
+ pi_ear = pi_ear->next;
+ tri[1] = pi_ear->index;
+ pi_ear = pi_ear->next;
+ tri[2] = pi_ear->index;
+ }
}
/**
@@ -604,319 +580,311 @@ static void pf_triangulate(PolyFill *pf)
*/
static void pf_coord_sign_calc(PolyFill *pf, PolyIndex *pi)
{
- /* localize */
- const float (*coords)[2] = pf->coords;
+ /* localize */
+ const float(*coords)[2] = pf->coords;
- pi->sign = span_tri_v2_sign(
- coords[pi->prev->index],
- coords[pi->index],
- coords[pi->next->index]);
+ pi->sign = span_tri_v2_sign(coords[pi->prev->index], coords[pi->index], coords[pi->next->index]);
}
-static PolyIndex *pf_ear_tip_find(
- PolyFill *pf
+static PolyIndex *pf_ear_tip_find(PolyFill *pf
#ifdef USE_CLIP_EVEN
- , PolyIndex *pi_ear_init
+ ,
+ PolyIndex *pi_ear_init
#endif
#ifdef USE_CLIP_SWEEP
- , bool reverse
+ ,
+ bool reverse
#endif
- )
+)
{
- /* localize */
- const uint coords_tot = pf->coords_tot;
- PolyIndex *pi_ear;
+ /* localize */
+ const uint coords_tot = pf->coords_tot;
+ PolyIndex *pi_ear;
- uint i;
+ uint i;
#ifdef USE_CLIP_EVEN
- pi_ear = pi_ear_init;
+ pi_ear = pi_ear_init;
#else
- pi_ear = pf->indices;
+ pi_ear = pf->indices;
#endif
- i = coords_tot;
- while (i--) {
- if (pf_ear_tip_check(pf, pi_ear)) {
- return pi_ear;
- }
+ i = coords_tot;
+ while (i--) {
+ if (pf_ear_tip_check(pf, pi_ear)) {
+ return pi_ear;
+ }
#ifdef USE_CLIP_SWEEP
- pi_ear = reverse ? pi_ear->prev : pi_ear->next;
+ pi_ear = reverse ? pi_ear->prev : pi_ear->next;
#else
- pi_ear = pi_ear->next;
-#endif
- }
-
- /* Desperate mode: if no vertex is an ear tip,
- * we are dealing with a degenerate polygon (e.g. nearly collinear).
- * Note that the input was not necessarily degenerate,
- * but we could have made it so by clipping some valid ears.
- *
- * Idea taken from Martin Held, "FIST: Fast industrial-strength triangulation of polygons",
- * Algorithmica (1998),
- * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.115.291
- *
- * Return a convex or tangential vertex if one exists.
- */
+ pi_ear = pi_ear->next;
+#endif
+ }
+
+ /* Desperate mode: if no vertex is an ear tip,
+ * we are dealing with a degenerate polygon (e.g. nearly collinear).
+ * Note that the input was not necessarily degenerate,
+ * but we could have made it so by clipping some valid ears.
+ *
+ * Idea taken from Martin Held, "FIST: Fast industrial-strength triangulation of polygons",
+ * Algorithmica (1998),
+ * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.115.291
+ *
+ * Return a convex or tangential vertex if one exists.
+ */
#ifdef USE_CLIP_EVEN
- pi_ear = pi_ear_init;
+ pi_ear = pi_ear_init;
#else
- pi_ear = pf->indices;
+ pi_ear = pf->indices;
#endif
- i = coords_tot;
- while (i--) {
- if (pi_ear->sign != CONCAVE) {
- return pi_ear;
- }
- pi_ear = pi_ear->next;
- }
+ i = coords_tot;
+ while (i--) {
+ if (pi_ear->sign != CONCAVE) {
+ return pi_ear;
+ }
+ pi_ear = pi_ear->next;
+ }
- /* If all vertices are concave, just return the last one. */
- return pi_ear;
+ /* If all vertices are concave, just return the last one. */
+ return pi_ear;
}
static bool pf_ear_tip_check(PolyFill *pf, PolyIndex *pi_ear_tip)
{
#ifndef USE_KDTREE
- /* localize */
- const float (*coords)[2] = pf->coords;
- PolyIndex *pi_curr;
+ /* localize */
+ const float(*coords)[2] = pf->coords;
+ PolyIndex *pi_curr;
- const float *v1, *v2, *v3;
+ const float *v1, *v2, *v3;
#endif
#if defined(USE_CONVEX_SKIP) && !defined(USE_KDTREE)
- uint coords_tot_concave_checked = 0;
+ uint coords_tot_concave_checked = 0;
#endif
-
#ifdef USE_CONVEX_SKIP
-#ifdef USE_CONVEX_SKIP_TEST
- /* check if counting is wrong */
- {
- uint coords_tot_concave_test = 0;
- PolyIndex *pi_iter = pi_ear_tip;
- do {
- if (pi_iter->sign != CONVEX) {
- coords_tot_concave_test += 1;
- }
- } while ((pi_iter = pi_iter->next) != pi_ear_tip);
- BLI_assert(coords_tot_concave_test == pf->coords_tot_concave);
- }
-#endif
-
- /* fast-path for circles */
- if (pf->coords_tot_concave == 0) {
- return true;
- }
-#endif
-
- if (UNLIKELY(pi_ear_tip->sign == CONCAVE)) {
- return false;
- }
+# ifdef USE_CONVEX_SKIP_TEST
+ /* check if counting is wrong */
+ {
+ uint coords_tot_concave_test = 0;
+ PolyIndex *pi_iter = pi_ear_tip;
+ do {
+ if (pi_iter->sign != CONVEX) {
+ coords_tot_concave_test += 1;
+ }
+ } while ((pi_iter = pi_iter->next) != pi_ear_tip);
+ BLI_assert(coords_tot_concave_test == pf->coords_tot_concave);
+ }
+# endif
+
+ /* fast-path for circles */
+ if (pf->coords_tot_concave == 0) {
+ return true;
+ }
+#endif
+
+ if (UNLIKELY(pi_ear_tip->sign == CONCAVE)) {
+ return false;
+ }
#ifdef USE_KDTREE
- {
- const uint ind[3] = {
- pi_ear_tip->index,
- pi_ear_tip->next->index,
- pi_ear_tip->prev->index};
-
- if (kdtree2d_isect_tri(&pf->kdtree, ind)) {
- return false;
- }
- }
-#else
+ {
+ const uint ind[3] = {pi_ear_tip->index, pi_ear_tip->next->index, pi_ear_tip->prev->index};
- v1 = coords[pi_ear_tip->prev->index];
- v2 = coords[pi_ear_tip->index];
- v3 = coords[pi_ear_tip->next->index];
-
- /* Check if any point is inside the triangle formed by previous, current and next vertices.
- * Only consider vertices that are not part of this triangle,
- * or else we'll always find one inside. */
-
- for (pi_curr = pi_ear_tip->next->next; pi_curr != pi_ear_tip->prev; pi_curr = pi_curr->next) {
- /* Concave vertices can obviously be inside the candidate ear,
- * but so can tangential vertices if they coincide with one of the triangle's vertices. */
- if (pi_curr->sign != CONVEX) {
- const float *v = coords[pi_curr->index];
- /* Because the polygon has clockwise winding order,
- * the area sign will be positive if the point is strictly inside.
- * It will be 0 on the edge, which we want to include as well. */
-
- /* note: check (v3, v1) first since it fails _far_ more often then the other 2 checks
- * (those fail equally).
- * It's logical - the chance is low that points exist on the
- * same side as the ear we're clipping off. */
- if ((span_tri_v2_sign(v3, v1, v) != CONCAVE) &&
- (span_tri_v2_sign(v1, v2, v) != CONCAVE) &&
- (span_tri_v2_sign(v2, v3, v) != CONCAVE))
- {
- return false;
- }
-
-#ifdef USE_CONVEX_SKIP
- coords_tot_concave_checked += 1;
- if (coords_tot_concave_checked == pf->coords_tot_concave) {
- break;
- }
-#endif
- }
- }
-#endif /* USE_KDTREE */
+ if (kdtree2d_isect_tri(&pf->kdtree, ind)) {
+ return false;
+ }
+ }
+#else
- return true;
+ v1 = coords[pi_ear_tip->prev->index];
+ v2 = coords[pi_ear_tip->index];
+ v3 = coords[pi_ear_tip->next->index];
+
+ /* Check if any point is inside the triangle formed by previous, current and next vertices.
+ * Only consider vertices that are not part of this triangle,
+ * or else we'll always find one inside. */
+
+ for (pi_curr = pi_ear_tip->next->next; pi_curr != pi_ear_tip->prev; pi_curr = pi_curr->next) {
+ /* Concave vertices can obviously be inside the candidate ear,
+ * but so can tangential vertices if they coincide with one of the triangle's vertices. */
+ if (pi_curr->sign != CONVEX) {
+ const float *v = coords[pi_curr->index];
+ /* Because the polygon has clockwise winding order,
+ * the area sign will be positive if the point is strictly inside.
+ * It will be 0 on the edge, which we want to include as well. */
+
+ /* note: check (v3, v1) first since it fails _far_ more often then the other 2 checks
+ * (those fail equally).
+ * It's logical - the chance is low that points exist on the
+ * same side as the ear we're clipping off. */
+ if ((span_tri_v2_sign(v3, v1, v) != CONCAVE) && (span_tri_v2_sign(v1, v2, v) != CONCAVE) &&
+ (span_tri_v2_sign(v2, v3, v) != CONCAVE)) {
+ return false;
+ }
+
+# ifdef USE_CONVEX_SKIP
+ coords_tot_concave_checked += 1;
+ if (coords_tot_concave_checked == pf->coords_tot_concave) {
+ break;
+ }
+# endif
+ }
+ }
+#endif /* USE_KDTREE */
+
+ return true;
}
static void pf_ear_tip_cut(PolyFill *pf, PolyIndex *pi_ear_tip)
{
- uint *tri = pf_tri_add(pf);
+ uint *tri = pf_tri_add(pf);
- tri[0] = pi_ear_tip->prev->index;
- tri[1] = pi_ear_tip->index;
- tri[2] = pi_ear_tip->next->index;
+ tri[0] = pi_ear_tip->prev->index;
+ tri[1] = pi_ear_tip->index;
+ tri[2] = pi_ear_tip->next->index;
- pf_coord_remove(pf, pi_ear_tip);
+ pf_coord_remove(pf, pi_ear_tip);
}
/**
* Initializes the #PolyFill structure before tessellating with #polyfill_calc.
*/
-static void polyfill_prepare(
- PolyFill *pf,
- const float (*coords)[2],
- const uint coords_tot,
- int coords_sign,
- uint (*r_tris)[3],
- PolyIndex *r_indices)
+static void polyfill_prepare(PolyFill *pf,
+ const float (*coords)[2],
+ const uint coords_tot,
+ int coords_sign,
+ uint (*r_tris)[3],
+ PolyIndex *r_indices)
{
- /* localize */
- PolyIndex *indices = r_indices;
+ /* localize */
+ PolyIndex *indices = r_indices;
- uint i;
+ uint i;
- /* assign all polyfill members here */
- pf->indices = r_indices;
- pf->coords = coords;
- pf->coords_tot = coords_tot;
+ /* assign all polyfill members here */
+ pf->indices = r_indices;
+ pf->coords = coords;
+ pf->coords_tot = coords_tot;
#ifdef USE_CONVEX_SKIP
- pf->coords_tot_concave = 0;
+ pf->coords_tot_concave = 0;
#endif
- pf->tris = r_tris;
- pf->tris_tot = 0;
+ pf->tris = r_tris;
+ pf->tris_tot = 0;
- if (coords_sign == 0) {
- coords_sign = (cross_poly_v2(coords, coords_tot) >= 0.0f) ? 1 : -1;
- }
- else {
- /* check we're passing in correcty args */
+ if (coords_sign == 0) {
+ coords_sign = (cross_poly_v2(coords, coords_tot) >= 0.0f) ? 1 : -1;
+ }
+ else {
+ /* check we're passing in correcty args */
#ifdef USE_STRICT_ASSERT
-#ifndef NDEBUG
- if (coords_sign == 1) {
- BLI_assert(cross_poly_v2(coords, coords_tot) >= 0.0f);
- }
- else {
- BLI_assert(cross_poly_v2(coords, coords_tot) <= 0.0f);
- }
-#endif
-#endif
- }
-
- if (coords_sign == 1) {
- for (i = 0; i < coords_tot; i++) {
- indices[i].next = &indices[i + 1];
- indices[i].prev = &indices[i - 1];
- indices[i].index = i;
- }
- }
- else {
- /* reversed */
- uint n = coords_tot - 1;
- for (i = 0; i < coords_tot; i++) {
- indices[i].next = &indices[i + 1];
- indices[i].prev = &indices[i - 1];
- indices[i].index = (n - i);
- }
- }
- indices[0].prev = &indices[coords_tot - 1];
- indices[coords_tot - 1].next = &indices[0];
-
- for (i = 0; i < coords_tot; i++) {
- PolyIndex *pi = &indices[i];
- pf_coord_sign_calc(pf, pi);
+# ifndef NDEBUG
+ if (coords_sign == 1) {
+ BLI_assert(cross_poly_v2(coords, coords_tot) >= 0.0f);
+ }
+ else {
+ BLI_assert(cross_poly_v2(coords, coords_tot) <= 0.0f);
+ }
+# endif
+#endif
+ }
+
+ if (coords_sign == 1) {
+ for (i = 0; i < coords_tot; i++) {
+ indices[i].next = &indices[i + 1];
+ indices[i].prev = &indices[i - 1];
+ indices[i].index = i;
+ }
+ }
+ else {
+ /* reversed */
+ uint n = coords_tot - 1;
+ for (i = 0; i < coords_tot; i++) {
+ indices[i].next = &indices[i + 1];
+ indices[i].prev = &indices[i - 1];
+ indices[i].index = (n - i);
+ }
+ }
+ indices[0].prev = &indices[coords_tot - 1];
+ indices[coords_tot - 1].next = &indices[0];
+
+ for (i = 0; i < coords_tot; i++) {
+ PolyIndex *pi = &indices[i];
+ pf_coord_sign_calc(pf, pi);
#ifdef USE_CONVEX_SKIP
- if (pi->sign != CONVEX) {
- pf->coords_tot_concave += 1;
- }
+ if (pi->sign != CONVEX) {
+ pf->coords_tot_concave += 1;
+ }
#endif
- }
+ }
}
-static void polyfill_calc(
- PolyFill *pf)
+static void polyfill_calc(PolyFill *pf)
{
#ifdef USE_KDTREE
-#ifdef USE_CONVEX_SKIP
- if (pf->coords_tot_concave)
-#endif
- {
- kdtree2d_new(&pf->kdtree, pf->coords_tot_concave, pf->coords);
- kdtree2d_init(&pf->kdtree, pf->coords_tot, pf->indices);
- kdtree2d_balance(&pf->kdtree);
- kdtree2d_init_mapping(&pf->kdtree);
- }
-#endif
-
- pf_triangulate(pf);
+# ifdef USE_CONVEX_SKIP
+ if (pf->coords_tot_concave)
+# endif
+ {
+ kdtree2d_new(&pf->kdtree, pf->coords_tot_concave, pf->coords);
+ kdtree2d_init(&pf->kdtree, pf->coords_tot, pf->indices);
+ kdtree2d_balance(&pf->kdtree);
+ kdtree2d_init_mapping(&pf->kdtree);
+ }
+#endif
+
+ pf_triangulate(pf);
}
/**
* A version of #BLI_polyfill_calc that uses a memory arena to avoid re-allocations.
*/
-void BLI_polyfill_calc_arena(
- const float (*coords)[2],
- const uint coords_tot,
- const int coords_sign,
- uint (*r_tris)[3],
+void BLI_polyfill_calc_arena(const float (*coords)[2],
+ const uint coords_tot,
+ const int coords_sign,
+ uint (*r_tris)[3],
- struct MemArena *arena)
+ struct MemArena *arena)
{
- PolyFill pf;
- PolyIndex *indices = BLI_memarena_alloc(arena, sizeof(*indices) * coords_tot);
+ PolyFill pf;
+ PolyIndex *indices = BLI_memarena_alloc(arena, sizeof(*indices) * coords_tot);
#ifdef DEBUG_TIME
- TIMEIT_START(polyfill2d);
+ TIMEIT_START(polyfill2d);
#endif
- polyfill_prepare(
- &pf,
- coords, coords_tot, coords_sign,
- r_tris,
- /* cache */
- indices);
+ polyfill_prepare(&pf,
+ coords,
+ coords_tot,
+ coords_sign,
+ r_tris,
+ /* cache */
+ indices);
#ifdef USE_KDTREE
- if (pf.coords_tot_concave) {
- pf.kdtree.nodes = BLI_memarena_alloc(arena, sizeof(*pf.kdtree.nodes) * pf.coords_tot_concave);
- pf.kdtree.nodes_map = memset(BLI_memarena_alloc(arena, sizeof(*pf.kdtree.nodes_map) * coords_tot),
- 0xff, sizeof(*pf.kdtree.nodes_map) * coords_tot);
- }
- else {
- pf.kdtree.totnode = 0;
- }
+ if (pf.coords_tot_concave) {
+ pf.kdtree.nodes = BLI_memarena_alloc(arena, sizeof(*pf.kdtree.nodes) * pf.coords_tot_concave);
+ pf.kdtree.nodes_map = memset(
+ BLI_memarena_alloc(arena, sizeof(*pf.kdtree.nodes_map) * coords_tot),
+ 0xff,
+ sizeof(*pf.kdtree.nodes_map) * coords_tot);
+ }
+ else {
+ pf.kdtree.totnode = 0;
+ }
#endif
- polyfill_calc(&pf);
+ polyfill_calc(&pf);
- /* indices are no longer needed,
- * caller can clear arena */
+ /* indices are no longer needed,
+ * caller can clear arena */
#ifdef DEBUG_TIME
- TIMEIT_END(polyfill2d);
+ TIMEIT_END(polyfill2d);
#endif
}
@@ -933,40 +901,41 @@ void BLI_polyfill_calc_arena(
* Indices are guaranteed to be assigned to unique triangles, with valid indices,
* even in the case of degenerate input (self intersecting polygons, zero area ears... etc).
*/
-void BLI_polyfill_calc(
- const float (*coords)[2],
- const uint coords_tot,
- const int coords_sign,
- uint (*r_tris)[3])
+void BLI_polyfill_calc(const float (*coords)[2],
+ const uint coords_tot,
+ const int coords_sign,
+ uint (*r_tris)[3])
{
- PolyFill pf;
- PolyIndex *indices = BLI_array_alloca(indices, coords_tot);
+ PolyFill pf;
+ PolyIndex *indices = BLI_array_alloca(indices, coords_tot);
#ifdef DEBUG_TIME
- TIMEIT_START(polyfill2d);
+ TIMEIT_START(polyfill2d);
#endif
- polyfill_prepare(
- &pf,
- coords, coords_tot, coords_sign,
- r_tris,
- /* cache */
- indices);
+ polyfill_prepare(&pf,
+ coords,
+ coords_tot,
+ coords_sign,
+ r_tris,
+ /* cache */
+ indices);
#ifdef USE_KDTREE
- if (pf.coords_tot_concave) {
- pf.kdtree.nodes = BLI_array_alloca(pf.kdtree.nodes, pf.coords_tot_concave);
- pf.kdtree.nodes_map = memset(BLI_array_alloca(pf.kdtree.nodes_map, coords_tot),
- 0xff, sizeof(*pf.kdtree.nodes_map) * coords_tot);
- }
- else {
- pf.kdtree.totnode = 0;
- }
+ if (pf.coords_tot_concave) {
+ pf.kdtree.nodes = BLI_array_alloca(pf.kdtree.nodes, pf.coords_tot_concave);
+ pf.kdtree.nodes_map = memset(BLI_array_alloca(pf.kdtree.nodes_map, coords_tot),
+ 0xff,
+ sizeof(*pf.kdtree.nodes_map) * coords_tot);
+ }
+ else {
+ pf.kdtree.totnode = 0;
+ }
#endif
- polyfill_calc(&pf);
+ polyfill_calc(&pf);
#ifdef DEBUG_TIME
- TIMEIT_END(polyfill2d);
+ TIMEIT_END(polyfill2d);
#endif
}
diff --git a/source/blender/blenlib/intern/polyfill_2d_beautify.c b/source/blender/blenlib/intern/polyfill_2d_beautify.c
index 17af81af866..2ca19d173c2 100644
--- a/source/blender/blenlib/intern/polyfill_2d_beautify.c
+++ b/source/blender/blenlib/intern/polyfill_2d_beautify.c
@@ -40,57 +40,57 @@
#include "BLI_memarena.h"
#include "BLI_heap.h"
-#include "BLI_polyfill_2d_beautify.h" /* own include */
+#include "BLI_polyfill_2d_beautify.h" /* own include */
#include "BLI_strict_flags.h"
/* Used to find matching edges. */
struct OrderEdge {
- uint verts[2];
- uint e_half;
+ uint verts[2];
+ uint e_half;
};
/* Half edge used for rotating in-place. */
struct HalfEdge {
- uint v;
- uint e_next;
- uint e_radial;
- uint base_index;
+ uint v;
+ uint e_next;
+ uint e_radial;
+ uint base_index;
};
static int oedge_cmp(const void *a1, const void *a2)
{
- const struct OrderEdge *x1 = a1, *x2 = a2;
- if (x1->verts[0] > x2->verts[0]) {
- return 1;
- }
- else if (x1->verts[0] < x2->verts[0]) {
- return -1;
- }
-
- if (x1->verts[1] > x2->verts[1]) {
- return 1;
- }
- else if (x1->verts[1] < x2->verts[1]) {
- return -1;
- }
-
- /* only for pradictability */
- if (x1->e_half > x2->e_half) {
- return 1;
- }
- else if (x1->e_half < x2->e_half) {
- return -1;
- }
- /* Should never get here, no two edges should be the same. */
- BLI_assert(false);
- return 0;
+ const struct OrderEdge *x1 = a1, *x2 = a2;
+ if (x1->verts[0] > x2->verts[0]) {
+ return 1;
+ }
+ else if (x1->verts[0] < x2->verts[0]) {
+ return -1;
+ }
+
+ if (x1->verts[1] > x2->verts[1]) {
+ return 1;
+ }
+ else if (x1->verts[1] < x2->verts[1]) {
+ return -1;
+ }
+
+ /* only for pradictability */
+ if (x1->e_half > x2->e_half) {
+ return 1;
+ }
+ else if (x1->e_half < x2->e_half) {
+ return -1;
+ }
+ /* Should never get here, no two edges should be the same. */
+ BLI_assert(false);
+ return 0;
}
BLI_INLINE bool is_boundary_edge(uint i_a, uint i_b, const uint coord_last)
{
- BLI_assert(i_a < i_b);
- return ((i_a + 1 == i_b) || UNLIKELY((i_a == 0) && (i_b == 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),
@@ -102,206 +102,200 @@ BLI_INLINE bool is_boundary_edge(uint i_a, uint i_b, const uint coord_last)
*
* \return (negative number means the edge can be rotated, lager == better).
*/
-float BLI_polyfill_beautify_quad_rotate_calc_ex(
- const float v1[2], const float v2[2], const float v3[2], const float v4[2],
- const bool lock_degenerate)
+float BLI_polyfill_beautify_quad_rotate_calc_ex(const float v1[2],
+ const float v2[2],
+ const float v3[2],
+ const float v4[2],
+ const bool lock_degenerate)
{
- /* not a loop (only to be able to break out) */
- do {
- /* Allow very small faces to be considered non-zero. */
- const float eps_zero_area = 1e-12f;
- 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));
- /*
- * Test for unusable (1-3) state.
- * - Area sign flipping to check faces aren't going to point in opposite directions.
- * - Area epsilon check that the one of the faces won't be zero area.
- */
- if ((area_2x_123 >= 0.0f) != (area_2x_134 >= 0.0f)) {
- break;
- }
- else if ((fabsf(area_2x_123) <= eps_zero_area) || (fabsf(area_2x_134) <= eps_zero_area)) {
- break;
- }
-
- /* Test for unusable (2-4) state (same as above). */
- if ((area_2x_234 >= 0.0f) != (area_2x_241 >= 0.0f)) {
- if (lock_degenerate) {
- break;
- }
- else {
- return -FLT_MAX; /* always rotate */
- }
- }
- else if ((fabsf(area_2x_234) <= eps_zero_area) || (fabsf(area_2x_241) <= eps_zero_area)) {
- return -FLT_MAX; /* always rotate */
- }
-
- {
- /* 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;
-
- /* 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);
-
- /* note, area is in fact (area * 2),
- * but in this case its OK, since we're comparing ratios */
-
- /* edge (2-4), current state */
- area_a = fabsf(area_2x_234);
- area_b = fabsf(area_2x_241);
- prim_a = len_23 + len_34 + len_24;
- prim_b = len_41 + len_12 + len_24;
- fac_24 = (area_a / prim_a) + (area_b / prim_b);
-
- /* edge (1-3), new state */
- area_a = fabsf(area_2x_123);
- area_b = fabsf(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);
-
- /* negative number if (1-3) is an improved state */
- return fac_24 - fac_13;
- }
- } while (false);
-
- return FLT_MAX;
+ /* not a loop (only to be able to break out) */
+ do {
+ /* Allow very small faces to be considered non-zero. */
+ const float eps_zero_area = 1e-12f;
+ 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));
+ /*
+ * Test for unusable (1-3) state.
+ * - Area sign flipping to check faces aren't going to point in opposite directions.
+ * - Area epsilon check that the one of the faces won't be zero area.
+ */
+ if ((area_2x_123 >= 0.0f) != (area_2x_134 >= 0.0f)) {
+ break;
+ }
+ else if ((fabsf(area_2x_123) <= eps_zero_area) || (fabsf(area_2x_134) <= eps_zero_area)) {
+ break;
+ }
+
+ /* Test for unusable (2-4) state (same as above). */
+ if ((area_2x_234 >= 0.0f) != (area_2x_241 >= 0.0f)) {
+ if (lock_degenerate) {
+ break;
+ }
+ else {
+ return -FLT_MAX; /* always rotate */
+ }
+ }
+ else if ((fabsf(area_2x_234) <= eps_zero_area) || (fabsf(area_2x_241) <= eps_zero_area)) {
+ return -FLT_MAX; /* always rotate */
+ }
+
+ {
+ /* 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;
+
+ /* 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);
+
+ /* note, area is in fact (area * 2),
+ * but in this case its OK, since we're comparing ratios */
+
+ /* edge (2-4), current state */
+ area_a = fabsf(area_2x_234);
+ area_b = fabsf(area_2x_241);
+ prim_a = len_23 + len_34 + len_24;
+ prim_b = len_41 + len_12 + len_24;
+ fac_24 = (area_a / prim_a) + (area_b / prim_b);
+
+ /* edge (1-3), new state */
+ area_a = fabsf(area_2x_123);
+ area_b = fabsf(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);
+
+ /* 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 struct HalfEdge *edges,
- const struct HalfEdge *e_a)
+static float polyedge_rotate_beauty_calc(const float (*coords)[2],
+ const struct HalfEdge *edges,
+ const struct HalfEdge *e_a)
{
- const struct HalfEdge *e_b = &edges[e_a->e_radial];
+ const struct HalfEdge *e_b = &edges[e_a->e_radial];
- const struct HalfEdge *e_a_other = &edges[edges[e_a->e_next].e_next];
- const struct HalfEdge *e_b_other = &edges[edges[e_b->e_next].e_next];
+ const struct HalfEdge *e_a_other = &edges[edges[e_a->e_next].e_next];
+ const struct HalfEdge *e_b_other = &edges[edges[e_b->e_next].e_next];
- const float *v1, *v2, *v3, *v4;
+ const float *v1, *v2, *v3, *v4;
- v1 = coords[e_a_other->v];
- v2 = coords[e_a->v];
- v3 = coords[e_b_other->v];
- v4 = coords[e_b->v];
+ v1 = coords[e_a_other->v];
+ v2 = coords[e_a->v];
+ v3 = coords[e_b_other->v];
+ v4 = coords[e_b->v];
- return BLI_polyfill_beautify_quad_rotate_calc(v1, v2, v3, v4);
+ return BLI_polyfill_beautify_quad_rotate_calc(v1, v2, v3, v4);
}
-static void polyedge_beauty_cost_update_single(
- const float (*coords)[2],
- const struct HalfEdge *edges,
- struct HalfEdge *e,
- Heap *eheap, HeapNode **eheap_table)
+static void polyedge_beauty_cost_update_single(const float (*coords)[2],
+ const struct HalfEdge *edges,
+ struct HalfEdge *e,
+ Heap *eheap,
+ HeapNode **eheap_table)
{
- const uint i = e->base_index;
- /* recalculate edge */
- const float cost = polyedge_rotate_beauty_calc(coords, edges, e);
- /* We can get cases where both choices generate very small negative costs,
- * which leads to infinite loop. Anyway, costs above that are not worth recomputing,
- * maybe we could even optimize it to a smaller limit?
- * Actually, FLT_EPSILON is too small in some cases, 1e-6f seems to work OK hopefully?
- * See T43578, T49478. */
- if (cost < -1e-6f) {
- BLI_heap_insert_or_update(eheap, &eheap_table[i], cost, e);
- }
- else {
- if (eheap_table[i]) {
- BLI_heap_remove(eheap, eheap_table[i]);
- eheap_table[i] = NULL;
- }
- }
+ const uint i = e->base_index;
+ /* recalculate edge */
+ const float cost = polyedge_rotate_beauty_calc(coords, edges, e);
+ /* We can get cases where both choices generate very small negative costs,
+ * which leads to infinite loop. Anyway, costs above that are not worth recomputing,
+ * maybe we could even optimize it to a smaller limit?
+ * Actually, FLT_EPSILON is too small in some cases, 1e-6f seems to work OK hopefully?
+ * See T43578, T49478. */
+ if (cost < -1e-6f) {
+ BLI_heap_insert_or_update(eheap, &eheap_table[i], cost, e);
+ }
+ else {
+ if (eheap_table[i]) {
+ BLI_heap_remove(eheap, eheap_table[i]);
+ eheap_table[i] = NULL;
+ }
+ }
}
-static void polyedge_beauty_cost_update(
- const float (*coords)[2],
- struct HalfEdge *edges,
- struct HalfEdge *e,
- Heap *eheap, HeapNode **eheap_table)
+static void polyedge_beauty_cost_update(const float (*coords)[2],
+ struct HalfEdge *edges,
+ struct HalfEdge *e,
+ Heap *eheap,
+ HeapNode **eheap_table)
{
- struct HalfEdge *e_arr[4];
- e_arr[0] = &edges[e->e_next];
- e_arr[1] = &edges[e_arr[0]->e_next];
-
- e = &edges[e->e_radial];
- e_arr[2] = &edges[e->e_next];
- e_arr[3] = &edges[e_arr[2]->e_next];
-
- for (uint i = 0; i < 4; i++) {
- if (e_arr[i] && e_arr[i]->base_index != UINT_MAX) {
- polyedge_beauty_cost_update_single(
- coords, edges,
- e_arr[i],
- eheap, eheap_table);
- }
- }
+ struct HalfEdge *e_arr[4];
+ e_arr[0] = &edges[e->e_next];
+ e_arr[1] = &edges[e_arr[0]->e_next];
+
+ e = &edges[e->e_radial];
+ e_arr[2] = &edges[e->e_next];
+ e_arr[3] = &edges[e_arr[2]->e_next];
+
+ for (uint i = 0; i < 4; i++) {
+ if (e_arr[i] && e_arr[i]->base_index != UINT_MAX) {
+ polyedge_beauty_cost_update_single(coords, edges, e_arr[i], eheap, eheap_table);
+ }
+ }
}
-static void polyedge_rotate(
- struct HalfEdge *edges,
- struct HalfEdge *e)
+static void polyedge_rotate(struct HalfEdge *edges, struct HalfEdge *e)
{
- /** CCW winding, rotate internal edge to new vertical state.
- *
- * \code{.unparsed}
- * Before After
- * X X
- * / \ /|\
- * e4/ \e5 e4/ | \e5
- * / e3 \ / | \
- * X ------- X -> X e0|e3 X
- * \ e0 / \ | /
- * e2\ /e1 e2\ | /e1
- * \ / \|/
- * X X
- * \endcode
- */
- struct HalfEdge *ed[6];
- uint ed_index[6];
-
- ed_index[0] = (uint)(e - edges);
- ed[0] = &edges[ed_index[0]];
- ed_index[1] = ed[0]->e_next;
- ed[1] = &edges[ed_index[1]];
- ed_index[2] = ed[1]->e_next;
- ed[2] = &edges[ed_index[2]];
-
- ed_index[3] = e->e_radial;
- ed[3] = &edges[ed_index[3]];
- ed_index[4] = ed[3]->e_next;
- ed[4] = &edges[ed_index[4]];
- ed_index[5] = ed[4]->e_next;
- ed[5] = &edges[ed_index[5]];
-
- ed[0]->e_next = ed_index[2];
- ed[1]->e_next = ed_index[3];
- ed[2]->e_next = ed_index[4];
- ed[3]->e_next = ed_index[5];
- ed[4]->e_next = ed_index[0];
- ed[5]->e_next = ed_index[1];
-
- ed[0]->v = ed[5]->v;
- ed[3]->v = ed[2]->v;
+ /** CCW winding, rotate internal edge to new vertical state.
+ *
+ * \code{.unparsed}
+ * Before After
+ * X X
+ * / \ /|\
+ * e4/ \e5 e4/ | \e5
+ * / e3 \ / | \
+ * X ------- X -> X e0|e3 X
+ * \ e0 / \ | /
+ * e2\ /e1 e2\ | /e1
+ * \ / \|/
+ * X X
+ * \endcode
+ */
+ struct HalfEdge *ed[6];
+ uint ed_index[6];
+
+ ed_index[0] = (uint)(e - edges);
+ ed[0] = &edges[ed_index[0]];
+ ed_index[1] = ed[0]->e_next;
+ ed[1] = &edges[ed_index[1]];
+ ed_index[2] = ed[1]->e_next;
+ ed[2] = &edges[ed_index[2]];
+
+ ed_index[3] = e->e_radial;
+ ed[3] = &edges[ed_index[3]];
+ ed_index[4] = ed[3]->e_next;
+ ed[4] = &edges[ed_index[4]];
+ ed_index[5] = ed[4]->e_next;
+ ed[5] = &edges[ed_index[5]];
+
+ ed[0]->e_next = ed_index[2];
+ ed[1]->e_next = ed_index[3];
+ ed[2]->e_next = ed_index[4];
+ ed[3]->e_next = ed_index[5];
+ ed[4]->e_next = ed_index[0];
+ ed[5]->e_next = ed_index[1];
+
+ ed[0]->v = ed[5]->v;
+ ed[3]->v = ed[2]->v;
}
/**
@@ -310,126 +304,124 @@ static void polyedge_rotate(
* 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 uint coords_tot,
- uint (*tris)[3],
+void BLI_polyfill_beautify(const float (*coords)[2],
+ const uint coords_tot,
+ uint (*tris)[3],
- /* structs for reuse */
- MemArena *arena, Heap *eheap)
+ /* structs for reuse */
+ MemArena *arena,
+ Heap *eheap)
{
- const uint coord_last = coords_tot - 1;
- const uint tris_len = coords_tot - 2;
- /* internal edges only (between 2 tris) */
- const uint edges_len = tris_len - 1;
-
- HeapNode **eheap_table;
-
- const uint half_edges_len = 3 * tris_len;
- struct HalfEdge *half_edges = BLI_memarena_alloc(arena, sizeof(*half_edges) * half_edges_len);
- struct OrderEdge *order_edges = BLI_memarena_alloc(arena, sizeof(struct OrderEdge) * 2 * edges_len);
- uint order_edges_len = 0;
-
- /* first build edges */
- for (uint i = 0; i < tris_len; i++) {
- for (uint j_curr = 0, j_prev = 2; j_curr < 3; j_prev = j_curr++) {
- const uint e_index_prev = (i * 3) + j_prev;
- const uint e_index_curr = (i * 3) + j_curr;
-
- half_edges[e_index_prev].v = tris[i][j_prev];
- half_edges[e_index_prev].e_next = e_index_curr;
- half_edges[e_index_prev].e_radial = UINT_MAX;
- half_edges[e_index_prev].base_index = UINT_MAX;
-
- uint e_pair[2] = {tris[i][j_prev], tris[i][j_curr]};
- if (e_pair[0] > e_pair[1]) {
- SWAP(uint, e_pair[0], e_pair[1]);
- }
-
- /* ensure internal edges. */
- if (!is_boundary_edge(e_pair[0], e_pair[1], coord_last)) {
- order_edges[order_edges_len].verts[0] = e_pair[0];
- order_edges[order_edges_len].verts[1] = e_pair[1];
- order_edges[order_edges_len].e_half = e_index_prev;
- order_edges_len += 1;
- }
- }
- }
- BLI_assert(edges_len * 2 == order_edges_len);
-
- qsort(order_edges, order_edges_len, sizeof(struct OrderEdge), oedge_cmp);
-
- for (uint i = 0, base_index = 0; i < order_edges_len; base_index++) {
- const struct OrderEdge *oe_a = &order_edges[i++];
- const struct OrderEdge *oe_b = &order_edges[i++];
- BLI_assert(oe_a->verts[0] == oe_a->verts[0] && oe_a->verts[1] == oe_a->verts[1]);
- half_edges[oe_a->e_half].e_radial = oe_b->e_half;
- half_edges[oe_b->e_half].e_radial = oe_a->e_half;
- half_edges[oe_a->e_half].base_index = base_index;
- half_edges[oe_b->e_half].base_index = base_index;
- }
- /* order_edges could be freed now. */
-
- /* Now perform iterative rotations. */
+ const uint coord_last = coords_tot - 1;
+ const uint tris_len = coords_tot - 2;
+ /* internal edges only (between 2 tris) */
+ const uint edges_len = tris_len - 1;
+
+ HeapNode **eheap_table;
+
+ const uint half_edges_len = 3 * tris_len;
+ struct HalfEdge *half_edges = BLI_memarena_alloc(arena, sizeof(*half_edges) * half_edges_len);
+ struct OrderEdge *order_edges = BLI_memarena_alloc(arena,
+ sizeof(struct OrderEdge) * 2 * edges_len);
+ uint order_edges_len = 0;
+
+ /* first build edges */
+ for (uint i = 0; i < tris_len; i++) {
+ for (uint j_curr = 0, j_prev = 2; j_curr < 3; j_prev = j_curr++) {
+ const uint e_index_prev = (i * 3) + j_prev;
+ const uint e_index_curr = (i * 3) + j_curr;
+
+ half_edges[e_index_prev].v = tris[i][j_prev];
+ half_edges[e_index_prev].e_next = e_index_curr;
+ half_edges[e_index_prev].e_radial = UINT_MAX;
+ half_edges[e_index_prev].base_index = UINT_MAX;
+
+ uint e_pair[2] = {tris[i][j_prev], tris[i][j_curr]};
+ if (e_pair[0] > e_pair[1]) {
+ SWAP(uint, e_pair[0], e_pair[1]);
+ }
+
+ /* ensure internal edges. */
+ if (!is_boundary_edge(e_pair[0], e_pair[1], coord_last)) {
+ order_edges[order_edges_len].verts[0] = e_pair[0];
+ order_edges[order_edges_len].verts[1] = e_pair[1];
+ order_edges[order_edges_len].e_half = e_index_prev;
+ order_edges_len += 1;
+ }
+ }
+ }
+ BLI_assert(edges_len * 2 == order_edges_len);
+
+ qsort(order_edges, order_edges_len, sizeof(struct OrderEdge), oedge_cmp);
+
+ for (uint i = 0, base_index = 0; i < order_edges_len; base_index++) {
+ const struct OrderEdge *oe_a = &order_edges[i++];
+ const struct OrderEdge *oe_b = &order_edges[i++];
+ BLI_assert(oe_a->verts[0] == oe_a->verts[0] && oe_a->verts[1] == oe_a->verts[1]);
+ half_edges[oe_a->e_half].e_radial = oe_b->e_half;
+ half_edges[oe_b->e_half].e_radial = oe_a->e_half;
+ half_edges[oe_a->e_half].base_index = base_index;
+ half_edges[oe_b->e_half].base_index = base_index;
+ }
+ /* order_edges could be freed now. */
+
+ /* Now perform iterative rotations. */
#if 0
- eheap_table = BLI_memarena_alloc(arena, sizeof(HeapNode *) * (size_t)edges_len);
+ eheap_table = BLI_memarena_alloc(arena, sizeof(HeapNode *) * (size_t)edges_len);
#else
- /* We can re-use this since its big enough. */
- eheap_table = (void *)order_edges;
- order_edges = NULL;
+ /* We can re-use this since its big enough. */
+ eheap_table = (void *)order_edges;
+ order_edges = NULL;
#endif
- /* Build heap. */
- {
- struct HalfEdge *e = half_edges;
- for (uint i = 0; i < half_edges_len; i++, e++) {
- /* Accounts for boundary edged too (UINT_MAX). */
- if (e->e_radial < i) {
- const float cost = polyedge_rotate_beauty_calc(coords, half_edges, e);
- if (cost < 0.0f) {
- eheap_table[e->base_index] = BLI_heap_insert(eheap, cost, e);
- }
- else {
- eheap_table[e->base_index] = NULL;
- }
- }
- }
- }
-
- while (BLI_heap_is_empty(eheap) == false) {
- struct HalfEdge *e = BLI_heap_pop_min(eheap);
- eheap_table[e->base_index] = NULL;
-
- polyedge_rotate(half_edges, e);
-
- /* recalculate faces connected on the heap */
- polyedge_beauty_cost_update(
- coords, half_edges,
- e,
- eheap, eheap_table);
- }
-
- BLI_heap_clear(eheap, NULL);
-
- /* MEM_freeN(eheap_table); */ /* arena */
-
- /* get tris from half edge. */
- uint tri_index = 0;
- for (uint i = 0; i < half_edges_len; i++) {
- struct HalfEdge *e = &half_edges[i];
- if (e->v != UINT_MAX) {
- uint *tri = tris[tri_index++];
-
- tri[0] = e->v;
- e->v = UINT_MAX;
-
- e = &half_edges[e->e_next];
- tri[1] = e->v;
- e->v = UINT_MAX;
-
- e = &half_edges[e->e_next];
- tri[2] = e->v;
- e->v = UINT_MAX;
- }
- }
+ /* Build heap. */
+ {
+ struct HalfEdge *e = half_edges;
+ for (uint i = 0; i < half_edges_len; i++, e++) {
+ /* Accounts for boundary edged too (UINT_MAX). */
+ if (e->e_radial < i) {
+ const float cost = polyedge_rotate_beauty_calc(coords, half_edges, e);
+ if (cost < 0.0f) {
+ eheap_table[e->base_index] = BLI_heap_insert(eheap, cost, e);
+ }
+ else {
+ eheap_table[e->base_index] = NULL;
+ }
+ }
+ }
+ }
+
+ while (BLI_heap_is_empty(eheap) == false) {
+ struct HalfEdge *e = BLI_heap_pop_min(eheap);
+ eheap_table[e->base_index] = NULL;
+
+ polyedge_rotate(half_edges, e);
+
+ /* recalculate faces connected on the heap */
+ polyedge_beauty_cost_update(coords, half_edges, e, eheap, eheap_table);
+ }
+
+ BLI_heap_clear(eheap, NULL);
+
+ /* MEM_freeN(eheap_table); */ /* arena */
+
+ /* get tris from half edge. */
+ uint tri_index = 0;
+ for (uint i = 0; i < half_edges_len; i++) {
+ struct HalfEdge *e = &half_edges[i];
+ if (e->v != UINT_MAX) {
+ uint *tri = tris[tri_index++];
+
+ tri[0] = e->v;
+ e->v = UINT_MAX;
+
+ e = &half_edges[e->e_next];
+ tri[1] = e->v;
+ e->v = UINT_MAX;
+
+ e = &half_edges[e->e_next];
+ tri[2] = e->v;
+ e->v = UINT_MAX;
+ }
+ }
}
diff --git a/source/blender/blenlib/intern/quadric.c b/source/blender/blenlib/intern/quadric.c
index 8d5998786f4..0a1ff9f8116 100644
--- a/source/blender/blenlib/intern/quadric.c
+++ b/source/blender/blenlib/intern/quadric.c
@@ -35,43 +35,42 @@
#include "BLI_math.h"
#include "BLI_strict_flags.h"
-#include "BLI_quadric.h" /* own include */
-
+#include "BLI_quadric.h" /* own include */
#define QUADRIC_FLT_TOT (sizeof(Quadric) / sizeof(double))
void BLI_quadric_from_plane(Quadric *q, const double v[4])
{
- q->a2 = v[0] * v[0];
- q->b2 = v[1] * v[1];
- q->c2 = v[2] * v[2];
+ q->a2 = v[0] * v[0];
+ q->b2 = v[1] * v[1];
+ q->c2 = v[2] * v[2];
- q->ab = v[0] * v[1];
- q->ac = v[0] * v[2];
- q->bc = v[1] * v[2];
+ q->ab = v[0] * v[1];
+ q->ac = v[0] * v[2];
+ q->bc = v[1] * v[2];
- q->ad = v[0] * v[3];
- q->bd = v[1] * v[3];
- q->cd = v[2] * v[3];
+ q->ad = v[0] * v[3];
+ q->bd = v[1] * v[3];
+ q->cd = v[2] * v[3];
- q->d2 = v[3] * v[3];
+ q->d2 = v[3] * v[3];
}
-#if 0 /* UNUSED */
+#if 0 /* UNUSED */
static void quadric_to_tensor_m3(const Quadric *q, double m[3][3])
{
- m[0][0] = q->a2;
- m[0][1] = q->ab;
- m[0][2] = q->ac;
+ m[0][0] = q->a2;
+ m[0][1] = q->ab;
+ m[0][2] = q->ac;
- m[1][0] = q->ab;
- m[1][1] = q->b2;
- m[1][2] = q->bc;
+ m[1][0] = q->ab;
+ m[1][1] = q->b2;
+ m[1][2] = q->bc;
- m[2][0] = q->ac;
- m[2][1] = q->bc;
- m[2][2] = q->c2;
+ m[2][0] = q->ac;
+ m[2][1] = q->bc;
+ m[2][2] = q->c2;
}
#endif
@@ -87,79 +86,77 @@ static void quadric_to_tensor_m3(const Quadric *q, double m[3][3])
*/
static bool quadric_to_tensor_m3_inverse(const Quadric *q, double m[3][3], double epsilon)
{
- const double det =
- (q->a2 * (q->b2 * q->c2 - q->bc * q->bc) -
- q->ab * (q->ab * q->c2 - q->ac * q->bc) +
- q->ac * (q->ab * q->bc - q->ac * q->b2));
-
- if (fabs(det) > epsilon) {
- const double invdet = 1.0 / det;
-
- m[0][0] = (q->b2 * q->c2 - q->bc * q->bc) * invdet;
- m[1][0] = (q->bc * q->ac - q->ab * q->c2) * invdet;
- m[2][0] = (q->ab * q->bc - q->b2 * q->ac) * invdet;
-
- m[0][1] = (q->ac * q->bc - q->ab * q->c2) * invdet;
- m[1][1] = (q->a2 * q->c2 - q->ac * q->ac) * invdet;
- m[2][1] = (q->ab * q->ac - q->a2 * q->bc) * invdet;
-
- m[0][2] = (q->ab * q->bc - q->ac * q->b2) * invdet;
- m[1][2] = (q->ac * q->ab - q->a2 * q->bc) * invdet;
- m[2][2] = (q->a2 * q->b2 - q->ab * q->ab) * invdet;
-
- return true;
- }
- else {
- return false;
- }
+ const double det = (q->a2 * (q->b2 * q->c2 - q->bc * q->bc) -
+ q->ab * (q->ab * q->c2 - q->ac * q->bc) +
+ q->ac * (q->ab * q->bc - q->ac * q->b2));
+
+ if (fabs(det) > epsilon) {
+ const double invdet = 1.0 / det;
+
+ m[0][0] = (q->b2 * q->c2 - q->bc * q->bc) * invdet;
+ m[1][0] = (q->bc * q->ac - q->ab * q->c2) * invdet;
+ m[2][0] = (q->ab * q->bc - q->b2 * q->ac) * invdet;
+
+ m[0][1] = (q->ac * q->bc - q->ab * q->c2) * invdet;
+ m[1][1] = (q->a2 * q->c2 - q->ac * q->ac) * invdet;
+ m[2][1] = (q->ab * q->ac - q->a2 * q->bc) * invdet;
+
+ m[0][2] = (q->ab * q->bc - q->ac * q->b2) * invdet;
+ m[1][2] = (q->ac * q->ab - q->a2 * q->bc) * invdet;
+ m[2][2] = (q->a2 * q->b2 - q->ab * q->ab) * invdet;
+
+ return true;
+ }
+ else {
+ return false;
+ }
}
void BLI_quadric_to_vector_v3(const Quadric *q, double v[3])
{
- v[0] = q->ad;
- v[1] = q->bd;
- v[2] = q->cd;
+ v[0] = q->ad;
+ v[1] = q->bd;
+ v[2] = q->cd;
}
void BLI_quadric_clear(Quadric *q)
{
- memset(q, 0, sizeof(*q));
+ memset(q, 0, sizeof(*q));
}
void BLI_quadric_add_qu_qu(Quadric *a, const Quadric *b)
{
- add_vn_vn_d((double *)a, (double *)b, QUADRIC_FLT_TOT);
+ add_vn_vn_d((double *)a, (double *)b, QUADRIC_FLT_TOT);
}
void BLI_quadric_add_qu_ququ(Quadric *r, const Quadric *a, const Quadric *b)
{
- add_vn_vnvn_d((double *)r, (const double *)a, (const double *)b, QUADRIC_FLT_TOT);
+ add_vn_vnvn_d((double *)r, (const double *)a, (const double *)b, QUADRIC_FLT_TOT);
}
void BLI_quadric_mul(Quadric *a, const double scalar)
{
- mul_vn_db((double *)a, QUADRIC_FLT_TOT, scalar);
+ mul_vn_db((double *)a, QUADRIC_FLT_TOT, scalar);
}
double BLI_quadric_evaluate(const Quadric *q, const double v[3])
{
- return ((q->a2 * v[0] * v[0]) + (q->ab * 2 * v[0] * v[1]) + (q->ac * 2 * v[0] * v[2]) + (q->ad * 2 * v[0]) +
- (q->b2 * v[1] * v[1]) + (q->bc * 2 * v[1] * v[2]) + (q->bd * 2 * v[1]) +
- (q->c2 * v[2] * v[2]) + (q->cd * 2 * v[2]) +
- (q->d2));
+ return ((q->a2 * v[0] * v[0]) + (q->ab * 2 * v[0] * v[1]) + (q->ac * 2 * v[0] * v[2]) +
+ (q->ad * 2 * v[0]) + (q->b2 * v[1] * v[1]) + (q->bc * 2 * v[1] * v[2]) +
+ (q->bd * 2 * v[1]) + (q->c2 * v[2] * v[2]) + (q->cd * 2 * v[2]) + (q->d2));
}
bool BLI_quadric_optimize(const Quadric *q, double v[3], const double epsilon)
{
- double m[3][3];
-
- if (quadric_to_tensor_m3_inverse(q, m, epsilon)) {
- BLI_quadric_to_vector_v3(q, v);
- mul_m3_v3_db(m, v);
- negate_v3_db(v);
- return true;
- }
- else {
- return false;
- }
+ double m[3][3];
+
+ if (quadric_to_tensor_m3_inverse(q, m, epsilon)) {
+ BLI_quadric_to_vector_v3(q, v);
+ mul_m3_v3_db(m, v);
+ negate_v3_db(v);
+ return true;
+ }
+ else {
+ return false;
+ }
}
diff --git a/source/blender/blenlib/intern/rand.c b/source/blender/blenlib/intern/rand.c
index 352bfe5dab6..9f47ada47d1 100644
--- a/source/blender/blenlib/intern/rand.c
+++ b/source/blender/blenlib/intern/rand.c
@@ -21,7 +21,6 @@
* \ingroup bli
*/
-
#include <stdlib.h>
#include <string.h>
#include <math.h>
@@ -39,30 +38,30 @@
#include "BLI_sys_types.h"
#include "BLI_strict_flags.h"
-#define MULTIPLIER 0x5DEECE66Dll
-#define MASK 0x0000FFFFFFFFFFFFll
-#define MASK_BYTES 2
+#define MULTIPLIER 0x5DEECE66Dll
+#define MASK 0x0000FFFFFFFFFFFFll
+#define MASK_BYTES 2
-#define ADDEND 0xB
-#define LOWSEED 0x330E
+#define ADDEND 0xB
+#define LOWSEED 0x330E
-extern unsigned char BLI_noise_hash_uchar_512[512]; /* noise.c */
+extern unsigned char BLI_noise_hash_uchar_512[512]; /* noise.c */
#define hash BLI_noise_hash_uchar_512
/**
* Random Number Generator.
*/
struct RNG {
- uint64_t X;
+ uint64_t X;
};
RNG *BLI_rng_new(unsigned int seed)
{
- RNG *rng = MEM_mallocN(sizeof(*rng), "rng");
+ RNG *rng = MEM_mallocN(sizeof(*rng), "rng");
- BLI_rng_seed(rng, seed);
+ BLI_rng_seed(rng, seed);
- return rng;
+ return rng;
}
/**
@@ -70,26 +69,26 @@ RNG *BLI_rng_new(unsigned int seed)
*/
RNG *BLI_rng_new_srandom(unsigned int seed)
{
- RNG *rng = MEM_mallocN(sizeof(*rng), "rng");
+ RNG *rng = MEM_mallocN(sizeof(*rng), "rng");
- BLI_rng_srandom(rng, seed);
+ BLI_rng_srandom(rng, seed);
- return rng;
+ return rng;
}
RNG *BLI_rng_copy(RNG *rng)
{
- return MEM_dupallocN(rng);
+ return MEM_dupallocN(rng);
}
void BLI_rng_free(RNG *rng)
{
- MEM_freeN(rng);
+ MEM_freeN(rng);
}
void BLI_rng_seed(RNG *rng, unsigned int seed)
{
- rng->X = (((uint64_t) seed) << 16) | LOWSEED;
+ rng->X = (((uint64_t)seed) << 16) | LOWSEED;
}
/**
@@ -97,67 +96,67 @@ void BLI_rng_seed(RNG *rng, unsigned int seed)
*/
void BLI_rng_srandom(RNG *rng, unsigned int seed)
{
- BLI_rng_seed(rng, seed + hash[seed & 255]);
- seed = BLI_rng_get_uint(rng);
- BLI_rng_seed(rng, seed + hash[seed & 255]);
- seed = BLI_rng_get_uint(rng);
- BLI_rng_seed(rng, seed + hash[seed & 255]);
+ BLI_rng_seed(rng, seed + hash[seed & 255]);
+ seed = BLI_rng_get_uint(rng);
+ BLI_rng_seed(rng, seed + hash[seed & 255]);
+ seed = BLI_rng_get_uint(rng);
+ BLI_rng_seed(rng, seed + hash[seed & 255]);
}
BLI_INLINE void rng_step(RNG *rng)
{
- rng->X = (MULTIPLIER * rng->X + ADDEND) & MASK;
+ rng->X = (MULTIPLIER * rng->X + ADDEND) & MASK;
}
void BLI_rng_get_char_n(RNG *rng, char *bytes, size_t bytes_len)
{
- size_t last_len = 0;
- size_t trim_len = bytes_len;
+ size_t last_len = 0;
+ size_t trim_len = bytes_len;
#define RAND_STRIDE (sizeof(rng->X) - MASK_BYTES)
- if (trim_len > RAND_STRIDE) {
- last_len = trim_len % RAND_STRIDE;
- trim_len = trim_len - last_len;
- }
- else {
- trim_len = 0;
- last_len = bytes_len;
- }
-
- const char *data_src = (void *)&(rng->X);
- size_t i = 0;
- while (i != trim_len) {
- BLI_assert(i < trim_len);
+ if (trim_len > RAND_STRIDE) {
+ last_len = trim_len % RAND_STRIDE;
+ trim_len = trim_len - last_len;
+ }
+ else {
+ trim_len = 0;
+ last_len = bytes_len;
+ }
+
+ const char *data_src = (void *)&(rng->X);
+ size_t i = 0;
+ while (i != trim_len) {
+ BLI_assert(i < trim_len);
#ifdef __BIG_ENDIAN__
- for (size_t j = (RAND_STRIDE + MASK_BYTES) - 1; j != MASK_BYTES - 1; j--)
+ for (size_t j = (RAND_STRIDE + MASK_BYTES) - 1; j != MASK_BYTES - 1; j--)
#else
- for (size_t j = 0; j != RAND_STRIDE; j++)
+ for (size_t j = 0; j != RAND_STRIDE; j++)
#endif
- {
- bytes[i++] = data_src[j];
- }
- rng_step(rng);
- }
- if (last_len) {
- for (size_t j = 0; j != last_len; j++) {
- bytes[i++] = data_src[j];
- }
- }
+ {
+ bytes[i++] = data_src[j];
+ }
+ rng_step(rng);
+ }
+ if (last_len) {
+ for (size_t j = 0; j != last_len; j++) {
+ bytes[i++] = data_src[j];
+ }
+ }
#undef RAND_STRIDE
}
int BLI_rng_get_int(RNG *rng)
{
- rng_step(rng);
- return (int) (rng->X >> 17);
+ rng_step(rng);
+ return (int)(rng->X >> 17);
}
unsigned int BLI_rng_get_uint(RNG *rng)
{
- rng_step(rng);
- return (unsigned int) (rng->X >> 17);
+ rng_step(rng);
+ return (unsigned int)(rng->X >> 17);
}
/**
@@ -165,7 +164,7 @@ unsigned int BLI_rng_get_uint(RNG *rng)
*/
double BLI_rng_get_double(RNG *rng)
{
- return (double) BLI_rng_get_int(rng) / 0x80000000;
+ return (double)BLI_rng_get_int(rng) / 0x80000000;
}
/**
@@ -173,80 +172,79 @@ double BLI_rng_get_double(RNG *rng)
*/
float BLI_rng_get_float(RNG *rng)
{
- return (float) BLI_rng_get_int(rng) / 0x80000000;
+ return (float)BLI_rng_get_int(rng) / 0x80000000;
}
void BLI_rng_get_float_unit_v2(RNG *rng, float v[2])
{
- float a = (float)(M_PI * 2.0) * BLI_rng_get_float(rng);
- v[0] = cosf(a);
- v[1] = sinf(a);
+ float a = (float)(M_PI * 2.0) * BLI_rng_get_float(rng);
+ v[0] = cosf(a);
+ v[1] = sinf(a);
}
void BLI_rng_get_float_unit_v3(RNG *rng, float v[3])
{
- float r;
- v[2] = (2.0f * BLI_rng_get_float(rng)) - 1.0f;
- if ((r = 1.0f - (v[2] * v[2])) > 0.0f) {
- float a = (float)(M_PI * 2.0) * BLI_rng_get_float(rng);
- r = sqrtf(r);
- v[0] = r * cosf(a);
- v[1] = r * sinf(a);
- }
- else {
- v[2] = 1.0f;
- }
+ float r;
+ v[2] = (2.0f * BLI_rng_get_float(rng)) - 1.0f;
+ if ((r = 1.0f - (v[2] * v[2])) > 0.0f) {
+ float a = (float)(M_PI * 2.0) * BLI_rng_get_float(rng);
+ r = sqrtf(r);
+ v[0] = r * cosf(a);
+ v[1] = r * sinf(a);
+ }
+ else {
+ v[2] = 1.0f;
+ }
}
/**
* Generate a random point inside given tri.
*/
void BLI_rng_get_tri_sample_float_v2(
- RNG *rng, const float v1[2], const float v2[2], const float v3[2],
- float r_pt[2])
+ RNG *rng, const float v1[2], const float v2[2], const float v3[2], float r_pt[2])
{
- float u = BLI_rng_get_float(rng);
- float v = BLI_rng_get_float(rng);
+ float u = BLI_rng_get_float(rng);
+ float v = BLI_rng_get_float(rng);
- float side_u[2], side_v[2];
+ float side_u[2], side_v[2];
- if ((u + v) > 1.0f) {
- u = 1.0f - u;
- v = 1.0f - v;
- }
+ if ((u + v) > 1.0f) {
+ u = 1.0f - u;
+ v = 1.0f - v;
+ }
- sub_v2_v2v2(side_u, v2, v1);
- sub_v2_v2v2(side_v, v3, v1);
+ sub_v2_v2v2(side_u, v2, v1);
+ sub_v2_v2v2(side_v, v3, v1);
- copy_v2_v2(r_pt, v1);
- madd_v2_v2fl(r_pt, side_u, u);
- madd_v2_v2fl(r_pt, side_v, v);
+ copy_v2_v2(r_pt, v1);
+ madd_v2_v2fl(r_pt, side_u, u);
+ madd_v2_v2fl(r_pt, side_v, v);
}
void BLI_rng_shuffle_array(RNG *rng, void *data, unsigned int elem_size_i, unsigned int elem_tot)
{
- const size_t elem_size = (size_t)elem_size_i;
- unsigned int i = elem_tot;
- void *temp;
+ const size_t elem_size = (size_t)elem_size_i;
+ unsigned int i = elem_tot;
+ void *temp;
- if (elem_tot <= 1) {
- return;
- }
+ if (elem_tot <= 1) {
+ return;
+ }
- temp = malloc(elem_size);
+ temp = malloc(elem_size);
- while (i--) {
- unsigned int j = BLI_rng_get_uint(rng) % elem_tot;
- if (i != j) {
- void *iElem = (unsigned char *)data + i * elem_size_i;
- void *jElem = (unsigned char *)data + j * elem_size_i;
- memcpy(temp, iElem, elem_size);
- memcpy(iElem, jElem, elem_size);
- memcpy(jElem, temp, elem_size);
- }
- }
+ while (i--) {
+ unsigned int j = BLI_rng_get_uint(rng) % elem_tot;
+ if (i != j) {
+ void *iElem = (unsigned char *)data + i * elem_size_i;
+ void *jElem = (unsigned char *)data + j * elem_size_i;
+ memcpy(temp, iElem, elem_size);
+ memcpy(iElem, jElem, elem_size);
+ memcpy(jElem, temp, elem_size);
+ }
+ }
- free(temp);
+ free(temp);
}
/**
@@ -256,9 +254,9 @@ void BLI_rng_shuffle_array(RNG *rng, void *data, unsigned int elem_size_i, unsig
*/
void BLI_rng_skip(RNG *rng, int n)
{
- while (n--) {
- rng_step(rng);
- }
+ while (n--) {
+ rng_step(rng);
+ }
}
/***/
@@ -266,29 +264,32 @@ void BLI_rng_skip(RNG *rng, int n)
/* fill an array with random numbers */
void BLI_array_frand(float *ar, int count, unsigned int seed)
{
- RNG rng;
+ RNG rng;
- BLI_rng_srandom(&rng, seed);
+ BLI_rng_srandom(&rng, seed);
- for (int i = 0; i < count; i++) {
- ar[i] = BLI_rng_get_float(&rng);
- }
+ for (int i = 0; i < count; i++) {
+ ar[i] = BLI_rng_get_float(&rng);
+ }
}
float BLI_hash_frand(unsigned int seed)
{
- RNG rng;
+ RNG rng;
- BLI_rng_srandom(&rng, seed);
- return BLI_rng_get_float(&rng);
+ BLI_rng_srandom(&rng, seed);
+ return BLI_rng_get_float(&rng);
}
-void BLI_array_randomize(void *data, unsigned int elem_size, unsigned int elem_tot, unsigned int seed)
+void BLI_array_randomize(void *data,
+ unsigned int elem_size,
+ unsigned int elem_tot,
+ unsigned int seed)
{
- RNG rng;
+ RNG rng;
- BLI_rng_seed(&rng, seed);
- BLI_rng_shuffle_array(&rng, data, elem_size, elem_tot);
+ BLI_rng_seed(&rng, seed);
+ BLI_rng_shuffle_array(&rng, data, elem_size, elem_tot);
}
/* ********* for threaded random ************** */
@@ -297,51 +298,51 @@ static RNG rng_tab[BLENDER_MAX_THREADS];
void BLI_thread_srandom(int thread, unsigned int seed)
{
- if (thread >= BLENDER_MAX_THREADS) {
- thread = 0;
- }
+ if (thread >= BLENDER_MAX_THREADS) {
+ thread = 0;
+ }
- BLI_rng_seed(&rng_tab[thread], seed + hash[seed & 255]);
- seed = BLI_rng_get_uint(&rng_tab[thread]);
- BLI_rng_seed(&rng_tab[thread], seed + hash[seed & 255]);
- seed = BLI_rng_get_uint(&rng_tab[thread]);
- BLI_rng_seed(&rng_tab[thread], seed + hash[seed & 255]);
+ BLI_rng_seed(&rng_tab[thread], seed + hash[seed & 255]);
+ seed = BLI_rng_get_uint(&rng_tab[thread]);
+ BLI_rng_seed(&rng_tab[thread], seed + hash[seed & 255]);
+ seed = BLI_rng_get_uint(&rng_tab[thread]);
+ BLI_rng_seed(&rng_tab[thread], seed + hash[seed & 255]);
}
int BLI_thread_rand(int thread)
{
- return BLI_rng_get_int(&rng_tab[thread]);
+ return BLI_rng_get_int(&rng_tab[thread]);
}
float BLI_thread_frand(int thread)
{
- return BLI_rng_get_float(&rng_tab[thread]);
+ return BLI_rng_get_float(&rng_tab[thread]);
}
struct RNG_THREAD_ARRAY {
- RNG rng_tab[BLENDER_MAX_THREADS];
+ RNG rng_tab[BLENDER_MAX_THREADS];
};
RNG_THREAD_ARRAY *BLI_rng_threaded_new(void)
{
- unsigned int i;
- RNG_THREAD_ARRAY *rngarr = MEM_mallocN(sizeof(RNG_THREAD_ARRAY), "random_array");
+ unsigned int i;
+ RNG_THREAD_ARRAY *rngarr = MEM_mallocN(sizeof(RNG_THREAD_ARRAY), "random_array");
- for (i = 0; i < BLENDER_MAX_THREADS; i++) {
- BLI_rng_srandom(&rngarr->rng_tab[i], (unsigned int)clock());
- }
+ for (i = 0; i < BLENDER_MAX_THREADS; i++) {
+ BLI_rng_srandom(&rngarr->rng_tab[i], (unsigned int)clock());
+ }
- return rngarr;
+ return rngarr;
}
void BLI_rng_threaded_free(struct RNG_THREAD_ARRAY *rngarr)
{
- MEM_freeN(rngarr);
+ MEM_freeN(rngarr);
}
int BLI_rng_thread_rand(RNG_THREAD_ARRAY *rngarr, int thread)
{
- return BLI_rng_get_int(&rngarr->rng_tab[thread]);
+ return BLI_rng_get_int(&rngarr->rng_tab[thread]);
}
/* ********* Low-discrepancy sequences ************** */
@@ -350,101 +351,101 @@ int BLI_rng_thread_rand(RNG_THREAD_ARRAY *rngarr, int thread)
* "Instant Radiosity", Keller A. */
BLI_INLINE double halton_ex(double invprimes, double *offset)
{
- double e = fabs((1.0 - *offset) - 1e-10);
+ double e = fabs((1.0 - *offset) - 1e-10);
- if (invprimes >= e) {
- double lasth;
- double h = invprimes;
+ if (invprimes >= e) {
+ double lasth;
+ double h = invprimes;
- do {
- lasth = h;
- h *= invprimes;
- } while (h >= e);
+ do {
+ lasth = h;
+ h *= invprimes;
+ } while (h >= e);
- *offset += ((lasth + h) - 1.0);
- }
- else {
- *offset += invprimes;
- }
+ *offset += ((lasth + h) - 1.0);
+ }
+ else {
+ *offset += invprimes;
+ }
- return *offset;
+ return *offset;
}
void BLI_halton_1d(unsigned int prime, double offset, int n, double *r)
{
- const double invprime = 1.0 / (double)prime;
+ const double invprime = 1.0 / (double)prime;
- *r = 0.0;
+ *r = 0.0;
- for (int s = 0; s < n; s++) {
- *r = halton_ex(invprime, &offset);
- }
+ for (int s = 0; s < n; s++) {
+ *r = halton_ex(invprime, &offset);
+ }
}
void BLI_halton_2d(unsigned int prime[2], double offset[2], int n, double *r)
{
- const double invprimes[2] = {1.0 / (double)prime[0], 1.0 / (double)prime[1]};
+ const double invprimes[2] = {1.0 / (double)prime[0], 1.0 / (double)prime[1]};
- r[0] = r[1] = 0.0;
+ r[0] = r[1] = 0.0;
- for (int s = 0; s < n; s++) {
- for (int i = 0; i < 2; i++) {
- r[i] = halton_ex(invprimes[i], &offset[i]);
- }
- }
+ for (int s = 0; s < n; s++) {
+ for (int i = 0; i < 2; i++) {
+ r[i] = halton_ex(invprimes[i], &offset[i]);
+ }
+ }
}
void BLI_halton_3d(unsigned int prime[3], double offset[3], int n, double *r)
{
- const double invprimes[3] = {1.0 / (double)prime[0], 1.0 / (double)prime[1], 1.0 / (double)prime[2]};
+ const double invprimes[3] = {
+ 1.0 / (double)prime[0], 1.0 / (double)prime[1], 1.0 / (double)prime[2]};
- r[0] = r[1] = r[2] = 0.0;
+ r[0] = r[1] = r[2] = 0.0;
- for (int s = 0; s < n; s++) {
- for (int i = 0; i < 3; i++) {
- r[i] = halton_ex(invprimes[i], &offset[i]);
- }
- }
+ for (int s = 0; s < n; s++) {
+ for (int i = 0; i < 3; i++) {
+ r[i] = halton_ex(invprimes[i], &offset[i]);
+ }
+ }
}
void BLI_halton_2d_sequence(unsigned int prime[2], double offset[2], int n, double *r)
{
- const double invprimes[2] = {1.0 / (double)prime[0], 1.0 / (double)prime[1]};
+ const double invprimes[2] = {1.0 / (double)prime[0], 1.0 / (double)prime[1]};
- for (int s = 0; s < n; s++) {
- for (int i = 0; i < 2; i++) {
- r[s * 2 + i] = halton_ex(invprimes[i], &offset[i]);
- }
- }
+ for (int s = 0; s < n; s++) {
+ for (int i = 0; i < 2; i++) {
+ r[s * 2 + i] = halton_ex(invprimes[i], &offset[i]);
+ }
+ }
}
-
/* From "Sampling with Hammersley and Halton Points" TT Wong
* Appendix: Source Code 1 */
BLI_INLINE double radical_inverse(unsigned int n)
{
- double u = 0;
+ double u = 0;
- /* This reverse the bitwise representation
- * around the decimal point. */
- for (double p = 0.5; n; p *= 0.5, n >>= 1) {
- if (n & 1) {
- u += p;
- }
- }
+ /* This reverse the bitwise representation
+ * around the decimal point. */
+ for (double p = 0.5; n; p *= 0.5, n >>= 1) {
+ if (n & 1) {
+ u += p;
+ }
+ }
- return u;
+ return u;
}
void BLI_hammersley_1d(unsigned int n, double *r)
{
- *r = radical_inverse(n);
+ *r = radical_inverse(n);
}
void BLI_hammersley_2d_sequence(unsigned int n, double *r)
{
- for (unsigned int s = 0; s < n; s++) {
- r[s * 2 + 0] = (double)(s + 0.5) / (double)n;
- r[s * 2 + 1] = radical_inverse(s);
- }
+ for (unsigned int s = 0; s < n; s++) {
+ r[s * 2 + 0] = (double)(s + 0.5) / (double)n;
+ r[s * 2 + 1] = radical_inverse(s);
+ }
}
diff --git a/source/blender/blenlib/intern/rct.c b/source/blender/blenlib/intern/rct.c
index 9437380a09d..2723e1708cb 100644
--- a/source/blender/blenlib/intern/rct.c
+++ b/source/blender/blenlib/intern/rct.c
@@ -47,76 +47,124 @@ static void unit_m4(float m[4][4]);
*/
bool BLI_rcti_is_empty(const rcti *rect)
{
- return ((rect->xmax <= rect->xmin) || (rect->ymax <= rect->ymin));
+ return ((rect->xmax <= rect->xmin) || (rect->ymax <= rect->ymin));
}
bool BLI_rctf_is_empty(const rctf *rect)
{
- return ((rect->xmax <= rect->xmin) || (rect->ymax <= rect->ymin));
+ return ((rect->xmax <= rect->xmin) || (rect->ymax <= rect->ymin));
}
bool BLI_rcti_isect_x(const rcti *rect, const int x)
{
- if (x < rect->xmin) { return false; }
- if (x > rect->xmax) { return false; }
- return true;
+ if (x < rect->xmin) {
+ return false;
+ }
+ if (x > rect->xmax) {
+ return false;
+ }
+ return true;
}
bool BLI_rcti_isect_y(const rcti *rect, const int y)
{
- if (y < rect->ymin) { return false; }
- if (y > rect->ymax) { return false; }
- return true;
+ if (y < rect->ymin) {
+ return false;
+ }
+ if (y > rect->ymax) {
+ return false;
+ }
+ return true;
}
bool BLI_rcti_isect_pt(const rcti *rect, const int x, const int y)
{
- if (x < rect->xmin) { return false; }
- if (x > rect->xmax) { return false; }
- if (y < rect->ymin) { return false; }
- if (y > rect->ymax) { return false; }
- return true;
+ if (x < rect->xmin) {
+ return false;
+ }
+ if (x > rect->xmax) {
+ return false;
+ }
+ if (y < rect->ymin) {
+ return false;
+ }
+ if (y > rect->ymax) {
+ return false;
+ }
+ return true;
}
bool BLI_rcti_isect_pt_v(const rcti *rect, const int xy[2])
{
- if (xy[0] < rect->xmin) { return false; }
- if (xy[0] > rect->xmax) { return false; }
- if (xy[1] < rect->ymin) { return false; }
- if (xy[1] > rect->ymax) { return false; }
- return true;
+ if (xy[0] < rect->xmin) {
+ return false;
+ }
+ if (xy[0] > rect->xmax) {
+ return false;
+ }
+ if (xy[1] < rect->ymin) {
+ return false;
+ }
+ if (xy[1] > rect->ymax) {
+ return false;
+ }
+ return true;
}
bool BLI_rctf_isect_x(const rctf *rect, const float x)
{
- if (x < rect->xmin) { return false; }
- if (x > rect->xmax) { return false; }
- return true;
+ if (x < rect->xmin) {
+ return false;
+ }
+ if (x > rect->xmax) {
+ return false;
+ }
+ return true;
}
bool BLI_rctf_isect_y(const rctf *rect, const float y)
{
- if (y < rect->ymin) { return false; }
- if (y > rect->ymax) { return false; }
- return true;
+ if (y < rect->ymin) {
+ return false;
+ }
+ if (y > rect->ymax) {
+ return false;
+ }
+ return true;
}
bool BLI_rctf_isect_pt(const rctf *rect, const float x, const float y)
{
- if (x < rect->xmin) { return false; }
- if (x > rect->xmax) { return false; }
- if (y < rect->ymin) { return false; }
- if (y > rect->ymax) { return false; }
- return true;
+ if (x < rect->xmin) {
+ return false;
+ }
+ if (x > rect->xmax) {
+ return false;
+ }
+ if (y < rect->ymin) {
+ return false;
+ }
+ if (y > rect->ymax) {
+ return false;
+ }
+ return true;
}
bool BLI_rctf_isect_pt_v(const rctf *rect, const float xy[2])
{
- if (xy[0] < rect->xmin) { return false; }
- if (xy[0] > rect->xmax) { return false; }
- if (xy[1] < rect->ymin) { return false; }
- if (xy[1] > rect->ymax) { return false; }
- return true;
+ if (xy[0] < rect->xmin) {
+ return false;
+ }
+ if (xy[0] > rect->xmax) {
+ return false;
+ }
+ if (xy[1] < rect->ymin) {
+ return false;
+ }
+ if (xy[1] > rect->ymax) {
+ return false;
+ }
+ return true;
}
/**
@@ -125,30 +173,46 @@ bool BLI_rctf_isect_pt_v(const rctf *rect, const float xy[2])
int BLI_rcti_length_x(const rcti *rect, const int x)
{
- if (x < rect->xmin) { return rect->xmin - x; }
- if (x > rect->xmax) { return x - rect->xmax; }
- return 0;
+ if (x < rect->xmin) {
+ return rect->xmin - x;
+ }
+ if (x > rect->xmax) {
+ return x - rect->xmax;
+ }
+ return 0;
}
int BLI_rcti_length_y(const rcti *rect, const int y)
{
- if (y < rect->ymin) { return rect->ymin - y; }
- if (y > rect->ymax) { return y - rect->ymax; }
- return 0;
+ if (y < rect->ymin) {
+ return rect->ymin - y;
+ }
+ if (y > rect->ymax) {
+ return y - rect->ymax;
+ }
+ return 0;
}
float BLI_rctf_length_x(const rctf *rect, const float x)
{
- if (x < rect->xmin) { return rect->xmin - x; }
- if (x > rect->xmax) { return x - rect->xmax; }
- return 0.0f;
+ if (x < rect->xmin) {
+ return rect->xmin - x;
+ }
+ if (x > rect->xmax) {
+ return x - rect->xmax;
+ }
+ return 0.0f;
}
float BLI_rctf_length_y(const rctf *rect, const float y)
{
- if (y < rect->ymin) { return rect->ymin - y; }
- if (y > rect->ymax) { return y - rect->ymax; }
- return 0.0f;
+ if (y < rect->ymin) {
+ return rect->ymin - y;
+ }
+ if (y > rect->ymax) {
+ return y - rect->ymax;
+ }
+ return 0.0f;
}
/**
@@ -156,267 +220,334 @@ float BLI_rctf_length_y(const rctf *rect, const float y)
*/
bool BLI_rctf_inside_rctf(const rctf *rct_a, const rctf *rct_b)
{
- return ((rct_a->xmin <= rct_b->xmin) &&
- (rct_a->xmax >= rct_b->xmax) &&
- (rct_a->ymin <= rct_b->ymin) &&
- (rct_a->ymax >= rct_b->ymax));
+ return ((rct_a->xmin <= rct_b->xmin) && (rct_a->xmax >= rct_b->xmax) &&
+ (rct_a->ymin <= rct_b->ymin) && (rct_a->ymax >= rct_b->ymax));
}
bool BLI_rcti_inside_rcti(const rcti *rct_a, const rcti *rct_b)
{
- return ((rct_a->xmin <= rct_b->xmin) &&
- (rct_a->xmax >= rct_b->xmax) &&
- (rct_a->ymin <= rct_b->ymin) &&
- (rct_a->ymax >= rct_b->ymax));
+ return ((rct_a->xmin <= rct_b->xmin) && (rct_a->xmax >= rct_b->xmax) &&
+ (rct_a->ymin <= rct_b->ymin) && (rct_a->ymax >= rct_b->ymax));
}
-
/* based closely on 'isect_seg_seg_v2_int',
* but in modified so corner cases are treated as intersections */
static int isect_segments_i(const int v1[2], const int v2[2], const int v3[2], const int v4[2])
{
- const double div = (double)((v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0]));
- if (div == 0.0) {
- return 1; /* co-linear */
- }
- else {
- const double lambda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div;
- const double mu = (double)((v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div;
- return (lambda >= 0.0 && lambda <= 1.0 && mu >= 0.0 && mu <= 1.0);
- }
-}
-static int isect_segments_fl(const float v1[2], const float v2[2], const float v3[2], const float v4[2])
-{
- const double div = (double)((v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0]));
- if (div == 0.0) {
- return 1; /* co-linear */
- }
- else {
- const double lambda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div;
- const double mu = (double)((v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div;
- return (lambda >= 0.0 && lambda <= 1.0 && mu >= 0.0 && mu <= 1.0);
- }
+ const double div = (double)((v2[0] - v1[0]) * (v4[1] - v3[1]) -
+ (v2[1] - v1[1]) * (v4[0] - v3[0]));
+ if (div == 0.0) {
+ return 1; /* co-linear */
+ }
+ else {
+ const double lambda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) -
+ (v1[0] - v3[0]) * (v4[1] - v3[1])) /
+ div;
+ const double mu = (double)((v1[1] - v3[1]) * (v2[0] - v1[0]) -
+ (v1[0] - v3[0]) * (v2[1] - v1[1])) /
+ div;
+ return (lambda >= 0.0 && lambda <= 1.0 && mu >= 0.0 && mu <= 1.0);
+ }
+}
+static int isect_segments_fl(const float v1[2],
+ const float v2[2],
+ const float v3[2],
+ const float v4[2])
+{
+ const double div = (double)((v2[0] - v1[0]) * (v4[1] - v3[1]) -
+ (v2[1] - v1[1]) * (v4[0] - v3[0]));
+ if (div == 0.0) {
+ return 1; /* co-linear */
+ }
+ else {
+ const double lambda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) -
+ (v1[0] - v3[0]) * (v4[1] - v3[1])) /
+ div;
+ const double mu = (double)((v1[1] - v3[1]) * (v2[0] - v1[0]) -
+ (v1[0] - v3[0]) * (v2[1] - v1[1])) /
+ div;
+ return (lambda >= 0.0 && lambda <= 1.0 && mu >= 0.0 && mu <= 1.0);
+ }
}
bool BLI_rcti_isect_segment(const rcti *rect, const int s1[2], const int s2[2])
{
- /* first do outside-bounds check for both points of the segment */
- if (s1[0] < rect->xmin && s2[0] < rect->xmin) { return false; }
- if (s1[0] > rect->xmax && s2[0] > rect->xmax) { return false; }
- if (s1[1] < rect->ymin && s2[1] < rect->ymin) { return false; }
- if (s1[1] > rect->ymax && s2[1] > rect->ymax) { return false; }
-
- /* if either points intersect then we definetly intersect */
- if (BLI_rcti_isect_pt_v(rect, s1) || BLI_rcti_isect_pt_v(rect, s2)) {
- return true;
- }
- else {
- /* both points are outside but may insersect the rect */
- int tvec1[2];
- int tvec2[2];
- /* diagonal: [/] */
- tvec1[0] = rect->xmin; tvec1[1] = rect->ymin;
- tvec2[0] = rect->xmin; tvec2[1] = rect->ymax;
- if (isect_segments_i(s1, s2, tvec1, tvec2)) {
- return true;
- }
-
- /* diagonal: [\] */
- tvec1[0] = rect->xmin; tvec1[1] = rect->ymax;
- tvec2[0] = rect->xmax; tvec2[1] = rect->ymin;
- if (isect_segments_i(s1, s2, tvec1, tvec2)) {
- return true;
- }
-
- /* no intersection */
- return false;
- }
+ /* first do outside-bounds check for both points of the segment */
+ if (s1[0] < rect->xmin && s2[0] < rect->xmin) {
+ return false;
+ }
+ if (s1[0] > rect->xmax && s2[0] > rect->xmax) {
+ return false;
+ }
+ if (s1[1] < rect->ymin && s2[1] < rect->ymin) {
+ return false;
+ }
+ if (s1[1] > rect->ymax && s2[1] > rect->ymax) {
+ return false;
+ }
+
+ /* if either points intersect then we definetly intersect */
+ if (BLI_rcti_isect_pt_v(rect, s1) || BLI_rcti_isect_pt_v(rect, s2)) {
+ return true;
+ }
+ else {
+ /* both points are outside but may insersect the rect */
+ int tvec1[2];
+ int tvec2[2];
+ /* diagonal: [/] */
+ tvec1[0] = rect->xmin;
+ tvec1[1] = rect->ymin;
+ tvec2[0] = rect->xmin;
+ tvec2[1] = rect->ymax;
+ if (isect_segments_i(s1, s2, tvec1, tvec2)) {
+ return true;
+ }
+
+ /* diagonal: [\] */
+ tvec1[0] = rect->xmin;
+ tvec1[1] = rect->ymax;
+ tvec2[0] = rect->xmax;
+ tvec2[1] = rect->ymin;
+ if (isect_segments_i(s1, s2, tvec1, tvec2)) {
+ return true;
+ }
+
+ /* no intersection */
+ return false;
+ }
}
bool BLI_rctf_isect_segment(const rctf *rect, const float s1[2], const float s2[2])
{
- /* first do outside-bounds check for both points of the segment */
- if (s1[0] < rect->xmin && s2[0] < rect->xmin) { return false; }
- if (s1[0] > rect->xmax && s2[0] > rect->xmax) { return false; }
- if (s1[1] < rect->ymin && s2[1] < rect->ymin) { return false; }
- if (s1[1] > rect->ymax && s2[1] > rect->ymax) { return false; }
-
- /* if either points intersect then we definetly intersect */
- if (BLI_rctf_isect_pt_v(rect, s1) || BLI_rctf_isect_pt_v(rect, s2)) {
- return true;
- }
- else {
- /* both points are outside but may insersect the rect */
- float tvec1[2];
- float tvec2[2];
- /* diagonal: [/] */
- tvec1[0] = rect->xmin; tvec1[1] = rect->ymin;
- tvec2[0] = rect->xmin; tvec2[1] = rect->ymax;
- if (isect_segments_fl(s1, s2, tvec1, tvec2)) {
- return true;
- }
-
- /* diagonal: [\] */
- tvec1[0] = rect->xmin; tvec1[1] = rect->ymax;
- tvec2[0] = rect->xmax; tvec2[1] = rect->ymin;
- if (isect_segments_fl(s1, s2, tvec1, tvec2)) {
- return true;
- }
-
- /* no intersection */
- return false;
- }
+ /* first do outside-bounds check for both points of the segment */
+ if (s1[0] < rect->xmin && s2[0] < rect->xmin) {
+ return false;
+ }
+ if (s1[0] > rect->xmax && s2[0] > rect->xmax) {
+ return false;
+ }
+ if (s1[1] < rect->ymin && s2[1] < rect->ymin) {
+ return false;
+ }
+ if (s1[1] > rect->ymax && s2[1] > rect->ymax) {
+ return false;
+ }
+
+ /* if either points intersect then we definetly intersect */
+ if (BLI_rctf_isect_pt_v(rect, s1) || BLI_rctf_isect_pt_v(rect, s2)) {
+ return true;
+ }
+ else {
+ /* both points are outside but may insersect the rect */
+ float tvec1[2];
+ float tvec2[2];
+ /* diagonal: [/] */
+ tvec1[0] = rect->xmin;
+ tvec1[1] = rect->ymin;
+ tvec2[0] = rect->xmin;
+ tvec2[1] = rect->ymax;
+ if (isect_segments_fl(s1, s2, tvec1, tvec2)) {
+ return true;
+ }
+
+ /* diagonal: [\] */
+ tvec1[0] = rect->xmin;
+ tvec1[1] = rect->ymax;
+ tvec2[0] = rect->xmax;
+ tvec2[1] = rect->ymin;
+ if (isect_segments_fl(s1, s2, tvec1, tvec2)) {
+ return true;
+ }
+
+ /* no intersection */
+ return false;
+ }
}
bool BLI_rcti_isect_circle(const rcti *rect, const float xy[2], const float radius)
{
- float dx, dy;
+ float dx, dy;
- if (xy[0] >= rect->xmin && xy[0] <= rect->xmax) {
- dx = 0;
- }
- else {
- dx = (xy[0] < rect->xmin) ? (rect->xmin - xy[0]) : (xy[0] - rect->xmax);
- }
+ if (xy[0] >= rect->xmin && xy[0] <= rect->xmax) {
+ dx = 0;
+ }
+ else {
+ dx = (xy[0] < rect->xmin) ? (rect->xmin - xy[0]) : (xy[0] - rect->xmax);
+ }
- if (xy[1] >= rect->ymin && xy[1] <= rect->ymax) {
- dy = 0;
- }
- else {
- dy = (xy[1] < rect->ymin) ? (rect->ymin - xy[1]) : (xy[1] - rect->ymax);
- }
+ if (xy[1] >= rect->ymin && xy[1] <= rect->ymax) {
+ dy = 0;
+ }
+ else {
+ dy = (xy[1] < rect->ymin) ? (rect->ymin - xy[1]) : (xy[1] - rect->ymax);
+ }
- return dx * dx + dy * dy <= radius * radius;
+ return dx * dx + dy * dy <= radius * radius;
}
bool BLI_rctf_isect_circle(const rctf *rect, const float xy[2], const float radius)
{
- float dx, dy;
+ float dx, dy;
- if (xy[0] >= rect->xmin && xy[0] <= rect->xmax) {
- dx = 0;
- }
- else {
- dx = (xy[0] < rect->xmin) ? (rect->xmin - xy[0]) : (xy[0] - rect->xmax);
- }
+ if (xy[0] >= rect->xmin && xy[0] <= rect->xmax) {
+ dx = 0;
+ }
+ else {
+ dx = (xy[0] < rect->xmin) ? (rect->xmin - xy[0]) : (xy[0] - rect->xmax);
+ }
- if (xy[1] >= rect->ymin && xy[1] <= rect->ymax) {
- dy = 0;
- }
- else {
- dy = (xy[1] < rect->ymin) ? (rect->ymin - xy[1]) : (xy[1] - rect->ymax);
- }
+ if (xy[1] >= rect->ymin && xy[1] <= rect->ymax) {
+ dy = 0;
+ }
+ else {
+ dy = (xy[1] < rect->ymin) ? (rect->ymin - xy[1]) : (xy[1] - rect->ymax);
+ }
- return dx * dx + dy * dy <= radius * radius;
+ return dx * dx + dy * dy <= radius * radius;
}
void BLI_rctf_union(rctf *rct1, const rctf *rct2)
{
- if (rct1->xmin > rct2->xmin) { rct1->xmin = rct2->xmin; }
- if (rct1->xmax < rct2->xmax) { rct1->xmax = rct2->xmax; }
- if (rct1->ymin > rct2->ymin) { rct1->ymin = rct2->ymin; }
- if (rct1->ymax < rct2->ymax) { rct1->ymax = rct2->ymax; }
+ if (rct1->xmin > rct2->xmin) {
+ rct1->xmin = rct2->xmin;
+ }
+ if (rct1->xmax < rct2->xmax) {
+ rct1->xmax = rct2->xmax;
+ }
+ if (rct1->ymin > rct2->ymin) {
+ rct1->ymin = rct2->ymin;
+ }
+ if (rct1->ymax < rct2->ymax) {
+ rct1->ymax = rct2->ymax;
+ }
}
void BLI_rcti_union(rcti *rct1, const rcti *rct2)
{
- if (rct1->xmin > rct2->xmin) { rct1->xmin = rct2->xmin; }
- if (rct1->xmax < rct2->xmax) { rct1->xmax = rct2->xmax; }
- if (rct1->ymin > rct2->ymin) { rct1->ymin = rct2->ymin; }
- if (rct1->ymax < rct2->ymax) { rct1->ymax = rct2->ymax; }
+ if (rct1->xmin > rct2->xmin) {
+ rct1->xmin = rct2->xmin;
+ }
+ if (rct1->xmax < rct2->xmax) {
+ rct1->xmax = rct2->xmax;
+ }
+ if (rct1->ymin > rct2->ymin) {
+ rct1->ymin = rct2->ymin;
+ }
+ if (rct1->ymax < rct2->ymax) {
+ rct1->ymax = rct2->ymax;
+ }
}
void BLI_rctf_init(rctf *rect, float xmin, float xmax, float ymin, float ymax)
{
- if (xmin <= xmax) {
- rect->xmin = xmin;
- rect->xmax = xmax;
- }
- else {
- rect->xmax = xmin;
- rect->xmin = xmax;
- }
- if (ymin <= ymax) {
- rect->ymin = ymin;
- rect->ymax = ymax;
- }
- else {
- rect->ymax = ymin;
- rect->ymin = ymax;
- }
+ if (xmin <= xmax) {
+ rect->xmin = xmin;
+ rect->xmax = xmax;
+ }
+ else {
+ rect->xmax = xmin;
+ rect->xmin = xmax;
+ }
+ if (ymin <= ymax) {
+ rect->ymin = ymin;
+ rect->ymax = ymax;
+ }
+ else {
+ rect->ymax = ymin;
+ rect->ymin = ymax;
+ }
}
void BLI_rcti_init(rcti *rect, int xmin, int xmax, int ymin, int ymax)
{
- if (xmin <= xmax) {
- rect->xmin = xmin;
- rect->xmax = xmax;
- }
- else {
- rect->xmax = xmin;
- rect->xmin = xmax;
- }
- if (ymin <= ymax) {
- rect->ymin = ymin;
- rect->ymax = ymax;
- }
- else {
- rect->ymax = ymin;
- rect->ymin = ymax;
- }
+ if (xmin <= xmax) {
+ rect->xmin = xmin;
+ rect->xmax = xmax;
+ }
+ else {
+ rect->xmax = xmin;
+ rect->xmin = xmax;
+ }
+ if (ymin <= ymax) {
+ rect->ymin = ymin;
+ rect->ymax = ymax;
+ }
+ else {
+ rect->ymax = ymin;
+ rect->ymin = ymax;
+ }
}
void BLI_rctf_init_pt_radius(rctf *rect, const float xy[2], float size)
{
- rect->xmin = xy[0] - size;
- rect->xmax = xy[0] + size;
- rect->ymin = xy[1] - size;
- rect->ymax = xy[1] + size;
+ rect->xmin = xy[0] - size;
+ rect->xmax = xy[0] + size;
+ rect->ymin = xy[1] - size;
+ rect->ymax = xy[1] + size;
}
void BLI_rcti_init_pt_radius(rcti *rect, const int xy[2], int size)
{
- rect->xmin = xy[0] - size;
- rect->xmax = xy[0] + size;
- rect->ymin = xy[1] - size;
- rect->ymax = xy[1] + size;
+ rect->xmin = xy[0] - size;
+ rect->xmax = xy[0] + size;
+ rect->ymin = xy[1] - size;
+ rect->ymax = xy[1] + size;
}
void BLI_rcti_init_minmax(rcti *rect)
{
- rect->xmin = rect->ymin = INT_MAX;
- rect->xmax = rect->ymax = INT_MIN;
+ rect->xmin = rect->ymin = INT_MAX;
+ rect->xmax = rect->ymax = INT_MIN;
}
void BLI_rctf_init_minmax(rctf *rect)
{
- rect->xmin = rect->ymin = FLT_MAX;
- rect->xmax = rect->ymax = -FLT_MAX;
+ rect->xmin = rect->ymin = FLT_MAX;
+ rect->xmax = rect->ymax = -FLT_MAX;
}
void BLI_rcti_do_minmax_v(rcti *rect, const int xy[2])
{
- if (xy[0] < rect->xmin) { rect->xmin = xy[0]; }
- if (xy[0] > rect->xmax) { rect->xmax = xy[0]; }
- if (xy[1] < rect->ymin) { rect->ymin = xy[1]; }
- if (xy[1] > rect->ymax) { rect->ymax = xy[1]; }
+ if (xy[0] < rect->xmin) {
+ rect->xmin = xy[0];
+ }
+ if (xy[0] > rect->xmax) {
+ rect->xmax = xy[0];
+ }
+ if (xy[1] < rect->ymin) {
+ rect->ymin = xy[1];
+ }
+ if (xy[1] > rect->ymax) {
+ rect->ymax = xy[1];
+ }
}
void BLI_rctf_do_minmax_v(rctf *rect, const float xy[2])
{
- if (xy[0] < rect->xmin) { rect->xmin = xy[0]; }
- if (xy[0] > rect->xmax) { rect->xmax = xy[0]; }
- if (xy[1] < rect->ymin) { rect->ymin = xy[1]; }
- if (xy[1] > rect->ymax) { rect->ymax = xy[1]; }
+ if (xy[0] < rect->xmin) {
+ rect->xmin = xy[0];
+ }
+ if (xy[0] > rect->xmax) {
+ rect->xmax = xy[0];
+ }
+ if (xy[1] < rect->ymin) {
+ rect->ymin = xy[1];
+ }
+ if (xy[1] > rect->ymax) {
+ rect->ymax = xy[1];
+ }
}
/* given 2 rectangles - transform a point from one to another */
-void BLI_rctf_transform_pt_v(const rctf *dst, const rctf *src, float xy_dst[2], const float xy_src[2])
+void BLI_rctf_transform_pt_v(const rctf *dst,
+ const rctf *src,
+ float xy_dst[2],
+ const float xy_src[2])
{
- xy_dst[0] = ((xy_src[0] - src->xmin) / (src->xmax - src->xmin));
- xy_dst[0] = dst->xmin + ((dst->xmax - dst->xmin) * xy_dst[0]);
+ xy_dst[0] = ((xy_src[0] - src->xmin) / (src->xmax - src->xmin));
+ xy_dst[0] = dst->xmin + ((dst->xmax - dst->xmin) * xy_dst[0]);
- xy_dst[1] = ((xy_src[1] - src->ymin) / (src->ymax - src->ymin));
- xy_dst[1] = dst->ymin + ((dst->ymax - dst->ymin) * xy_dst[1]);
+ xy_dst[1] = ((xy_src[1] - src->ymin) / (src->ymax - src->ymin));
+ xy_dst[1] = dst->ymin + ((dst->ymax - dst->ymin) * xy_dst[1]);
}
/**
@@ -425,124 +556,145 @@ void BLI_rctf_transform_pt_v(const rctf *dst, const rctf *src, float xy_dst[2],
* \note Multiplying a vector by this matrix does *not* give the same value as #BLI_rctf_transform_pt_v.
*/
void BLI_rctf_transform_calc_m4_pivot_min_ex(
- const rctf *dst, const rctf *src, float matrix[4][4],
- uint x, uint y)
+ const rctf *dst, const rctf *src, float matrix[4][4], uint x, uint y)
{
- BLI_assert(x < 3 && y < 3);
+ BLI_assert(x < 3 && y < 3);
- unit_m4(matrix);
+ unit_m4(matrix);
- matrix[x][x] = BLI_rctf_size_x(src) / BLI_rctf_size_x(dst);
- matrix[y][y] = BLI_rctf_size_y(src) / BLI_rctf_size_y(dst);
- matrix[3][x] = (src->xmin - dst->xmin) * matrix[x][x];
- matrix[3][y] = (src->ymin - dst->ymin) * matrix[y][y];
+ matrix[x][x] = BLI_rctf_size_x(src) / BLI_rctf_size_x(dst);
+ matrix[y][y] = BLI_rctf_size_y(src) / BLI_rctf_size_y(dst);
+ matrix[3][x] = (src->xmin - dst->xmin) * matrix[x][x];
+ matrix[3][y] = (src->ymin - dst->ymin) * matrix[y][y];
}
-void BLI_rctf_transform_calc_m4_pivot_min(
- const rctf *dst, const rctf *src, float matrix[4][4])
+void BLI_rctf_transform_calc_m4_pivot_min(const rctf *dst, const rctf *src, float matrix[4][4])
{
- BLI_rctf_transform_calc_m4_pivot_min_ex(dst, src, matrix, 0, 1);
+ BLI_rctf_transform_calc_m4_pivot_min_ex(dst, src, matrix, 0, 1);
}
void BLI_rcti_translate(rcti *rect, int x, int y)
{
- rect->xmin += x;
- rect->ymin += y;
- rect->xmax += x;
- rect->ymax += y;
+ rect->xmin += x;
+ rect->ymin += y;
+ rect->xmax += x;
+ rect->ymax += y;
}
void BLI_rctf_translate(rctf *rect, float x, float y)
{
- rect->xmin += x;
- rect->ymin += y;
- rect->xmax += x;
- rect->ymax += y;
+ rect->xmin += x;
+ rect->ymin += y;
+ rect->xmax += x;
+ rect->ymax += y;
}
void BLI_rcti_recenter(rcti *rect, int x, int y)
{
- const int dx = x - BLI_rcti_cent_x(rect);
- const int dy = y - BLI_rcti_cent_y(rect);
- BLI_rcti_translate(rect, dx, dy);
+ const int dx = x - BLI_rcti_cent_x(rect);
+ const int dy = y - BLI_rcti_cent_y(rect);
+ BLI_rcti_translate(rect, dx, dy);
}
void BLI_rctf_recenter(rctf *rect, float x, float y)
{
- const float dx = x - BLI_rctf_cent_x(rect);
- const float dy = y - BLI_rctf_cent_y(rect);
- BLI_rctf_translate(rect, dx, dy);
+ const float dx = x - BLI_rctf_cent_x(rect);
+ const float dy = y - BLI_rctf_cent_y(rect);
+ BLI_rctf_translate(rect, dx, dy);
}
/* change width & height around the central location */
void BLI_rcti_resize(rcti *rect, int x, int y)
{
- rect->xmin = BLI_rcti_cent_x(rect) - (x / 2);
- rect->ymin = BLI_rcti_cent_y(rect) - (y / 2);
- rect->xmax = rect->xmin + x;
- rect->ymax = rect->ymin + y;
+ rect->xmin = BLI_rcti_cent_x(rect) - (x / 2);
+ rect->ymin = BLI_rcti_cent_y(rect) - (y / 2);
+ rect->xmax = rect->xmin + x;
+ rect->ymax = rect->ymin + y;
}
void BLI_rctf_resize(rctf *rect, float x, float y)
{
- rect->xmin = BLI_rctf_cent_x(rect) - (x * 0.5f);
- rect->ymin = BLI_rctf_cent_y(rect) - (y * 0.5f);
- rect->xmax = rect->xmin + x;
- rect->ymax = rect->ymin + y;
+ rect->xmin = BLI_rctf_cent_x(rect) - (x * 0.5f);
+ rect->ymin = BLI_rctf_cent_y(rect) - (y * 0.5f);
+ rect->xmax = rect->xmin + x;
+ rect->ymax = rect->ymin + y;
}
void BLI_rcti_scale(rcti *rect, const float scale)
{
- const int cent_x = BLI_rcti_cent_x(rect);
- const int cent_y = BLI_rcti_cent_y(rect);
- const int size_x_half = BLI_rcti_size_x(rect) * (scale * 0.5f);
- const int size_y_half = BLI_rcti_size_y(rect) * (scale * 0.5f);
- rect->xmin = cent_x - size_x_half;
- rect->ymin = cent_y - size_y_half;
- rect->xmax = cent_x + size_x_half;
- rect->ymax = cent_y + size_y_half;
+ const int cent_x = BLI_rcti_cent_x(rect);
+ const int cent_y = BLI_rcti_cent_y(rect);
+ const int size_x_half = BLI_rcti_size_x(rect) * (scale * 0.5f);
+ const int size_y_half = BLI_rcti_size_y(rect) * (scale * 0.5f);
+ rect->xmin = cent_x - size_x_half;
+ rect->ymin = cent_y - size_y_half;
+ rect->xmax = cent_x + size_x_half;
+ rect->ymax = cent_y + size_y_half;
}
void BLI_rctf_scale(rctf *rect, const float scale)
{
- const float cent_x = BLI_rctf_cent_x(rect);
- const float cent_y = BLI_rctf_cent_y(rect);
- const float size_x_half = BLI_rctf_size_x(rect) * (scale * 0.5f);
- const float size_y_half = BLI_rctf_size_y(rect) * (scale * 0.5f);
- rect->xmin = cent_x - size_x_half;
- rect->ymin = cent_y - size_y_half;
- rect->xmax = cent_x + size_x_half;
- rect->ymax = cent_y + size_y_half;
+ const float cent_x = BLI_rctf_cent_x(rect);
+ const float cent_y = BLI_rctf_cent_y(rect);
+ const float size_x_half = BLI_rctf_size_x(rect) * (scale * 0.5f);
+ const float size_y_half = BLI_rctf_size_y(rect) * (scale * 0.5f);
+ rect->xmin = cent_x - size_x_half;
+ rect->ymin = cent_y - size_y_half;
+ rect->xmax = cent_x + size_x_half;
+ rect->ymax = cent_y + size_y_half;
}
void BLI_rctf_interp(rctf *rect, const rctf *rect_a, const rctf *rect_b, const float fac)
{
- const float ifac = 1.0f - fac;
- rect->xmin = (rect_a->xmin * ifac) + (rect_b->xmin * fac);
- rect->xmax = (rect_a->xmax * ifac) + (rect_b->xmax * fac);
- rect->ymin = (rect_a->ymin * ifac) + (rect_b->ymin * fac);
- rect->ymax = (rect_a->ymax * ifac) + (rect_b->ymax * fac);
+ const float ifac = 1.0f - fac;
+ rect->xmin = (rect_a->xmin * ifac) + (rect_b->xmin * fac);
+ rect->xmax = (rect_a->xmax * ifac) + (rect_b->xmax * fac);
+ rect->ymin = (rect_a->ymin * ifac) + (rect_b->ymin * fac);
+ rect->ymax = (rect_a->ymax * ifac) + (rect_b->ymax * fac);
}
/* BLI_rcti_interp() not needed yet */
-
bool BLI_rctf_clamp_pt_v(const rctf *rect, float xy[2])
{
- bool changed = false;
- if (xy[0] < rect->xmin) { xy[0] = rect->xmin; changed = true; }
- if (xy[0] > rect->xmax) { xy[0] = rect->xmax; changed = true; }
- if (xy[1] < rect->ymin) { xy[1] = rect->ymin; changed = true; }
- if (xy[1] > rect->ymax) { xy[1] = rect->ymax; changed = true; }
- return changed;
+ bool changed = false;
+ if (xy[0] < rect->xmin) {
+ xy[0] = rect->xmin;
+ changed = true;
+ }
+ if (xy[0] > rect->xmax) {
+ xy[0] = rect->xmax;
+ changed = true;
+ }
+ if (xy[1] < rect->ymin) {
+ xy[1] = rect->ymin;
+ changed = true;
+ }
+ if (xy[1] > rect->ymax) {
+ xy[1] = rect->ymax;
+ changed = true;
+ }
+ return changed;
}
bool BLI_rcti_clamp_pt_v(const rcti *rect, int xy[2])
{
- bool changed = false;
- if (xy[0] < rect->xmin) { xy[0] = rect->xmin; changed = true; }
- if (xy[0] > rect->xmax) { xy[0] = rect->xmax; changed = true; }
- if (xy[1] < rect->ymin) { xy[1] = rect->ymin; changed = true; }
- if (xy[1] > rect->ymax) { xy[1] = rect->ymax; changed = true; }
- return changed;
+ bool changed = false;
+ if (xy[0] < rect->xmin) {
+ xy[0] = rect->xmin;
+ changed = true;
+ }
+ if (xy[0] > rect->xmax) {
+ xy[0] = rect->xmax;
+ changed = true;
+ }
+ if (xy[1] < rect->ymin) {
+ xy[1] = rect->ymin;
+ changed = true;
+ }
+ if (xy[1] > rect->ymax) {
+ xy[1] = rect->ymax;
+ changed = true;
+ }
+ return changed;
}
/**
@@ -552,259 +704,272 @@ bool BLI_rcti_clamp_pt_v(const rcti *rect, int xy[2])
*/
bool BLI_rctf_clamp(rctf *rect, const rctf *rect_bounds, float r_xy[2])
{
- bool changed = false;
-
- r_xy[0] = 0.0f;
- r_xy[1] = 0.0f;
-
- if (rect->xmin < rect_bounds->xmin) {
- float ofs = rect_bounds->xmin - rect->xmin;
- rect->xmin += ofs;
- rect->xmax += ofs;
- r_xy[0] += ofs;
- changed = true;
- }
-
- if (rect->xmax > rect_bounds->xmax) {
- float ofs = rect_bounds->xmax - rect->xmax;
- rect->xmin += ofs;
- rect->xmax += ofs;
- r_xy[0] += ofs;
- changed = true;
- }
-
- if (rect->ymin < rect_bounds->ymin) {
- float ofs = rect_bounds->ymin - rect->ymin;
- rect->ymin += ofs;
- rect->ymax += ofs;
- r_xy[1] += ofs;
- changed = true;
- }
-
- if (rect->ymax > rect_bounds->ymax) {
- float ofs = rect_bounds->ymax - rect->ymax;
- rect->ymin += ofs;
- rect->ymax += ofs;
- r_xy[1] += ofs;
- changed = true;
- }
-
- return changed;
+ bool changed = false;
+
+ r_xy[0] = 0.0f;
+ r_xy[1] = 0.0f;
+
+ if (rect->xmin < rect_bounds->xmin) {
+ float ofs = rect_bounds->xmin - rect->xmin;
+ rect->xmin += ofs;
+ rect->xmax += ofs;
+ r_xy[0] += ofs;
+ changed = true;
+ }
+
+ if (rect->xmax > rect_bounds->xmax) {
+ float ofs = rect_bounds->xmax - rect->xmax;
+ rect->xmin += ofs;
+ rect->xmax += ofs;
+ r_xy[0] += ofs;
+ changed = true;
+ }
+
+ if (rect->ymin < rect_bounds->ymin) {
+ float ofs = rect_bounds->ymin - rect->ymin;
+ rect->ymin += ofs;
+ rect->ymax += ofs;
+ r_xy[1] += ofs;
+ changed = true;
+ }
+
+ if (rect->ymax > rect_bounds->ymax) {
+ float ofs = rect_bounds->ymax - rect->ymax;
+ rect->ymin += ofs;
+ rect->ymax += ofs;
+ r_xy[1] += ofs;
+ changed = true;
+ }
+
+ return changed;
}
bool BLI_rcti_clamp(rcti *rect, const rcti *rect_bounds, int r_xy[2])
{
- bool changed = false;
-
- r_xy[0] = 0;
- r_xy[1] = 0;
-
- if (rect->xmin < rect_bounds->xmin) {
- int ofs = rect_bounds->xmin - rect->xmin;
- rect->xmin += ofs;
- rect->xmax += ofs;
- r_xy[0] += ofs;
- changed = true;
- }
-
- if (rect->xmax > rect_bounds->xmax) {
- int ofs = rect_bounds->xmax - rect->xmax;
- rect->xmin += ofs;
- rect->xmax += ofs;
- r_xy[0] += ofs;
- changed = true;
- }
-
- if (rect->ymin < rect_bounds->ymin) {
- int ofs = rect_bounds->ymin - rect->ymin;
- rect->ymin += ofs;
- rect->ymax += ofs;
- r_xy[1] += ofs;
- changed = true;
- }
-
- if (rect->ymax > rect_bounds->ymax) {
- int ofs = rect_bounds->ymax - rect->ymax;
- rect->ymin += ofs;
- rect->ymax += ofs;
- r_xy[1] += ofs;
- changed = true;
- }
-
- return changed;
+ bool changed = false;
+
+ r_xy[0] = 0;
+ r_xy[1] = 0;
+
+ if (rect->xmin < rect_bounds->xmin) {
+ int ofs = rect_bounds->xmin - rect->xmin;
+ rect->xmin += ofs;
+ rect->xmax += ofs;
+ r_xy[0] += ofs;
+ changed = true;
+ }
+
+ if (rect->xmax > rect_bounds->xmax) {
+ int ofs = rect_bounds->xmax - rect->xmax;
+ rect->xmin += ofs;
+ rect->xmax += ofs;
+ r_xy[0] += ofs;
+ changed = true;
+ }
+
+ if (rect->ymin < rect_bounds->ymin) {
+ int ofs = rect_bounds->ymin - rect->ymin;
+ rect->ymin += ofs;
+ rect->ymax += ofs;
+ r_xy[1] += ofs;
+ changed = true;
+ }
+
+ if (rect->ymax > rect_bounds->ymax) {
+ int ofs = rect_bounds->ymax - rect->ymax;
+ rect->ymin += ofs;
+ rect->ymax += ofs;
+ r_xy[1] += ofs;
+ changed = true;
+ }
+
+ return changed;
}
bool BLI_rctf_compare(const rctf *rect_a, const rctf *rect_b, const float limit)
{
- if (fabsf(rect_a->xmin - rect_b->xmin) < limit) {
- if (fabsf(rect_a->xmax - rect_b->xmax) < limit) {
- if (fabsf(rect_a->ymin - rect_b->ymin) < limit) {
- if (fabsf(rect_a->ymax - rect_b->ymax) < limit) {
- return true;
- }
- }
- }
- }
+ if (fabsf(rect_a->xmin - rect_b->xmin) < limit) {
+ if (fabsf(rect_a->xmax - rect_b->xmax) < limit) {
+ if (fabsf(rect_a->ymin - rect_b->ymin) < limit) {
+ if (fabsf(rect_a->ymax - rect_b->ymax) < limit) {
+ return true;
+ }
+ }
+ }
+ }
- return false;
+ return false;
}
bool BLI_rcti_compare(const rcti *rect_a, const rcti *rect_b)
{
- if (rect_a->xmin == rect_b->xmin) {
- if (rect_a->xmax == rect_b->xmax) {
- if (rect_a->ymin == rect_b->ymin) {
- if (rect_a->ymax == rect_b->ymax) {
- return true;
- }
- }
- }
- }
+ if (rect_a->xmin == rect_b->xmin) {
+ if (rect_a->xmax == rect_b->xmax) {
+ if (rect_a->ymin == rect_b->ymin) {
+ if (rect_a->ymax == rect_b->ymax) {
+ return true;
+ }
+ }
+ }
+ }
- return false;
+ return false;
}
bool BLI_rctf_isect(const rctf *src1, const rctf *src2, rctf *dest)
{
- float xmin, xmax;
- float ymin, ymax;
-
- xmin = (src1->xmin) > (src2->xmin) ? (src1->xmin) : (src2->xmin);
- xmax = (src1->xmax) < (src2->xmax) ? (src1->xmax) : (src2->xmax);
- ymin = (src1->ymin) > (src2->ymin) ? (src1->ymin) : (src2->ymin);
- ymax = (src1->ymax) < (src2->ymax) ? (src1->ymax) : (src2->ymax);
-
- if (xmax >= xmin && ymax >= ymin) {
- if (dest) {
- dest->xmin = xmin;
- dest->xmax = xmax;
- dest->ymin = ymin;
- dest->ymax = ymax;
- }
- return true;
- }
- else {
- if (dest) {
- dest->xmin = 0;
- dest->xmax = 0;
- dest->ymin = 0;
- dest->ymax = 0;
- }
- return false;
- }
+ float xmin, xmax;
+ float ymin, ymax;
+
+ xmin = (src1->xmin) > (src2->xmin) ? (src1->xmin) : (src2->xmin);
+ xmax = (src1->xmax) < (src2->xmax) ? (src1->xmax) : (src2->xmax);
+ ymin = (src1->ymin) > (src2->ymin) ? (src1->ymin) : (src2->ymin);
+ ymax = (src1->ymax) < (src2->ymax) ? (src1->ymax) : (src2->ymax);
+
+ if (xmax >= xmin && ymax >= ymin) {
+ if (dest) {
+ dest->xmin = xmin;
+ dest->xmax = xmax;
+ dest->ymin = ymin;
+ dest->ymax = ymax;
+ }
+ return true;
+ }
+ else {
+ if (dest) {
+ dest->xmin = 0;
+ dest->xmax = 0;
+ dest->ymin = 0;
+ dest->ymax = 0;
+ }
+ return false;
+ }
}
bool BLI_rcti_isect(const rcti *src1, const rcti *src2, rcti *dest)
{
- int xmin, xmax;
- int ymin, ymax;
-
- xmin = (src1->xmin) > (src2->xmin) ? (src1->xmin) : (src2->xmin);
- xmax = (src1->xmax) < (src2->xmax) ? (src1->xmax) : (src2->xmax);
- ymin = (src1->ymin) > (src2->ymin) ? (src1->ymin) : (src2->ymin);
- ymax = (src1->ymax) < (src2->ymax) ? (src1->ymax) : (src2->ymax);
-
- if (xmax >= xmin && ymax >= ymin) {
- if (dest) {
- dest->xmin = xmin;
- dest->xmax = xmax;
- dest->ymin = ymin;
- dest->ymax = ymax;
- }
- return true;
- }
- else {
- if (dest) {
- dest->xmin = 0;
- dest->xmax = 0;
- dest->ymin = 0;
- dest->ymax = 0;
- }
- return false;
- }
+ int xmin, xmax;
+ int ymin, ymax;
+
+ xmin = (src1->xmin) > (src2->xmin) ? (src1->xmin) : (src2->xmin);
+ xmax = (src1->xmax) < (src2->xmax) ? (src1->xmax) : (src2->xmax);
+ ymin = (src1->ymin) > (src2->ymin) ? (src1->ymin) : (src2->ymin);
+ ymax = (src1->ymax) < (src2->ymax) ? (src1->ymax) : (src2->ymax);
+
+ if (xmax >= xmin && ymax >= ymin) {
+ if (dest) {
+ dest->xmin = xmin;
+ dest->xmax = xmax;
+ dest->ymin = ymin;
+ dest->ymax = ymax;
+ }
+ return true;
+ }
+ else {
+ if (dest) {
+ dest->xmin = 0;
+ dest->xmax = 0;
+ dest->ymin = 0;
+ dest->ymax = 0;
+ }
+ return false;
+ }
}
void BLI_rcti_rctf_copy(rcti *dst, const rctf *src)
{
- dst->xmin = floorf(src->xmin + 0.5f);
- dst->xmax = dst->xmin + floorf(BLI_rctf_size_x(src) + 0.5f);
- dst->ymin = floorf(src->ymin + 0.5f);
- dst->ymax = dst->ymin + floorf(BLI_rctf_size_y(src) + 0.5f);
+ dst->xmin = floorf(src->xmin + 0.5f);
+ dst->xmax = dst->xmin + floorf(BLI_rctf_size_x(src) + 0.5f);
+ dst->ymin = floorf(src->ymin + 0.5f);
+ dst->ymax = dst->ymin + floorf(BLI_rctf_size_y(src) + 0.5f);
}
void BLI_rcti_rctf_copy_floor(rcti *dst, const rctf *src)
{
- dst->xmin = floorf(src->xmin);
- dst->xmax = floorf(src->xmax);
- dst->ymin = floorf(src->ymin);
- dst->ymax = floorf(src->ymax);
+ dst->xmin = floorf(src->xmin);
+ dst->xmax = floorf(src->xmax);
+ dst->ymin = floorf(src->ymin);
+ dst->ymax = floorf(src->ymax);
}
void BLI_rcti_rctf_copy_round(rcti *dst, const rctf *src)
{
- dst->xmin = floorf(src->xmin + 0.5f);
- dst->xmax = floorf(src->xmax + 0.5f);
- dst->ymin = floorf(src->ymin + 0.5f);
- dst->ymax = floorf(src->ymax + 0.5f);
+ dst->xmin = floorf(src->xmin + 0.5f);
+ dst->xmax = floorf(src->xmax + 0.5f);
+ dst->ymin = floorf(src->ymin + 0.5f);
+ dst->ymax = floorf(src->ymax + 0.5f);
}
void BLI_rctf_rcti_copy(rctf *dst, const rcti *src)
{
- dst->xmin = src->xmin;
- dst->xmax = src->xmax;
- dst->ymin = src->ymin;
- dst->ymax = src->ymax;
+ dst->xmin = src->xmin;
+ dst->xmax = src->xmax;
+ dst->ymin = src->ymin;
+ dst->ymax = src->ymax;
}
void print_rctf(const char *str, const rctf *rect)
{
- printf("%s: xmin %.8f, xmax %.8f, ymin %.8f, ymax %.8f (%.12fx%.12f)\n", str,
- rect->xmin, rect->xmax, rect->ymin, rect->ymax, BLI_rctf_size_x(rect), BLI_rctf_size_y(rect));
+ printf("%s: xmin %.8f, xmax %.8f, ymin %.8f, ymax %.8f (%.12fx%.12f)\n",
+ str,
+ rect->xmin,
+ rect->xmax,
+ rect->ymin,
+ rect->ymax,
+ BLI_rctf_size_x(rect),
+ BLI_rctf_size_y(rect));
}
void print_rcti(const char *str, const rcti *rect)
{
- printf("%s: xmin %d, xmax %d, ymin %d, ymax %d (%dx%d)\n", str,
- rect->xmin, rect->xmax, rect->ymin, rect->ymax, BLI_rcti_size_x(rect), BLI_rcti_size_y(rect));
+ printf("%s: xmin %d, xmax %d, ymin %d, ymax %d (%dx%d)\n",
+ str,
+ rect->xmin,
+ rect->xmax,
+ rect->ymin,
+ rect->ymax,
+ BLI_rcti_size_x(rect),
+ BLI_rcti_size_y(rect));
}
-
/* -------------------------------------------------------------------- */
/* Comprehensive math (float only) */
/** \name Rect math functions
* \{ */
-#define ROTATE_SINCOS(r_vec, mat2, vec) { \
- (r_vec)[0] = (mat2)[1] * (vec)[0] + (+(mat2)[0]) * (vec)[1]; \
- (r_vec)[1] = (mat2)[0] * (vec)[0] + (-(mat2)[1]) * (vec)[1]; \
-} ((void)0)
+#define ROTATE_SINCOS(r_vec, mat2, vec) \
+ { \
+ (r_vec)[0] = (mat2)[1] * (vec)[0] + (+(mat2)[0]) * (vec)[1]; \
+ (r_vec)[1] = (mat2)[0] * (vec)[0] + (-(mat2)[1]) * (vec)[1]; \
+ } \
+ ((void)0)
/**
* Expand the rectangle to fit a rotated \a src.
*/
void BLI_rctf_rotate_expand(rctf *dst, const rctf *src, const float angle)
{
- const float mat2[2] = {sinf(angle), cosf(angle)};
- const float cent[2] = {BLI_rctf_cent_x(src), BLI_rctf_cent_y(src)};
- float corner[2], corner_rot[2], corder_max[2];
+ const float mat2[2] = {sinf(angle), cosf(angle)};
+ const float cent[2] = {BLI_rctf_cent_x(src), BLI_rctf_cent_y(src)};
+ float corner[2], corner_rot[2], corder_max[2];
- /* x is same for both corners */
- corner[0] = src->xmax - cent[0];
- corner[1] = src->ymax - cent[1];
- ROTATE_SINCOS(corner_rot, mat2, corner);
- corder_max[0] = fabsf(corner_rot[0]);
- corder_max[1] = fabsf(corner_rot[1]);
+ /* x is same for both corners */
+ corner[0] = src->xmax - cent[0];
+ corner[1] = src->ymax - cent[1];
+ ROTATE_SINCOS(corner_rot, mat2, corner);
+ corder_max[0] = fabsf(corner_rot[0]);
+ corder_max[1] = fabsf(corner_rot[1]);
- corner[1] *= -1;
- ROTATE_SINCOS(corner_rot, mat2, corner);
- corder_max[0] = MAX2(corder_max[0], fabsf(corner_rot[0]));
- corder_max[1] = MAX2(corder_max[1], fabsf(corner_rot[1]));
+ corner[1] *= -1;
+ ROTATE_SINCOS(corner_rot, mat2, corner);
+ corder_max[0] = MAX2(corder_max[0], fabsf(corner_rot[0]));
+ corder_max[1] = MAX2(corder_max[1], fabsf(corner_rot[1]));
- dst->xmin = cent[0] - corder_max[0];
- dst->xmax = cent[0] + corder_max[0];
- dst->ymin = cent[1] - corder_max[1];
- dst->ymax = cent[1] + corder_max[1];
+ dst->xmin = cent[0] - corder_max[0];
+ dst->xmax = cent[0] + corder_max[0];
+ dst->ymin = cent[1] - corder_max[1];
+ dst->ymax = cent[1] + corder_max[1];
}
#undef ROTATE_SINCOS
@@ -813,9 +978,9 @@ void BLI_rctf_rotate_expand(rctf *dst, const rctf *src, const float angle)
static void unit_m4(float m[4][4])
{
- m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1.0f;
- m[0][1] = m[0][2] = m[0][3] = 0.0f;
- m[1][0] = m[1][2] = m[1][3] = 0.0f;
- m[2][0] = m[2][1] = m[2][3] = 0.0f;
- m[3][0] = m[3][1] = m[3][2] = 0.0f;
+ m[0][0] = m[1][1] = m[2][2] = m[3][3] = 1.0f;
+ m[0][1] = m[0][2] = m[0][3] = 0.0f;
+ m[1][0] = m[1][2] = m[1][3] = 0.0f;
+ m[2][0] = m[2][1] = m[2][3] = 0.0f;
+ m[3][0] = m[3][1] = m[3][2] = 0.0f;
}
diff --git a/source/blender/blenlib/intern/scanfill.c b/source/blender/blenlib/intern/scanfill.c
index 80b4acc90a7..9b71c9e6797 100644
--- a/source/blender/blenlib/intern/scanfill.c
+++ b/source/blender/blenlib/intern/scanfill.c
@@ -44,1103 +44,1122 @@
#include "BLI_memarena.h"
#include "BLI_utildefines.h"
-#include "BLI_scanfill.h" /* own include */
+#include "BLI_scanfill.h" /* own include */
#include "BLI_strict_flags.h"
/* local types */
typedef struct PolyFill {
- unsigned int edges, verts;
- float min_xy[2], max_xy[2];
- unsigned short nr;
- bool f;
+ unsigned int edges, verts;
+ float min_xy[2], max_xy[2];
+ unsigned short nr;
+ bool f;
} PolyFill;
typedef struct ScanFillVertLink {
- ScanFillVert *vert;
- ScanFillEdge *edge_first, *edge_last;
+ ScanFillVert *vert;
+ ScanFillEdge *edge_first, *edge_last;
} ScanFillVertLink;
-
/* local funcs */
-#define SF_EPSILON 0.00003f
+#define SF_EPSILON 0.00003f
#define SF_EPSILON_SQ (SF_EPSILON * SF_EPSILON)
-
/* ScanFillVert.status */
-#define SF_VERT_NEW 0 /* all new verts have this flag set */
-#define SF_VERT_AVAILABLE 1 /* available - in an edge */
-#define SF_VERT_ZERO_LEN 2
-
+#define SF_VERT_NEW 0 /* all new verts have this flag set */
+#define SF_VERT_AVAILABLE 1 /* available - in an edge */
+#define SF_VERT_ZERO_LEN 2
/* ScanFillEdge.status */
/* Optionally set ScanFillEdge f to this to mark original boundary edges.
* Only needed if there are internal diagonal edges passed to BLI_scanfill_calc. */
-#define SF_EDGE_NEW 0 /* all new edges have this flag set */
+#define SF_EDGE_NEW 0 /* all new edges have this flag set */
// #define SF_EDGE_BOUNDARY 1 /* UNUSED */
-#define SF_EDGE_INTERNAL 2 /* edge is created while scan-filling */
-
+#define SF_EDGE_INTERNAL 2 /* edge is created while scan-filling */
/* PolyFill.status */
-#define SF_POLY_NEW 0 /* all polys initialized to this */
-#define SF_POLY_VALID 1 /* has at least 3 verts */
+#define SF_POLY_NEW 0 /* all polys initialized to this */
+#define SF_POLY_VALID 1 /* has at least 3 verts */
/* **** FUNCTIONS FOR QSORT *************************** */
-
static int vergscdata(const void *a1, const void *a2)
{
- const ScanFillVertLink *x1 = a1, *x2 = a2;
-
- if (x1->vert->xy[1] < x2->vert->xy[1]) { return 1; }
- else if (x1->vert->xy[1] > x2->vert->xy[1]) { return -1; }
- else if (x1->vert->xy[0] > x2->vert->xy[0]) { return 1; }
- else if (x1->vert->xy[0] < x2->vert->xy[0]) { return -1; }
-
- return 0;
+ const ScanFillVertLink *x1 = a1, *x2 = a2;
+
+ if (x1->vert->xy[1] < x2->vert->xy[1]) {
+ return 1;
+ }
+ else if (x1->vert->xy[1] > x2->vert->xy[1]) {
+ return -1;
+ }
+ else if (x1->vert->xy[0] > x2->vert->xy[0]) {
+ return 1;
+ }
+ else if (x1->vert->xy[0] < x2->vert->xy[0]) {
+ return -1;
+ }
+
+ return 0;
}
static int vergpoly(const void *a1, const void *a2)
{
- const PolyFill *x1 = a1, *x2 = a2;
-
- if (x1->min_xy[0] > x2->min_xy[0]) { return 1; }
- else if (x1->min_xy[0] < x2->min_xy[0]) { return -1; }
- else if (x1->min_xy[1] > x2->min_xy[1]) { return 1; }
- else if (x1->min_xy[1] < x2->min_xy[1]) { return -1; }
-
- return 0;
+ const PolyFill *x1 = a1, *x2 = a2;
+
+ if (x1->min_xy[0] > x2->min_xy[0]) {
+ return 1;
+ }
+ else if (x1->min_xy[0] < x2->min_xy[0]) {
+ return -1;
+ }
+ else if (x1->min_xy[1] > x2->min_xy[1]) {
+ return 1;
+ }
+ else if (x1->min_xy[1] < x2->min_xy[1]) {
+ return -1;
+ }
+
+ return 0;
}
/* **** FILL ROUTINES *************************** */
ScanFillVert *BLI_scanfill_vert_add(ScanFillContext *sf_ctx, const float vec[3])
{
- ScanFillVert *sf_v;
+ ScanFillVert *sf_v;
- sf_v = BLI_memarena_alloc(sf_ctx->arena, sizeof(ScanFillVert));
+ sf_v = BLI_memarena_alloc(sf_ctx->arena, sizeof(ScanFillVert));
- BLI_addtail(&sf_ctx->fillvertbase, sf_v);
+ BLI_addtail(&sf_ctx->fillvertbase, sf_v);
- sf_v->tmp.p = NULL;
- copy_v3_v3(sf_v->co, vec);
+ sf_v->tmp.p = NULL;
+ copy_v3_v3(sf_v->co, vec);
- /* just zero out the rest */
- zero_v2(sf_v->xy);
- sf_v->keyindex = 0;
- sf_v->poly_nr = sf_ctx->poly_nr;
- sf_v->edge_tot = 0;
- sf_v->f = SF_VERT_NEW;
- sf_v->user_flag = 0;
+ /* just zero out the rest */
+ zero_v2(sf_v->xy);
+ sf_v->keyindex = 0;
+ sf_v->poly_nr = sf_ctx->poly_nr;
+ sf_v->edge_tot = 0;
+ sf_v->f = SF_VERT_NEW;
+ sf_v->user_flag = 0;
- return sf_v;
+ return sf_v;
}
ScanFillEdge *BLI_scanfill_edge_add(ScanFillContext *sf_ctx, ScanFillVert *v1, ScanFillVert *v2)
{
- ScanFillEdge *sf_ed;
+ ScanFillEdge *sf_ed;
- sf_ed = BLI_memarena_alloc(sf_ctx->arena, sizeof(ScanFillEdge));
- BLI_addtail(&sf_ctx->filledgebase, sf_ed);
+ sf_ed = BLI_memarena_alloc(sf_ctx->arena, sizeof(ScanFillEdge));
+ BLI_addtail(&sf_ctx->filledgebase, sf_ed);
- sf_ed->v1 = v1;
- sf_ed->v2 = v2;
+ sf_ed->v1 = v1;
+ sf_ed->v2 = v2;
- /* just zero out the rest */
- sf_ed->poly_nr = sf_ctx->poly_nr;
- sf_ed->f = SF_EDGE_NEW;
- sf_ed->user_flag = 0;
- sf_ed->tmp.c = 0;
+ /* just zero out the rest */
+ sf_ed->poly_nr = sf_ctx->poly_nr;
+ sf_ed->f = SF_EDGE_NEW;
+ sf_ed->user_flag = 0;
+ sf_ed->tmp.c = 0;
- return sf_ed;
+ return sf_ed;
}
-static void addfillface(ScanFillContext *sf_ctx, ScanFillVert *v1, ScanFillVert *v2, ScanFillVert *v3)
+static void addfillface(ScanFillContext *sf_ctx,
+ ScanFillVert *v1,
+ ScanFillVert *v2,
+ ScanFillVert *v3)
{
- /* does not make edges */
- ScanFillFace *sf_tri;
+ /* does not make edges */
+ ScanFillFace *sf_tri;
- sf_tri = BLI_memarena_alloc(sf_ctx->arena, sizeof(ScanFillFace));
- BLI_addtail(&sf_ctx->fillfacebase, sf_tri);
+ sf_tri = BLI_memarena_alloc(sf_ctx->arena, sizeof(ScanFillFace));
+ BLI_addtail(&sf_ctx->fillfacebase, sf_tri);
- sf_tri->v1 = v1;
- sf_tri->v2 = v2;
- sf_tri->v3 = v3;
+ sf_tri->v1 = v1;
+ sf_tri->v2 = v2;
+ sf_tri->v3 = v3;
}
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 false; }
-
- 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 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]; }
- if (pf2->max_xy[1] < pf1->max_xy[1]) { pf2->max_xy[1] = pf1->max_xy[1]; }
-
- 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 true;
+ /* has pf2 been touched (intersected) by pf1 ? with bounding box */
+ /* test first if polys exist */
+
+ if (pf1->edges == 0 || pf2->edges == 0) {
+ return false;
+ }
+
+ 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 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];
+ }
+ if (pf2->max_xy[1] < pf1->max_xy[1]) {
+ pf2->max_xy[1] = pf1->max_xy[1];
+ }
+
+ 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 true;
}
-
/* add pf2 to pf1 */
static void mergepolysSimp(ScanFillContext *sf_ctx, PolyFill *pf1, PolyFill *pf2)
{
- ScanFillVert *eve;
- ScanFillEdge *eed;
-
- /* replace old poly numbers */
- for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
- if (eve->poly_nr == pf2->nr) {
- eve->poly_nr = pf1->nr;
- }
- }
-
- for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
- if (eed->poly_nr == pf2->nr) {
- eed->poly_nr = pf1->nr;
- }
- }
-
- pf1->verts += pf2->verts;
- pf1->edges += pf2->edges;
- pf2->verts = pf2->edges = 0;
- pf1->f = (pf1->f | pf2->f);
+ ScanFillVert *eve;
+ ScanFillEdge *eed;
+
+ /* replace old poly numbers */
+ for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
+ if (eve->poly_nr == pf2->nr) {
+ eve->poly_nr = pf1->nr;
+ }
+ }
+
+ for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
+ if (eed->poly_nr == pf2->nr) {
+ eed->poly_nr = pf1->nr;
+ }
+ }
+
+ pf1->verts += pf2->verts;
+ pf1->edges += pf2->edges;
+ pf2->verts = pf2->edges = 0;
+ pf1->f = (pf1->f | pf2->f);
}
static bool testedgeside(const float v1[2], const float v2[2], const float v3[2])
/* is v3 to the right of v1-v2 ? With exception: v3 == v1 || v3 == v2 */
{
- float inp;
-
- inp = (v2[0] - v1[0]) * (v1[1] - v3[1]) +
- (v1[1] - v2[1]) * (v1[0] - v3[0]);
-
- if (inp < 0.0f) {
- return false;
- }
- else if (inp == 0.0f) {
- if (v1[0] == v3[0] && v1[1] == v3[1]) {
- return false;
- }
- if (v2[0] == v3[0] && v2[1] == v3[1]) {
- return false;
- }
- }
- return true;
+ float inp;
+
+ inp = (v2[0] - v1[0]) * (v1[1] - v3[1]) + (v1[1] - v2[1]) * (v1[0] - v3[0]);
+
+ if (inp < 0.0f) {
+ return false;
+ }
+ else if (inp == 0.0f) {
+ if (v1[0] == v3[0] && v1[1] == v3[1]) {
+ return false;
+ }
+ if (v2[0] == v3[0] && v2[1] == v3[1]) {
+ return false;
+ }
+ }
+ return true;
}
static bool addedgetoscanvert(ScanFillVertLink *sc, ScanFillEdge *eed)
{
- /* find first edge to the right of eed, and insert eed before that */
- ScanFillEdge *ed;
- float fac, fac1, x, y;
-
- if (sc->edge_first == NULL) {
- sc->edge_first = sc->edge_last = eed;
- eed->prev = eed->next = NULL;
- return 1;
- }
-
- x = eed->v1->xy[0];
- y = eed->v1->xy[1];
-
- fac1 = eed->v2->xy[1] - y;
- if (fac1 == 0.0f) {
- fac1 = 1.0e10f * (eed->v2->xy[0] - x);
-
- }
- else {
- fac1 = (x - eed->v2->xy[0]) / fac1;
- }
-
- for (ed = sc->edge_first; ed; ed = ed->next) {
-
- if (ed->v2 == eed->v2) {
- return false;
- }
-
- fac = ed->v2->xy[1] - y;
- if (fac == 0.0f) {
- fac = 1.0e10f * (ed->v2->xy[0] - x);
- }
- else {
- fac = (x - ed->v2->xy[0]) / fac;
- }
-
- if (fac > fac1) {
- break;
- }
- }
- if (ed) {
- BLI_insertlinkbefore((ListBase *)&(sc->edge_first), ed, eed);
- }
- else {
- BLI_addtail((ListBase *)&(sc->edge_first), eed);
- }
-
- return true;
+ /* find first edge to the right of eed, and insert eed before that */
+ ScanFillEdge *ed;
+ float fac, fac1, x, y;
+
+ if (sc->edge_first == NULL) {
+ sc->edge_first = sc->edge_last = eed;
+ eed->prev = eed->next = NULL;
+ return 1;
+ }
+
+ x = eed->v1->xy[0];
+ y = eed->v1->xy[1];
+
+ fac1 = eed->v2->xy[1] - y;
+ if (fac1 == 0.0f) {
+ fac1 = 1.0e10f * (eed->v2->xy[0] - x);
+ }
+ else {
+ fac1 = (x - eed->v2->xy[0]) / fac1;
+ }
+
+ for (ed = sc->edge_first; ed; ed = ed->next) {
+
+ if (ed->v2 == eed->v2) {
+ return false;
+ }
+
+ fac = ed->v2->xy[1] - y;
+ if (fac == 0.0f) {
+ fac = 1.0e10f * (ed->v2->xy[0] - x);
+ }
+ else {
+ fac = (x - ed->v2->xy[0]) / fac;
+ }
+
+ if (fac > fac1) {
+ break;
+ }
+ }
+ if (ed) {
+ BLI_insertlinkbefore((ListBase *)&(sc->edge_first), ed, eed);
+ }
+ else {
+ BLI_addtail((ListBase *)&(sc->edge_first), eed);
+ }
+
+ return true;
}
-
-static ScanFillVertLink *addedgetoscanlist(ScanFillVertLink *scdata, ScanFillEdge *eed, unsigned int len)
+static ScanFillVertLink *addedgetoscanlist(ScanFillVertLink *scdata,
+ ScanFillEdge *eed,
+ unsigned int len)
{
- /* inserts edge at correct location in ScanFillVertLink list */
- /* returns sc when edge already exists */
- ScanFillVertLink *sc, scsearch;
- ScanFillVert *eve;
-
- /* which vert is left-top? */
- if (eed->v1->xy[1] == eed->v2->xy[1]) {
- if (eed->v1->xy[0] > eed->v2->xy[0]) {
- eve = eed->v1;
- eed->v1 = eed->v2;
- eed->v2 = eve;
- }
- }
- else if (eed->v1->xy[1] < eed->v2->xy[1]) {
- eve = eed->v1;
- eed->v1 = eed->v2;
- eed->v2 = eve;
- }
- /* find location in list */
- scsearch.vert = eed->v1;
- sc = (ScanFillVertLink *)bsearch(&scsearch, scdata, len,
- sizeof(ScanFillVertLink), vergscdata);
-
- if (UNLIKELY(sc == NULL)) {
- printf("Error in search edge: %p\n", (void *)eed);
- }
- else if (addedgetoscanvert(sc, eed) == false) {
- return sc;
- }
-
- return NULL;
+ /* inserts edge at correct location in ScanFillVertLink list */
+ /* returns sc when edge already exists */
+ ScanFillVertLink *sc, scsearch;
+ ScanFillVert *eve;
+
+ /* which vert is left-top? */
+ if (eed->v1->xy[1] == eed->v2->xy[1]) {
+ if (eed->v1->xy[0] > eed->v2->xy[0]) {
+ eve = eed->v1;
+ eed->v1 = eed->v2;
+ eed->v2 = eve;
+ }
+ }
+ else if (eed->v1->xy[1] < eed->v2->xy[1]) {
+ eve = eed->v1;
+ eed->v1 = eed->v2;
+ eed->v2 = eve;
+ }
+ /* find location in list */
+ scsearch.vert = eed->v1;
+ sc = (ScanFillVertLink *)bsearch(&scsearch, scdata, len, sizeof(ScanFillVertLink), vergscdata);
+
+ if (UNLIKELY(sc == NULL)) {
+ printf("Error in search edge: %p\n", (void *)eed);
+ }
+ else if (addedgetoscanvert(sc, eed) == false) {
+ return sc;
+ }
+
+ return NULL;
}
static bool boundinsideEV(ScanFillEdge *eed, ScanFillVert *eve)
/* is eve inside boundbox eed */
{
- float minx, maxx, miny, maxy;
-
- if (eed->v1->xy[0] < eed->v2->xy[0]) {
- minx = eed->v1->xy[0];
- maxx = eed->v2->xy[0];
- }
- else {
- minx = eed->v2->xy[0];
- maxx = eed->v1->xy[0];
- }
- if (eve->xy[0] >= minx && eve->xy[0] <= maxx) {
- if (eed->v1->xy[1] < eed->v2->xy[1]) {
- miny = eed->v1->xy[1];
- maxy = eed->v2->xy[1];
- }
- else {
- miny = eed->v2->xy[1];
- maxy = eed->v1->xy[1];
- }
- if (eve->xy[1] >= miny && eve->xy[1] <= maxy) {
- return true;
- }
- }
- return false;
+ float minx, maxx, miny, maxy;
+
+ if (eed->v1->xy[0] < eed->v2->xy[0]) {
+ minx = eed->v1->xy[0];
+ maxx = eed->v2->xy[0];
+ }
+ else {
+ minx = eed->v2->xy[0];
+ maxx = eed->v1->xy[0];
+ }
+ if (eve->xy[0] >= minx && eve->xy[0] <= maxx) {
+ if (eed->v1->xy[1] < eed->v2->xy[1]) {
+ miny = eed->v1->xy[1];
+ maxy = eed->v2->xy[1];
+ }
+ else {
+ miny = eed->v2->xy[1];
+ maxy = eed->v1->xy[1];
+ }
+ if (eve->xy[1] >= miny && eve->xy[1] <= maxy) {
+ return true;
+ }
+ }
+ return false;
}
-
static void testvertexnearedge(ScanFillContext *sf_ctx)
{
- /* only vertices with (->edge_tot == 1) are being tested for
- * being close to an edge, if true insert */
-
- ScanFillVert *eve;
- ScanFillEdge *eed, *ed1;
-
- for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
- if (eve->edge_tot == 1) {
- /* find the edge which has vertex eve,
- * note: we _know_ this will crash if 'ed1' becomes NULL
- * but this will never happen. */
- for (ed1 = sf_ctx->filledgebase.first;
- !(ed1->v1 == eve || ed1->v2 == eve);
- ed1 = ed1->next)
- {
- /* do nothing */
- }
-
- if (ed1->v1 == eve) {
- ed1->v1 = ed1->v2;
- ed1->v2 = eve;
- }
-
- for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
- if (eve != eed->v1 && eve != eed->v2 && eve->poly_nr == eed->poly_nr) {
- if (compare_v2v2(eve->xy, eed->v1->xy, SF_EPSILON)) {
- ed1->v2 = eed->v1;
- eed->v1->edge_tot++;
- eve->edge_tot = 0;
- break;
- }
- else if (compare_v2v2(eve->xy, eed->v2->xy, SF_EPSILON)) {
- ed1->v2 = eed->v2;
- eed->v2->edge_tot++;
- eve->edge_tot = 0;
- break;
- }
- else {
- if (boundinsideEV(eed, eve)) {
- const float dist = dist_squared_to_line_v2(eed->v1->xy, eed->v2->xy, eve->xy);
- if (dist < SF_EPSILON_SQ) {
- /* new edge */
- ed1 = BLI_scanfill_edge_add(sf_ctx, eed->v1, eve);
-
- /* printf("fill: vertex near edge %x\n", eve); */
- ed1->poly_nr = eed->poly_nr;
- eed->v1 = eve;
- eve->edge_tot = 3;
- break;
- }
- }
- }
- }
- }
- }
- }
+ /* only vertices with (->edge_tot == 1) are being tested for
+ * being close to an edge, if true insert */
+
+ ScanFillVert *eve;
+ ScanFillEdge *eed, *ed1;
+
+ for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
+ if (eve->edge_tot == 1) {
+ /* find the edge which has vertex eve,
+ * note: we _know_ this will crash if 'ed1' becomes NULL
+ * but this will never happen. */
+ for (ed1 = sf_ctx->filledgebase.first; !(ed1->v1 == eve || ed1->v2 == eve);
+ ed1 = ed1->next) {
+ /* do nothing */
+ }
+
+ if (ed1->v1 == eve) {
+ ed1->v1 = ed1->v2;
+ ed1->v2 = eve;
+ }
+
+ for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
+ if (eve != eed->v1 && eve != eed->v2 && eve->poly_nr == eed->poly_nr) {
+ if (compare_v2v2(eve->xy, eed->v1->xy, SF_EPSILON)) {
+ ed1->v2 = eed->v1;
+ eed->v1->edge_tot++;
+ eve->edge_tot = 0;
+ break;
+ }
+ else if (compare_v2v2(eve->xy, eed->v2->xy, SF_EPSILON)) {
+ ed1->v2 = eed->v2;
+ eed->v2->edge_tot++;
+ eve->edge_tot = 0;
+ break;
+ }
+ else {
+ if (boundinsideEV(eed, eve)) {
+ const float dist = dist_squared_to_line_v2(eed->v1->xy, eed->v2->xy, eve->xy);
+ if (dist < SF_EPSILON_SQ) {
+ /* new edge */
+ ed1 = BLI_scanfill_edge_add(sf_ctx, eed->v1, eve);
+
+ /* printf("fill: vertex near edge %x\n", eve); */
+ ed1->poly_nr = eed->poly_nr;
+ eed->v1 = eve;
+ eve->edge_tot = 3;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
}
-static void splitlist(ScanFillContext *sf_ctx, ListBase *tempve, ListBase *temped, unsigned short nr)
+static void splitlist(ScanFillContext *sf_ctx,
+ ListBase *tempve,
+ ListBase *temped,
+ unsigned short nr)
{
- /* everything is in templist, write only poly nr to fillist */
- ScanFillVert *eve, *eve_next;
- ScanFillEdge *eed, *eed_next;
-
- BLI_movelisttolist(tempve, &sf_ctx->fillvertbase);
- BLI_movelisttolist(temped, &sf_ctx->filledgebase);
-
-
- for (eve = tempve->first; eve; eve = eve_next) {
- eve_next = eve->next;
- if (eve->poly_nr == nr) {
- BLI_remlink(tempve, eve);
- BLI_addtail(&sf_ctx->fillvertbase, eve);
- }
-
- }
-
- for (eed = temped->first; eed; eed = eed_next) {
- eed_next = eed->next;
- if (eed->poly_nr == nr) {
- BLI_remlink(temped, eed);
- BLI_addtail(&sf_ctx->filledgebase, eed);
- }
- }
+ /* everything is in templist, write only poly nr to fillist */
+ ScanFillVert *eve, *eve_next;
+ ScanFillEdge *eed, *eed_next;
+
+ BLI_movelisttolist(tempve, &sf_ctx->fillvertbase);
+ BLI_movelisttolist(temped, &sf_ctx->filledgebase);
+
+ for (eve = tempve->first; eve; eve = eve_next) {
+ eve_next = eve->next;
+ if (eve->poly_nr == nr) {
+ BLI_remlink(tempve, eve);
+ BLI_addtail(&sf_ctx->fillvertbase, eve);
+ }
+ }
+
+ for (eed = temped->first; eed; eed = eed_next) {
+ eed_next = eed->next;
+ if (eed->poly_nr == nr) {
+ BLI_remlink(temped, eed);
+ BLI_addtail(&sf_ctx->filledgebase, eed);
+ }
+ }
}
static unsigned int scanfill(ScanFillContext *sf_ctx, PolyFill *pf, const int flag)
{
- ScanFillVertLink *scdata;
- ScanFillVertLink *sc = NULL, *sc1;
- ScanFillVert *eve, *v1, *v2, *v3;
- ScanFillEdge *eed, *eed_next, *ed1, *ed2, *ed3;
- unsigned int a, b, verts, maxface, totface;
- const unsigned short nr = pf->nr;
- bool twoconnected = false;
-
- /* PRINTS */
+ ScanFillVertLink *scdata;
+ ScanFillVertLink *sc = NULL, *sc1;
+ ScanFillVert *eve, *v1, *v2, *v3;
+ ScanFillEdge *eed, *eed_next, *ed1, *ed2, *ed3;
+ unsigned int a, b, verts, maxface, totface;
+ const unsigned short nr = pf->nr;
+ bool twoconnected = false;
+
+ /* PRINTS */
#if 0
- verts = pf->verts;
- for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
- printf("vert: %x co: %f %f\n", eve, eve->xy[0], eve->xy[1]);
- }
-
- for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
- printf("edge: %x verts: %x %x\n", eed, eed->v1, eed->v2);
- }
+ verts = pf->verts;
+ for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
+ printf("vert: %x co: %f %f\n", eve, eve->xy[0], eve->xy[1]);
+ }
+
+ for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
+ printf("edge: %x verts: %x %x\n", eed, eed->v1, eed->v2);
+ }
#endif
- /* STEP 0: remove zero sized edges */
- if (flag & BLI_SCANFILL_CALC_REMOVE_DOUBLES) {
- for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
- if (equals_v2v2(eed->v1->xy, eed->v2->xy)) {
- if (eed->v1->f == SF_VERT_ZERO_LEN && eed->v2->f != SF_VERT_ZERO_LEN) {
- eed->v2->f = SF_VERT_ZERO_LEN;
- eed->v2->tmp.v = eed->v1->tmp.v;
- }
- else if (eed->v2->f == SF_VERT_ZERO_LEN && eed->v1->f != SF_VERT_ZERO_LEN) {
- eed->v1->f = SF_VERT_ZERO_LEN;
- eed->v1->tmp.v = eed->v2->tmp.v;
- }
- else if (eed->v2->f == SF_VERT_ZERO_LEN && eed->v1->f == SF_VERT_ZERO_LEN) {
- eed->v1->tmp.v = eed->v2->tmp.v;
- }
- else {
- eed->v2->f = SF_VERT_ZERO_LEN;
- eed->v2->tmp.v = eed->v1;
- }
- }
- }
- }
-
- /* STEP 1: make using FillVert and FillEdge lists a sorted
- * ScanFillVertLink list
- */
- sc = scdata = MEM_mallocN(sizeof(*scdata) * pf->verts, "Scanfill1");
- verts = 0;
- for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
- if (eve->poly_nr == nr) {
- if (eve->f != SF_VERT_ZERO_LEN) {
- verts++;
- eve->f = SF_VERT_NEW; /* flag for connectedges later on */
- sc->vert = eve;
- sc->edge_first = sc->edge_last = NULL;
- /* Note, debug print only will work for curve polyfill, union is in use for mesh */
- /* if (even->tmp.v == NULL) eve->tmp.u = verts; */
- sc++;
- }
- }
- }
-
- qsort(scdata, verts, sizeof(ScanFillVertLink), vergscdata);
-
- if (flag & BLI_SCANFILL_CALC_REMOVE_DOUBLES) {
- for (eed = sf_ctx->filledgebase.first; eed; eed = eed_next) {
- eed_next = eed->next;
- BLI_remlink(&sf_ctx->filledgebase, eed);
- /* This code is for handling zero-length edges that get
- * collapsed in step 0. It was removed for some time to
- * fix trunk bug #4544, so if that comes back, this code
- * may need some work, or there will have to be a better
- * fix to #4544.
- *
- * warning, this can hang on un-ordered edges, see: [#33281]
- * for now disable 'BLI_SCANFILL_CALC_REMOVE_DOUBLES' for ngons.
- */
- if (eed->v1->f == SF_VERT_ZERO_LEN) {
- v1 = eed->v1;
- while ((eed->v1->f == SF_VERT_ZERO_LEN) && (eed->v1->tmp.v != v1) && (eed->v1 != eed->v1->tmp.v)) {
- eed->v1 = eed->v1->tmp.v;
- }
- }
- if (eed->v2->f == SF_VERT_ZERO_LEN) {
- v2 = eed->v2;
- while ((eed->v2->f == SF_VERT_ZERO_LEN) && (eed->v2->tmp.v != v2) && (eed->v2 != eed->v2->tmp.v)) {
- eed->v2 = eed->v2->tmp.v;
- }
- }
- if (eed->v1 != eed->v2) {
- addedgetoscanlist(scdata, eed, verts);
- }
- }
- }
- else {
- for (eed = sf_ctx->filledgebase.first; eed; eed = eed_next) {
- eed_next = eed->next;
- BLI_remlink(&sf_ctx->filledgebase, eed);
- if (eed->v1 != eed->v2) {
- addedgetoscanlist(scdata, eed, verts);
- }
- }
- }
+ /* STEP 0: remove zero sized edges */
+ if (flag & BLI_SCANFILL_CALC_REMOVE_DOUBLES) {
+ for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
+ if (equals_v2v2(eed->v1->xy, eed->v2->xy)) {
+ if (eed->v1->f == SF_VERT_ZERO_LEN && eed->v2->f != SF_VERT_ZERO_LEN) {
+ eed->v2->f = SF_VERT_ZERO_LEN;
+ eed->v2->tmp.v = eed->v1->tmp.v;
+ }
+ else if (eed->v2->f == SF_VERT_ZERO_LEN && eed->v1->f != SF_VERT_ZERO_LEN) {
+ eed->v1->f = SF_VERT_ZERO_LEN;
+ eed->v1->tmp.v = eed->v2->tmp.v;
+ }
+ else if (eed->v2->f == SF_VERT_ZERO_LEN && eed->v1->f == SF_VERT_ZERO_LEN) {
+ eed->v1->tmp.v = eed->v2->tmp.v;
+ }
+ else {
+ eed->v2->f = SF_VERT_ZERO_LEN;
+ eed->v2->tmp.v = eed->v1;
+ }
+ }
+ }
+ }
+
+ /* STEP 1: make using FillVert and FillEdge lists a sorted
+ * ScanFillVertLink list
+ */
+ sc = scdata = MEM_mallocN(sizeof(*scdata) * pf->verts, "Scanfill1");
+ verts = 0;
+ for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
+ if (eve->poly_nr == nr) {
+ if (eve->f != SF_VERT_ZERO_LEN) {
+ verts++;
+ eve->f = SF_VERT_NEW; /* flag for connectedges later on */
+ sc->vert = eve;
+ sc->edge_first = sc->edge_last = NULL;
+ /* Note, debug print only will work for curve polyfill, union is in use for mesh */
+ /* if (even->tmp.v == NULL) eve->tmp.u = verts; */
+ sc++;
+ }
+ }
+ }
+
+ qsort(scdata, verts, sizeof(ScanFillVertLink), vergscdata);
+
+ if (flag & BLI_SCANFILL_CALC_REMOVE_DOUBLES) {
+ for (eed = sf_ctx->filledgebase.first; eed; eed = eed_next) {
+ eed_next = eed->next;
+ BLI_remlink(&sf_ctx->filledgebase, eed);
+ /* This code is for handling zero-length edges that get
+ * collapsed in step 0. It was removed for some time to
+ * fix trunk bug #4544, so if that comes back, this code
+ * may need some work, or there will have to be a better
+ * fix to #4544.
+ *
+ * warning, this can hang on un-ordered edges, see: [#33281]
+ * for now disable 'BLI_SCANFILL_CALC_REMOVE_DOUBLES' for ngons.
+ */
+ if (eed->v1->f == SF_VERT_ZERO_LEN) {
+ v1 = eed->v1;
+ while ((eed->v1->f == SF_VERT_ZERO_LEN) && (eed->v1->tmp.v != v1) &&
+ (eed->v1 != eed->v1->tmp.v)) {
+ eed->v1 = eed->v1->tmp.v;
+ }
+ }
+ if (eed->v2->f == SF_VERT_ZERO_LEN) {
+ v2 = eed->v2;
+ while ((eed->v2->f == SF_VERT_ZERO_LEN) && (eed->v2->tmp.v != v2) &&
+ (eed->v2 != eed->v2->tmp.v)) {
+ eed->v2 = eed->v2->tmp.v;
+ }
+ }
+ if (eed->v1 != eed->v2) {
+ addedgetoscanlist(scdata, eed, verts);
+ }
+ }
+ }
+ else {
+ for (eed = sf_ctx->filledgebase.first; eed; eed = eed_next) {
+ eed_next = eed->next;
+ BLI_remlink(&sf_ctx->filledgebase, eed);
+ if (eed->v1 != eed->v2) {
+ addedgetoscanlist(scdata, eed, verts);
+ }
+ }
+ }
#if 0
- sc = sf_ctx->_scdata;
- for (a = 0; a < verts; a++) {
- printf("\nscvert: %x\n", sc->vert);
- for (eed = sc->edge_first; eed; eed = eed->next) {
- printf(" ed %x %x %x\n", eed, eed->v1, eed->v2);
- }
- sc++;
- }
+ sc = sf_ctx->_scdata;
+ for (a = 0; a < verts; a++) {
+ printf("\nscvert: %x\n", sc->vert);
+ for (eed = sc->edge_first; eed; eed = eed->next) {
+ printf(" ed %x %x %x\n", eed, eed->v1, eed->v2);
+ }
+ sc++;
+ }
#endif
-
- /* STEP 2: FILL LOOP */
-
- if (pf->f == SF_POLY_NEW) {
- twoconnected = true;
- }
-
- /* (temporal) security: never much more faces than vertices */
- totface = 0;
- if (flag & BLI_SCANFILL_CALC_HOLES) {
- maxface = 2 * verts; /* 2*verts: based at a filled circle within a triangle */
- }
- else {
- /* when we don't calc any holes, we assume face is a non overlapping loop */
- maxface = verts - 2;
- }
-
- sc = scdata;
- for (a = 0; a < verts; a++) {
- /* printf("VERTEX %d index %d\n", a, sc->vert->tmp.u); */
- /* set connectflags */
- for (ed1 = sc->edge_first; ed1; ed1 = eed_next) {
- eed_next = ed1->next;
- if (ed1->v1->edge_tot == 1 || ed1->v2->edge_tot == 1) {
- BLI_remlink((ListBase *)&(sc->edge_first), ed1);
- BLI_addtail(&sf_ctx->filledgebase, ed1);
- if (ed1->v1->edge_tot > 1) {
- ed1->v1->edge_tot--;
- }
- if (ed1->v2->edge_tot > 1) {
- ed1->v2->edge_tot--;
- }
- }
- else {
- ed1->v2->f = SF_VERT_AVAILABLE;
- }
- }
- while (sc->edge_first) { /* for as long there are edges */
- ed1 = sc->edge_first;
- ed2 = ed1->next;
-
- /* commented out... the ESC here delivers corrupted memory
- * (and doesnt work during grab) */
- /* if (callLocalInterruptCallBack()) break; */
- if (totface >= maxface) {
- /* printf("Fill error: endless loop. Escaped at vert %d, tot: %d.\n", a, verts); */
- a = verts;
- break;
- }
- if (ed2 == NULL) {
- sc->edge_first = sc->edge_last = NULL;
- /* printf("just 1 edge to vert\n"); */
- BLI_addtail(&sf_ctx->filledgebase, ed1);
- ed1->v2->f = SF_VERT_NEW;
- ed1->v1->edge_tot--;
- ed1->v2->edge_tot--;
- }
- else {
- /* test rest of vertices */
- ScanFillVertLink *best_sc = NULL;
- float angle_best_cos = -1.0f;
- float miny;
- bool firsttime = false;
-
- v1 = ed1->v2;
- v2 = ed1->v1;
- v3 = ed2->v2;
-
- /* this happens with a serial of overlapping edges */
- if (v1 == v2 || v2 == v3) {
- break;
- }
-
- /* printf("test verts %d %d %d\n", v1->tmp.u, v2->tmp.u, v3->tmp.u); */
- miny = min_ff(v1->xy[1], v3->xy[1]);
- sc1 = sc + 1;
-
- for (b = a + 1; b < verts; b++, sc1++) {
- if (sc1->vert->f == SF_VERT_NEW) {
- if (sc1->vert->xy[1] <= miny) {
- break;
- }
- if (testedgeside(v1->xy, v2->xy, sc1->vert->xy)) {
- if (testedgeside(v2->xy, v3->xy, sc1->vert->xy)) {
- if (testedgeside(v3->xy, v1->xy, sc1->vert->xy)) {
- /* point is in triangle */
-
- /* Because multiple points can be inside triangle
- * (concave holes) we continue searching and pick the
- * one with sharpest corner. */
- if (best_sc == NULL) {
- /* even without holes we need to keep checking [#35861] */
- best_sc = sc1;
- }
- else {
- /* Prevent angle calc for the simple cases
- * only 1 vertex is found. */
- if (firsttime == false) {
- angle_best_cos = cos_v2v2v2(v2->xy, v1->xy, best_sc->vert->xy);
- firsttime = true;
- }
-
- const float angle_test_cos = cos_v2v2v2(v2->xy, v1->xy, sc1->vert->xy);
- if (angle_test_cos > angle_best_cos) {
- best_sc = sc1;
- angle_best_cos = angle_test_cos;
- }
- }
- }
- }
- }
- }
- }
-
- if (best_sc) {
- /* make new edge, and start over */
- /* printf("add new edge %d %d and start again\n", v2->tmp.u, best_sc->vert->tmp.u); */
-
- ed3 = BLI_scanfill_edge_add(sf_ctx, v2, best_sc->vert);
- BLI_remlink(&sf_ctx->filledgebase, ed3);
- BLI_insertlinkbefore((ListBase *)&(sc->edge_first), ed2, ed3);
- ed3->v2->f = SF_VERT_AVAILABLE;
- ed3->f = SF_EDGE_INTERNAL;
- ed3->v1->edge_tot++;
- ed3->v2->edge_tot++;
- }
- else {
- /* new triangle */
- /* printf("add face %d %d %d\n", v1->tmp.u, v2->tmp.u, v3->tmp.u); */
- addfillface(sf_ctx, v1, v2, v3);
- totface++;
- BLI_remlink((ListBase *)&(sc->edge_first), ed1);
- BLI_addtail(&sf_ctx->filledgebase, ed1);
- ed1->v2->f = SF_VERT_NEW;
- ed1->v1->edge_tot--;
- ed1->v2->edge_tot--;
- /* ed2 can be removed when it's a boundary edge */
- if (((ed2->f == SF_EDGE_NEW) && twoconnected) /* || (ed2->f == SF_EDGE_BOUNDARY) */) {
- BLI_remlink((ListBase *)&(sc->edge_first), ed2);
- BLI_addtail(&sf_ctx->filledgebase, ed2);
- ed2->v2->f = SF_VERT_NEW;
- ed2->v1->edge_tot--;
- ed2->v2->edge_tot--;
- }
-
- /* new edge */
- ed3 = BLI_scanfill_edge_add(sf_ctx, v1, v3);
- BLI_remlink(&sf_ctx->filledgebase, ed3);
- ed3->f = SF_EDGE_INTERNAL;
- ed3->v1->edge_tot++;
- ed3->v2->edge_tot++;
-
- /* printf("add new edge %x %x\n", v1, v3); */
- sc1 = addedgetoscanlist(scdata, ed3, verts);
-
- if (sc1) { /* ed3 already exists: remove if a boundary */
- /* printf("Edge exists\n"); */
- ed3->v1->edge_tot--;
- ed3->v2->edge_tot--;
-
- for (ed3 = sc1->edge_first; ed3; ed3 = ed3->next) {
- if ((ed3->v1 == v1 && ed3->v2 == v3) || (ed3->v1 == v3 && ed3->v2 == v1)) {
- if (twoconnected /* || (ed3->f == SF_EDGE_BOUNDARY) */) {
- BLI_remlink((ListBase *)&(sc1->edge_first), ed3);
- BLI_addtail(&sf_ctx->filledgebase, ed3);
- ed3->v1->edge_tot--;
- ed3->v2->edge_tot--;
- }
- break;
- }
- }
- }
- }
- }
-
- /* test for loose edges */
- for (ed1 = sc->edge_first; ed1; ed1 = eed_next) {
- eed_next = ed1->next;
- if (ed1->v1->edge_tot < 2 || ed1->v2->edge_tot < 2) {
- BLI_remlink((ListBase *)&(sc->edge_first), ed1);
- BLI_addtail(&sf_ctx->filledgebase, ed1);
- if (ed1->v1->edge_tot > 1) {
- ed1->v1->edge_tot--;
- }
- if (ed1->v2->edge_tot > 1) {
- ed1->v2->edge_tot--;
- }
- }
- }
- /* done with loose edges */
- }
-
- sc++;
- }
-
- MEM_freeN(scdata);
-
- BLI_assert(totface <= maxface);
-
- return totface;
+ /* STEP 2: FILL LOOP */
+
+ if (pf->f == SF_POLY_NEW) {
+ twoconnected = true;
+ }
+
+ /* (temporal) security: never much more faces than vertices */
+ totface = 0;
+ if (flag & BLI_SCANFILL_CALC_HOLES) {
+ maxface = 2 * verts; /* 2*verts: based at a filled circle within a triangle */
+ }
+ else {
+ /* when we don't calc any holes, we assume face is a non overlapping loop */
+ maxface = verts - 2;
+ }
+
+ sc = scdata;
+ for (a = 0; a < verts; a++) {
+ /* printf("VERTEX %d index %d\n", a, sc->vert->tmp.u); */
+ /* set connectflags */
+ for (ed1 = sc->edge_first; ed1; ed1 = eed_next) {
+ eed_next = ed1->next;
+ if (ed1->v1->edge_tot == 1 || ed1->v2->edge_tot == 1) {
+ BLI_remlink((ListBase *)&(sc->edge_first), ed1);
+ BLI_addtail(&sf_ctx->filledgebase, ed1);
+ if (ed1->v1->edge_tot > 1) {
+ ed1->v1->edge_tot--;
+ }
+ if (ed1->v2->edge_tot > 1) {
+ ed1->v2->edge_tot--;
+ }
+ }
+ else {
+ ed1->v2->f = SF_VERT_AVAILABLE;
+ }
+ }
+ while (sc->edge_first) { /* for as long there are edges */
+ ed1 = sc->edge_first;
+ ed2 = ed1->next;
+
+ /* commented out... the ESC here delivers corrupted memory
+ * (and doesnt work during grab) */
+ /* if (callLocalInterruptCallBack()) break; */
+ if (totface >= maxface) {
+ /* printf("Fill error: endless loop. Escaped at vert %d, tot: %d.\n", a, verts); */
+ a = verts;
+ break;
+ }
+ if (ed2 == NULL) {
+ sc->edge_first = sc->edge_last = NULL;
+ /* printf("just 1 edge to vert\n"); */
+ BLI_addtail(&sf_ctx->filledgebase, ed1);
+ ed1->v2->f = SF_VERT_NEW;
+ ed1->v1->edge_tot--;
+ ed1->v2->edge_tot--;
+ }
+ else {
+ /* test rest of vertices */
+ ScanFillVertLink *best_sc = NULL;
+ float angle_best_cos = -1.0f;
+ float miny;
+ bool firsttime = false;
+
+ v1 = ed1->v2;
+ v2 = ed1->v1;
+ v3 = ed2->v2;
+
+ /* this happens with a serial of overlapping edges */
+ if (v1 == v2 || v2 == v3) {
+ break;
+ }
+
+ /* printf("test verts %d %d %d\n", v1->tmp.u, v2->tmp.u, v3->tmp.u); */
+ miny = min_ff(v1->xy[1], v3->xy[1]);
+ sc1 = sc + 1;
+
+ for (b = a + 1; b < verts; b++, sc1++) {
+ if (sc1->vert->f == SF_VERT_NEW) {
+ if (sc1->vert->xy[1] <= miny) {
+ break;
+ }
+ if (testedgeside(v1->xy, v2->xy, sc1->vert->xy)) {
+ if (testedgeside(v2->xy, v3->xy, sc1->vert->xy)) {
+ if (testedgeside(v3->xy, v1->xy, sc1->vert->xy)) {
+ /* point is in triangle */
+
+ /* Because multiple points can be inside triangle
+ * (concave holes) we continue searching and pick the
+ * one with sharpest corner. */
+ if (best_sc == NULL) {
+ /* even without holes we need to keep checking [#35861] */
+ best_sc = sc1;
+ }
+ else {
+ /* Prevent angle calc for the simple cases
+ * only 1 vertex is found. */
+ if (firsttime == false) {
+ angle_best_cos = cos_v2v2v2(v2->xy, v1->xy, best_sc->vert->xy);
+ firsttime = true;
+ }
+
+ const float angle_test_cos = cos_v2v2v2(v2->xy, v1->xy, sc1->vert->xy);
+ if (angle_test_cos > angle_best_cos) {
+ best_sc = sc1;
+ angle_best_cos = angle_test_cos;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ if (best_sc) {
+ /* make new edge, and start over */
+ /* printf("add new edge %d %d and start again\n", v2->tmp.u, best_sc->vert->tmp.u); */
+
+ ed3 = BLI_scanfill_edge_add(sf_ctx, v2, best_sc->vert);
+ BLI_remlink(&sf_ctx->filledgebase, ed3);
+ BLI_insertlinkbefore((ListBase *)&(sc->edge_first), ed2, ed3);
+ ed3->v2->f = SF_VERT_AVAILABLE;
+ ed3->f = SF_EDGE_INTERNAL;
+ ed3->v1->edge_tot++;
+ ed3->v2->edge_tot++;
+ }
+ else {
+ /* new triangle */
+ /* printf("add face %d %d %d\n", v1->tmp.u, v2->tmp.u, v3->tmp.u); */
+ addfillface(sf_ctx, v1, v2, v3);
+ totface++;
+ BLI_remlink((ListBase *)&(sc->edge_first), ed1);
+ BLI_addtail(&sf_ctx->filledgebase, ed1);
+ ed1->v2->f = SF_VERT_NEW;
+ ed1->v1->edge_tot--;
+ ed1->v2->edge_tot--;
+ /* ed2 can be removed when it's a boundary edge */
+ if (((ed2->f == SF_EDGE_NEW) && twoconnected) /* || (ed2->f == SF_EDGE_BOUNDARY) */) {
+ BLI_remlink((ListBase *)&(sc->edge_first), ed2);
+ BLI_addtail(&sf_ctx->filledgebase, ed2);
+ ed2->v2->f = SF_VERT_NEW;
+ ed2->v1->edge_tot--;
+ ed2->v2->edge_tot--;
+ }
+
+ /* new edge */
+ ed3 = BLI_scanfill_edge_add(sf_ctx, v1, v3);
+ BLI_remlink(&sf_ctx->filledgebase, ed3);
+ ed3->f = SF_EDGE_INTERNAL;
+ ed3->v1->edge_tot++;
+ ed3->v2->edge_tot++;
+
+ /* printf("add new edge %x %x\n", v1, v3); */
+ sc1 = addedgetoscanlist(scdata, ed3, verts);
+
+ if (sc1) { /* ed3 already exists: remove if a boundary */
+ /* printf("Edge exists\n"); */
+ ed3->v1->edge_tot--;
+ ed3->v2->edge_tot--;
+
+ for (ed3 = sc1->edge_first; ed3; ed3 = ed3->next) {
+ if ((ed3->v1 == v1 && ed3->v2 == v3) || (ed3->v1 == v3 && ed3->v2 == v1)) {
+ if (twoconnected /* || (ed3->f == SF_EDGE_BOUNDARY) */) {
+ BLI_remlink((ListBase *)&(sc1->edge_first), ed3);
+ BLI_addtail(&sf_ctx->filledgebase, ed3);
+ ed3->v1->edge_tot--;
+ ed3->v2->edge_tot--;
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ /* test for loose edges */
+ for (ed1 = sc->edge_first; ed1; ed1 = eed_next) {
+ eed_next = ed1->next;
+ if (ed1->v1->edge_tot < 2 || ed1->v2->edge_tot < 2) {
+ BLI_remlink((ListBase *)&(sc->edge_first), ed1);
+ BLI_addtail(&sf_ctx->filledgebase, ed1);
+ if (ed1->v1->edge_tot > 1) {
+ ed1->v1->edge_tot--;
+ }
+ if (ed1->v2->edge_tot > 1) {
+ ed1->v2->edge_tot--;
+ }
+ }
+ }
+ /* done with loose edges */
+ }
+
+ sc++;
+ }
+
+ MEM_freeN(scdata);
+
+ BLI_assert(totface <= maxface);
+
+ return totface;
}
-
void BLI_scanfill_begin(ScanFillContext *sf_ctx)
{
- memset(sf_ctx, 0, sizeof(*sf_ctx));
- sf_ctx->poly_nr = SF_POLY_UNSET;
- sf_ctx->arena = BLI_memarena_new(BLI_SCANFILL_ARENA_SIZE, __func__);
+ memset(sf_ctx, 0, sizeof(*sf_ctx));
+ sf_ctx->poly_nr = SF_POLY_UNSET;
+ sf_ctx->arena = BLI_memarena_new(BLI_SCANFILL_ARENA_SIZE, __func__);
}
void BLI_scanfill_begin_arena(ScanFillContext *sf_ctx, MemArena *arena)
{
- memset(sf_ctx, 0, sizeof(*sf_ctx));
- sf_ctx->poly_nr = SF_POLY_UNSET;
- sf_ctx->arena = arena;
+ memset(sf_ctx, 0, sizeof(*sf_ctx));
+ sf_ctx->poly_nr = SF_POLY_UNSET;
+ sf_ctx->arena = arena;
}
void BLI_scanfill_end(ScanFillContext *sf_ctx)
{
- BLI_memarena_free(sf_ctx->arena);
- sf_ctx->arena = NULL;
+ BLI_memarena_free(sf_ctx->arena);
+ sf_ctx->arena = NULL;
- BLI_listbase_clear(&sf_ctx->fillvertbase);
- BLI_listbase_clear(&sf_ctx->filledgebase);
- BLI_listbase_clear(&sf_ctx->fillfacebase);
+ BLI_listbase_clear(&sf_ctx->fillvertbase);
+ BLI_listbase_clear(&sf_ctx->filledgebase);
+ BLI_listbase_clear(&sf_ctx->fillfacebase);
}
void BLI_scanfill_end_arena(ScanFillContext *sf_ctx, MemArena *arena)
{
- BLI_memarena_clear(arena);
- BLI_assert(sf_ctx->arena == arena);
+ BLI_memarena_clear(arena);
+ BLI_assert(sf_ctx->arena == arena);
- BLI_listbase_clear(&sf_ctx->fillvertbase);
- BLI_listbase_clear(&sf_ctx->filledgebase);
- BLI_listbase_clear(&sf_ctx->fillfacebase);
+ BLI_listbase_clear(&sf_ctx->fillvertbase);
+ BLI_listbase_clear(&sf_ctx->filledgebase);
+ BLI_listbase_clear(&sf_ctx->fillfacebase);
}
unsigned int BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float nor_proj[3])
{
- /*
- * - fill works with its own lists, so create that first (no faces!)
- * - for vertices, put in ->tmp.v the old pointer
- * - struct elements xs en ys are not used here: don't hide stuff in it
- * - edge flag ->f becomes 2 when it's a new edge
- * - mode: & 1 is check for crossings, then create edges (TO DO )
- * - returns number of triangle faces added.
- */
- ListBase tempve, temped;
- ScanFillVert *eve;
- ScanFillEdge *eed, *eed_next;
- PolyFill *pflist, *pf;
- float *min_xy_p, *max_xy_p;
- unsigned int totfaces = 0; /* total faces added */
- unsigned short a, c, poly = 0;
- bool ok;
- float mat_2d[3][3];
-
- BLI_assert(!nor_proj || len_squared_v3(nor_proj) > FLT_EPSILON);
+ /*
+ * - fill works with its own lists, so create that first (no faces!)
+ * - for vertices, put in ->tmp.v the old pointer
+ * - struct elements xs en ys are not used here: don't hide stuff in it
+ * - edge flag ->f becomes 2 when it's a new edge
+ * - mode: & 1 is check for crossings, then create edges (TO DO )
+ * - returns number of triangle faces added.
+ */
+ ListBase tempve, temped;
+ ScanFillVert *eve;
+ ScanFillEdge *eed, *eed_next;
+ PolyFill *pflist, *pf;
+ float *min_xy_p, *max_xy_p;
+ unsigned int totfaces = 0; /* total faces added */
+ unsigned short a, c, poly = 0;
+ bool ok;
+ float mat_2d[3][3];
+
+ BLI_assert(!nor_proj || len_squared_v3(nor_proj) > FLT_EPSILON);
#ifdef DEBUG
- for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
- /* these values used to be set,
- * however they should always be zero'd so check instead */
- BLI_assert(eve->f == 0);
- BLI_assert(sf_ctx->poly_nr || eve->poly_nr == 0);
- BLI_assert(eve->edge_tot == 0);
- }
+ for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
+ /* these values used to be set,
+ * however they should always be zero'd so check instead */
+ BLI_assert(eve->f == 0);
+ BLI_assert(sf_ctx->poly_nr || eve->poly_nr == 0);
+ BLI_assert(eve->edge_tot == 0);
+ }
#endif
- /* first test vertices if they are in edges */
- /* including resetting of flags */
- for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
- BLI_assert(sf_ctx->poly_nr != SF_POLY_UNSET || eed->poly_nr == SF_POLY_UNSET);
- eed->v1->f = SF_VERT_AVAILABLE;
- eed->v2->f = SF_VERT_AVAILABLE;
- }
-
- for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
- if (eve->f == SF_VERT_AVAILABLE) {
- break;
- }
- }
-
- if (UNLIKELY(eve == NULL)) {
- return 0;
- }
- else {
- float n[3];
-
- if (nor_proj) {
- copy_v3_v3(n, nor_proj);
- }
- else {
- /* define projection: with 'best' normal */
- /* Newell's Method */
- /* Similar code used elsewhere, but this checks for double ups
- * which historically this function supports so better not change */
-
- /* warning: this only gives stable direction with single polygons,
- * ideally we'd calculate connectivity and each polys normal, see T41047 */
- const float *v_prev;
-
- zero_v3(n);
- eve = sf_ctx->fillvertbase.last;
- v_prev = eve->co;
-
- for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
- if (LIKELY(!compare_v3v3(v_prev, eve->co, SF_EPSILON))) {
- add_newell_cross_v3_v3v3(n, v_prev, eve->co);
- v_prev = eve->co;
- }
- }
- }
-
- if (UNLIKELY(normalize_v3(n) == 0.0f)) {
- return 0;
- }
-
- axis_dominant_v3_to_m3(mat_2d, n);
- }
-
-
- /* STEP 1: COUNT POLYS */
- if (sf_ctx->poly_nr != SF_POLY_UNSET) {
- poly = (unsigned short)(sf_ctx->poly_nr + 1);
- sf_ctx->poly_nr = SF_POLY_UNSET;
- }
-
- if (flag & BLI_SCANFILL_CALC_POLYS && (poly == 0)) {
- for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
- mul_v2_m3v3(eve->xy, mat_2d, eve->co);
-
- /* get first vertex with no poly number */
- if (eve->poly_nr == SF_POLY_UNSET) {
- unsigned int toggle = 0;
- /* now a sort of select connected */
- ok = true;
- eve->poly_nr = poly;
-
- while (ok) {
-
- ok = false;
-
- toggle++;
- for (eed = (toggle & 1) ? sf_ctx->filledgebase.first : sf_ctx->filledgebase.last;
- eed;
- eed = (toggle & 1) ? eed->next : eed->prev)
- {
- if (eed->v1->poly_nr == SF_POLY_UNSET && eed->v2->poly_nr == poly) {
- eed->v1->poly_nr = poly;
- eed->poly_nr = poly;
- ok = true;
- }
- else if (eed->v2->poly_nr == SF_POLY_UNSET && eed->v1->poly_nr == poly) {
- eed->v2->poly_nr = poly;
- eed->poly_nr = poly;
- ok = true;
- }
- else if (eed->poly_nr == SF_POLY_UNSET) {
- if (eed->v1->poly_nr == poly && eed->v2->poly_nr == poly) {
- eed->poly_nr = poly;
- ok = true;
- }
- }
- }
- }
-
- poly++;
- }
- }
- /* printf("amount of poly's: %d\n", poly); */
- }
- else if (poly) {
- /* we pre-calculated poly_nr */
- for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
- mul_v2_m3v3(eve->xy, mat_2d, eve->co);
- }
- }
- else {
- poly = 1;
-
- for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
- mul_v2_m3v3(eve->xy, mat_2d, eve->co);
- eve->poly_nr = 0;
- }
-
- for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
- eed->poly_nr = 0;
- }
- }
-
- /* STEP 2: remove loose edges and strings of edges */
- if (flag & BLI_SCANFILL_CALC_LOOSE) {
- unsigned int toggle = 0;
- for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
- if (eed->v1->edge_tot++ > 250) {
- break;
- }
- if (eed->v2->edge_tot++ > 250) {
- break;
- }
- }
- if (eed) {
- /* otherwise it's impossible to be sure you can clear vertices */
+ /* first test vertices if they are in edges */
+ /* including resetting of flags */
+ for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
+ BLI_assert(sf_ctx->poly_nr != SF_POLY_UNSET || eed->poly_nr == SF_POLY_UNSET);
+ eed->v1->f = SF_VERT_AVAILABLE;
+ eed->v2->f = SF_VERT_AVAILABLE;
+ }
+
+ for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
+ if (eve->f == SF_VERT_AVAILABLE) {
+ break;
+ }
+ }
+
+ if (UNLIKELY(eve == NULL)) {
+ return 0;
+ }
+ else {
+ float n[3];
+
+ if (nor_proj) {
+ copy_v3_v3(n, nor_proj);
+ }
+ else {
+ /* define projection: with 'best' normal */
+ /* Newell's Method */
+ /* Similar code used elsewhere, but this checks for double ups
+ * which historically this function supports so better not change */
+
+ /* warning: this only gives stable direction with single polygons,
+ * ideally we'd calculate connectivity and each polys normal, see T41047 */
+ const float *v_prev;
+
+ zero_v3(n);
+ eve = sf_ctx->fillvertbase.last;
+ v_prev = eve->co;
+
+ for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
+ if (LIKELY(!compare_v3v3(v_prev, eve->co, SF_EPSILON))) {
+ add_newell_cross_v3_v3v3(n, v_prev, eve->co);
+ v_prev = eve->co;
+ }
+ }
+ }
+
+ if (UNLIKELY(normalize_v3(n) == 0.0f)) {
+ return 0;
+ }
+
+ axis_dominant_v3_to_m3(mat_2d, n);
+ }
+
+ /* STEP 1: COUNT POLYS */
+ if (sf_ctx->poly_nr != SF_POLY_UNSET) {
+ poly = (unsigned short)(sf_ctx->poly_nr + 1);
+ sf_ctx->poly_nr = SF_POLY_UNSET;
+ }
+
+ if (flag & BLI_SCANFILL_CALC_POLYS && (poly == 0)) {
+ for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
+ mul_v2_m3v3(eve->xy, mat_2d, eve->co);
+
+ /* get first vertex with no poly number */
+ if (eve->poly_nr == SF_POLY_UNSET) {
+ unsigned int toggle = 0;
+ /* now a sort of select connected */
+ ok = true;
+ eve->poly_nr = poly;
+
+ while (ok) {
+
+ ok = false;
+
+ toggle++;
+ for (eed = (toggle & 1) ? sf_ctx->filledgebase.first : sf_ctx->filledgebase.last; eed;
+ eed = (toggle & 1) ? eed->next : eed->prev) {
+ if (eed->v1->poly_nr == SF_POLY_UNSET && eed->v2->poly_nr == poly) {
+ eed->v1->poly_nr = poly;
+ eed->poly_nr = poly;
+ ok = true;
+ }
+ else if (eed->v2->poly_nr == SF_POLY_UNSET && eed->v1->poly_nr == poly) {
+ eed->v2->poly_nr = poly;
+ eed->poly_nr = poly;
+ ok = true;
+ }
+ else if (eed->poly_nr == SF_POLY_UNSET) {
+ if (eed->v1->poly_nr == poly && eed->v2->poly_nr == poly) {
+ eed->poly_nr = poly;
+ ok = true;
+ }
+ }
+ }
+ }
+
+ poly++;
+ }
+ }
+ /* printf("amount of poly's: %d\n", poly); */
+ }
+ else if (poly) {
+ /* we pre-calculated poly_nr */
+ for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
+ mul_v2_m3v3(eve->xy, mat_2d, eve->co);
+ }
+ }
+ else {
+ poly = 1;
+
+ for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
+ mul_v2_m3v3(eve->xy, mat_2d, eve->co);
+ eve->poly_nr = 0;
+ }
+
+ for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
+ eed->poly_nr = 0;
+ }
+ }
+
+ /* STEP 2: remove loose edges and strings of edges */
+ if (flag & BLI_SCANFILL_CALC_LOOSE) {
+ unsigned int toggle = 0;
+ for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
+ if (eed->v1->edge_tot++ > 250) {
+ break;
+ }
+ if (eed->v2->edge_tot++ > 250) {
+ break;
+ }
+ }
+ if (eed) {
+ /* otherwise it's impossible to be sure you can clear vertices */
#ifdef DEBUG
- printf("No vertices with 250 edges allowed!\n");
+ printf("No vertices with 250 edges allowed!\n");
#endif
- return 0;
- }
-
- /* does it only for vertices with (->edge_tot == 1) */
- testvertexnearedge(sf_ctx);
-
- ok = true;
- while (ok) {
- ok = false;
-
- toggle++;
- for (eed = (toggle & 1) ? sf_ctx->filledgebase.first : sf_ctx->filledgebase.last;
- eed;
- eed = eed_next)
- {
- eed_next = (toggle & 1) ? eed->next : eed->prev;
- if (eed->v1->edge_tot == 1) {
- eed->v2->edge_tot--;
- BLI_remlink(&sf_ctx->fillvertbase, eed->v1);
- BLI_remlink(&sf_ctx->filledgebase, eed);
- ok = true;
- }
- else if (eed->v2->edge_tot == 1) {
- eed->v1->edge_tot--;
- BLI_remlink(&sf_ctx->fillvertbase, eed->v2);
- BLI_remlink(&sf_ctx->filledgebase, eed);
- ok = true;
- }
- }
- }
- if (BLI_listbase_is_empty(&sf_ctx->filledgebase)) {
- /* printf("All edges removed\n"); */
- return 0;
- }
- }
- else {
- /* skip checks for loose edges */
- for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
- eed->v1->edge_tot++;
- eed->v2->edge_tot++;
- }
+ return 0;
+ }
+
+ /* does it only for vertices with (->edge_tot == 1) */
+ testvertexnearedge(sf_ctx);
+
+ ok = true;
+ while (ok) {
+ ok = false;
+
+ toggle++;
+ for (eed = (toggle & 1) ? sf_ctx->filledgebase.first : sf_ctx->filledgebase.last; eed;
+ eed = eed_next) {
+ eed_next = (toggle & 1) ? eed->next : eed->prev;
+ if (eed->v1->edge_tot == 1) {
+ eed->v2->edge_tot--;
+ BLI_remlink(&sf_ctx->fillvertbase, eed->v1);
+ BLI_remlink(&sf_ctx->filledgebase, eed);
+ ok = true;
+ }
+ else if (eed->v2->edge_tot == 1) {
+ eed->v1->edge_tot--;
+ BLI_remlink(&sf_ctx->fillvertbase, eed->v2);
+ BLI_remlink(&sf_ctx->filledgebase, eed);
+ ok = true;
+ }
+ }
+ }
+ if (BLI_listbase_is_empty(&sf_ctx->filledgebase)) {
+ /* printf("All edges removed\n"); */
+ return 0;
+ }
+ }
+ else {
+ /* skip checks for loose edges */
+ for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
+ eed->v1->edge_tot++;
+ eed->v2->edge_tot++;
+ }
#ifdef DEBUG
- /* ensure we're right! */
- for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
- BLI_assert(eed->v1->edge_tot != 1);
- BLI_assert(eed->v2->edge_tot != 1);
- }
+ /* ensure we're right! */
+ for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
+ BLI_assert(eed->v1->edge_tot != 1);
+ BLI_assert(eed->v2->edge_tot != 1);
+ }
#endif
- }
-
-
- /* CURRENT STATUS:
- * - eve->f :1 = available in edges
- * - eve->poly_nr :polynumber
- * - eve->edge_tot :amount of edges connected to vertex
- * - eve->tmp.v :store! original vertex number
- *
- * - eed->f :1 = boundary edge (optionally set by caller)
- * - eed->poly_nr :poly number
- */
-
-
- /* STEP 3: MAKE POLYFILL STRUCT */
- pflist = MEM_mallocN(sizeof(*pflist) * (size_t)poly, "edgefill");
- pf = pflist;
- for (a = 0; a < poly; a++) {
- pf->edges = pf->verts = 0;
- pf->min_xy[0] = pf->min_xy[1] = 1.0e20f;
- pf->max_xy[0] = pf->max_xy[1] = -1.0e20f;
- pf->f = SF_POLY_NEW;
- pf->nr = a;
- pf++;
- }
- for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
- pflist[eed->poly_nr].edges++;
- }
-
- for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
- pflist[eve->poly_nr].verts++;
- min_xy_p = pflist[eve->poly_nr].min_xy;
- max_xy_p = pflist[eve->poly_nr].max_xy;
-
- min_xy_p[0] = (min_xy_p[0]) < (eve->xy[0]) ? (min_xy_p[0]) : (eve->xy[0]);
- min_xy_p[1] = (min_xy_p[1]) < (eve->xy[1]) ? (min_xy_p[1]) : (eve->xy[1]);
- max_xy_p[0] = (max_xy_p[0]) > (eve->xy[0]) ? (max_xy_p[0]) : (eve->xy[0]);
- max_xy_p[1] = (max_xy_p[1]) > (eve->xy[1]) ? (max_xy_p[1]) : (eve->xy[1]);
- if (eve->edge_tot > 2) {
- pflist[eve->poly_nr].f = SF_POLY_VALID;
- }
- }
-
- /* STEP 4: FIND HOLES OR BOUNDS, JOIN THEM
- * ( bounds just to divide it in pieces for optimization,
- * the edgefill itself has good auto-hole detection)
- * WATCH IT: ONLY WORKS WITH SORTED POLYS!!! */
-
- if ((flag & BLI_SCANFILL_CALC_HOLES) && (poly > 1)) {
- unsigned short *polycache, *pc;
-
- /* so, sort first */
- qsort(pflist, (size_t)poly, sizeof(PolyFill), vergpoly);
+ }
+
+ /* CURRENT STATUS:
+ * - eve->f :1 = available in edges
+ * - eve->poly_nr :polynumber
+ * - eve->edge_tot :amount of edges connected to vertex
+ * - eve->tmp.v :store! original vertex number
+ *
+ * - eed->f :1 = boundary edge (optionally set by caller)
+ * - eed->poly_nr :poly number
+ */
+
+ /* STEP 3: MAKE POLYFILL STRUCT */
+ pflist = MEM_mallocN(sizeof(*pflist) * (size_t)poly, "edgefill");
+ pf = pflist;
+ for (a = 0; a < poly; a++) {
+ pf->edges = pf->verts = 0;
+ pf->min_xy[0] = pf->min_xy[1] = 1.0e20f;
+ pf->max_xy[0] = pf->max_xy[1] = -1.0e20f;
+ pf->f = SF_POLY_NEW;
+ pf->nr = a;
+ pf++;
+ }
+ for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
+ pflist[eed->poly_nr].edges++;
+ }
+
+ for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
+ pflist[eve->poly_nr].verts++;
+ min_xy_p = pflist[eve->poly_nr].min_xy;
+ max_xy_p = pflist[eve->poly_nr].max_xy;
+
+ min_xy_p[0] = (min_xy_p[0]) < (eve->xy[0]) ? (min_xy_p[0]) : (eve->xy[0]);
+ min_xy_p[1] = (min_xy_p[1]) < (eve->xy[1]) ? (min_xy_p[1]) : (eve->xy[1]);
+ max_xy_p[0] = (max_xy_p[0]) > (eve->xy[0]) ? (max_xy_p[0]) : (eve->xy[0]);
+ max_xy_p[1] = (max_xy_p[1]) > (eve->xy[1]) ? (max_xy_p[1]) : (eve->xy[1]);
+ if (eve->edge_tot > 2) {
+ pflist[eve->poly_nr].f = SF_POLY_VALID;
+ }
+ }
+
+ /* STEP 4: FIND HOLES OR BOUNDS, JOIN THEM
+ * ( bounds just to divide it in pieces for optimization,
+ * the edgefill itself has good auto-hole detection)
+ * WATCH IT: ONLY WORKS WITH SORTED POLYS!!! */
+
+ if ((flag & BLI_SCANFILL_CALC_HOLES) && (poly > 1)) {
+ unsigned short *polycache, *pc;
+
+ /* so, sort first */
+ qsort(pflist, (size_t)poly, sizeof(PolyFill), vergpoly);
#if 0
- pf = pflist;
- for (a = 0; a < poly; a++) {
- printf("poly:%d edges:%d verts:%d flag: %d\n", a, pf->edges, pf->verts, pf->f);
- PRINT2(f, f, pf->min[0], pf->min[1]);
- pf++;
- }
+ pf = pflist;
+ for (a = 0; a < poly; a++) {
+ printf("poly:%d edges:%d verts:%d flag: %d\n", a, pf->edges, pf->verts, pf->f);
+ PRINT2(f, f, pf->min[0], pf->min[1]);
+ pf++;
+ }
#endif
- polycache = pc = MEM_callocN(sizeof(*polycache) * (size_t)poly, "polycache");
- pf = pflist;
- for (a = 0; a < poly; a++, pf++) {
- for (c = (unsigned short)(a + 1); c < poly; c++) {
-
- /* if 'a' inside 'c': join (bbox too)
- * Careful: 'a' can also be inside another poly.
- */
- if (boundisect(pf, pflist + c)) {
- *pc = c;
- pc++;
- }
- /* only for optimize! */
- /* else if (pf->max_xy[0] < (pflist+c)->min[cox]) break; */
-
- }
- while (pc != polycache) {
- pc--;
- mergepolysSimp(sf_ctx, pf, pflist + *pc);
- }
- }
- MEM_freeN(polycache);
- }
+ polycache = pc = MEM_callocN(sizeof(*polycache) * (size_t)poly, "polycache");
+ pf = pflist;
+ for (a = 0; a < poly; a++, pf++) {
+ for (c = (unsigned short)(a + 1); c < poly; c++) {
+
+ /* if 'a' inside 'c': join (bbox too)
+ * Careful: 'a' can also be inside another poly.
+ */
+ if (boundisect(pf, pflist + c)) {
+ *pc = c;
+ pc++;
+ }
+ /* only for optimize! */
+ /* else if (pf->max_xy[0] < (pflist+c)->min[cox]) break; */
+ }
+ while (pc != polycache) {
+ pc--;
+ mergepolysSimp(sf_ctx, pf, pflist + *pc);
+ }
+ }
+ MEM_freeN(polycache);
+ }
#if 0
- printf("after merge\n");
- pf = pflist;
- for (a = 0; a < poly; a++) {
- printf("poly:%d edges:%d verts:%d flag: %d\n", a, pf->edges, pf->verts, pf->f);
- pf++;
- }
+ printf("after merge\n");
+ pf = pflist;
+ for (a = 0; a < poly; a++) {
+ printf("poly:%d edges:%d verts:%d flag: %d\n", a, pf->edges, pf->verts, pf->f);
+ pf++;
+ }
#endif
- /* STEP 5: MAKE TRIANGLES */
+ /* STEP 5: MAKE TRIANGLES */
- tempve.first = sf_ctx->fillvertbase.first;
- tempve.last = sf_ctx->fillvertbase.last;
- temped.first = sf_ctx->filledgebase.first;
- temped.last = sf_ctx->filledgebase.last;
- BLI_listbase_clear(&sf_ctx->fillvertbase);
- BLI_listbase_clear(&sf_ctx->filledgebase);
+ tempve.first = sf_ctx->fillvertbase.first;
+ tempve.last = sf_ctx->fillvertbase.last;
+ temped.first = sf_ctx->filledgebase.first;
+ temped.last = sf_ctx->filledgebase.last;
+ BLI_listbase_clear(&sf_ctx->fillvertbase);
+ BLI_listbase_clear(&sf_ctx->filledgebase);
- pf = pflist;
- for (a = 0; a < poly; a++) {
- if (pf->edges > 1) {
- splitlist(sf_ctx, &tempve, &temped, pf->nr);
- totfaces += scanfill(sf_ctx, pf, flag);
- }
- pf++;
- }
- BLI_movelisttolist(&sf_ctx->fillvertbase, &tempve);
- BLI_movelisttolist(&sf_ctx->filledgebase, &temped);
+ pf = pflist;
+ for (a = 0; a < poly; a++) {
+ if (pf->edges > 1) {
+ splitlist(sf_ctx, &tempve, &temped, pf->nr);
+ totfaces += scanfill(sf_ctx, pf, flag);
+ }
+ pf++;
+ }
+ BLI_movelisttolist(&sf_ctx->fillvertbase, &tempve);
+ BLI_movelisttolist(&sf_ctx->filledgebase, &temped);
- /* FREE */
+ /* FREE */
- MEM_freeN(pflist);
+ MEM_freeN(pflist);
- return totfaces;
+ return totfaces;
}
unsigned int BLI_scanfill_calc(ScanFillContext *sf_ctx, const int flag)
{
- return BLI_scanfill_calc_ex(sf_ctx, flag, NULL);
+ return BLI_scanfill_calc_ex(sf_ctx, flag, NULL);
}
diff --git a/source/blender/blenlib/intern/scanfill_utils.c b/source/blender/blenlib/intern/scanfill_utils.c
index f0107908787..0c4151e6575 100644
--- a/source/blender/blenlib/intern/scanfill_utils.c
+++ b/source/blender/blenlib/intern/scanfill_utils.c
@@ -31,348 +31,345 @@
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
-#include "BLI_scanfill.h" /* own include */
+#include "BLI_scanfill.h" /* own include */
#include "BLI_strict_flags.h"
typedef struct PolyInfo {
- ScanFillEdge *edge_first, *edge_last;
- ScanFillVert *vert_outer;
+ ScanFillEdge *edge_first, *edge_last;
+ ScanFillVert *vert_outer;
} PolyInfo;
typedef struct ScanFillIsect {
- struct ScanFillIsect *next, *prev;
- float co[3];
+ struct ScanFillIsect *next, *prev;
+ float co[3];
- /* newly created vertex */
- ScanFillVert *v;
+ /* newly created vertex */
+ ScanFillVert *v;
} ScanFillIsect;
-
#define V_ISISECT 1
#define E_ISISECT 1
#define E_ISDELETE 2
-
-#define EFLAG_SET(eed, val) { CHECK_TYPE(eed, ScanFillEdge *); \
- (eed)->user_flag = (eed)->user_flag | (unsigned int)val; } (void)0
+#define EFLAG_SET(eed, val) \
+ { \
+ CHECK_TYPE(eed, ScanFillEdge *); \
+ (eed)->user_flag = (eed)->user_flag | (unsigned int)val; \
+ } \
+ (void)0
#if 0
-#define EFLAG_CLEAR(eed, val) { CHECK_TYPE(eed, ScanFillEdge *); \
- (eed)->user_flag = (eed)->user_flag & ~(unsigned int)val; } (void)0
+# define EFLAG_CLEAR(eed, val) \
+ { \
+ CHECK_TYPE(eed, ScanFillEdge *); \
+ (eed)->user_flag = (eed)->user_flag & ~(unsigned int)val; \
+ } \
+ (void)0
#endif
-#define VFLAG_SET(eve, val) { CHECK_TYPE(eve, ScanFillVert *); \
- (eve)->user_flag = (eve)->user_flag | (unsigned int)val; } (void)0
+#define VFLAG_SET(eve, val) \
+ { \
+ CHECK_TYPE(eve, ScanFillVert *); \
+ (eve)->user_flag = (eve)->user_flag | (unsigned int)val; \
+ } \
+ (void)0
#if 0
-#define VFLAG_CLEAR(eve, val) { CHECK_TYPE(eve, ScanFillVert *); \
- (eve)->user_flags = (eve)->user_flag & ~(unsigned int)val; } (void)0
+# define VFLAG_CLEAR(eve, val) \
+ { \
+ CHECK_TYPE(eve, ScanFillVert *); \
+ (eve)->user_flags = (eve)->user_flag & ~(unsigned int)val; \
+ } \
+ (void)0
#endif
-
#if 0
void BLI_scanfill_obj_dump(ScanFillContext *sf_ctx)
{
- FILE *f = fopen("test.obj", "w");
- unsigned int i = 1;
-
- ScanFillVert *eve;
- ScanFillEdge *eed;
-
- for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next, i++) {
- fprintf(f, "v %f %f %f\n", UNPACK3(eve->co));
- eve->keyindex = i;
- }
- for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
- fprintf(f, "f %d %d\n", eed->v1->keyindex, eed->v2->keyindex);
- }
- fclose(f);
+ FILE *f = fopen("test.obj", "w");
+ unsigned int i = 1;
+
+ ScanFillVert *eve;
+ ScanFillEdge *eed;
+
+ for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next, i++) {
+ fprintf(f, "v %f %f %f\n", UNPACK3(eve->co));
+ eve->keyindex = i;
+ }
+ for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
+ fprintf(f, "f %d %d\n", eed->v1->keyindex, eed->v2->keyindex);
+ }
+ fclose(f);
}
#endif
static ListBase *edge_isect_ls_ensure(GHash *isect_hash, ScanFillEdge *eed)
{
- ListBase *e_ls;
- void **val_p;
+ ListBase *e_ls;
+ void **val_p;
- if (!BLI_ghash_ensure_p(isect_hash, eed, &val_p)) {
- *val_p = MEM_callocN(sizeof(ListBase), __func__);
- }
- e_ls = *val_p;
+ if (!BLI_ghash_ensure_p(isect_hash, eed, &val_p)) {
+ *val_p = MEM_callocN(sizeof(ListBase), __func__);
+ }
+ e_ls = *val_p;
- return e_ls;
+ return e_ls;
}
static ListBase *edge_isect_ls_add(GHash *isect_hash, ScanFillEdge *eed, ScanFillIsect *isect)
{
- ListBase *e_ls;
- LinkData *isect_link;
- e_ls = edge_isect_ls_ensure(isect_hash, eed);
- isect_link = MEM_callocN(sizeof(*isect_link), __func__);
- isect_link->data = isect;
- EFLAG_SET(eed, E_ISISECT);
- BLI_addtail(e_ls, isect_link);
- return e_ls;
+ ListBase *e_ls;
+ LinkData *isect_link;
+ e_ls = edge_isect_ls_ensure(isect_hash, eed);
+ isect_link = MEM_callocN(sizeof(*isect_link), __func__);
+ isect_link->data = isect;
+ EFLAG_SET(eed, E_ISISECT);
+ BLI_addtail(e_ls, isect_link);
+ return e_ls;
}
static int edge_isect_ls_sort_cb(void *thunk, const void *def_a_ptr, const void *def_b_ptr)
{
- const float *co = thunk;
-
- const ScanFillIsect *i_a = ((const LinkData *)def_a_ptr)->data;
- const ScanFillIsect *i_b = ((const LinkData *)def_b_ptr)->data;
- const float a = len_squared_v2v2(co, i_a->co);
- const float b = len_squared_v2v2(co, i_b->co);
-
- if (a > b) {
- return -1;
- }
- else {
- return (a < b);
- }
+ const float *co = thunk;
+
+ const ScanFillIsect *i_a = ((const LinkData *)def_a_ptr)->data;
+ const ScanFillIsect *i_b = ((const LinkData *)def_b_ptr)->data;
+ const float a = len_squared_v2v2(co, i_a->co);
+ const float b = len_squared_v2v2(co, i_b->co);
+
+ if (a > b) {
+ return -1;
+ }
+ else {
+ return (a < b);
+ }
}
static ScanFillEdge *edge_step(PolyInfo *poly_info,
const unsigned short poly_nr,
- ScanFillVert *v_prev, ScanFillVert *v_curr,
+ ScanFillVert *v_prev,
+ ScanFillVert *v_curr,
ScanFillEdge *e_curr)
{
- ScanFillEdge *eed;
-
- BLI_assert(ELEM(v_prev, e_curr->v1, e_curr->v2));
- BLI_assert(ELEM(v_curr, e_curr->v1, e_curr->v2));
-
- eed = (e_curr->next && e_curr != poly_info[poly_nr].edge_last) ? e_curr->next : poly_info[poly_nr].edge_first;
- if ((v_curr == eed->v1 || v_curr == eed->v2) == true &&
- (v_prev == eed->v1 || v_prev == eed->v2) == false)
- {
- return eed;
- }
-
- eed = (e_curr->prev && e_curr != poly_info[poly_nr].edge_first) ? e_curr->prev : poly_info[poly_nr].edge_last;
- if ((v_curr == eed->v1 || v_curr == eed->v2) == true &&
- (v_prev == eed->v1 || v_prev == eed->v2) == false)
- {
- return eed;
- }
-
- BLI_assert(0);
- return NULL;
+ ScanFillEdge *eed;
+
+ BLI_assert(ELEM(v_prev, e_curr->v1, e_curr->v2));
+ BLI_assert(ELEM(v_curr, e_curr->v1, e_curr->v2));
+
+ eed = (e_curr->next && e_curr != poly_info[poly_nr].edge_last) ? e_curr->next :
+ poly_info[poly_nr].edge_first;
+ if ((v_curr == eed->v1 || v_curr == eed->v2) == true &&
+ (v_prev == eed->v1 || v_prev == eed->v2) == false) {
+ return eed;
+ }
+
+ eed = (e_curr->prev && e_curr != poly_info[poly_nr].edge_first) ? e_curr->prev :
+ poly_info[poly_nr].edge_last;
+ if ((v_curr == eed->v1 || v_curr == eed->v2) == true &&
+ (v_prev == eed->v1 || v_prev == eed->v2) == false) {
+ return eed;
+ }
+
+ BLI_assert(0);
+ return NULL;
}
-static bool scanfill_preprocess_self_isect(
- ScanFillContext *sf_ctx,
- PolyInfo *poly_info,
- const unsigned short poly_nr,
- ListBase *filledgebase)
+static bool scanfill_preprocess_self_isect(ScanFillContext *sf_ctx,
+ PolyInfo *poly_info,
+ const unsigned short poly_nr,
+ ListBase *filledgebase)
{
- PolyInfo *pi = &poly_info[poly_nr];
- GHash *isect_hash = NULL;
- ListBase isect_lb = {NULL};
-
- /* warning, O(n2) check here, should use spatial lookup */
- {
- ScanFillEdge *eed;
-
- for (eed = pi->edge_first;
- eed;
- eed = (eed == pi->edge_last) ? NULL : eed->next)
- {
- ScanFillEdge *eed_other;
-
- for (eed_other = eed->next;
- eed_other;
- eed_other = (eed_other == pi->edge_last) ? NULL : eed_other->next)
- {
- if (!ELEM(eed->v1, eed_other->v1, eed_other->v2) &&
- !ELEM(eed->v2, eed_other->v1, eed_other->v2) &&
- (eed != eed_other))
- {
- /* check isect */
- float pt[2];
- BLI_assert(eed != eed_other);
-
- if (isect_seg_seg_v2_point(eed->v1->co, eed->v2->co,
- eed_other->v1->co, eed_other->v2->co,
- pt) == 1)
- {
- ScanFillIsect *isect;
-
- if (UNLIKELY(isect_hash == NULL)) {
- isect_hash = BLI_ghash_ptr_new(__func__);
- }
-
- isect = MEM_mallocN(sizeof(ScanFillIsect), __func__);
-
- BLI_addtail(&isect_lb, isect);
-
- copy_v2_v2(isect->co, pt);
- isect->co[2] = eed->v1->co[2];
- isect->v = BLI_scanfill_vert_add(sf_ctx, isect->co);
-
- /* NOTE: vert may belong to 2 polys now */
- isect->v->poly_nr = eed->v1->poly_nr;
-
- VFLAG_SET(isect->v, V_ISISECT);
- edge_isect_ls_add(isect_hash, eed, isect);
- edge_isect_ls_add(isect_hash, eed_other, isect);
- }
- }
- }
- }
- }
-
- if (isect_hash == NULL) {
- return false;
- }
-
- /* now subdiv the edges */
- {
- ScanFillEdge *eed;
-
- for (eed = pi->edge_first;
- eed;
- eed = (eed == pi->edge_last) ? NULL : eed->next)
- {
- if (eed->user_flag & E_ISISECT) {
- ListBase *e_ls = BLI_ghash_lookup(isect_hash, eed);
-
- LinkData *isect_link;
-
- if (UNLIKELY(e_ls == NULL)) {
- /* only happens in very rare cases (entirely overlapping splines).
- * in this case we can't do much useful. but at least don't crash */
- continue;
- }
-
- /* maintain coorect terminating edge */
- if (pi->edge_last == eed) {
- pi->edge_last = NULL;
- }
-
- if (BLI_listbase_is_single(e_ls) == false) {
- BLI_listbase_sort_r(e_ls, edge_isect_ls_sort_cb, eed->v2->co);
- }
-
- /* move original edge to filledgebase and add replacement
- * (which gets subdivided next) */
- {
- ScanFillEdge *eed_tmp;
- eed_tmp = BLI_scanfill_edge_add(sf_ctx, eed->v1, eed->v2);
- BLI_remlink(&sf_ctx->filledgebase, eed_tmp);
- BLI_insertlinkafter(&sf_ctx->filledgebase, eed, eed_tmp);
- BLI_remlink(&sf_ctx->filledgebase, eed);
- BLI_addtail(filledgebase, eed);
- if (pi->edge_first == eed) {
- pi->edge_first = eed_tmp;
- }
- eed = eed_tmp;
- }
-
- for (isect_link = e_ls->first; isect_link; isect_link = isect_link->next) {
- ScanFillIsect *isect = isect_link->data;
- ScanFillEdge *eed_subd;
-
- eed_subd = BLI_scanfill_edge_add(sf_ctx, isect->v, eed->v2);
- eed_subd->poly_nr = poly_nr;
- eed->v2 = isect->v;
-
- BLI_remlink(&sf_ctx->filledgebase, eed_subd);
- BLI_insertlinkafter(&sf_ctx->filledgebase, eed, eed_subd);
-
- /* step to the next edge and continue dividing */
- eed = eed_subd;
- }
-
- BLI_freelistN(e_ls);
- MEM_freeN(e_ls);
-
- if (pi->edge_last == NULL) {
- pi->edge_last = eed;
- }
- }
- }
- }
-
- BLI_freelistN(&isect_lb);
- BLI_ghash_free(isect_hash, NULL, NULL);
-
- {
- ScanFillEdge *e_init;
- ScanFillEdge *e_curr;
- ScanFillEdge *e_next;
-
- ScanFillVert *v_prev;
- ScanFillVert *v_curr;
-
- bool inside = false;
-
- /* first vert */
+ PolyInfo *pi = &poly_info[poly_nr];
+ GHash *isect_hash = NULL;
+ ListBase isect_lb = {NULL};
+
+ /* warning, O(n2) check here, should use spatial lookup */
+ {
+ ScanFillEdge *eed;
+
+ for (eed = pi->edge_first; eed; eed = (eed == pi->edge_last) ? NULL : eed->next) {
+ ScanFillEdge *eed_other;
+
+ for (eed_other = eed->next; eed_other;
+ eed_other = (eed_other == pi->edge_last) ? NULL : eed_other->next) {
+ if (!ELEM(eed->v1, eed_other->v1, eed_other->v2) &&
+ !ELEM(eed->v2, eed_other->v1, eed_other->v2) && (eed != eed_other)) {
+ /* check isect */
+ float pt[2];
+ BLI_assert(eed != eed_other);
+
+ if (isect_seg_seg_v2_point(
+ eed->v1->co, eed->v2->co, eed_other->v1->co, eed_other->v2->co, pt) == 1) {
+ ScanFillIsect *isect;
+
+ if (UNLIKELY(isect_hash == NULL)) {
+ isect_hash = BLI_ghash_ptr_new(__func__);
+ }
+
+ isect = MEM_mallocN(sizeof(ScanFillIsect), __func__);
+
+ BLI_addtail(&isect_lb, isect);
+
+ copy_v2_v2(isect->co, pt);
+ isect->co[2] = eed->v1->co[2];
+ isect->v = BLI_scanfill_vert_add(sf_ctx, isect->co);
+
+ /* NOTE: vert may belong to 2 polys now */
+ isect->v->poly_nr = eed->v1->poly_nr;
+
+ VFLAG_SET(isect->v, V_ISISECT);
+ edge_isect_ls_add(isect_hash, eed, isect);
+ edge_isect_ls_add(isect_hash, eed_other, isect);
+ }
+ }
+ }
+ }
+ }
+
+ if (isect_hash == NULL) {
+ return false;
+ }
+
+ /* now subdiv the edges */
+ {
+ ScanFillEdge *eed;
+
+ for (eed = pi->edge_first; eed; eed = (eed == pi->edge_last) ? NULL : eed->next) {
+ if (eed->user_flag & E_ISISECT) {
+ ListBase *e_ls = BLI_ghash_lookup(isect_hash, eed);
+
+ LinkData *isect_link;
+
+ if (UNLIKELY(e_ls == NULL)) {
+ /* only happens in very rare cases (entirely overlapping splines).
+ * in this case we can't do much useful. but at least don't crash */
+ continue;
+ }
+
+ /* maintain coorect terminating edge */
+ if (pi->edge_last == eed) {
+ pi->edge_last = NULL;
+ }
+
+ if (BLI_listbase_is_single(e_ls) == false) {
+ BLI_listbase_sort_r(e_ls, edge_isect_ls_sort_cb, eed->v2->co);
+ }
+
+ /* move original edge to filledgebase and add replacement
+ * (which gets subdivided next) */
+ {
+ ScanFillEdge *eed_tmp;
+ eed_tmp = BLI_scanfill_edge_add(sf_ctx, eed->v1, eed->v2);
+ BLI_remlink(&sf_ctx->filledgebase, eed_tmp);
+ BLI_insertlinkafter(&sf_ctx->filledgebase, eed, eed_tmp);
+ BLI_remlink(&sf_ctx->filledgebase, eed);
+ BLI_addtail(filledgebase, eed);
+ if (pi->edge_first == eed) {
+ pi->edge_first = eed_tmp;
+ }
+ eed = eed_tmp;
+ }
+
+ for (isect_link = e_ls->first; isect_link; isect_link = isect_link->next) {
+ ScanFillIsect *isect = isect_link->data;
+ ScanFillEdge *eed_subd;
+
+ eed_subd = BLI_scanfill_edge_add(sf_ctx, isect->v, eed->v2);
+ eed_subd->poly_nr = poly_nr;
+ eed->v2 = isect->v;
+
+ BLI_remlink(&sf_ctx->filledgebase, eed_subd);
+ BLI_insertlinkafter(&sf_ctx->filledgebase, eed, eed_subd);
+
+ /* step to the next edge and continue dividing */
+ eed = eed_subd;
+ }
+
+ BLI_freelistN(e_ls);
+ MEM_freeN(e_ls);
+
+ if (pi->edge_last == NULL) {
+ pi->edge_last = eed;
+ }
+ }
+ }
+ }
+
+ BLI_freelistN(&isect_lb);
+ BLI_ghash_free(isect_hash, NULL, NULL);
+
+ {
+ ScanFillEdge *e_init;
+ ScanFillEdge *e_curr;
+ ScanFillEdge *e_next;
+
+ ScanFillVert *v_prev;
+ ScanFillVert *v_curr;
+
+ bool inside = false;
+
+ /* first vert */
#if 0
- e_init = pi->edge_last;
- e_curr = e_init;
- e_next = pi->edge_first;
+ e_init = pi->edge_last;
+ e_curr = e_init;
+ e_next = pi->edge_first;
- v_prev = e_curr->v1;
- v_curr = e_curr->v2;
+ v_prev = e_curr->v1;
+ v_curr = e_curr->v2;
#else
- /* find outside vertex */
- {
- ScanFillEdge *eed;
- ScanFillEdge *eed_prev;
- float min_x = FLT_MAX;
-
- e_curr = pi->edge_last;
- e_next = pi->edge_first;
-
- eed_prev = pi->edge_last;
- for (eed = pi->edge_first;
- eed;
- eed = (eed == pi->edge_last) ? NULL : eed->next)
- {
- if (eed->v2->co[0] < min_x) {
- min_x = eed->v2->co[0];
- e_curr = eed_prev;
- e_next = eed;
-
- }
- eed_prev = eed;
- }
-
- e_init = e_curr;
- v_prev = e_curr->v1;
- v_curr = e_curr->v2;
- }
+ /* find outside vertex */
+ {
+ ScanFillEdge *eed;
+ ScanFillEdge *eed_prev;
+ float min_x = FLT_MAX;
+
+ e_curr = pi->edge_last;
+ e_next = pi->edge_first;
+
+ eed_prev = pi->edge_last;
+ for (eed = pi->edge_first; eed; eed = (eed == pi->edge_last) ? NULL : eed->next) {
+ if (eed->v2->co[0] < min_x) {
+ min_x = eed->v2->co[0];
+ e_curr = eed_prev;
+ e_next = eed;
+ }
+ eed_prev = eed;
+ }
+
+ e_init = e_curr;
+ v_prev = e_curr->v1;
+ v_curr = e_curr->v2;
+ }
#endif
- BLI_assert(e_curr->poly_nr == poly_nr);
- BLI_assert(pi->edge_last->poly_nr == poly_nr);
+ BLI_assert(e_curr->poly_nr == poly_nr);
+ BLI_assert(pi->edge_last->poly_nr == poly_nr);
- do {
- ScanFillVert *v_next;
+ do {
+ ScanFillVert *v_next;
- v_next = (e_next->v1 == v_curr) ? e_next->v2 : e_next->v1;
- BLI_assert(ELEM(v_curr, e_next->v1, e_next->v2));
+ v_next = (e_next->v1 == v_curr) ? e_next->v2 : e_next->v1;
+ BLI_assert(ELEM(v_curr, e_next->v1, e_next->v2));
- /* track intersections */
- if (inside) {
- EFLAG_SET(e_next, E_ISDELETE);
- }
- if (v_next->user_flag & V_ISISECT) {
- inside = !inside;
- }
- /* now step... */
+ /* track intersections */
+ if (inside) {
+ EFLAG_SET(e_next, E_ISDELETE);
+ }
+ if (v_next->user_flag & V_ISISECT) {
+ inside = !inside;
+ }
+ /* now step... */
- v_prev = v_curr;
- v_curr = v_next;
- e_curr = e_next;
+ v_prev = v_curr;
+ v_curr = v_next;
+ e_curr = e_next;
- e_next = edge_step(poly_info, poly_nr, v_prev, v_curr, e_curr);
+ e_next = edge_step(poly_info, poly_nr, v_prev, v_curr, e_curr);
- } while (e_curr != e_init);
- }
+ } while (e_curr != e_init);
+ }
- return true;
+ return true;
}
/**
@@ -380,122 +377,120 @@ static bool scanfill_preprocess_self_isect(
*
* \return false if no changes were made.
*/
-bool BLI_scanfill_calc_self_isect(
- ScanFillContext *sf_ctx,
- ListBase *remvertbase,
- ListBase *remedgebase)
+bool BLI_scanfill_calc_self_isect(ScanFillContext *sf_ctx,
+ ListBase *remvertbase,
+ ListBase *remedgebase)
{
- const unsigned int poly_tot = (unsigned int)sf_ctx->poly_nr + 1;
- unsigned int eed_index = 0;
- int totvert_new = 0;
- bool changed = false;
-
- PolyInfo *poly_info;
-
- if (UNLIKELY(sf_ctx->poly_nr == SF_POLY_UNSET)) {
- return false;
- }
-
- poly_info = MEM_callocN(sizeof(*poly_info) * poly_tot, __func__);
-
- /* get the polygon span */
- if (sf_ctx->poly_nr == 0) {
- poly_info->edge_first = sf_ctx->filledgebase.first;
- poly_info->edge_last = sf_ctx->filledgebase.last;
- }
- else {
- unsigned short poly_nr;
- ScanFillEdge *eed;
-
- poly_nr = 0;
-
- for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next, eed_index++) {
-
- BLI_assert(eed->poly_nr == eed->v1->poly_nr);
- BLI_assert(eed->poly_nr == eed->v2->poly_nr);
-
- if ((poly_info[poly_nr].edge_last != NULL) &&
- (poly_info[poly_nr].edge_last->poly_nr != eed->poly_nr))
- {
- poly_nr++;
- }
-
- if (poly_info[poly_nr].edge_first == NULL) {
- poly_info[poly_nr].edge_first = eed;
- poly_info[poly_nr].edge_last = eed;
- }
- else if (poly_info[poly_nr].edge_last->poly_nr == eed->poly_nr) {
- poly_info[poly_nr].edge_last = eed;
- }
-
- BLI_assert(poly_info[poly_nr].edge_first->poly_nr == poly_info[poly_nr].edge_last->poly_nr);
- }
- }
-
- /* self-intersect each polygon */
- {
- unsigned short poly_nr;
- for (poly_nr = 0; poly_nr < poly_tot; poly_nr++) {
- changed |= scanfill_preprocess_self_isect(sf_ctx, poly_info, poly_nr, remedgebase);
- }
- }
-
- MEM_freeN(poly_info);
-
- if (changed == false) {
- return false;
- }
-
- /* move free edges into own list */
- {
- ScanFillEdge *eed;
- ScanFillEdge *eed_next;
- for (eed = sf_ctx->filledgebase.first; eed; eed = eed_next) {
- eed_next = eed->next;
- if (eed->user_flag & E_ISDELETE) {
- BLI_remlink(&sf_ctx->filledgebase, eed);
- BLI_addtail(remedgebase, eed);
- }
- }
- }
-
- /* move free vertices into own list */
- {
- ScanFillEdge *eed;
- ScanFillVert *eve;
- ScanFillVert *eve_next;
-
- for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
- eve->user_flag = 0;
- eve->poly_nr = SF_POLY_UNSET;
- }
- for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
- eed->v1->user_flag = 1;
- eed->v2->user_flag = 1;
- eed->poly_nr = SF_POLY_UNSET;
- }
-
- for (eve = sf_ctx->fillvertbase.first; eve; eve = eve_next) {
- eve_next = eve->next;
- if (eve->user_flag != 1) {
- BLI_remlink(&sf_ctx->fillvertbase, eve);
- BLI_addtail(remvertbase, eve);
- totvert_new--;
- }
- else {
- eve->user_flag = 0;
- }
- }
- }
-
- /* polygon id's are no longer meaningful,
- * when removing self intersections we may have created new isolated polys */
- sf_ctx->poly_nr = SF_POLY_UNSET;
+ const unsigned int poly_tot = (unsigned int)sf_ctx->poly_nr + 1;
+ unsigned int eed_index = 0;
+ int totvert_new = 0;
+ bool changed = false;
+
+ PolyInfo *poly_info;
+
+ if (UNLIKELY(sf_ctx->poly_nr == SF_POLY_UNSET)) {
+ return false;
+ }
+
+ poly_info = MEM_callocN(sizeof(*poly_info) * poly_tot, __func__);
+
+ /* get the polygon span */
+ if (sf_ctx->poly_nr == 0) {
+ poly_info->edge_first = sf_ctx->filledgebase.first;
+ poly_info->edge_last = sf_ctx->filledgebase.last;
+ }
+ else {
+ unsigned short poly_nr;
+ ScanFillEdge *eed;
+
+ poly_nr = 0;
+
+ for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next, eed_index++) {
+
+ BLI_assert(eed->poly_nr == eed->v1->poly_nr);
+ BLI_assert(eed->poly_nr == eed->v2->poly_nr);
+
+ if ((poly_info[poly_nr].edge_last != NULL) &&
+ (poly_info[poly_nr].edge_last->poly_nr != eed->poly_nr)) {
+ poly_nr++;
+ }
+
+ if (poly_info[poly_nr].edge_first == NULL) {
+ poly_info[poly_nr].edge_first = eed;
+ poly_info[poly_nr].edge_last = eed;
+ }
+ else if (poly_info[poly_nr].edge_last->poly_nr == eed->poly_nr) {
+ poly_info[poly_nr].edge_last = eed;
+ }
+
+ BLI_assert(poly_info[poly_nr].edge_first->poly_nr == poly_info[poly_nr].edge_last->poly_nr);
+ }
+ }
+
+ /* self-intersect each polygon */
+ {
+ unsigned short poly_nr;
+ for (poly_nr = 0; poly_nr < poly_tot; poly_nr++) {
+ changed |= scanfill_preprocess_self_isect(sf_ctx, poly_info, poly_nr, remedgebase);
+ }
+ }
+
+ MEM_freeN(poly_info);
+
+ if (changed == false) {
+ return false;
+ }
+
+ /* move free edges into own list */
+ {
+ ScanFillEdge *eed;
+ ScanFillEdge *eed_next;
+ for (eed = sf_ctx->filledgebase.first; eed; eed = eed_next) {
+ eed_next = eed->next;
+ if (eed->user_flag & E_ISDELETE) {
+ BLI_remlink(&sf_ctx->filledgebase, eed);
+ BLI_addtail(remedgebase, eed);
+ }
+ }
+ }
+
+ /* move free vertices into own list */
+ {
+ ScanFillEdge *eed;
+ ScanFillVert *eve;
+ ScanFillVert *eve_next;
+
+ for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
+ eve->user_flag = 0;
+ eve->poly_nr = SF_POLY_UNSET;
+ }
+ for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
+ eed->v1->user_flag = 1;
+ eed->v2->user_flag = 1;
+ eed->poly_nr = SF_POLY_UNSET;
+ }
+
+ for (eve = sf_ctx->fillvertbase.first; eve; eve = eve_next) {
+ eve_next = eve->next;
+ if (eve->user_flag != 1) {
+ BLI_remlink(&sf_ctx->fillvertbase, eve);
+ BLI_addtail(remvertbase, eve);
+ totvert_new--;
+ }
+ else {
+ eve->user_flag = 0;
+ }
+ }
+ }
+
+ /* polygon id's are no longer meaningful,
+ * when removing self intersections we may have created new isolated polys */
+ sf_ctx->poly_nr = SF_POLY_UNSET;
#if 0
- BLI_scanfill_view3d_dump(sf_ctx);
- BLI_scanfill_obj_dump(sf_ctx);
+ BLI_scanfill_view3d_dump(sf_ctx);
+ BLI_scanfill_obj_dump(sf_ctx);
#endif
- return changed;
+ return changed;
}
diff --git a/source/blender/blenlib/intern/smallhash.c b/source/blender/blenlib/intern/smallhash.c
index 7da5ff114be..4060ad15fe3 100644
--- a/source/blender/blenlib/intern/smallhash.c
+++ b/source/blender/blenlib/intern/smallhash.c
@@ -55,17 +55,15 @@
#include "BLI_strict_flags.h"
-#define SMHASH_KEY_UNUSED ((uintptr_t)(UINTPTR_MAX - 0))
-#define SMHASH_CELL_FREE ((void *) (UINTPTR_MAX - 1))
-#define SMHASH_CELL_UNUSED ((void *) (UINTPTR_MAX - 2))
+#define SMHASH_KEY_UNUSED ((uintptr_t)(UINTPTR_MAX - 0))
+#define SMHASH_CELL_FREE ((void *)(UINTPTR_MAX - 1))
+#define SMHASH_CELL_UNUSED ((void *)(UINTPTR_MAX - 2))
/* typically this re-assigns 'h' */
-#define SMHASH_NEXT(h, hoff) ( \
- CHECK_TYPE_INLINE(&(h), uint *), \
- CHECK_TYPE_INLINE(&(hoff), uint *), \
- ((h) + (((hoff) = ((hoff) * 2) + 1), (hoff))) \
- )
-
+#define SMHASH_NEXT(h, hoff) \
+ (CHECK_TYPE_INLINE(&(h), uint *), \
+ CHECK_TYPE_INLINE(&(hoff), uint *), \
+ ((h) + (((hoff) = ((hoff)*2) + 1), (hoff))))
/* nothing uses BLI_smallhash_remove yet */
// #define USE_REMOVE
@@ -73,9 +71,9 @@
BLI_INLINE bool smallhash_val_is_used(const void *val)
{
#ifdef USE_REMOVE
- return !ELEM(val, SMHASH_CELL_FREE, SMHASH_CELL_UNUSED);
+ return !ELEM(val, SMHASH_CELL_FREE, SMHASH_CELL_UNUSED);
#else
- return (val != SMHASH_CELL_FREE);
+ return (val != SMHASH_CELL_FREE);
#endif
}
@@ -84,7 +82,7 @@ extern const uint BLI_ghash_hash_sizes[];
BLI_INLINE uint smallhash_key(const uintptr_t key)
{
- return (uint)key;
+ return (uint)key;
}
/**
@@ -92,18 +90,18 @@ BLI_INLINE uint smallhash_key(const uintptr_t key)
*/
BLI_INLINE bool smallhash_test_expand_buckets(const uint nentries, const uint nbuckets)
{
- /* (approx * 1.5) */
- return (nentries + (nentries >> 1)) > nbuckets;
+ /* (approx * 1.5) */
+ return (nentries + (nentries >> 1)) > nbuckets;
}
BLI_INLINE void smallhash_init_empty(SmallHash *sh)
{
- uint i;
+ uint i;
- for (i = 0; i < sh->nbuckets; i++) {
- sh->buckets[i].key = SMHASH_KEY_UNUSED;
- sh->buckets[i].val = SMHASH_CELL_FREE;
- }
+ for (i = 0; i < sh->nbuckets; i++) {
+ sh->buckets[i].key = SMHASH_KEY_UNUSED;
+ sh->buckets[i].val = SMHASH_CELL_FREE;
+ }
}
/**
@@ -111,137 +109,132 @@ BLI_INLINE void smallhash_init_empty(SmallHash *sh)
*/
BLI_INLINE void smallhash_buckets_reserve(SmallHash *sh, const uint nentries_reserve)
{
- while (smallhash_test_expand_buckets(nentries_reserve, sh->nbuckets)) {
- sh->nbuckets = hashsizes[++sh->cursize];
- }
+ while (smallhash_test_expand_buckets(nentries_reserve, sh->nbuckets)) {
+ sh->nbuckets = hashsizes[++sh->cursize];
+ }
}
BLI_INLINE SmallHashEntry *smallhash_lookup(const SmallHash *sh, const uintptr_t key)
{
- SmallHashEntry *e;
- uint h = smallhash_key(key);
- uint hoff = 1;
-
- BLI_assert(key != SMHASH_KEY_UNUSED);
-
- /* note: there are always more buckets than entries,
- * so we know there will always be a free bucket if the key isn't found. */
- for (e = &sh->buckets[h % sh->nbuckets];
- e->val != SMHASH_CELL_FREE;
- h = SMHASH_NEXT(h, hoff), e = &sh->buckets[h % sh->nbuckets])
- {
- if (e->key == key) {
- /* should never happen because unused keys are zero'd */
- BLI_assert(e->val != SMHASH_CELL_UNUSED);
- return e;
- }
- }
-
- return NULL;
+ SmallHashEntry *e;
+ uint h = smallhash_key(key);
+ uint hoff = 1;
+
+ BLI_assert(key != SMHASH_KEY_UNUSED);
+
+ /* note: there are always more buckets than entries,
+ * so we know there will always be a free bucket if the key isn't found. */
+ for (e = &sh->buckets[h % sh->nbuckets]; e->val != SMHASH_CELL_FREE;
+ h = SMHASH_NEXT(h, hoff), e = &sh->buckets[h % sh->nbuckets]) {
+ if (e->key == key) {
+ /* should never happen because unused keys are zero'd */
+ BLI_assert(e->val != SMHASH_CELL_UNUSED);
+ return e;
+ }
+ }
+
+ return NULL;
}
BLI_INLINE SmallHashEntry *smallhash_lookup_first_free(SmallHash *sh, const uintptr_t key)
{
- SmallHashEntry *e;
- uint h = smallhash_key(key);
- uint hoff = 1;
-
- for (e = &sh->buckets[h % sh->nbuckets];
- smallhash_val_is_used(e->val);
- h = SMHASH_NEXT(h, hoff), e = &sh->buckets[h % sh->nbuckets])
- {
- /* pass */
- }
-
- return e;
+ SmallHashEntry *e;
+ uint h = smallhash_key(key);
+ uint hoff = 1;
+
+ for (e = &sh->buckets[h % sh->nbuckets]; smallhash_val_is_used(e->val);
+ h = SMHASH_NEXT(h, hoff), e = &sh->buckets[h % sh->nbuckets]) {
+ /* pass */
+ }
+
+ return e;
}
BLI_INLINE void smallhash_resize_buckets(SmallHash *sh, const uint nbuckets)
{
- SmallHashEntry *buckets_old = sh->buckets;
- const uint nbuckets_old = sh->nbuckets;
- const bool was_alloc = (buckets_old != sh->buckets_stack);
- uint i = 0;
-
- BLI_assert(sh->nbuckets != nbuckets);
- if (nbuckets <= SMSTACKSIZE) {
- const size_t size = sizeof(*buckets_old) * nbuckets_old;
- buckets_old = alloca(size);
- memcpy(buckets_old, sh->buckets, size);
-
- sh->buckets = sh->buckets_stack;
- }
- else {
- sh->buckets = MEM_mallocN(sizeof(*sh->buckets) * nbuckets, __func__);
- }
-
- sh->nbuckets = nbuckets;
-
- smallhash_init_empty(sh);
-
- for (i = 0; i < nbuckets_old; i++) {
- if (smallhash_val_is_used(buckets_old[i].val)) {
- SmallHashEntry *e = smallhash_lookup_first_free(sh, buckets_old[i].key);
- e->key = buckets_old[i].key;
- e->val = buckets_old[i].val;
- }
- }
-
- if (was_alloc) {
- MEM_freeN(buckets_old);
- }
+ SmallHashEntry *buckets_old = sh->buckets;
+ const uint nbuckets_old = sh->nbuckets;
+ const bool was_alloc = (buckets_old != sh->buckets_stack);
+ uint i = 0;
+
+ BLI_assert(sh->nbuckets != nbuckets);
+ if (nbuckets <= SMSTACKSIZE) {
+ const size_t size = sizeof(*buckets_old) * nbuckets_old;
+ buckets_old = alloca(size);
+ memcpy(buckets_old, sh->buckets, size);
+
+ sh->buckets = sh->buckets_stack;
+ }
+ else {
+ sh->buckets = MEM_mallocN(sizeof(*sh->buckets) * nbuckets, __func__);
+ }
+
+ sh->nbuckets = nbuckets;
+
+ smallhash_init_empty(sh);
+
+ for (i = 0; i < nbuckets_old; i++) {
+ if (smallhash_val_is_used(buckets_old[i].val)) {
+ SmallHashEntry *e = smallhash_lookup_first_free(sh, buckets_old[i].key);
+ e->key = buckets_old[i].key;
+ e->val = buckets_old[i].val;
+ }
+ }
+
+ if (was_alloc) {
+ MEM_freeN(buckets_old);
+ }
}
-void BLI_smallhash_init_ex(SmallHash *sh,
- const uint nentries_reserve)
+void BLI_smallhash_init_ex(SmallHash *sh, const uint nentries_reserve)
{
- /* assume 'sh' is uninitialized */
+ /* assume 'sh' is uninitialized */
- sh->nentries = 0;
- sh->cursize = 2;
- sh->nbuckets = hashsizes[sh->cursize];
+ sh->nentries = 0;
+ sh->cursize = 2;
+ sh->nbuckets = hashsizes[sh->cursize];
- sh->buckets = sh->buckets_stack;
+ sh->buckets = sh->buckets_stack;
- if (nentries_reserve) {
- smallhash_buckets_reserve(sh, nentries_reserve);
+ if (nentries_reserve) {
+ smallhash_buckets_reserve(sh, nentries_reserve);
- if (sh->nbuckets > SMSTACKSIZE) {
- sh->buckets = MEM_mallocN(sizeof(*sh->buckets) * sh->nbuckets, __func__);
- }
- }
+ if (sh->nbuckets > SMSTACKSIZE) {
+ sh->buckets = MEM_mallocN(sizeof(*sh->buckets) * sh->nbuckets, __func__);
+ }
+ }
- smallhash_init_empty(sh);
+ smallhash_init_empty(sh);
}
void BLI_smallhash_init(SmallHash *sh)
{
- BLI_smallhash_init_ex(sh, 0);
+ BLI_smallhash_init_ex(sh, 0);
}
/* NOTE: does *not* free *sh itself! only the direct data! */
void BLI_smallhash_release(SmallHash *sh)
{
- if (sh->buckets != sh->buckets_stack) {
- MEM_freeN(sh->buckets);
- }
+ if (sh->buckets != sh->buckets_stack) {
+ MEM_freeN(sh->buckets);
+ }
}
void BLI_smallhash_insert(SmallHash *sh, uintptr_t key, void *val)
{
- SmallHashEntry *e;
+ SmallHashEntry *e;
- BLI_assert(key != SMHASH_KEY_UNUSED);
- BLI_assert(smallhash_val_is_used(val));
- BLI_assert(BLI_smallhash_haskey(sh, key) == false);
+ BLI_assert(key != SMHASH_KEY_UNUSED);
+ BLI_assert(smallhash_val_is_used(val));
+ BLI_assert(BLI_smallhash_haskey(sh, key) == false);
- if (UNLIKELY(smallhash_test_expand_buckets(++sh->nentries, sh->nbuckets))) {
- smallhash_resize_buckets(sh, hashsizes[++sh->cursize]);
- }
+ if (UNLIKELY(smallhash_test_expand_buckets(++sh->nentries, sh->nbuckets))) {
+ smallhash_resize_buckets(sh, hashsizes[++sh->cursize]);
+ }
- e = smallhash_lookup_first_free(sh, key);
- e->key = key;
- e->val = val;
+ e = smallhash_lookup_first_free(sh, key);
+ e->key = key;
+ e->val = val;
}
/**
@@ -253,109 +246,108 @@ void BLI_smallhash_insert(SmallHash *sh, uintptr_t key, void *val)
*/
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;
- }
+ 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)
{
- SmallHashEntry *e = smallhash_lookup(sh, key);
-
- if (e) {
- e->key = SMHASH_KEY_UNUSED;
- e->val = SMHASH_CELL_UNUSED;
- sh->nentries--;
-
- return true;
- }
- else {
- return false;
- }
+ SmallHashEntry *e = smallhash_lookup(sh, key);
+
+ if (e) {
+ e->key = SMHASH_KEY_UNUSED;
+ e->val = SMHASH_CELL_UNUSED;
+ sh->nentries--;
+
+ return true;
+ }
+ else {
+ return false;
+ }
}
#endif
void *BLI_smallhash_lookup(const SmallHash *sh, uintptr_t key)
{
- SmallHashEntry *e = smallhash_lookup(sh, key);
+ SmallHashEntry *e = smallhash_lookup(sh, key);
- return e ? e->val : NULL;
+ return e ? e->val : NULL;
}
void **BLI_smallhash_lookup_p(const SmallHash *sh, uintptr_t key)
{
- SmallHashEntry *e = smallhash_lookup(sh, key);
+ SmallHashEntry *e = smallhash_lookup(sh, key);
- return e ? &e->val : NULL;
+ return e ? &e->val : NULL;
}
bool BLI_smallhash_haskey(const SmallHash *sh, uintptr_t key)
{
- SmallHashEntry *e = smallhash_lookup(sh, key);
+ SmallHashEntry *e = smallhash_lookup(sh, key);
- return (e != NULL);
+ return (e != NULL);
}
int BLI_smallhash_len(const SmallHash *sh)
{
- return (int)sh->nentries;
+ return (int)sh->nentries;
}
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)) {
- if (key) {
- *key = iter->sh->buckets[iter->i].key;
- }
+ while (iter->i < iter->sh->nbuckets) {
+ if (smallhash_val_is_used(iter->sh->buckets[iter->i].val)) {
+ if (key) {
+ *key = iter->sh->buckets[iter->i].key;
+ }
- return &iter->sh->buckets[iter->i++];
- }
+ return &iter->sh->buckets[iter->i++];
+ }
- iter->i++;
- }
+ iter->i++;
+ }
- return NULL;
+ return NULL;
}
void *BLI_smallhash_iternext(SmallHashIter *iter, uintptr_t *key)
{
- SmallHashEntry *e = smallhash_iternext(iter, key);
+ SmallHashEntry *e = smallhash_iternext(iter, key);
- return e ? e->val : NULL;
+ return e ? e->val : NULL;
}
void **BLI_smallhash_iternext_p(SmallHashIter *iter, uintptr_t *key)
{
- SmallHashEntry *e = smallhash_iternext(iter, key);
+ SmallHashEntry *e = smallhash_iternext(iter, key);
- return e ? &e->val : NULL;
+ return e ? &e->val : NULL;
}
void *BLI_smallhash_iternew(const SmallHash *sh, SmallHashIter *iter, uintptr_t *key)
{
- iter->sh = sh;
- iter->i = 0;
+ iter->sh = sh;
+ iter->i = 0;
- return BLI_smallhash_iternext(iter, key);
+ return BLI_smallhash_iternext(iter, key);
}
void **BLI_smallhash_iternew_p(const SmallHash *sh, SmallHashIter *iter, uintptr_t *key)
{
- iter->sh = sh;
- iter->i = 0;
+ iter->sh = sh;
+ iter->i = 0;
- return BLI_smallhash_iternext_p(iter, key);
+ return BLI_smallhash_iternext_p(iter, key);
}
-
/** \name Debugging & Introspection
* \{ */
@@ -364,32 +356,32 @@ void **BLI_smallhash_iternew_p(const SmallHash *sh, SmallHashIter *iter, uintptr
#if 0
void BLI_smallhash_print(SmallHash *sh)
{
- uint i, linecol = 79, c = 0;
-
- printf("{");
- for (i = 0; i < sh->nbuckets; i++) {
- if (sh->buckets[i].val == SMHASH_CELL_UNUSED) {
- printf("--u-");
- }
- else if (sh->buckets[i].val == SMHASH_CELL_FREE) {
- printf("--f-");
- }
- else {
- printf("%2x", (uint)sh->buckets[i].key);
- }
-
- if (i != sh->nbuckets - 1)
- printf(", ");
-
- c += 6;
-
- if (c >= linecol) {
- printf("\n ");
- c = 0;
- }
- }
-
- fflush(stdout);
+ uint i, linecol = 79, c = 0;
+
+ printf("{");
+ for (i = 0; i < sh->nbuckets; i++) {
+ if (sh->buckets[i].val == SMHASH_CELL_UNUSED) {
+ printf("--u-");
+ }
+ else if (sh->buckets[i].val == SMHASH_CELL_FREE) {
+ printf("--f-");
+ }
+ else {
+ printf("%2x", (uint)sh->buckets[i].key);
+ }
+
+ if (i != sh->nbuckets - 1)
+ printf(", ");
+
+ c += 6;
+
+ if (c >= linecol) {
+ printf("\n ");
+ c = 0;
+ }
+ }
+
+ fflush(stdout);
}
#endif
@@ -402,31 +394,29 @@ void BLI_smallhash_print(SmallHash *sh)
*/
double BLI_smallhash_calc_quality(SmallHash *sh)
{
- uint64_t sum = 0;
- uint i;
-
- if (sh->nentries == 0) {
- return -1.0;
- }
-
- for (i = 0; i < sh->nbuckets; i++) {
- if (sh->buckets[i].key != SMHASH_KEY_UNUSED) {
- uint64_t count = 0;
- SmallHashEntry *e, *e_final = &sh->buckets[i];
- uint h = smallhash_key(e_final->key);
- uint hoff = 1;
-
- for (e = &sh->buckets[h % sh->nbuckets];
- e != e_final;
- h = SMHASH_NEXT(h, hoff), e = &sh->buckets[h % sh->nbuckets])
- {
- count += 1;
- }
-
- sum += count;
- }
- }
- return ((double)(sh->nentries + sum) / (double)sh->nentries);
+ uint64_t sum = 0;
+ uint i;
+
+ if (sh->nentries == 0) {
+ return -1.0;
+ }
+
+ for (i = 0; i < sh->nbuckets; i++) {
+ if (sh->buckets[i].key != SMHASH_KEY_UNUSED) {
+ uint64_t count = 0;
+ SmallHashEntry *e, *e_final = &sh->buckets[i];
+ uint h = smallhash_key(e_final->key);
+ uint hoff = 1;
+
+ for (e = &sh->buckets[h % sh->nbuckets]; e != e_final;
+ h = SMHASH_NEXT(h, hoff), e = &sh->buckets[h % sh->nbuckets]) {
+ count += 1;
+ }
+
+ sum += count;
+ }
+ }
+ return ((double)(sh->nentries + sum) / (double)sh->nentries);
}
#endif
diff --git a/source/blender/blenlib/intern/sort.c b/source/blender/blenlib/intern/sort.c
index 07c85e6ba7b..225015db00d 100644
--- a/source/blender/blenlib/intern/sort.c
+++ b/source/blender/blenlib/intern/sort.c
@@ -27,13 +27,13 @@
/* do nothing! */
#else
-#include "BLI_utildefines.h"
+# include "BLI_utildefines.h"
-#include "BLI_sort.h"
+# include "BLI_sort.h"
-#ifdef min /* for msvc */
-# undef min
-#endif
+# ifdef min /* for msvc */
+# undef min
+# endif
/* Maintained by FreeBSD. */
/* clang-format off */
@@ -45,48 +45,48 @@
*
* \note modified to use glibc arg order for callbacks.
*/
-BLI_INLINE char *med3(char *, char *, char *, BLI_sort_cmp_t, void *);
-BLI_INLINE void swapfunc(char *, char *, int, int);
-
-#define min(a, b) (a) < (b) ? (a) : (b)
-#define swapcode(TYPE, parmi, parmj, n) \
-{ \
- long i = (n) / sizeof(TYPE); \
- TYPE *pi = (TYPE *) (parmi); \
- TYPE *pj = (TYPE *) (parmj); \
- do { \
- TYPE t = *pi; \
- *pi++ = *pj; \
- *pj++ = t; \
- } while (--i > 0); \
+BLI_INLINE char *med3(char *, char *, char *, BLI_sort_cmp_t, void *);
+BLI_INLINE void swapfunc(char *, char *, int, int);
+
+#define min(a, b) (a) < (b) ? (a) : (b)
+#define swapcode(TYPE, parmi, parmj, n) \
+{ \
+ long i = (n) / sizeof(TYPE); \
+ TYPE *pi = (TYPE *) (parmi); \
+ TYPE *pj = (TYPE *) (parmj); \
+ do { \
+ TYPE t = *pi; \
+ *pi++ = *pj; \
+ *pj++ = t; \
+ } while (--i > 0); \
}
#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
- es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
+ es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
BLI_INLINE void swapfunc(char *a, char *b, int n, int swaptype)
{
- if (swaptype <= 1)
- swapcode(long, a, b, n)
- else
- swapcode(char, a, b, n)
+ if (swaptype <= 1)
+ swapcode(long, a, b, n)
+ else
+ swapcode(char, a, b, n)
}
-#define swap(a, b) \
- if (swaptype == 0) { \
- long t = *(long *)(a); \
- *(long *)(a) = *(long *)(b);\
- *(long *)(b) = t; \
- } else \
- swapfunc(a, b, es, swaptype)
+#define swap(a, b) \
+ if (swaptype == 0) { \
+ long t = *(long *)(a); \
+ *(long *)(a) = *(long *)(b);\
+ *(long *)(b) = t; \
+ } else \
+ swapfunc(a, b, es, swaptype)
-#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
-#define CMP(t, x, y) (cmp((x), (y), (t)))
+#define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype)
+#define CMP(t, x, y) (cmp((x), (y), (t)))
BLI_INLINE char *med3(char *a, char *b, char *c, BLI_sort_cmp_t cmp, void *thunk)
{
- return CMP(thunk, a, b) < 0 ?
- (CMP(thunk, b, c) < 0 ? b : (CMP(thunk, a, c) < 0 ? c : a )) :
- (CMP(thunk, b, c) > 0 ? b : (CMP(thunk, a, c) < 0 ? a : c ));
+ return CMP(thunk, a, b) < 0 ?
+ (CMP(thunk, b, c) < 0 ? b : (CMP(thunk, a, c) < 0 ? c : a )) :
+ (CMP(thunk, b, c) > 0 ? b : (CMP(thunk, a, c) < 0 ? a : c ));
}
/**
@@ -94,92 +94,92 @@ BLI_INLINE char *med3(char *a, char *b, char *c, BLI_sort_cmp_t cmp, void *thunk
*/
void BLI_qsort_r(void *a, size_t n, size_t es, BLI_sort_cmp_t cmp, void *thunk)
{
- char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
- int d, r, swaptype, swap_cnt;
+ char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
+ int d, r, swaptype, swap_cnt;
loop:
- SWAPINIT(a, es);
- swap_cnt = 0;
- if (n < 7) {
- for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es) {
- for (pl = pm;
- pl > (char *)a && CMP(thunk, pl - es, pl) > 0;
- pl -= es)
- {
- swap(pl, pl - es);
- }
- }
- return;
- }
- pm = (char *)a + (n / 2) * es;
- if (n > 7) {
- pl = (char *)a;
- pn = (char *)a + (n - 1) * es;
- if (n > 40) {
- d = (n / 8) * es;
- pl = med3(pl, pl + d, pl + 2 * d, cmp, thunk);
- pm = med3(pm - d, pm, pm + d, cmp, thunk);
- pn = med3(pn - 2 * d, pn - d, pn, cmp, thunk);
- }
- pm = med3(pl, pm, pn, cmp, thunk);
- }
- swap((char *)a, pm);
- pa = pb = (char *)a + es;
-
- pc = pd = (char *)a + (n - 1) * es;
- for (;;) {
- while (pb <= pc && (r = CMP(thunk, pb, a)) <= 0) {
- if (r == 0) {
- swap_cnt = 1;
- swap(pa, pb);
- pa += es;
- }
- pb += es;
- }
- while (pb <= pc && (r = CMP(thunk, pc, a)) >= 0) {
- if (r == 0) {
- swap_cnt = 1;
- swap(pc, pd);
- pd -= es;
- }
- pc -= es;
- }
- if (pb > pc) {
- break;
- }
- swap(pb, pc);
- swap_cnt = 1;
- pb += es;
- pc -= es;
- }
- if (swap_cnt == 0) { /* Switch to insertion sort */
- for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es) {
- for (pl = pm;
- pl > (char *)a && CMP(thunk, pl - es, pl) > 0;
- pl -= es)
- {
- swap(pl, pl - es);
- }
- }
- return;
- }
-
- pn = (char *)a + n * es;
- r = min(pa - (char *)a, pb - pa);
- vecswap((char *)a, pb - r, r);
- r = min(pd - pc, pn - pd - es);
- vecswap(pb, pn - r, r);
- if ((r = pb - pa) > es) {
- BLI_qsort_r(a, r / es, es, cmp, thunk);
- }
- if ((r = pd - pc) > es) {
- /* Iterate rather than recurse to save stack space */
- a = pn - r;
- n = r / es;
- goto loop;
- }
+ SWAPINIT(a, es);
+ swap_cnt = 0;
+ if (n < 7) {
+ for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es) {
+ for (pl = pm;
+ pl > (char *)a && CMP(thunk, pl - es, pl) > 0;
+ pl -= es)
+ {
+ swap(pl, pl - es);
+ }
+ }
+ return;
+ }
+ pm = (char *)a + (n / 2) * es;
+ if (n > 7) {
+ pl = (char *)a;
+ pn = (char *)a + (n - 1) * es;
+ if (n > 40) {
+ d = (n / 8) * es;
+ pl = med3(pl, pl + d, pl + 2 * d, cmp, thunk);
+ pm = med3(pm - d, pm, pm + d, cmp, thunk);
+ pn = med3(pn - 2 * d, pn - d, pn, cmp, thunk);
+ }
+ pm = med3(pl, pm, pn, cmp, thunk);
+ }
+ swap((char *)a, pm);
+ pa = pb = (char *)a + es;
+
+ pc = pd = (char *)a + (n - 1) * es;
+ for (;;) {
+ while (pb <= pc && (r = CMP(thunk, pb, a)) <= 0) {
+ if (r == 0) {
+ swap_cnt = 1;
+ swap(pa, pb);
+ pa += es;
+ }
+ pb += es;
+ }
+ while (pb <= pc && (r = CMP(thunk, pc, a)) >= 0) {
+ if (r == 0) {
+ swap_cnt = 1;
+ swap(pc, pd);
+ pd -= es;
+ }
+ pc -= es;
+ }
+ if (pb > pc) {
+ break;
+ }
+ swap(pb, pc);
+ swap_cnt = 1;
+ pb += es;
+ pc -= es;
+ }
+ if (swap_cnt == 0) { /* Switch to insertion sort */
+ for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es) {
+ for (pl = pm;
+ pl > (char *)a && CMP(thunk, pl - es, pl) > 0;
+ pl -= es)
+ {
+ swap(pl, pl - es);
+ }
+ }
+ return;
+ }
+
+ pn = (char *)a + n * es;
+ r = min(pa - (char *)a, pb - pa);
+ vecswap((char *)a, pb - r, r);
+ r = min(pd - pc, pn - pd - es);
+ vecswap(pb, pn - r, r);
+ if ((r = pb - pa) > es) {
+ BLI_qsort_r(a, r / es, es, cmp, thunk);
+ }
+ if ((r = pd - pc) > es) {
+ /* Iterate rather than recurse to save stack space */
+ a = pn - r;
+ n = r / es;
+ goto loop;
+ }
}
/* clang-format on */
-#endif /* __GLIBC__ */
+#endif /* __GLIBC__ */
diff --git a/source/blender/blenlib/intern/sort_utils.c b/source/blender/blenlib/intern/sort_utils.c
index 3220f753397..09babd3d424 100644
--- a/source/blender/blenlib/intern/sort_utils.c
+++ b/source/blender/blenlib/intern/sort_utils.c
@@ -23,70 +23,106 @@
* Utility functions for sorting common types.
*/
-#include "BLI_sort_utils.h" /* own include */
+#include "BLI_sort_utils.h" /* own include */
struct SortAnyByFloat {
- float sort_value;
+ float sort_value;
};
struct SortAnyByInt {
- int sort_value;
+ int sort_value;
};
struct SortAnyByPtr {
- const void *sort_value;
+ const void *sort_value;
};
int BLI_sortutil_cmp_float(const void *a_, const void *b_)
{
- const struct SortAnyByFloat *a = a_;
- const struct SortAnyByFloat *b = b_;
- if (a->sort_value > b->sort_value) { return 1; }
- else if (a->sort_value < b->sort_value) { return -1; }
- else { return 0; }
+ const struct SortAnyByFloat *a = a_;
+ const struct SortAnyByFloat *b = b_;
+ if (a->sort_value > b->sort_value) {
+ return 1;
+ }
+ else if (a->sort_value < b->sort_value) {
+ return -1;
+ }
+ else {
+ return 0;
+ }
}
int BLI_sortutil_cmp_float_reverse(const void *a_, const void *b_)
{
- const struct SortAnyByFloat *a = a_;
- const struct SortAnyByFloat *b = b_;
- if (a->sort_value < b->sort_value) { return 1; }
- else if (a->sort_value > b->sort_value) { return -1; }
- else { return 0; }
+ const struct SortAnyByFloat *a = a_;
+ const struct SortAnyByFloat *b = b_;
+ if (a->sort_value < b->sort_value) {
+ return 1;
+ }
+ else if (a->sort_value > b->sort_value) {
+ return -1;
+ }
+ else {
+ return 0;
+ }
}
int BLI_sortutil_cmp_int(const void *a_, const void *b_)
{
- const struct SortAnyByInt *a = a_;
- const struct SortAnyByInt *b = b_;
- if (a->sort_value > b->sort_value) { return 1; }
- else if (a->sort_value < b->sort_value) { return -1; }
- else { return 0; }
+ const struct SortAnyByInt *a = a_;
+ const struct SortAnyByInt *b = b_;
+ if (a->sort_value > b->sort_value) {
+ return 1;
+ }
+ else if (a->sort_value < b->sort_value) {
+ return -1;
+ }
+ else {
+ return 0;
+ }
}
int BLI_sortutil_cmp_int_reverse(const void *a_, const void *b_)
{
- const struct SortAnyByInt *a = a_;
- const struct SortAnyByInt *b = b_;
- if (a->sort_value < b->sort_value) { return 1; }
- else if (a->sort_value > b->sort_value) { return -1; }
- else { return 0; }
+ const struct SortAnyByInt *a = a_;
+ const struct SortAnyByInt *b = b_;
+ if (a->sort_value < b->sort_value) {
+ return 1;
+ }
+ else if (a->sort_value > b->sort_value) {
+ return -1;
+ }
+ else {
+ return 0;
+ }
}
int BLI_sortutil_cmp_ptr(const void *a_, const void *b_)
{
- const struct SortAnyByPtr *a = a_;
- const struct SortAnyByPtr *b = b_;
- if (a->sort_value > b->sort_value) { return 1; }
- else if (a->sort_value < b->sort_value) { return -1; }
- else { return 0; }
+ const struct SortAnyByPtr *a = a_;
+ const struct SortAnyByPtr *b = b_;
+ if (a->sort_value > b->sort_value) {
+ return 1;
+ }
+ else if (a->sort_value < b->sort_value) {
+ return -1;
+ }
+ else {
+ return 0;
+ }
}
int BLI_sortutil_cmp_ptr_reverse(const void *a_, const void *b_)
{
- const struct SortAnyByPtr *a = a_;
- const struct SortAnyByPtr *b = b_;
- if (a->sort_value < b->sort_value) { return 1; }
- else if (a->sort_value > b->sort_value) { return -1; }
- else { return 0; }
+ const struct SortAnyByPtr *a = a_;
+ const struct SortAnyByPtr *b = b_;
+ if (a->sort_value < b->sort_value) {
+ return 1;
+ }
+ else if (a->sort_value > b->sort_value) {
+ return -1;
+ }
+ else {
+ return 0;
+ }
}
diff --git a/source/blender/blenlib/intern/stack.c b/source/blender/blenlib/intern/stack.c
index 4f6f9024fa5..76aef3761ae 100644
--- a/source/blender/blenlib/intern/stack.c
+++ b/source/blender/blenlib/intern/stack.c
@@ -19,12 +19,12 @@
*/
#include <string.h>
-#include <stdlib.h> /* abort() */
+#include <stdlib.h> /* abort() */
#include "BLI_utildefines.h"
#include "MEM_guardedalloc.h"
-#include "BLI_stack.h" /* own include */
+#include "BLI_stack.h" /* own include */
#include "BLI_strict_flags.h"
@@ -34,26 +34,25 @@
/* target chunks size: 64kb */
#define CHUNK_SIZE_DEFAULT (1 << 16)
/* ensure we get at least this many elems per chunk */
-#define CHUNK_ELEM_MIN 32
+#define CHUNK_ELEM_MIN 32
/* Gets the last element in the stack */
#define CHUNK_LAST_ELEM(_stack) \
- ((void)0, (((char *)(_stack)->chunk_curr->data) + \
- ((_stack)->elem_size * (_stack)->chunk_index)))
+ ((void)0, (((char *)(_stack)->chunk_curr->data) + ((_stack)->elem_size * (_stack)->chunk_index)))
struct StackChunk {
- struct StackChunk *next;
- char data[0];
+ struct StackChunk *next;
+ char data[0];
};
struct BLI_Stack {
- struct StackChunk *chunk_curr; /* currently active chunk */
- struct StackChunk *chunk_free; /* free chunks */
- size_t chunk_index; /* index into 'chunk_curr' */
- size_t chunk_elem_max; /* number of elements per chunk */
- size_t elem_size;
+ struct StackChunk *chunk_curr; /* currently active chunk */
+ struct StackChunk *chunk_free; /* free chunks */
+ size_t chunk_index; /* index into 'chunk_curr' */
+ size_t chunk_elem_max; /* number of elements per chunk */
+ size_t elem_size;
#ifdef USE_TOTELEM
- size_t totelem;
+ size_t totelem;
#endif
};
@@ -62,32 +61,33 @@ struct BLI_Stack {
*/
static size_t stack_chunk_elem_max_calc(const size_t elem_size, size_t chunk_size)
{
- /* get at least this number of elems per chunk */
- const size_t elem_size_min = elem_size * CHUNK_ELEM_MIN;
+ /* get at least this number of elems per chunk */
+ const size_t elem_size_min = elem_size * CHUNK_ELEM_MIN;
- BLI_assert((elem_size != 0) && (chunk_size != 0));
+ BLI_assert((elem_size != 0) && (chunk_size != 0));
- while (UNLIKELY(chunk_size <= elem_size_min)) {
- chunk_size <<= 1;
- }
+ while (UNLIKELY(chunk_size <= elem_size_min)) {
+ chunk_size <<= 1;
+ }
- /* account for slop-space */
- chunk_size -= (sizeof(struct StackChunk) + MEM_SIZE_OVERHEAD);
+ /* account for slop-space */
+ chunk_size -= (sizeof(struct StackChunk) + MEM_SIZE_OVERHEAD);
- return chunk_size / elem_size;
+ return chunk_size / elem_size;
}
-BLI_Stack *BLI_stack_new_ex(const size_t elem_size, const char *description,
+BLI_Stack *BLI_stack_new_ex(const size_t elem_size,
+ const char *description,
const size_t chunk_size)
{
- BLI_Stack *stack = MEM_callocN(sizeof(*stack), description);
+ BLI_Stack *stack = MEM_callocN(sizeof(*stack), description);
- stack->chunk_elem_max = stack_chunk_elem_max_calc(elem_size, chunk_size);
- stack->elem_size = elem_size;
- /* force init */
- stack->chunk_index = stack->chunk_elem_max - 1;
+ stack->chunk_elem_max = stack_chunk_elem_max_calc(elem_size, chunk_size);
+ stack->elem_size = elem_size;
+ /* force init */
+ stack->chunk_index = stack->chunk_elem_max - 1;
- return stack;
+ return stack;
}
/**
@@ -95,16 +95,16 @@ BLI_Stack *BLI_stack_new_ex(const size_t elem_size, const char *description,
*/
BLI_Stack *BLI_stack_new(const size_t elem_size, const char *description)
{
- return BLI_stack_new_ex(elem_size, description, CHUNK_SIZE_DEFAULT);
+ return BLI_stack_new_ex(elem_size, description, CHUNK_SIZE_DEFAULT);
}
static void stack_free_chunks(struct StackChunk *data)
{
- while (data) {
- struct StackChunk *data_next = data->next;
- MEM_freeN(data);
- data = data_next;
- }
+ while (data) {
+ struct StackChunk *data_next = data->next;
+ MEM_freeN(data);
+ data = data_next;
+ }
}
/**
@@ -112,9 +112,9 @@ static void stack_free_chunks(struct StackChunk *data)
*/
void BLI_stack_free(BLI_Stack *stack)
{
- stack_free_chunks(stack->chunk_curr);
- stack_free_chunks(stack->chunk_free);
- MEM_freeN(stack);
+ stack_free_chunks(stack->chunk_curr);
+ stack_free_chunks(stack->chunk_free);
+ MEM_freeN(stack);
}
/**
@@ -125,32 +125,30 @@ void BLI_stack_free(BLI_Stack *stack)
*/
void *BLI_stack_push_r(BLI_Stack *stack)
{
- stack->chunk_index++;
-
- if (UNLIKELY(stack->chunk_index == stack->chunk_elem_max)) {
- struct StackChunk *chunk;
- if (stack->chunk_free) {
- chunk = stack->chunk_free;
- stack->chunk_free = chunk->next;
- }
- else {
- chunk = MEM_mallocN(
- sizeof(*chunk) + (stack->elem_size * stack->chunk_elem_max),
- __func__);
- }
- chunk->next = stack->chunk_curr;
- stack->chunk_curr = chunk;
- stack->chunk_index = 0;
- }
-
- BLI_assert(stack->chunk_index < stack->chunk_elem_max);
+ stack->chunk_index++;
+
+ if (UNLIKELY(stack->chunk_index == stack->chunk_elem_max)) {
+ struct StackChunk *chunk;
+ if (stack->chunk_free) {
+ chunk = stack->chunk_free;
+ stack->chunk_free = chunk->next;
+ }
+ else {
+ chunk = MEM_mallocN(sizeof(*chunk) + (stack->elem_size * stack->chunk_elem_max), __func__);
+ }
+ chunk->next = stack->chunk_curr;
+ stack->chunk_curr = chunk;
+ stack->chunk_index = 0;
+ }
+
+ BLI_assert(stack->chunk_index < stack->chunk_elem_max);
#ifdef USE_TOTELEM
- stack->totelem++;
+ stack->totelem++;
#endif
- /* Return end of stack */
- return CHUNK_LAST_ELEM(stack);
+ /* Return end of stack */
+ return CHUNK_LAST_ELEM(stack);
}
/**
@@ -163,8 +161,8 @@ void *BLI_stack_push_r(BLI_Stack *stack)
*/
void BLI_stack_push(BLI_Stack *stack, const void *src)
{
- void *dst = BLI_stack_push_r(stack);
- memcpy(dst, src, stack->elem_size);
+ void *dst = BLI_stack_push_r(stack);
+ memcpy(dst, src, stack->elem_size);
}
/**
@@ -175,11 +173,11 @@ void BLI_stack_push(BLI_Stack *stack, const void *src)
*/
void BLI_stack_pop(BLI_Stack *stack, void *dst)
{
- BLI_assert(BLI_stack_is_empty(stack) == false);
+ BLI_assert(BLI_stack_is_empty(stack) == false);
- memcpy(dst, CHUNK_LAST_ELEM(stack), stack->elem_size);
+ memcpy(dst, CHUNK_LAST_ELEM(stack), stack->elem_size);
- BLI_stack_discard(stack);
+ BLI_stack_discard(stack);
}
/**
@@ -193,12 +191,12 @@ void BLI_stack_pop(BLI_Stack *stack, void *dst)
*/
void BLI_stack_pop_n(BLI_Stack *stack, void *dst, unsigned int n)
{
- BLI_assert(n <= BLI_stack_count(stack));
+ BLI_assert(n <= BLI_stack_count(stack));
- while (n--) {
- BLI_stack_pop(stack, dst);
- dst = (void *)((char *)dst + stack->elem_size);
- }
+ while (n--) {
+ BLI_stack_pop(stack, dst);
+ dst = (void *)((char *)dst + stack->elem_size);
+ }
}
/**
@@ -208,21 +206,21 @@ void BLI_stack_pop_n(BLI_Stack *stack, void *dst, unsigned int n)
*/
void BLI_stack_pop_n_reverse(BLI_Stack *stack, void *dst, unsigned int n)
{
- BLI_assert(n <= BLI_stack_count(stack));
+ BLI_assert(n <= BLI_stack_count(stack));
- dst = (void *)((char *)dst + (stack->elem_size * n));
+ dst = (void *)((char *)dst + (stack->elem_size * n));
- while (n--) {
- dst = (void *)((char *)dst - stack->elem_size);
- BLI_stack_pop(stack, dst);
- }
+ while (n--) {
+ dst = (void *)((char *)dst - stack->elem_size);
+ BLI_stack_pop(stack, dst);
+ }
}
void *BLI_stack_peek(BLI_Stack *stack)
{
- BLI_assert(BLI_stack_is_empty(stack) == false);
+ BLI_assert(BLI_stack_is_empty(stack) == false);
- return CHUNK_LAST_ELEM(stack);
+ return CHUNK_LAST_ELEM(stack);
}
/**
@@ -230,22 +228,22 @@ void *BLI_stack_peek(BLI_Stack *stack)
*/
void BLI_stack_discard(BLI_Stack *stack)
{
- BLI_assert(BLI_stack_is_empty(stack) == false);
+ BLI_assert(BLI_stack_is_empty(stack) == false);
#ifdef USE_TOTELEM
- stack->totelem--;
+ stack->totelem--;
#endif
- if (UNLIKELY(--stack->chunk_index == CHUNK_EMPTY)) {
- struct StackChunk *chunk_free;
+ if (UNLIKELY(--stack->chunk_index == CHUNK_EMPTY)) {
+ struct StackChunk *chunk_free;
- chunk_free = stack->chunk_curr;
- stack->chunk_curr = stack->chunk_curr->next;
+ chunk_free = stack->chunk_curr;
+ stack->chunk_curr = stack->chunk_curr->next;
- chunk_free->next = stack->chunk_free;
- stack->chunk_free = chunk_free;
+ chunk_free->next = stack->chunk_free;
+ stack->chunk_free = chunk_free;
- stack->chunk_index = stack->chunk_elem_max - 1;
- }
+ stack->chunk_index = stack->chunk_elem_max - 1;
+ }
}
/**
@@ -254,54 +252,54 @@ void BLI_stack_discard(BLI_Stack *stack)
void BLI_stack_clear(BLI_Stack *stack)
{
#ifdef USE_TOTELEM
- if (UNLIKELY(stack->totelem == 0)) {
- return;
- }
- stack->totelem = 0;
+ if (UNLIKELY(stack->totelem == 0)) {
+ return;
+ }
+ stack->totelem = 0;
#else
- if (UNLIKELY(stack->chunk_curr == NULL)) {
- return;
- }
+ if (UNLIKELY(stack->chunk_curr == NULL)) {
+ return;
+ }
#endif
- stack->chunk_index = stack->chunk_elem_max - 1;
-
- if (stack->chunk_free) {
- if (stack->chunk_curr) {
- /* move all used chunks into tail of free list */
- struct StackChunk *chunk_free_last = stack->chunk_free;
- while (chunk_free_last->next) {
- chunk_free_last = chunk_free_last->next;
- }
- chunk_free_last->next = stack->chunk_curr;
- stack->chunk_curr = NULL;
- }
- }
- else {
- stack->chunk_free = stack->chunk_curr;
- stack->chunk_curr = NULL;
- }
+ stack->chunk_index = stack->chunk_elem_max - 1;
+
+ if (stack->chunk_free) {
+ if (stack->chunk_curr) {
+ /* move all used chunks into tail of free list */
+ struct StackChunk *chunk_free_last = stack->chunk_free;
+ while (chunk_free_last->next) {
+ chunk_free_last = chunk_free_last->next;
+ }
+ chunk_free_last->next = stack->chunk_curr;
+ stack->chunk_curr = NULL;
+ }
+ }
+ else {
+ stack->chunk_free = stack->chunk_curr;
+ stack->chunk_curr = NULL;
+ }
}
size_t BLI_stack_count(const BLI_Stack *stack)
{
#ifdef USE_TOTELEM
- return stack->totelem;
+ return stack->totelem;
#else
- struct StackChunk *data = stack->chunk_curr;
- size_t totelem = stack->chunk_index + 1;
- size_t i;
- if (totelem != stack->chunk_elem_max) {
- data = data->next;
- }
- else {
- totelem = 0;
- }
- for (i = 0; data; data = data->next) {
- i++;
- }
- totelem += stack->chunk_elem_max * i;
- return totelem;
+ struct StackChunk *data = stack->chunk_curr;
+ size_t totelem = stack->chunk_index + 1;
+ size_t i;
+ if (totelem != stack->chunk_elem_max) {
+ data = data->next;
+ }
+ else {
+ totelem = 0;
+ }
+ for (i = 0; data; data = data->next) {
+ i++;
+ }
+ totelem += stack->chunk_elem_max * i;
+ return totelem;
#endif
}
@@ -311,7 +309,7 @@ size_t BLI_stack_count(const BLI_Stack *stack)
bool BLI_stack_is_empty(const BLI_Stack *stack)
{
#ifdef USE_TOTELEM
- BLI_assert((stack->chunk_curr == NULL) == (stack->totelem == 0));
+ BLI_assert((stack->chunk_curr == NULL) == (stack->totelem == 0));
#endif
- return (stack->chunk_curr == NULL);
+ return (stack->chunk_curr == NULL);
}
diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c
index 7b460c77fa8..64b8ff40bcf 100644
--- a/source/blender/blenlib/intern/storage.c
+++ b/source/blender/blenlib/intern/storage.c
@@ -30,13 +30,14 @@
#include <sys/stat.h>
#if defined(__NetBSD__) || defined(__DragonFly__) || defined(__HAIKU__)
- /* Other modern unix os's should probably use this also */
+/* Other modern unix os's should probably use this also */
# include <sys/statvfs.h>
# define USE_STATFS_STATVFS
#endif
-#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
- /* For statfs */
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || \
+ defined(__DragonFly__)
+/* For statfs */
# include <sys/param.h>
# include <sys/mount.h>
#endif
@@ -46,7 +47,7 @@
#endif
#include <fcntl.h>
-#include <string.h> /* strcpy etc.. */
+#include <string.h> /* strcpy etc.. */
#ifdef WIN32
# include <io.h>
@@ -76,19 +77,19 @@
*/
char *BLI_current_working_dir(char *dir, const size_t maxncpy)
{
- const char *pwd = BLI_getenv("PWD");
- if (pwd) {
- size_t srclen = BLI_strnlen(pwd, maxncpy);
- if (srclen != maxncpy) {
- memcpy(dir, pwd, srclen + 1);
- return dir;
- }
- else {
- return NULL;
- }
- }
-
- return getcwd(dir, maxncpy);
+ const char *pwd = BLI_getenv("PWD");
+ if (pwd) {
+ size_t srclen = BLI_strnlen(pwd, maxncpy);
+ if (srclen != maxncpy) {
+ memcpy(dir, pwd, srclen + 1);
+ return dir;
+ }
+ else {
+ return NULL;
+ }
+ }
+
+ return getcwd(dir, maxncpy);
}
/**
@@ -98,81 +99,81 @@ char *BLI_current_working_dir(char *dir, const size_t maxncpy)
double BLI_dir_free_space(const char *dir)
{
#ifdef WIN32
- DWORD sectorspc, bytesps, freec, clusters;
- char tmp[4];
-
- tmp[0] = '\\'; tmp[1] = 0; /* Just a failsafe */
- if (dir[0] == '/' || dir[0] == '\\') {
- tmp[0] = '\\';
- tmp[1] = 0;
- }
- else if (dir[1] == ':') {
- tmp[0] = dir[0];
- tmp[1] = ':';
- tmp[2] = '\\';
- tmp[3] = 0;
- }
-
- GetDiskFreeSpace(tmp, &sectorspc, &bytesps, &freec, &clusters);
-
- return (double) (freec * bytesps * sectorspc);
+ DWORD sectorspc, bytesps, freec, clusters;
+ char tmp[4];
+
+ tmp[0] = '\\';
+ tmp[1] = 0; /* Just a failsafe */
+ if (dir[0] == '/' || dir[0] == '\\') {
+ tmp[0] = '\\';
+ tmp[1] = 0;
+ }
+ else if (dir[1] == ':') {
+ tmp[0] = dir[0];
+ tmp[1] = ':';
+ tmp[2] = '\\';
+ tmp[3] = 0;
+ }
+
+ GetDiskFreeSpace(tmp, &sectorspc, &bytesps, &freec, &clusters);
+
+ return (double)(freec * bytesps * sectorspc);
#else
-#ifdef USE_STATFS_STATVFS
- struct statvfs disk;
-#else
- struct statfs disk;
-#endif
-
- char name[FILE_MAXDIR], *slash;
- int len = strlen(dir);
-
- if (len >= FILE_MAXDIR) {
- /* path too long */
- return -1;
- }
-
- strcpy(name, dir);
-
- if (len) {
- slash = strrchr(name, '/');
- if (slash) {
- slash[1] = 0;
- }
- }
- else {
- strcpy(name, "/");
- }
-
-#if defined(USE_STATFS_STATVFS)
- if (statvfs(name, &disk)) {
- return -1;
- }
-#elif defined(USE_STATFS_4ARGS)
- if (statfs(name, &disk, sizeof(struct statfs), 0)) {
- return -1;
- }
-#else
- if (statfs(name, &disk)) {
- return -1;
- }
-#endif
-
- return ( ((double) disk.f_bsize) * ((double) disk.f_bfree));
+# ifdef USE_STATFS_STATVFS
+ struct statvfs disk;
+# else
+ struct statfs disk;
+# endif
+
+ char name[FILE_MAXDIR], *slash;
+ int len = strlen(dir);
+
+ if (len >= FILE_MAXDIR) {
+ /* path too long */
+ return -1;
+ }
+
+ strcpy(name, dir);
+
+ if (len) {
+ slash = strrchr(name, '/');
+ if (slash) {
+ slash[1] = 0;
+ }
+ }
+ else {
+ strcpy(name, "/");
+ }
+
+# if defined(USE_STATFS_STATVFS)
+ if (statvfs(name, &disk)) {
+ return -1;
+ }
+# elif defined(USE_STATFS_4ARGS)
+ if (statfs(name, &disk, sizeof(struct statfs), 0)) {
+ return -1;
+ }
+# else
+ if (statfs(name, &disk)) {
+ return -1;
+ }
+# endif
+
+ return (((double)disk.f_bsize) * ((double)disk.f_bfree));
#endif
}
-
/**
* Returns the file size of an opened file descriptor.
*/
size_t BLI_file_descriptor_size(int file)
{
- struct stat st;
- if ((file < 0) || (fstat(file, &st) == -1)) {
- return -1;
- }
- return st.st_size;
+ struct stat st;
+ if ((file < 0) || (fstat(file, &st) == -1)) {
+ return -1;
+ }
+ return st.st_size;
}
/**
@@ -180,11 +181,11 @@ size_t BLI_file_descriptor_size(int file)
*/
size_t BLI_file_size(const char *path)
{
- BLI_stat_t stats;
- if (BLI_stat(path, &stats) == -1) {
- return -1;
- }
- return stats.st_size;
+ BLI_stat_t stats;
+ if (BLI_stat(path, &stats) == -1) {
+ return -1;
+ }
+ return stats.st_size;
}
/**
@@ -194,78 +195,76 @@ size_t BLI_file_size(const char *path)
int BLI_exists(const char *name)
{
#if defined(WIN32)
- BLI_stat_t st;
- wchar_t *tmp_16 = alloc_utf16_from_8(name, 1);
- int len, res;
- unsigned int old_error_mode;
-
- len = wcslen(tmp_16);
- /* in Windows #stat doesn't recognize dir ending on a slash
- * so we remove it here */
- if (len > 3 && (tmp_16[len - 1] == L'\\' || tmp_16[len - 1] == L'/')) {
- tmp_16[len - 1] = '\0';
- }
- /* two special cases where the trailing slash is needed:
- * 1. after the share part of a UNC path
- * 2. after the C:\ when the path is the volume only
- */
- if ((len >= 3) && (tmp_16[0] == L'\\') && (tmp_16[1] == L'\\')) {
- BLI_cleanup_unc_16(tmp_16);
- }
-
- if ((tmp_16[1] == L':') && (tmp_16[2] == L'\0')) {
- tmp_16[2] = L'\\';
- tmp_16[3] = L'\0';
- }
-
-
- /* change error mode so user does not get a "no disk in drive" popup
- * when looking for a file on an empty CD/DVD drive */
- old_error_mode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
-
- res = BLI_wstat(tmp_16, &st);
-
- SetErrorMode(old_error_mode);
-
- free(tmp_16);
- if (res == -1) {
- return(0);
- }
+ BLI_stat_t st;
+ wchar_t *tmp_16 = alloc_utf16_from_8(name, 1);
+ int len, res;
+ unsigned int old_error_mode;
+
+ len = wcslen(tmp_16);
+ /* in Windows #stat doesn't recognize dir ending on a slash
+ * so we remove it here */
+ if (len > 3 && (tmp_16[len - 1] == L'\\' || tmp_16[len - 1] == L'/')) {
+ tmp_16[len - 1] = '\0';
+ }
+ /* two special cases where the trailing slash is needed:
+ * 1. after the share part of a UNC path
+ * 2. after the C:\ when the path is the volume only
+ */
+ if ((len >= 3) && (tmp_16[0] == L'\\') && (tmp_16[1] == L'\\')) {
+ BLI_cleanup_unc_16(tmp_16);
+ }
+
+ if ((tmp_16[1] == L':') && (tmp_16[2] == L'\0')) {
+ tmp_16[2] = L'\\';
+ tmp_16[3] = L'\0';
+ }
+
+ /* change error mode so user does not get a "no disk in drive" popup
+ * when looking for a file on an empty CD/DVD drive */
+ old_error_mode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
+
+ res = BLI_wstat(tmp_16, &st);
+
+ SetErrorMode(old_error_mode);
+
+ free(tmp_16);
+ if (res == -1) {
+ return (0);
+ }
#else
- struct stat st;
- BLI_assert(!BLI_path_is_rel(name));
- if (stat(name, &st)) {
- return(0);
- }
+ struct stat st;
+ BLI_assert(!BLI_path_is_rel(name));
+ if (stat(name, &st)) {
+ return (0);
+ }
#endif
- return(st.st_mode);
+ return (st.st_mode);
}
-
#ifdef WIN32
int BLI_stat(const char *path, BLI_stat_t *buffer)
{
- int r;
- UTF16_ENCODE(path);
+ int r;
+ UTF16_ENCODE(path);
- r = BLI_wstat(path_16, buffer);
+ r = BLI_wstat(path_16, buffer);
- UTF16_UN_ENCODE(path);
- return r;
+ UTF16_UN_ENCODE(path);
+ return r;
}
int BLI_wstat(const wchar_t *path, BLI_stat_t *buffer)
{
-#if defined(_MSC_VER)
- return _wstat64(path, buffer);
-#else
- return _wstat(path, buffer);
-#endif
+# if defined(_MSC_VER)
+ return _wstat64(path, buffer);
+# else
+ return _wstat(path, buffer);
+# endif
}
#else
int BLI_stat(const char *path, struct stat *buffer)
{
- return stat(path, buffer);
+ return stat(path, buffer);
}
#endif
@@ -275,7 +274,7 @@ int BLI_stat(const char *path, struct stat *buffer)
*/
bool BLI_is_dir(const char *file)
{
- return S_ISDIR(BLI_exists(file));
+ return S_ISDIR(BLI_exists(file));
}
/**
@@ -283,83 +282,83 @@ bool BLI_is_dir(const char *file)
*/
bool BLI_is_file(const char *path)
{
- const int mode = BLI_exists(path);
- return (mode && !S_ISDIR(mode));
+ const int mode = BLI_exists(path);
+ return (mode && !S_ISDIR(mode));
}
void *BLI_file_read_text_as_mem(const char *filepath, size_t pad_bytes, size_t *r_size)
{
- FILE *fp = BLI_fopen(filepath, "r");
- void *mem = NULL;
-
- if (fp) {
- fseek(fp, 0L, SEEK_END);
- const long int filelen = ftell(fp);
- if (filelen == -1) {
- goto finally;
- }
- fseek(fp, 0L, SEEK_SET);
-
- mem = MEM_mallocN(filelen + pad_bytes, __func__);
- if (mem == NULL) {
- goto finally;
- }
-
- const long int filelen_read = fread(mem, 1, filelen, fp);
- if ((filelen_read < 0) || ferror(fp)) {
- MEM_freeN(mem);
- mem = NULL;
- goto finally;
- }
-
- if (filelen_read < filelen) {
- mem = MEM_reallocN(mem, filelen_read + pad_bytes);
- if (mem == NULL) {
- goto finally;
- }
- }
-
- *r_size = filelen_read;
-
-finally:
- fclose(fp);
- }
-
- return mem;
+ FILE *fp = BLI_fopen(filepath, "r");
+ void *mem = NULL;
+
+ if (fp) {
+ fseek(fp, 0L, SEEK_END);
+ const long int filelen = ftell(fp);
+ if (filelen == -1) {
+ goto finally;
+ }
+ fseek(fp, 0L, SEEK_SET);
+
+ mem = MEM_mallocN(filelen + pad_bytes, __func__);
+ if (mem == NULL) {
+ goto finally;
+ }
+
+ const long int filelen_read = fread(mem, 1, filelen, fp);
+ if ((filelen_read < 0) || ferror(fp)) {
+ MEM_freeN(mem);
+ mem = NULL;
+ goto finally;
+ }
+
+ if (filelen_read < filelen) {
+ mem = MEM_reallocN(mem, filelen_read + pad_bytes);
+ if (mem == NULL) {
+ goto finally;
+ }
+ }
+
+ *r_size = filelen_read;
+
+ finally:
+ fclose(fp);
+ }
+
+ return mem;
}
void *BLI_file_read_binary_as_mem(const char *filepath, size_t pad_bytes, size_t *r_size)
{
- FILE *fp = BLI_fopen(filepath, "rb");
- void *mem = NULL;
-
- if (fp) {
- fseek(fp, 0L, SEEK_END);
- const long int filelen = ftell(fp);
- if (filelen == -1) {
- goto finally;
- }
- fseek(fp, 0L, SEEK_SET);
-
- mem = MEM_mallocN(filelen + pad_bytes, __func__);
- if (mem == NULL) {
- goto finally;
- }
-
- const long int filelen_read = fread(mem, 1, filelen, fp);
- if ((filelen_read != filelen) || ferror(fp)) {
- MEM_freeN(mem);
- mem = NULL;
- goto finally;
- }
-
- *r_size = filelen_read;
-
-finally:
- fclose(fp);
- }
-
- return mem;
+ FILE *fp = BLI_fopen(filepath, "rb");
+ void *mem = NULL;
+
+ if (fp) {
+ fseek(fp, 0L, SEEK_END);
+ const long int filelen = ftell(fp);
+ if (filelen == -1) {
+ goto finally;
+ }
+ fseek(fp, 0L, SEEK_SET);
+
+ mem = MEM_mallocN(filelen + pad_bytes, __func__);
+ if (mem == NULL) {
+ goto finally;
+ }
+
+ const long int filelen_read = fread(mem, 1, filelen, fp);
+ if ((filelen_read != filelen) || ferror(fp)) {
+ MEM_freeN(mem);
+ mem = NULL;
+ goto finally;
+ }
+
+ *r_size = filelen_read;
+
+ finally:
+ fclose(fp);
+ }
+
+ return mem;
}
/**
@@ -367,48 +366,48 @@ finally:
*/
LinkNode *BLI_file_read_as_lines(const char *name)
{
- FILE *fp = BLI_fopen(name, "r");
- LinkNodePair lines = {NULL, NULL};
- char *buf;
- size_t size;
-
- if (!fp) {
- return NULL;
- }
-
- fseek(fp, 0, SEEK_END);
- size = (size_t)ftell(fp);
- fseek(fp, 0, SEEK_SET);
-
- if (UNLIKELY(size == (size_t)-1)) {
- fclose(fp);
- return NULL;
- }
-
- buf = MEM_mallocN(size, "file_as_lines");
- if (buf) {
- size_t i, last = 0;
-
- /*
- * size = because on win32 reading
- * all the bytes in the file will return
- * less bytes because of `CRNL` changes.
- */
- size = fread(buf, 1, size, fp);
- for (i = 0; i <= size; i++) {
- if (i == size || buf[i] == '\n') {
- char *line = BLI_strdupn(&buf[last], i - last);
- BLI_linklist_append(&lines, line);
- last = i + 1;
- }
- }
-
- MEM_freeN(buf);
- }
-
- fclose(fp);
-
- return lines.list;
+ FILE *fp = BLI_fopen(name, "r");
+ LinkNodePair lines = {NULL, NULL};
+ char *buf;
+ size_t size;
+
+ if (!fp) {
+ return NULL;
+ }
+
+ fseek(fp, 0, SEEK_END);
+ size = (size_t)ftell(fp);
+ fseek(fp, 0, SEEK_SET);
+
+ if (UNLIKELY(size == (size_t)-1)) {
+ fclose(fp);
+ return NULL;
+ }
+
+ buf = MEM_mallocN(size, "file_as_lines");
+ if (buf) {
+ size_t i, last = 0;
+
+ /*
+ * size = because on win32 reading
+ * all the bytes in the file will return
+ * less bytes because of `CRNL` changes.
+ */
+ size = fread(buf, 1, size, fp);
+ for (i = 0; i <= size; i++) {
+ if (i == size || buf[i] == '\n') {
+ char *line = BLI_strdupn(&buf[last], i - last);
+ BLI_linklist_append(&lines, line);
+ last = i + 1;
+ }
+ }
+
+ MEM_freeN(buf);
+ }
+
+ fclose(fp);
+
+ return lines.list;
}
/*
@@ -416,36 +415,36 @@ LinkNode *BLI_file_read_as_lines(const char *name)
*/
void BLI_file_free_lines(LinkNode *lines)
{
- BLI_linklist_freeN(lines);
+ BLI_linklist_freeN(lines);
}
/** is file1 older then file2 */
bool BLI_file_older(const char *file1, const char *file2)
{
#ifdef WIN32
- struct _stat st1, st2;
+ struct _stat st1, st2;
- UTF16_ENCODE(file1);
- UTF16_ENCODE(file2);
+ UTF16_ENCODE(file1);
+ UTF16_ENCODE(file2);
- if (_wstat(file1_16, &st1)) {
- return false;
- }
- if (_wstat(file2_16, &st2)) {
- return false;
- }
+ if (_wstat(file1_16, &st1)) {
+ return false;
+ }
+ if (_wstat(file2_16, &st2)) {
+ return false;
+ }
- UTF16_UN_ENCODE(file2);
- UTF16_UN_ENCODE(file1);
+ UTF16_UN_ENCODE(file2);
+ UTF16_UN_ENCODE(file1);
#else
- struct stat st1, st2;
-
- if (stat(file1, &st1)) {
- return false;
- }
- if (stat(file2, &st2)) {
- return false;
- }
+ struct stat st1, st2;
+
+ if (stat(file1, &st1)) {
+ return false;
+ }
+ if (stat(file2, &st2)) {
+ return false;
+ }
#endif
- return (st1.st_mtime < st2.st_mtime);
+ return (st1.st_mtime < st2.st_mtime);
}
diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c
index dfb32e5b76c..01cb635b044 100644
--- a/source/blender/blenlib/intern/string.c
+++ b/source/blender/blenlib/intern/string.c
@@ -21,7 +21,6 @@
* \ingroup bli
*/
-
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
@@ -52,11 +51,11 @@
*/
char *BLI_strdupn(const char *str, const size_t len)
{
- char *n = MEM_mallocN(len + 1, "strdup");
- memcpy(n, str, len);
- n[len] = '\0';
+ char *n = MEM_mallocN(len + 1, "strdup");
+ memcpy(n, str, len);
+ n[len] = '\0';
- return n;
+ return n;
}
/**
@@ -68,7 +67,7 @@ char *BLI_strdupn(const char *str, const size_t len)
*/
char *BLI_strdup(const char *str)
{
- return BLI_strdupn(str, strlen(str));
+ return BLI_strdupn(str, strlen(str));
}
/**
@@ -79,18 +78,19 @@ char *BLI_strdup(const char *str)
*/
char *BLI_strdupcat(const char *__restrict str1, const char *__restrict str2)
{
- /* include the NULL terminator of str2 only */
- const size_t str1_len = strlen(str1);
- const size_t str2_len = strlen(str2) + 1;
- char *str, *s;
+ /* include the NULL terminator of str2 only */
+ const size_t str1_len = strlen(str1);
+ const size_t str2_len = strlen(str2) + 1;
+ char *str, *s;
- str = MEM_mallocN(str1_len + str2_len, "strdupcat");
- s = str;
+ str = MEM_mallocN(str1_len + str2_len, "strdupcat");
+ s = str;
- memcpy(s, str1, str1_len); s += str1_len;
- memcpy(s, str2, str2_len);
+ memcpy(s, str1, str1_len);
+ s += str1_len;
+ memcpy(s, str2, str2_len);
- return str;
+ return str;
}
/**
@@ -105,16 +105,16 @@ char *BLI_strdupcat(const char *__restrict str1, const char *__restrict str2)
*/
char *BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy)
{
- size_t srclen = BLI_strnlen(src, maxncpy - 1);
- BLI_assert(maxncpy != 0);
+ size_t srclen = BLI_strnlen(src, maxncpy - 1);
+ BLI_assert(maxncpy != 0);
#ifdef DEBUG_STRSIZE
- memset(dst, 0xff, sizeof(*dst) * maxncpy);
+ memset(dst, 0xff, sizeof(*dst) * maxncpy);
#endif
- memcpy(dst, src, srclen);
- dst[srclen] = '\0';
- return dst;
+ memcpy(dst, src, srclen);
+ dst[srclen] = '\0';
+ return dst;
}
/**
@@ -126,43 +126,46 @@ char *BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t
* \param maxncpy: Maximum number of characters to copy (generally the size of dst)
* \retval Returns dst
*/
-char *BLI_strncpy_ensure_pad(char *__restrict dst, const char *__restrict src, const char pad, size_t maxncpy)
+char *BLI_strncpy_ensure_pad(char *__restrict dst,
+ const char *__restrict src,
+ const char pad,
+ size_t maxncpy)
{
- BLI_assert(maxncpy != 0);
+ BLI_assert(maxncpy != 0);
#ifdef DEBUG_STRSIZE
- memset(dst, 0xff, sizeof(*dst) * maxncpy);
+ memset(dst, 0xff, sizeof(*dst) * maxncpy);
#endif
- if (src[0] == '\0') {
- dst[0] = '\0';
- }
- else {
- /* Add heading/trailing wildcards if needed. */
- size_t idx = 0;
- size_t srclen;
-
- if (src[idx] != pad) {
- dst[idx++] = pad;
- maxncpy--;
- }
- maxncpy--; /* trailing '\0' */
-
- srclen = BLI_strnlen(src, maxncpy);
- if ((src[srclen - 1] != pad) && (srclen == maxncpy)) {
- srclen--;
- }
-
- memcpy(&dst[idx], src, srclen);
- idx += srclen;
-
- if (dst[idx - 1] != pad) {
- dst[idx++] = pad;
- }
- dst[idx] = '\0';
- }
-
- return dst;
+ if (src[0] == '\0') {
+ dst[0] = '\0';
+ }
+ else {
+ /* Add heading/trailing wildcards if needed. */
+ size_t idx = 0;
+ size_t srclen;
+
+ if (src[idx] != pad) {
+ dst[idx++] = pad;
+ maxncpy--;
+ }
+ maxncpy--; /* trailing '\0' */
+
+ srclen = BLI_strnlen(src, maxncpy);
+ if ((src[srclen - 1] != pad) && (srclen == maxncpy)) {
+ srclen--;
+ }
+
+ memcpy(&dst[idx], src, srclen);
+ idx += srclen;
+
+ if (dst[idx - 1] != pad) {
+ dst[idx++] = pad;
+ }
+ dst[idx] = '\0';
+ }
+
+ return dst;
}
/**
@@ -180,70 +183,76 @@ char *BLI_strncpy_ensure_pad(char *__restrict dst, const char *__restrict src, c
*/
size_t BLI_strncpy_rlen(char *__restrict dst, const char *__restrict src, const size_t maxncpy)
{
- size_t srclen = BLI_strnlen(src, maxncpy - 1);
- BLI_assert(maxncpy != 0);
+ size_t srclen = BLI_strnlen(src, maxncpy - 1);
+ BLI_assert(maxncpy != 0);
#ifdef DEBUG_STRSIZE
- memset(dst, 0xff, sizeof(*dst) * maxncpy);
+ memset(dst, 0xff, sizeof(*dst) * maxncpy);
#endif
- memcpy(dst, src, srclen);
- dst[srclen] = '\0';
- return srclen;
+ memcpy(dst, src, srclen);
+ dst[srclen] = '\0';
+ return srclen;
}
size_t BLI_strcpy_rlen(char *__restrict dst, const char *__restrict src)
{
- size_t srclen = strlen(src);
- memcpy(dst, src, srclen + 1);
- return srclen;
+ size_t srclen = strlen(src);
+ memcpy(dst, src, srclen + 1);
+ return srclen;
}
/**
* Portable replacement for `vsnprintf`.
*/
-size_t BLI_vsnprintf(char *__restrict buffer, size_t maxncpy, const char *__restrict format, va_list arg)
+size_t BLI_vsnprintf(char *__restrict buffer,
+ size_t maxncpy,
+ const char *__restrict format,
+ va_list arg)
{
- size_t n;
+ size_t n;
- BLI_assert(buffer != NULL);
- BLI_assert(maxncpy > 0);
- BLI_assert(format != NULL);
+ BLI_assert(buffer != NULL);
+ BLI_assert(maxncpy > 0);
+ BLI_assert(format != NULL);
- n = (size_t)vsnprintf(buffer, maxncpy, format, arg);
+ n = (size_t)vsnprintf(buffer, maxncpy, format, arg);
- if (n != -1 && n < maxncpy) {
- buffer[n] = '\0';
- }
- else {
- buffer[maxncpy - 1] = '\0';
- }
+ if (n != -1 && n < maxncpy) {
+ buffer[n] = '\0';
+ }
+ else {
+ buffer[maxncpy - 1] = '\0';
+ }
- return n;
+ return n;
}
/**
* A version of #BLI_vsnprintf that returns ``strlen(buffer)``
*/
-size_t BLI_vsnprintf_rlen(char *__restrict buffer, size_t maxncpy, const char *__restrict format, va_list arg)
+size_t BLI_vsnprintf_rlen(char *__restrict buffer,
+ size_t maxncpy,
+ const char *__restrict format,
+ va_list arg)
{
- size_t n;
+ size_t n;
- BLI_assert(buffer != NULL);
- BLI_assert(maxncpy > 0);
- BLI_assert(format != NULL);
+ BLI_assert(buffer != NULL);
+ BLI_assert(maxncpy > 0);
+ BLI_assert(format != NULL);
- n = (size_t)vsnprintf(buffer, maxncpy, format, arg);
+ n = (size_t)vsnprintf(buffer, maxncpy, format, arg);
- if (n != -1 && n < maxncpy) {
- /* pass */
- }
- else {
- n = maxncpy - 1;
- }
- buffer[n] = '\0';
+ if (n != -1 && n < maxncpy) {
+ /* pass */
+ }
+ else {
+ n = maxncpy - 1;
+ }
+ buffer[n] = '\0';
- return n;
+ return n;
}
/**
@@ -251,18 +260,18 @@ size_t BLI_vsnprintf_rlen(char *__restrict buffer, size_t maxncpy, const char *_
*/
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format, ...)
{
- size_t n;
- va_list arg;
+ size_t n;
+ va_list arg;
#ifdef DEBUG_STRSIZE
- memset(dst, 0xff, sizeof(*dst) * maxncpy);
+ memset(dst, 0xff, sizeof(*dst) * maxncpy);
#endif
- va_start(arg, format);
- n = BLI_vsnprintf(dst, maxncpy, format, arg);
- va_end(arg);
+ va_start(arg, format);
+ n = BLI_vsnprintf(dst, maxncpy, format, arg);
+ va_end(arg);
- return n;
+ return n;
}
/**
@@ -270,18 +279,18 @@ size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict
*/
size_t BLI_snprintf_rlen(char *__restrict dst, size_t maxncpy, const char *__restrict format, ...)
{
- size_t n;
- va_list arg;
+ size_t n;
+ va_list arg;
#ifdef DEBUG_STRSIZE
- memset(dst, 0xff, sizeof(*dst) * maxncpy);
+ memset(dst, 0xff, sizeof(*dst) * maxncpy);
#endif
- va_start(arg, format);
- n = BLI_vsnprintf_rlen(dst, maxncpy, format, arg);
- va_end(arg);
+ va_start(arg, format);
+ n = BLI_vsnprintf_rlen(dst, maxncpy, format, arg);
+ va_end(arg);
- return n;
+ return n;
}
/**
@@ -290,23 +299,22 @@ size_t BLI_snprintf_rlen(char *__restrict dst, size_t maxncpy, const char *__res
*/
char *BLI_sprintfN(const char *__restrict format, ...)
{
- DynStr *ds;
- va_list arg;
- char *n;
+ DynStr *ds;
+ va_list arg;
+ char *n;
- va_start(arg, format);
+ va_start(arg, format);
- ds = BLI_dynstr_new();
- BLI_dynstr_vappendf(ds, format, arg);
- n = BLI_dynstr_get_cstring(ds);
- BLI_dynstr_free(ds);
+ ds = BLI_dynstr_new();
+ BLI_dynstr_vappendf(ds, format, arg);
+ n = BLI_dynstr_get_cstring(ds);
+ BLI_dynstr_free(ds);
- va_end(arg);
+ va_end(arg);
- return n;
+ return n;
}
-
/* match pythons string escaping, assume double quotes - (")
* TODO: should be used to create RNA animation paths.
* TODO: support more fancy string escaping. current code is primitive
@@ -314,45 +322,45 @@ char *BLI_sprintfN(const char *__restrict format, ...)
* which is a useful reference. */
size_t BLI_strescape(char *__restrict dst, const char *__restrict src, const size_t maxncpy)
{
- size_t len = 0;
-
- BLI_assert(maxncpy != 0);
-
- while (len < maxncpy) {
- switch (*src) {
- case '\0':
- goto escape_finish;
- case '\\':
- case '"':
- ATTR_FALLTHROUGH;
-
- /* less common but should also be support */
- case '\t':
- case '\n':
- case '\r':
- if (len + 1 < maxncpy) {
- *dst++ = '\\';
- len++;
- }
- else {
- /* not enough space to escape */
- break;
- }
- ATTR_FALLTHROUGH;
- default:
- *dst = *src;
- break;
- }
- dst++;
- src++;
- len++;
- }
+ size_t len = 0;
+
+ BLI_assert(maxncpy != 0);
+
+ while (len < maxncpy) {
+ switch (*src) {
+ case '\0':
+ goto escape_finish;
+ case '\\':
+ case '"':
+ ATTR_FALLTHROUGH;
+
+ /* less common but should also be support */
+ case '\t':
+ case '\n':
+ case '\r':
+ if (len + 1 < maxncpy) {
+ *dst++ = '\\';
+ len++;
+ }
+ else {
+ /* not enough space to escape */
+ break;
+ }
+ ATTR_FALLTHROUGH;
+ default:
+ *dst = *src;
+ break;
+ }
+ dst++;
+ src++;
+ len++;
+ }
escape_finish:
- *dst = '\0';
+ *dst = '\0';
- return len;
+ return len;
}
/**
@@ -369,32 +377,32 @@ escape_finish:
*/
char *BLI_str_quoted_substrN(const char *__restrict str, const char *__restrict prefix)
{
- const char *startMatch, *endMatch;
-
- /* get the starting point (i.e. where prefix starts, and add prefixLen+1
- * to it to get be after the first " */
- startMatch = strstr(str, prefix);
- if (startMatch) {
- const size_t prefixLen = strlen(prefix);
- startMatch += prefixLen + 1;
- /* get the end point (i.e. where the next occurrence of " is after the starting point) */
-
- endMatch = startMatch;
- while ((endMatch = strchr(endMatch, '"'))) {
- if (LIKELY(*(endMatch - 1) != '\\')) {
- break;
- }
- else {
- endMatch++;
- }
- }
-
- if (endMatch) {
- /* return the slice indicated */
- return BLI_strdupn(startMatch, (size_t)(endMatch - startMatch));
- }
- }
- return BLI_strdupn("", 0);
+ const char *startMatch, *endMatch;
+
+ /* get the starting point (i.e. where prefix starts, and add prefixLen+1
+ * to it to get be after the first " */
+ startMatch = strstr(str, prefix);
+ if (startMatch) {
+ const size_t prefixLen = strlen(prefix);
+ startMatch += prefixLen + 1;
+ /* get the end point (i.e. where the next occurrence of " is after the starting point) */
+
+ endMatch = startMatch;
+ while ((endMatch = strchr(endMatch, '"'))) {
+ if (LIKELY(*(endMatch - 1) != '\\')) {
+ break;
+ }
+ else {
+ endMatch++;
+ }
+ }
+
+ if (endMatch) {
+ /* return the slice indicated */
+ return BLI_strdupn(startMatch, (size_t)(endMatch - startMatch));
+ }
+ }
+ return BLI_strdupn("", 0);
}
/**
@@ -410,63 +418,65 @@ char *BLI_str_quoted_substrN(const char *__restrict str, const char *__restrict
* \param substr_new: The text in the string to find and replace
* \retval Returns the duplicated string
*/
-char *BLI_str_replaceN(const char *__restrict str, const char *__restrict substr_old, const char *__restrict substr_new)
+char *BLI_str_replaceN(const char *__restrict str,
+ const char *__restrict substr_old,
+ const char *__restrict substr_new)
{
- DynStr *ds = NULL;
- size_t len_old = strlen(substr_old);
- const char *match;
-
- BLI_assert(substr_old[0] != '\0');
-
- /* while we can still find a match for the old substring that we're searching for,
- * keep dicing and replacing
- */
- while ((match = strstr(str, substr_old))) {
- /* the assembly buffer only gets created when we actually need to rebuild the string */
- if (ds == NULL) {
- ds = BLI_dynstr_new();
- }
-
- /* if the match position does not match the current position in the string,
- * copy the text up to this position and advance the current position in the string
- */
- if (str != match) {
- /* add the segment of the string from str to match to the buffer,
- * then restore the value at match */
- BLI_dynstr_nappend(ds, str, (match - str));
-
- /* now our current position should be set on the start of the match */
- str = match;
- }
-
- /* add the replacement text to the accumulation buffer */
- BLI_dynstr_append(ds, substr_new);
-
- /* advance the current position of the string up to the end of the replaced segment */
- str += len_old;
- }
-
- /* finish off and return a new string that has had all occurrences of */
- if (ds) {
- char *str_new;
-
- /* add what's left of the string to the assembly buffer
- * - we've been adjusting str to point at the end of the replaced segments
- */
- BLI_dynstr_append(ds, str);
-
- /* convert to new c-string (MEM_malloc'd), and free the buffer */
- str_new = BLI_dynstr_get_cstring(ds);
- BLI_dynstr_free(ds);
-
- return str_new;
- }
- else {
- /* just create a new copy of the entire string - we avoid going through the assembly buffer
- * for what should be a bit more efficiency...
- */
- return BLI_strdup(str);
- }
+ DynStr *ds = NULL;
+ size_t len_old = strlen(substr_old);
+ const char *match;
+
+ BLI_assert(substr_old[0] != '\0');
+
+ /* while we can still find a match for the old substring that we're searching for,
+ * keep dicing and replacing
+ */
+ while ((match = strstr(str, substr_old))) {
+ /* the assembly buffer only gets created when we actually need to rebuild the string */
+ if (ds == NULL) {
+ ds = BLI_dynstr_new();
+ }
+
+ /* if the match position does not match the current position in the string,
+ * copy the text up to this position and advance the current position in the string
+ */
+ if (str != match) {
+ /* add the segment of the string from str to match to the buffer,
+ * then restore the value at match */
+ BLI_dynstr_nappend(ds, str, (match - str));
+
+ /* now our current position should be set on the start of the match */
+ str = match;
+ }
+
+ /* add the replacement text to the accumulation buffer */
+ BLI_dynstr_append(ds, substr_new);
+
+ /* advance the current position of the string up to the end of the replaced segment */
+ str += len_old;
+ }
+
+ /* finish off and return a new string that has had all occurrences of */
+ if (ds) {
+ char *str_new;
+
+ /* add what's left of the string to the assembly buffer
+ * - we've been adjusting str to point at the end of the replaced segments
+ */
+ BLI_dynstr_append(ds, str);
+
+ /* convert to new c-string (MEM_malloc'd), and free the buffer */
+ str_new = BLI_dynstr_get_cstring(ds);
+ BLI_dynstr_free(ds);
+
+ return str_new;
+ }
+ else {
+ /* just create a new copy of the entire string - we avoid going through the assembly buffer
+ * for what should be a bit more efficiency...
+ */
+ return BLI_strdup(str);
+ }
}
/**
@@ -478,12 +488,12 @@ char *BLI_str_replaceN(const char *__restrict str, const char *__restrict substr
*/
void BLI_str_replace_char(char *str, char src, char dst)
{
- while (*str) {
- if (*str == src) {
- *str = dst;
- }
- str++;
- }
+ while (*str) {
+ if (*str == src) {
+ *str = dst;
+ }
+ str++;
+ }
}
/**
@@ -493,7 +503,7 @@ void BLI_str_replace_char(char *str, char src, char dst)
*/
int BLI_strcaseeq(const char *a, const char *b)
{
- return (BLI_strcasecmp(a, b) == 0);
+ return (BLI_strcasecmp(a, b) == 0);
}
/**
@@ -501,23 +511,23 @@ int BLI_strcaseeq(const char *a, const char *b)
*/
char *BLI_strcasestr(const char *s, const char *find)
{
- register char c, sc;
- register size_t len;
-
- if ((c = *find++) != 0) {
- c = tolower(c);
- len = strlen(find);
- do {
- do {
- if ((sc = *s++) == 0) {
- return (NULL);
- }
- sc = tolower(sc);
- } while (sc != c);
- } while (BLI_strncasecmp(s, find, len) != 0);
- s--;
- }
- return ((char *) s);
+ register char c, sc;
+ register size_t len;
+
+ if ((c = *find++) != 0) {
+ c = tolower(c);
+ len = strlen(find);
+ do {
+ do {
+ if ((sc = *s++) == 0) {
+ return (NULL);
+ }
+ sc = tolower(sc);
+ } while (sc != c);
+ } while (BLI_strncasecmp(s, find, len) != 0);
+ s--;
+ }
+ return ((char *)s);
}
/**
@@ -525,195 +535,195 @@ char *BLI_strcasestr(const char *s, const char *find)
*/
char *BLI_strncasestr(const char *s, const char *find, size_t len)
{
- register char c, sc;
-
- if ((c = *find++) != 0) {
- c = tolower(c);
- if (len > 1) {
- do {
- do {
- if ((sc = *s++) == 0) {
- return NULL;
- }
- sc = tolower(sc);
- } while (sc != c);
- } while (BLI_strncasecmp(s, find, len - 1) != 0);
- }
- else {
- {
- do {
- if ((sc = *s++) == 0) {
- return NULL;
- }
- sc = tolower(sc);
- } while (sc != c);
- }
- }
- s--;
- }
- return ((char *)s);
+ register char c, sc;
+
+ if ((c = *find++) != 0) {
+ c = tolower(c);
+ if (len > 1) {
+ do {
+ do {
+ if ((sc = *s++) == 0) {
+ return NULL;
+ }
+ sc = tolower(sc);
+ } while (sc != c);
+ } while (BLI_strncasecmp(s, find, len - 1) != 0);
+ }
+ else {
+ {
+ do {
+ if ((sc = *s++) == 0) {
+ return NULL;
+ }
+ sc = tolower(sc);
+ } while (sc != c);
+ }
+ }
+ s--;
+ }
+ return ((char *)s);
}
int BLI_strcasecmp(const char *s1, const char *s2)
{
- register int i;
- register char c1, c2;
-
- for (i = 0;; i++) {
- c1 = tolower(s1[i]);
- c2 = tolower(s2[i]);
-
- if (c1 < c2) {
- return -1;
- }
- else if (c1 > c2) {
- return 1;
- }
- else if (c1 == 0) {
- break;
- }
- }
-
- return 0;
+ register int i;
+ register char c1, c2;
+
+ for (i = 0;; i++) {
+ c1 = tolower(s1[i]);
+ c2 = tolower(s2[i]);
+
+ if (c1 < c2) {
+ return -1;
+ }
+ else if (c1 > c2) {
+ return 1;
+ }
+ else if (c1 == 0) {
+ break;
+ }
+ }
+
+ return 0;
}
int BLI_strncasecmp(const char *s1, const char *s2, size_t len)
{
- register size_t i;
- register char c1, c2;
-
- for (i = 0; i < len; i++) {
- c1 = tolower(s1[i]);
- c2 = tolower(s2[i]);
-
- if (c1 < c2) {
- return -1;
- }
- else if (c1 > c2) {
- return 1;
- }
- else if (c1 == 0) {
- break;
- }
- }
-
- return 0;
+ register size_t i;
+ register char c1, c2;
+
+ for (i = 0; i < len; i++) {
+ c1 = tolower(s1[i]);
+ c2 = tolower(s2[i]);
+
+ if (c1 < c2) {
+ return -1;
+ }
+ else if (c1 > c2) {
+ return 1;
+ }
+ else if (c1 == 0) {
+ break;
+ }
+ }
+
+ return 0;
}
/* compare number on the left size of the string */
static int left_number_strcmp(const char *s1, const char *s2, int *tiebreaker)
{
- const char *p1 = s1, *p2 = s2;
- int numdigit, numzero1, numzero2;
-
- /* count and skip leading zeros */
- for (numzero1 = 0; *p1 == '0'; numzero1++) {
- p1++;
- }
- for (numzero2 = 0; *p2 == '0'; numzero2++) {
- p2++;
- }
-
- /* find number of consecutive digits */
- for (numdigit = 0; ; numdigit++) {
- if (isdigit(*(p1 + numdigit)) && isdigit(*(p2 + numdigit))) {
- continue;
- }
- else if (isdigit(*(p1 + numdigit))) {
- return 1; /* s2 is bigger */
- }
- else if (isdigit(*(p2 + numdigit))) {
- return -1; /* s1 is bigger */
- }
- else {
- break;
- }
- }
-
- /* same number of digits, compare size of number */
- if (numdigit > 0) {
- int compare = (int)strncmp(p1, p2, (size_t)numdigit);
-
- if (compare != 0) {
- return compare;
- }
- }
-
- /* use number of leading zeros as tie breaker if still equal */
- if (*tiebreaker == 0) {
- if (numzero1 > numzero2) {
- *tiebreaker = 1;
- }
- else if (numzero1 < numzero2) {
- *tiebreaker = -1;
- }
- }
-
- return 0;
+ const char *p1 = s1, *p2 = s2;
+ int numdigit, numzero1, numzero2;
+
+ /* count and skip leading zeros */
+ for (numzero1 = 0; *p1 == '0'; numzero1++) {
+ p1++;
+ }
+ for (numzero2 = 0; *p2 == '0'; numzero2++) {
+ p2++;
+ }
+
+ /* find number of consecutive digits */
+ for (numdigit = 0;; numdigit++) {
+ if (isdigit(*(p1 + numdigit)) && isdigit(*(p2 + numdigit))) {
+ continue;
+ }
+ else if (isdigit(*(p1 + numdigit))) {
+ return 1; /* s2 is bigger */
+ }
+ else if (isdigit(*(p2 + numdigit))) {
+ return -1; /* s1 is bigger */
+ }
+ else {
+ break;
+ }
+ }
+
+ /* same number of digits, compare size of number */
+ if (numdigit > 0) {
+ int compare = (int)strncmp(p1, p2, (size_t)numdigit);
+
+ if (compare != 0) {
+ return compare;
+ }
+ }
+
+ /* use number of leading zeros as tie breaker if still equal */
+ if (*tiebreaker == 0) {
+ if (numzero1 > numzero2) {
+ *tiebreaker = 1;
+ }
+ else if (numzero1 < numzero2) {
+ *tiebreaker = -1;
+ }
+ }
+
+ return 0;
}
/* natural string compare, keeping numbers in order */
int BLI_natstrcmp(const char *s1, const char *s2)
{
- register int d1 = 0, d2 = 0;
- register char c1, c2;
- int tiebreaker = 0;
-
- /* if both chars are numeric, to a left_number_strcmp().
- * then increase string deltas as long they are
- * numeric, else do a tolower and char compare */
-
- while (1) {
- c1 = tolower(s1[d1]);
- c2 = tolower(s2[d2]);
-
- if (isdigit(c1) && isdigit(c2)) {
- int numcompare = left_number_strcmp(s1 + d1, s2 + d2, &tiebreaker);
-
- if (numcompare != 0) {
- return numcompare;
- }
-
- d1++;
- while (isdigit(s1[d1])) {
- d1++;
- }
- d2++;
- while (isdigit(s2[d2])) {
- d2++;
- }
-
- c1 = tolower(s1[d1]);
- c2 = tolower(s2[d2]);
- }
-
- /* first check for '.' so "foo.bar" comes before "foo 1.bar" */
- if (c1 == '.' && c2 != '.') {
- return -1;
- }
- if (c1 != '.' && c2 == '.') {
- return 1;
- }
- else if (c1 < c2) {
- return -1;
- }
- else if (c1 > c2) {
- return 1;
- }
- else if (c1 == 0) {
- break;
- }
- d1++;
- d2++;
- }
-
- if (tiebreaker) {
- return tiebreaker;
- }
-
- /* we might still have a different string because of lower/upper case, in
- * that case fall back to regular string comparison */
- return strcmp(s1, s2);
+ register int d1 = 0, d2 = 0;
+ register char c1, c2;
+ int tiebreaker = 0;
+
+ /* if both chars are numeric, to a left_number_strcmp().
+ * then increase string deltas as long they are
+ * numeric, else do a tolower and char compare */
+
+ while (1) {
+ c1 = tolower(s1[d1]);
+ c2 = tolower(s2[d2]);
+
+ if (isdigit(c1) && isdigit(c2)) {
+ int numcompare = left_number_strcmp(s1 + d1, s2 + d2, &tiebreaker);
+
+ if (numcompare != 0) {
+ return numcompare;
+ }
+
+ d1++;
+ while (isdigit(s1[d1])) {
+ d1++;
+ }
+ d2++;
+ while (isdigit(s2[d2])) {
+ d2++;
+ }
+
+ c1 = tolower(s1[d1]);
+ c2 = tolower(s2[d2]);
+ }
+
+ /* first check for '.' so "foo.bar" comes before "foo 1.bar" */
+ if (c1 == '.' && c2 != '.') {
+ return -1;
+ }
+ if (c1 != '.' && c2 == '.') {
+ return 1;
+ }
+ else if (c1 < c2) {
+ return -1;
+ }
+ else if (c1 > c2) {
+ return 1;
+ }
+ else if (c1 == 0) {
+ break;
+ }
+ d1++;
+ d2++;
+ }
+
+ if (tiebreaker) {
+ return tiebreaker;
+ }
+
+ /* we might still have a different string because of lower/upper case, in
+ * that case fall back to regular string comparison */
+ return strcmp(s1, s2);
}
/**
@@ -722,77 +732,77 @@ int BLI_natstrcmp(const char *s1, const char *s2)
*/
int BLI_strcmp_ignore_pad(const char *str1, const char *str2, const char pad)
{
- size_t str1_len, str2_len;
-
- while (*str1 == pad) {
- str1++;
- }
- while (*str2 == pad) {
- str2++;
- }
-
- str1_len = strlen(str1);
- str2_len = strlen(str2);
-
- while (str1_len && (str1[str1_len - 1] == pad)) {
- str1_len--;
- }
- while (str2_len && (str2[str2_len - 1] == pad)) {
- str2_len--;
- }
-
- if (str1_len == str2_len) {
- return strncmp(str1, str2, str2_len);
- }
- else if (str1_len > str2_len) {
- int ret = strncmp(str1, str2, str2_len);
- if (ret == 0) {
- ret = 1;
- }
- return ret;
- }
- else {
- int ret = strncmp(str1, str2, str1_len);
- if (ret == 0) {
- ret = -1;
- }
- return ret;
- }
+ size_t str1_len, str2_len;
+
+ while (*str1 == pad) {
+ str1++;
+ }
+ while (*str2 == pad) {
+ str2++;
+ }
+
+ str1_len = strlen(str1);
+ str2_len = strlen(str2);
+
+ while (str1_len && (str1[str1_len - 1] == pad)) {
+ str1_len--;
+ }
+ while (str2_len && (str2[str2_len - 1] == pad)) {
+ str2_len--;
+ }
+
+ if (str1_len == str2_len) {
+ return strncmp(str1, str2, str2_len);
+ }
+ else if (str1_len > str2_len) {
+ int ret = strncmp(str1, str2, str2_len);
+ if (ret == 0) {
+ ret = 1;
+ }
+ return ret;
+ }
+ else {
+ int ret = strncmp(str1, str2, str1_len);
+ if (ret == 0) {
+ ret = -1;
+ }
+ return ret;
+ }
}
/* determine the length of a fixed-size string */
size_t BLI_strnlen(const char *s, const size_t maxlen)
{
- size_t len;
-
- for (len = 0; len < maxlen; len++, s++) {
- if (!*s) {
- break;
- }
- }
- return len;
+ size_t len;
+
+ for (len = 0; len < maxlen; len++, s++) {
+ if (!*s) {
+ break;
+ }
+ }
+ return len;
}
void BLI_str_tolower_ascii(char *str, const size_t len)
{
- size_t i;
+ size_t i;
- for (i = 0; (i < len) && str[i]; i++) {
- if (str[i] >= 'A' && str[i] <= 'Z') {
- str[i] += 'a' - 'A';
- }
- }
+ for (i = 0; (i < len) && str[i]; i++) {
+ if (str[i] >= 'A' && str[i] <= 'Z') {
+ str[i] += 'a' - 'A';
+ }
+ }
}
void BLI_str_toupper_ascii(char *str, const size_t len)
{
- size_t i;
+ size_t i;
- for (i = 0; (i < len) && str[i]; i++) {
- if (str[i] >= 'a' && str[i] <= 'z') {
- str[i] -= 'a' - 'A';
- }
- }
+ for (i = 0; (i < len) && str[i]; i++) {
+ if (str[i] >= 'a' && str[i] <= 'z') {
+ str[i] -= 'a' - 'A';
+ }
+ }
}
/**
@@ -800,14 +810,14 @@ void BLI_str_toupper_ascii(char *str, const size_t len)
*/
void BLI_str_rstrip(char *str)
{
- for (int i = (int)strlen(str) - 1; i > 0; i--) {
- if (isspace(str[i])) {
- str[i] = '\0';
- }
- else {
- break;
- }
- }
+ for (int i = (int)strlen(str) - 1; i > 0; i--) {
+ if (isspace(str[i])) {
+ str[i] = '\0';
+ }
+ else {
+ break;
+ }
+ }
}
/**
@@ -821,22 +831,22 @@ void BLI_str_rstrip(char *str)
*/
int BLI_str_rstrip_float_zero(char *str, const char pad)
{
- char *p = strchr(str, '.');
- int totstrip = 0;
- if (p) {
- char *end_p;
- p++; /* position at first decimal place */
- end_p = p + (strlen(p) - 1); /* position at last character */
- if (end_p > p) {
- while (end_p != p && *end_p == '0') {
- *end_p = pad;
- end_p--;
- totstrip++;
- }
- }
- }
-
- return totstrip;
+ char *p = strchr(str, '.');
+ int totstrip = 0;
+ if (p) {
+ char *end_p;
+ p++; /* position at first decimal place */
+ end_p = p + (strlen(p) - 1); /* position at last character */
+ if (end_p > p) {
+ while (end_p != p && *end_p == '0') {
+ *end_p = pad;
+ end_p--;
+ totstrip++;
+ }
+ }
+ }
+
+ return totstrip;
}
/**
@@ -847,17 +857,19 @@ int BLI_str_rstrip_float_zero(char *str, const char pad)
* \param str_array_len: The length of the array, or -1 for a NULL-terminated array.
* \return The index of str in str_array or -1.
*/
-int BLI_str_index_in_array_n(const char *__restrict str, const char **__restrict str_array, const int str_array_len)
+int BLI_str_index_in_array_n(const char *__restrict str,
+ const char **__restrict str_array,
+ const int str_array_len)
{
- int index;
- const char **str_iter = str_array;
-
- for (index = 0; index < str_array_len; str_iter++, index++) {
- if (STREQ(str, *str_iter)) {
- return index;
- }
- }
- return -1;
+ int index;
+ const char **str_iter = str_array;
+
+ for (index = 0; index < str_array_len; str_iter++, index++) {
+ if (STREQ(str, *str_iter)) {
+ return index;
+ }
+ }
+ return -1;
}
/**
@@ -869,31 +881,31 @@ int BLI_str_index_in_array_n(const char *__restrict str, const char **__restrict
*/
int BLI_str_index_in_array(const char *__restrict str, const char **__restrict str_array)
{
- int index;
- const char **str_iter = str_array;
-
- for (index = 0; *str_iter; str_iter++, index++) {
- if (STREQ(str, *str_iter)) {
- return index;
- }
- }
- return -1;
+ int index;
+ const char **str_iter = str_array;
+
+ for (index = 0; *str_iter; str_iter++, index++) {
+ if (STREQ(str, *str_iter)) {
+ return index;
+ }
+ }
+ return -1;
}
bool BLI_strn_endswith(const char *__restrict str, const char *__restrict end, size_t slength)
{
- size_t elength = strlen(end);
-
- if (elength < slength) {
- const char *iter = &str[slength - elength];
- while (*iter) {
- if (*iter++ != *end++) {
- return false;
- }
- }
- return true;
- }
- return false;
+ size_t elength = strlen(end);
+
+ if (elength < slength) {
+ const char *iter = &str[slength - elength];
+ while (*iter) {
+ if (*iter++ != *end++) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
}
/**
@@ -903,10 +915,10 @@ bool BLI_strn_endswith(const char *__restrict str, const char *__restrict end, s
* \param end: The string we look for at the end.
* \return If str ends with end.
*/
-bool BLI_str_endswith(const char *__restrict str, const char * __restrict end)
+bool BLI_str_endswith(const char *__restrict str, const char *__restrict end)
{
- const size_t slength = strlen(str);
- return BLI_strn_endswith(str, end, slength);
+ const size_t slength = strlen(str);
+ return BLI_strn_endswith(str, end, slength);
}
/**
@@ -920,7 +932,7 @@ bool BLI_str_endswith(const char *__restrict str, const char * __restrict end)
*/
size_t BLI_str_partition(const char *str, const char delim[], const char **sep, const char **suf)
{
- return BLI_str_partition_ex(str, NULL, delim, sep, suf, false);
+ return BLI_str_partition_ex(str, NULL, delim, sep, suf, false);
}
/**
@@ -934,7 +946,7 @@ size_t BLI_str_partition(const char *str, const char delim[], const char **sep,
*/
size_t BLI_str_rpartition(const char *str, const char delim[], const char **sep, const char **suf)
{
- return BLI_str_partition_ex(str, NULL, delim, sep, suf, true);
+ return BLI_str_partition_ex(str, NULL, delim, sep, suf, true);
}
/**
@@ -948,74 +960,78 @@ size_t BLI_str_rpartition(const char *str, const char delim[], const char **sep,
* \param from_right: If %true, search from the right of \a str, else, search from its left.
* \return The length of the prefix (i.e. *sep - str).
*/
-size_t BLI_str_partition_ex(
- const char *str, const char *end, const char delim[], const char **sep, const char **suf, const bool from_right)
+size_t BLI_str_partition_ex(const char *str,
+ const char *end,
+ const char delim[],
+ const char **sep,
+ const char **suf,
+ const bool from_right)
{
- const char *d;
- char *(*func)(const char *str, int c) = from_right ? strrchr : strchr;
-
- BLI_assert(end == NULL || end > str);
-
- *sep = *suf = NULL;
-
- for (d = delim; *d != '\0'; ++d) {
- const char *tmp;
-
- if (end) {
- if (from_right) {
- for (tmp = end - 1; (tmp >= str) && (*tmp != *d); tmp--) {
- /* pass */
- }
- if (tmp < str) {
- tmp = NULL;
- }
- }
- else {
- tmp = func(str, *d);
- if (tmp >= end) {
- tmp = NULL;
- }
- }
- }
- else {
- tmp = func(str, *d);
- }
-
- if (tmp && (from_right ? (*sep < tmp) : (!*sep || *sep > tmp))) {
- *sep = tmp;
- }
- }
-
- if (*sep) {
- *suf = *sep + 1;
- return (size_t)(*sep - str);
- }
-
- return end ? (size_t)(end - str) : strlen(str);
+ const char *d;
+ char *(*func)(const char *str, int c) = from_right ? strrchr : strchr;
+
+ BLI_assert(end == NULL || end > str);
+
+ *sep = *suf = NULL;
+
+ for (d = delim; *d != '\0'; ++d) {
+ const char *tmp;
+
+ if (end) {
+ if (from_right) {
+ for (tmp = end - 1; (tmp >= str) && (*tmp != *d); tmp--) {
+ /* pass */
+ }
+ if (tmp < str) {
+ tmp = NULL;
+ }
+ }
+ else {
+ tmp = func(str, *d);
+ if (tmp >= end) {
+ tmp = NULL;
+ }
+ }
+ }
+ else {
+ tmp = func(str, *d);
+ }
+
+ if (tmp && (from_right ? (*sep < tmp) : (!*sep || *sep > tmp))) {
+ *sep = tmp;
+ }
+ }
+
+ if (*sep) {
+ *suf = *sep + 1;
+ return (size_t)(*sep - str);
+ }
+
+ return end ? (size_t)(end - str) : strlen(str);
}
static size_t BLI_str_format_int_grouped_ex(char src[16], char dst[16], int num_len)
{
- char *p_src = src;
- char *p_dst = dst;
-
- const char separator = ',';
- int commas;
-
- if (*p_src == '-') {
- *p_dst++ = *p_src++;
- num_len--;
- }
-
- for (commas = 2 - num_len % 3; *p_src; commas = (commas + 1) % 3) {
- *p_dst++ = *p_src++;
- if (commas == 1) {
- *p_dst++ = separator;
- }
- }
- *--p_dst = '\0';
-
- return (size_t)(p_dst - dst);
+ char *p_src = src;
+ char *p_dst = dst;
+
+ const char separator = ',';
+ int commas;
+
+ if (*p_src == '-') {
+ *p_dst++ = *p_src++;
+ num_len--;
+ }
+
+ for (commas = 2 - num_len % 3; *p_src; commas = (commas + 1) % 3) {
+ *p_dst++ = *p_src++;
+ if (commas == 1) {
+ *p_dst++ = separator;
+ }
+ }
+ *--p_dst = '\0';
+
+ return (size_t)(p_dst - dst);
}
/**
@@ -1028,10 +1044,10 @@ static size_t BLI_str_format_int_grouped_ex(char src[16], char dst[16], int num_
*/
size_t BLI_str_format_int_grouped(char dst[16], int num)
{
- char src[16];
- int num_len = sprintf(src, "%d", num);
+ char src[16];
+ int num_len = sprintf(src, "%d", num);
- return BLI_str_format_int_grouped_ex(src, dst, num_len);
+ return BLI_str_format_int_grouped_ex(src, dst, num_len);
}
/**
@@ -1044,12 +1060,12 @@ size_t BLI_str_format_int_grouped(char dst[16], int num)
*/
size_t BLI_str_format_uint64_grouped(char dst[16], uint64_t num)
{
- /* NOTE: Buffer to hold maximum unsigned int64, which is 1.8e+19. but
- * we also need space for commas and null-terminator. */
- char src[27];
- int num_len = sprintf(src, "%"PRIu64"", num);
+ /* NOTE: Buffer to hold maximum unsigned int64, which is 1.8e+19. but
+ * we also need space for commas and null-terminator. */
+ char src[27];
+ int num_len = sprintf(src, "%" PRIu64 "", num);
- return BLI_str_format_int_grouped_ex(src, dst, num_len);
+ return BLI_str_format_int_grouped_ex(src, dst, num_len);
}
/**
@@ -1063,28 +1079,28 @@ size_t BLI_str_format_uint64_grouped(char dst[16], uint64_t num)
*/
void BLI_str_format_byte_unit(char dst[15], long long int bytes, const bool base_10)
{
- double bytes_converted = bytes;
- int order = 0;
- int decimals;
- const int base = base_10 ? 1000 : 1024;
- const char *units_base_10[] = {"B", "KB", "MB", "GB", "TB", "PB"};
- const char *units_base_2[] = {"B", "KiB", "MiB", "GiB", "TiB", "PiB"};
- const int tot_units = ARRAY_SIZE(units_base_2);
-
- BLI_STATIC_ASSERT(ARRAY_SIZE(units_base_2) == ARRAY_SIZE(units_base_10), "array size mismatch");
-
- while ((ABS(bytes_converted) >= base) && ((order + 1) < tot_units)) {
- bytes_converted /= base;
- order++;
- }
- decimals = MAX2(order - 1, 0);
-
- /* Format value first, stripping away floating zeroes. */
- const size_t dst_len = 15;
- size_t len = BLI_snprintf_rlen(dst, dst_len, "%.*f", decimals, bytes_converted);
- len -= (size_t)BLI_str_rstrip_float_zero(dst, '\0');
- dst[len++] = ' ';
- BLI_strncpy(dst + len, base_10 ? units_base_10[order] : units_base_2[order], dst_len - len);
+ double bytes_converted = bytes;
+ int order = 0;
+ int decimals;
+ const int base = base_10 ? 1000 : 1024;
+ const char *units_base_10[] = {"B", "KB", "MB", "GB", "TB", "PB"};
+ const char *units_base_2[] = {"B", "KiB", "MiB", "GiB", "TiB", "PiB"};
+ const int tot_units = ARRAY_SIZE(units_base_2);
+
+ BLI_STATIC_ASSERT(ARRAY_SIZE(units_base_2) == ARRAY_SIZE(units_base_10), "array size mismatch");
+
+ while ((ABS(bytes_converted) >= base) && ((order + 1) < tot_units)) {
+ bytes_converted /= base;
+ order++;
+ }
+ decimals = MAX2(order - 1, 0);
+
+ /* Format value first, stripping away floating zeroes. */
+ const size_t dst_len = 15;
+ size_t len = BLI_snprintf_rlen(dst, dst_len, "%.*f", decimals, bytes_converted);
+ len -= (size_t)BLI_str_rstrip_float_zero(dst, '\0');
+ dst[len++] = ' ';
+ BLI_strncpy(dst + len, base_10 ? units_base_10[order] : units_base_2[order], dst_len - len);
}
/**
@@ -1098,37 +1114,36 @@ void BLI_str_format_byte_unit(char dst[15], long long int bytes, const bool base
* \return The number of words found in \a str
*/
int BLI_string_find_split_words(
- const char *str, const size_t len,
- const char delim, int r_words[][2], int words_max)
+ const char *str, const size_t len, const char delim, int r_words[][2], int words_max)
{
- int n = 0, i;
- bool charsearch = true;
-
- /* Skip leading spaces */
- for (i = 0; (i < len) && (str[i] != '\0'); i++) {
- if (str[i] != delim) {
- break;
- }
- }
-
- for (; (i < len) && (str[i] != '\0') && (n < words_max); i++) {
- if ((str[i] != delim) && (charsearch == true)) {
- r_words[n][0] = i;
- charsearch = false;
- }
- else {
- if ((str[i] == delim) && (charsearch == false)) {
- r_words[n][1] = i - r_words[n][0];
- n++;
- charsearch = true;
- }
- }
- }
-
- if (charsearch == false) {
- r_words[n][1] = i - r_words[n][0];
- n++;
- }
-
- return n;
+ int n = 0, i;
+ bool charsearch = true;
+
+ /* Skip leading spaces */
+ for (i = 0; (i < len) && (str[i] != '\0'); i++) {
+ if (str[i] != delim) {
+ break;
+ }
+ }
+
+ for (; (i < len) && (str[i] != '\0') && (n < words_max); i++) {
+ if ((str[i] != delim) && (charsearch == true)) {
+ r_words[n][0] = i;
+ charsearch = false;
+ }
+ else {
+ if ((str[i] == delim) && (charsearch == false)) {
+ r_words[n][1] = i - r_words[n][0];
+ n++;
+ charsearch = true;
+ }
+ }
+ }
+
+ if (charsearch == false) {
+ r_words[n][1] = i - r_words[n][0];
+ n++;
+ }
+
+ return n;
}
diff --git a/source/blender/blenlib/intern/string_cursor_utf8.c b/source/blender/blenlib/intern/string_cursor_utf8.c
index 8839661dea2..1526a052aad 100644
--- a/source/blender/blenlib/intern/string_cursor_utf8.c
+++ b/source/blender/blenlib/intern/string_cursor_utf8.c
@@ -34,182 +34,181 @@
#endif
typedef enum eStrCursorDelimType {
- STRCUR_DELIM_NONE,
- STRCUR_DELIM_ALPHANUMERIC,
- STRCUR_DELIM_PUNCT,
- STRCUR_DELIM_BRACE,
- STRCUR_DELIM_OPERATOR,
- STRCUR_DELIM_QUOTE,
- STRCUR_DELIM_WHITESPACE,
- STRCUR_DELIM_OTHER,
+ STRCUR_DELIM_NONE,
+ STRCUR_DELIM_ALPHANUMERIC,
+ STRCUR_DELIM_PUNCT,
+ STRCUR_DELIM_BRACE,
+ STRCUR_DELIM_OPERATOR,
+ STRCUR_DELIM_QUOTE,
+ STRCUR_DELIM_WHITESPACE,
+ STRCUR_DELIM_OTHER,
} eStrCursorDelimType;
static eStrCursorDelimType cursor_delim_type_unicode(const uint uch)
{
- switch (uch) {
- case ',':
- case '.':
- return STRCUR_DELIM_PUNCT;
+ switch (uch) {
+ case ',':
+ case '.':
+ return STRCUR_DELIM_PUNCT;
- case '{':
- case '}':
- case '[':
- case ']':
- case '(':
- case ')':
- return STRCUR_DELIM_BRACE;
+ case '{':
+ case '}':
+ case '[':
+ case ']':
+ case '(':
+ case ')':
+ return STRCUR_DELIM_BRACE;
- case '+':
- case '-':
- case '=':
- case '~':
- case '%':
- case '/':
- case '<':
- case '>':
- case '^':
- case '*':
- case '&':
- case '|':
- return STRCUR_DELIM_OPERATOR;
+ case '+':
+ case '-':
+ case '=':
+ case '~':
+ case '%':
+ case '/':
+ case '<':
+ case '>':
+ case '^':
+ case '*':
+ case '&':
+ case '|':
+ return STRCUR_DELIM_OPERATOR;
- case '\'':
- case '\"':
- return STRCUR_DELIM_QUOTE;
+ case '\'':
+ case '\"':
+ return STRCUR_DELIM_QUOTE;
- case ' ':
- case '\t':
- case '\n':
- return STRCUR_DELIM_WHITESPACE;
+ case ' ':
+ case '\t':
+ case '\n':
+ return STRCUR_DELIM_WHITESPACE;
- case '\\':
- case '@':
- case '#':
- case '$':
- case ':':
- case ';':
- case '?':
- case '!':
- case 0xA3: /* pound */
- case 0x80: /* euro */
- /* case '_': *//* special case, for python */
- return STRCUR_DELIM_OTHER;
+ case '\\':
+ case '@':
+ case '#':
+ case '$':
+ case ':':
+ case ';':
+ case '?':
+ case '!':
+ case 0xA3: /* pound */
+ case 0x80: /* euro */
+ /* case '_': */ /* special case, for python */
+ return STRCUR_DELIM_OTHER;
- default:
- break;
- }
- return STRCUR_DELIM_ALPHANUMERIC; /* Not quite true, but ok for now */
+ default:
+ break;
+ }
+ return STRCUR_DELIM_ALPHANUMERIC; /* Not quite true, but ok for now */
}
static eStrCursorDelimType cursor_delim_type_utf8(const char *ch_utf8)
{
- /* for full unicode support we really need to have large lookup tables to figure
- * out whats what in every possible char set - and python, glib both have these. */
- uint uch = BLI_str_utf8_as_unicode(ch_utf8);
- return cursor_delim_type_unicode(uch);
+ /* for full unicode support we really need to have large lookup tables to figure
+ * out whats what in every possible char set - and python, glib both have these. */
+ uint uch = BLI_str_utf8_as_unicode(ch_utf8);
+ return cursor_delim_type_unicode(uch);
}
bool BLI_str_cursor_step_next_utf8(const char *str, size_t maxlen, int *pos)
{
- const char *str_end = str + (maxlen + 1);
- const char *str_pos = str + (*pos);
- const char *str_next = BLI_str_find_next_char_utf8(str_pos, str_end);
- if (str_next) {
- (*pos) += (str_next - str_pos);
- if ((*pos) > (int)maxlen) {
- (*pos) = (int)maxlen;
- }
- return true;
- }
+ const char *str_end = str + (maxlen + 1);
+ const char *str_pos = str + (*pos);
+ const char *str_next = BLI_str_find_next_char_utf8(str_pos, str_end);
+ if (str_next) {
+ (*pos) += (str_next - str_pos);
+ if ((*pos) > (int)maxlen) {
+ (*pos) = (int)maxlen;
+ }
+ return true;
+ }
- return false;
+ return false;
}
bool BLI_str_cursor_step_prev_utf8(const char *str, size_t UNUSED(maxlen), int *pos)
{
- if ((*pos) > 0) {
- const char *str_pos = str + (*pos);
- const char *str_prev = BLI_str_find_prev_char_utf8(str, str_pos);
- if (str_prev) {
- (*pos) -= (str_pos - str_prev);
- return true;
- }
- }
+ if ((*pos) > 0) {
+ const char *str_pos = str + (*pos);
+ const char *str_prev = BLI_str_find_prev_char_utf8(str, str_pos);
+ if (str_prev) {
+ (*pos) -= (str_pos - str_prev);
+ return true;
+ }
+ }
- return false;
+ return false;
}
-void BLI_str_cursor_step_utf8(
- const char *str, size_t maxlen,
- int *pos, eStrCursorJumpDirection direction,
- eStrCursorJumpType jump, bool use_init_step)
+void BLI_str_cursor_step_utf8(const char *str,
+ size_t maxlen,
+ int *pos,
+ eStrCursorJumpDirection direction,
+ eStrCursorJumpType jump,
+ bool use_init_step)
{
- const int pos_orig = *pos;
+ const int pos_orig = *pos;
- if (direction == STRCUR_DIR_NEXT) {
- if (use_init_step) {
- BLI_str_cursor_step_next_utf8(str, maxlen, pos);
- }
- else {
- BLI_assert(jump == STRCUR_JUMP_DELIM);
- }
+ if (direction == STRCUR_DIR_NEXT) {
+ if (use_init_step) {
+ BLI_str_cursor_step_next_utf8(str, maxlen, pos);
+ }
+ else {
+ BLI_assert(jump == STRCUR_JUMP_DELIM);
+ }
- if (jump != STRCUR_JUMP_NONE) {
- const eStrCursorDelimType delim_type =
- (*pos) < maxlen ? cursor_delim_type_utf8(&str[*pos]) : STRCUR_DELIM_NONE;
- /* jump between special characters (/,\,_,-, etc.),
- * look at function cursor_delim_type() for complete
- * list of special character, ctr -> */
- while ((*pos) < maxlen) {
- if (BLI_str_cursor_step_next_utf8(str, maxlen, pos)) {
- if ((jump != STRCUR_JUMP_ALL) &&
- (delim_type != cursor_delim_type_utf8(&str[*pos])))
- {
- break;
- }
- }
- else {
- break; /* unlikely but just in case */
- }
- }
- }
- }
- else if (direction == STRCUR_DIR_PREV) {
- if (use_init_step) {
- BLI_str_cursor_step_prev_utf8(str, maxlen, pos);
- }
- else {
- BLI_assert(jump == STRCUR_JUMP_DELIM);
- }
+ if (jump != STRCUR_JUMP_NONE) {
+ const eStrCursorDelimType delim_type = (*pos) < maxlen ? cursor_delim_type_utf8(&str[*pos]) :
+ STRCUR_DELIM_NONE;
+ /* jump between special characters (/,\,_,-, etc.),
+ * look at function cursor_delim_type() for complete
+ * list of special character, ctr -> */
+ while ((*pos) < maxlen) {
+ if (BLI_str_cursor_step_next_utf8(str, maxlen, pos)) {
+ if ((jump != STRCUR_JUMP_ALL) && (delim_type != cursor_delim_type_utf8(&str[*pos]))) {
+ break;
+ }
+ }
+ else {
+ break; /* unlikely but just in case */
+ }
+ }
+ }
+ }
+ else if (direction == STRCUR_DIR_PREV) {
+ if (use_init_step) {
+ BLI_str_cursor_step_prev_utf8(str, maxlen, pos);
+ }
+ else {
+ BLI_assert(jump == STRCUR_JUMP_DELIM);
+ }
- if (jump != STRCUR_JUMP_NONE) {
- const eStrCursorDelimType delim_type =
- (*pos) > 0 ? cursor_delim_type_utf8(&str[(*pos) - 1]) : STRCUR_DELIM_NONE;
- /* jump between special characters (/,\,_,-, etc.),
- * look at function cursor_delim_type() for complete
- * list of special character, ctr -> */
- while ((*pos) > 0) {
- const int pos_prev = *pos;
- if (BLI_str_cursor_step_prev_utf8(str, maxlen, pos)) {
- if ((jump != STRCUR_JUMP_ALL) &&
- (delim_type != cursor_delim_type_utf8(&str[*pos])))
- {
- /* left only: compensate for index/change in direction */
- if ((pos_orig - (*pos)) >= 1) {
- *pos = pos_prev;
- }
- break;
- }
- }
- else {
- break;
- }
- }
- }
- }
- else {
- BLI_assert(0);
- }
+ if (jump != STRCUR_JUMP_NONE) {
+ const eStrCursorDelimType delim_type = (*pos) > 0 ?
+ cursor_delim_type_utf8(&str[(*pos) - 1]) :
+ STRCUR_DELIM_NONE;
+ /* jump between special characters (/,\,_,-, etc.),
+ * look at function cursor_delim_type() for complete
+ * list of special character, ctr -> */
+ while ((*pos) > 0) {
+ const int pos_prev = *pos;
+ if (BLI_str_cursor_step_prev_utf8(str, maxlen, pos)) {
+ if ((jump != STRCUR_JUMP_ALL) && (delim_type != cursor_delim_type_utf8(&str[*pos]))) {
+ /* left only: compensate for index/change in direction */
+ if ((pos_orig - (*pos)) >= 1) {
+ *pos = pos_prev;
+ }
+ break;
+ }
+ }
+ else {
+ break;
+ }
+ }
+ }
+ }
+ else {
+ BLI_assert(0);
+ }
}
/* wchar_t version of BLI_str_cursor_step_utf8 (keep in sync!)
@@ -219,91 +218,93 @@ void BLI_str_cursor_step_utf8(
/* helper funcs so we can match BLI_str_cursor_step_utf8 */
static bool wchar_t_step_next(const wchar_t *UNUSED(str), size_t maxlen, int *pos)
{
- if ((*pos) >= (int)maxlen) {
- return false;
- }
- (*pos)++;
- return true;
+ if ((*pos) >= (int)maxlen) {
+ return false;
+ }
+ (*pos)++;
+ return true;
}
static bool wchar_t_step_prev(const wchar_t *UNUSED(str), size_t UNUSED(maxlen), int *pos)
{
- if ((*pos) <= 0) {
- return false;
- }
- (*pos)--;
- return true;
+ if ((*pos) <= 0) {
+ return false;
+ }
+ (*pos)--;
+ return true;
}
-void BLI_str_cursor_step_wchar(
- const wchar_t *str, size_t maxlen,
- int *pos, eStrCursorJumpDirection direction,
- eStrCursorJumpType jump, bool use_init_step)
+void BLI_str_cursor_step_wchar(const wchar_t *str,
+ size_t maxlen,
+ int *pos,
+ eStrCursorJumpDirection direction,
+ eStrCursorJumpType jump,
+ bool use_init_step)
{
- const int pos_orig = *pos;
+ const int pos_orig = *pos;
- if (direction == STRCUR_DIR_NEXT) {
- if (use_init_step) {
- wchar_t_step_next(str, maxlen, pos);
- }
- else {
- BLI_assert(jump == STRCUR_JUMP_DELIM);
- }
+ if (direction == STRCUR_DIR_NEXT) {
+ if (use_init_step) {
+ wchar_t_step_next(str, maxlen, pos);
+ }
+ else {
+ BLI_assert(jump == STRCUR_JUMP_DELIM);
+ }
- if (jump != STRCUR_JUMP_NONE) {
- const eStrCursorDelimType delim_type =
- (*pos) < maxlen ? cursor_delim_type_unicode((uint)str[*pos]) : STRCUR_DELIM_NONE;
- /* jump between special characters (/,\,_,-, etc.),
- * look at function cursor_delim_type_unicode() for complete
- * list of special character, ctr -> */
- while ((*pos) < maxlen) {
- if (wchar_t_step_next(str, maxlen, pos)) {
- if ((jump != STRCUR_JUMP_ALL) &&
- (delim_type != cursor_delim_type_unicode((uint)str[*pos])))
- {
- break;
- }
- }
- else {
- break; /* unlikely but just in case */
- }
- }
- }
- }
- else if (direction == STRCUR_DIR_PREV) {
- if (use_init_step) {
- wchar_t_step_prev(str, maxlen, pos);
- }
- else {
- BLI_assert(jump == STRCUR_JUMP_DELIM);
- }
+ if (jump != STRCUR_JUMP_NONE) {
+ const eStrCursorDelimType delim_type = (*pos) < maxlen ?
+ cursor_delim_type_unicode((uint)str[*pos]) :
+ STRCUR_DELIM_NONE;
+ /* jump between special characters (/,\,_,-, etc.),
+ * look at function cursor_delim_type_unicode() for complete
+ * list of special character, ctr -> */
+ while ((*pos) < maxlen) {
+ if (wchar_t_step_next(str, maxlen, pos)) {
+ if ((jump != STRCUR_JUMP_ALL) &&
+ (delim_type != cursor_delim_type_unicode((uint)str[*pos]))) {
+ break;
+ }
+ }
+ else {
+ break; /* unlikely but just in case */
+ }
+ }
+ }
+ }
+ else if (direction == STRCUR_DIR_PREV) {
+ if (use_init_step) {
+ wchar_t_step_prev(str, maxlen, pos);
+ }
+ else {
+ BLI_assert(jump == STRCUR_JUMP_DELIM);
+ }
- if (jump != STRCUR_JUMP_NONE) {
- const eStrCursorDelimType delim_type =
- (*pos) > 0 ? cursor_delim_type_unicode((uint)str[(*pos) - 1]) : STRCUR_DELIM_NONE;
- /* jump between special characters (/,\,_,-, etc.),
- * look at function cursor_delim_type() for complete
- * list of special character, ctr -> */
- while ((*pos) > 0) {
- const int pos_prev = *pos;
- if (wchar_t_step_prev(str, maxlen, pos)) {
- if ((jump != STRCUR_JUMP_ALL) &&
- (delim_type != cursor_delim_type_unicode((uint)str[*pos])))
- {
- /* left only: compensate for index/change in direction */
- if ((pos_orig - (*pos)) >= 1) {
- *pos = pos_prev;
- }
- break;
- }
- }
- else {
- break;
- }
- }
- }
- }
- else {
- BLI_assert(0);
- }
+ if (jump != STRCUR_JUMP_NONE) {
+ const eStrCursorDelimType delim_type = (*pos) > 0 ?
+ cursor_delim_type_unicode((uint)str[(*pos) - 1]) :
+ STRCUR_DELIM_NONE;
+ /* jump between special characters (/,\,_,-, etc.),
+ * look at function cursor_delim_type() for complete
+ * list of special character, ctr -> */
+ while ((*pos) > 0) {
+ const int pos_prev = *pos;
+ if (wchar_t_step_prev(str, maxlen, pos)) {
+ if ((jump != STRCUR_JUMP_ALL) &&
+ (delim_type != cursor_delim_type_unicode((uint)str[*pos]))) {
+ /* left only: compensate for index/change in direction */
+ if ((pos_orig - (*pos)) >= 1) {
+ *pos = pos_prev;
+ }
+ break;
+ }
+ }
+ else {
+ break;
+ }
+ }
+ }
+ }
+ else {
+ BLI_assert(0);
+ }
}
diff --git a/source/blender/blenlib/intern/string_utf8.c b/source/blender/blenlib/intern/string_utf8.c
index 0c07d1c361a..01412416854 100644
--- a/source/blender/blenlib/intern/string_utf8.c
+++ b/source/blender/blenlib/intern/string_utf8.c
@@ -32,7 +32,7 @@
#include "BLI_utildefines.h"
-#include "BLI_string_utf8.h" /* own include */
+#include "BLI_string_utf8.h" /* own include */
#ifdef __GNUC__
# pragma GCC diagnostic error "-Wsign-conversion"
@@ -44,14 +44,14 @@
/* Note: last two values (0xfe and 0xff) are forbidden in utf-8,
* so they are considered 1 byte length too. */
static const size_t utf8_skip_data[256] = {
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 1, 1,
};
/* from libswish3, originally called u8_isvalid(),
@@ -70,97 +70,127 @@ static const size_t utf8_skip_data[256] = {
*/
ptrdiff_t BLI_utf8_invalid_byte(const char *str, size_t length)
{
- const unsigned char *p, *perr, *pend = (const unsigned char *)str + length;
- unsigned char c;
- int ab;
-
- for (p = (const unsigned char *)str; p < pend; p++, length--) {
- c = *p;
- perr = p; /* Erroneous char is always the first of an invalid utf8 sequence... */
- if (ELEM(c, 0xfe, 0xff, 0x00)) {
- /* Those three values are not allowed in utf8 string. */
- goto utf8_error;
- }
- if (c < 128) {
- continue;
- }
- if ((c & 0xc0) != 0xc0) {
- goto utf8_error;
- }
-
- /* Note that since we always increase p (and decrease length) by one byte in main loop,
- * we only add/subtract extra utf8 bytes in code below
- * (ab number, aka number of bytes remaining in the utf8 sequence after the initial one). */
- ab = (int)utf8_skip_data[c] - 1;
- if (length <= ab) {
- goto utf8_error;
- }
-
- /* Check top bits in the second byte */
- p++;
- length--;
- if ((*p & 0xc0) != 0x80) {
- goto utf8_error;
- }
-
- /* Check for overlong sequences for each different length */
- switch (ab) {
- case 1:
- /* Check for xx00 000x */
- if ((c & 0x3e) == 0) { goto utf8_error; }
- continue; /* We know there aren't any more bytes to check */
-
- case 2:
- /* Check for 1110 0000, xx0x xxxx */
- if (c == 0xe0 && (*p & 0x20) == 0) { goto utf8_error; }
- /* Some special cases, see section 5 of utf-8 decoder stress-test by Markus Kuhn
- * (https://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt). */
- /* From section 5.1 (and 5.2) */
- if (c == 0xed) {
- if (*p == 0xa0 && *(p + 1) == 0x80) { goto utf8_error; }
- if (*p == 0xad && *(p + 1) == 0xbf) { goto utf8_error; }
- if (*p == 0xae && *(p + 1) == 0x80) { goto utf8_error; }
- if (*p == 0xaf && *(p + 1) == 0xbf) { goto utf8_error; }
- if (*p == 0xb0 && *(p + 1) == 0x80) { goto utf8_error; }
- if (*p == 0xbe && *(p + 1) == 0x80) { goto utf8_error; }
- if (*p == 0xbf && *(p + 1) == 0xbf) { goto utf8_error; }
- }
- /* From section 5.3 */
- if (c == 0xef) {
- if (*p == 0xbf && *(p + 1) == 0xbe) { goto utf8_error; }
- if (*p == 0xbf && *(p + 1) == 0xbf) { goto utf8_error; }
- }
- break;
-
- case 3:
- /* Check for 1111 0000, xx00 xxxx */
- if (c == 0xf0 && (*p & 0x30) == 0) { goto utf8_error; }
- break;
-
- case 4:
- /* Check for 1111 1000, xx00 0xxx */
- if (c == 0xf8 && (*p & 0x38) == 0) { goto utf8_error; }
- break;
-
- case 5:
- /* Check for 1111 1100, xx00 00xx */
- if (c == 0xfc && (*p & 0x3c) == 0) { goto utf8_error; }
- break;
- }
-
- /* Check for valid bytes after the 2nd, if any; all must start 10 */
- while (--ab > 0) {
- p++;
- length--;
- if ((*p & 0xc0) != 0x80) { goto utf8_error; }
- }
- }
-
- return -1;
+ const unsigned char *p, *perr, *pend = (const unsigned char *)str + length;
+ unsigned char c;
+ int ab;
+
+ for (p = (const unsigned char *)str; p < pend; p++, length--) {
+ c = *p;
+ perr = p; /* Erroneous char is always the first of an invalid utf8 sequence... */
+ if (ELEM(c, 0xfe, 0xff, 0x00)) {
+ /* Those three values are not allowed in utf8 string. */
+ goto utf8_error;
+ }
+ if (c < 128) {
+ continue;
+ }
+ if ((c & 0xc0) != 0xc0) {
+ goto utf8_error;
+ }
+
+ /* Note that since we always increase p (and decrease length) by one byte in main loop,
+ * we only add/subtract extra utf8 bytes in code below
+ * (ab number, aka number of bytes remaining in the utf8 sequence after the initial one). */
+ ab = (int)utf8_skip_data[c] - 1;
+ if (length <= ab) {
+ goto utf8_error;
+ }
+
+ /* Check top bits in the second byte */
+ p++;
+ length--;
+ if ((*p & 0xc0) != 0x80) {
+ goto utf8_error;
+ }
+
+ /* Check for overlong sequences for each different length */
+ switch (ab) {
+ case 1:
+ /* Check for xx00 000x */
+ if ((c & 0x3e) == 0) {
+ goto utf8_error;
+ }
+ continue; /* We know there aren't any more bytes to check */
+
+ case 2:
+ /* Check for 1110 0000, xx0x xxxx */
+ if (c == 0xe0 && (*p & 0x20) == 0) {
+ goto utf8_error;
+ }
+ /* Some special cases, see section 5 of utf-8 decoder stress-test by Markus Kuhn
+ * (https://www.cl.cam.ac.uk/~mgk25/ucs/examples/UTF-8-test.txt). */
+ /* From section 5.1 (and 5.2) */
+ if (c == 0xed) {
+ if (*p == 0xa0 && *(p + 1) == 0x80) {
+ goto utf8_error;
+ }
+ if (*p == 0xad && *(p + 1) == 0xbf) {
+ goto utf8_error;
+ }
+ if (*p == 0xae && *(p + 1) == 0x80) {
+ goto utf8_error;
+ }
+ if (*p == 0xaf && *(p + 1) == 0xbf) {
+ goto utf8_error;
+ }
+ if (*p == 0xb0 && *(p + 1) == 0x80) {
+ goto utf8_error;
+ }
+ if (*p == 0xbe && *(p + 1) == 0x80) {
+ goto utf8_error;
+ }
+ if (*p == 0xbf && *(p + 1) == 0xbf) {
+ goto utf8_error;
+ }
+ }
+ /* From section 5.3 */
+ if (c == 0xef) {
+ if (*p == 0xbf && *(p + 1) == 0xbe) {
+ goto utf8_error;
+ }
+ if (*p == 0xbf && *(p + 1) == 0xbf) {
+ goto utf8_error;
+ }
+ }
+ break;
+
+ case 3:
+ /* Check for 1111 0000, xx00 xxxx */
+ if (c == 0xf0 && (*p & 0x30) == 0) {
+ goto utf8_error;
+ }
+ break;
+
+ case 4:
+ /* Check for 1111 1000, xx00 0xxx */
+ if (c == 0xf8 && (*p & 0x38) == 0) {
+ goto utf8_error;
+ }
+ break;
+
+ case 5:
+ /* Check for 1111 1100, xx00 00xx */
+ if (c == 0xfc && (*p & 0x3c) == 0) {
+ goto utf8_error;
+ }
+ break;
+ }
+
+ /* Check for valid bytes after the 2nd, if any; all must start 10 */
+ while (--ab > 0) {
+ p++;
+ length--;
+ if ((*p & 0xc0) != 0x80) {
+ goto utf8_error;
+ }
+ }
+ }
+
+ return -1;
utf8_error:
- return ((const char *)perr - (const char *)str);
+ return ((const char *)perr - (const char *)str);
}
/**
@@ -170,97 +200,108 @@ utf8_error:
*/
int BLI_utf8_invalid_strip(char *str, size_t length)
{
- ptrdiff_t bad_char;
- int tot = 0;
-
- BLI_assert(str[length] == '\0');
-
- while ((bad_char = BLI_utf8_invalid_byte(str, length)) != -1) {
- str += bad_char;
- length -= (size_t)(bad_char + 1);
-
- if (length == 0) {
- /* last character bad, strip it */
- *str = '\0';
- tot++;
- break;
- }
- else {
- /* strip, keep looking */
- memmove(str, str + 1, length + 1); /* +1 for NULL char! */
- tot++;
- }
- }
-
- return tot;
+ ptrdiff_t bad_char;
+ int tot = 0;
+
+ BLI_assert(str[length] == '\0');
+
+ while ((bad_char = BLI_utf8_invalid_byte(str, length)) != -1) {
+ str += bad_char;
+ length -= (size_t)(bad_char + 1);
+
+ if (length == 0) {
+ /* last character bad, strip it */
+ *str = '\0';
+ tot++;
+ break;
+ }
+ else {
+ /* strip, keep looking */
+ memmove(str, str + 1, length + 1); /* +1 for NULL char! */
+ tot++;
+ }
+ }
+
+ return tot;
}
-
/* compatible with BLI_strncpy, but esnure no partial utf8 chars */
-#define BLI_STR_UTF8_CPY(dst, src, maxncpy) \
- { \
- size_t utf8_size; \
- while (*src != '\0' && (utf8_size = utf8_skip_data[*src]) < maxncpy) {\
- maxncpy -= utf8_size; \
- switch (utf8_size) { \
- case 6: *dst ++ = *src ++; ATTR_FALLTHROUGH; \
- case 5: *dst ++ = *src ++; ATTR_FALLTHROUGH; \
- case 4: *dst ++ = *src ++; ATTR_FALLTHROUGH; \
- case 3: *dst ++ = *src ++; ATTR_FALLTHROUGH; \
- case 2: *dst ++ = *src ++; ATTR_FALLTHROUGH; \
- case 1: *dst ++ = *src ++; \
- } \
- } \
- *dst = '\0'; \
- } (void)0
+#define BLI_STR_UTF8_CPY(dst, src, maxncpy) \
+ { \
+ size_t utf8_size; \
+ while (*src != '\0' && (utf8_size = utf8_skip_data[*src]) < maxncpy) { \
+ maxncpy -= utf8_size; \
+ switch (utf8_size) { \
+ case 6: \
+ *dst++ = *src++; \
+ ATTR_FALLTHROUGH; \
+ case 5: \
+ *dst++ = *src++; \
+ ATTR_FALLTHROUGH; \
+ case 4: \
+ *dst++ = *src++; \
+ ATTR_FALLTHROUGH; \
+ case 3: \
+ *dst++ = *src++; \
+ ATTR_FALLTHROUGH; \
+ case 2: \
+ *dst++ = *src++; \
+ ATTR_FALLTHROUGH; \
+ case 1: \
+ *dst++ = *src++; \
+ } \
+ } \
+ *dst = '\0'; \
+ } \
+ (void)0
char *BLI_strncpy_utf8(char *__restrict dst, const char *__restrict src, size_t maxncpy)
{
- char *r_dst = dst;
+ char *r_dst = dst;
- BLI_assert(maxncpy != 0);
+ BLI_assert(maxncpy != 0);
#ifdef DEBUG_STRSIZE
- memset(dst, 0xff, sizeof(*dst) * maxncpy);
+ memset(dst, 0xff, sizeof(*dst) * maxncpy);
#endif
- /* note: currently we don't attempt to deal with invalid utf8 chars */
- BLI_STR_UTF8_CPY(dst, src, maxncpy);
+ /* note: currently we don't attempt to deal with invalid utf8 chars */
+ BLI_STR_UTF8_CPY(dst, src, maxncpy);
- return r_dst;
+ return r_dst;
}
size_t BLI_strncpy_utf8_rlen(char *__restrict dst, const char *__restrict src, size_t maxncpy)
{
- char *r_dst = dst;
+ char *r_dst = dst;
- BLI_assert(maxncpy != 0);
+ BLI_assert(maxncpy != 0);
#ifdef DEBUG_STRSIZE
- memset(dst, 0xff, sizeof(*dst) * maxncpy);
+ memset(dst, 0xff, sizeof(*dst) * maxncpy);
#endif
- /* note: currently we don't attempt to deal with invalid utf8 chars */
- BLI_STR_UTF8_CPY(dst, src, maxncpy);
+ /* note: currently we don't attempt to deal with invalid utf8 chars */
+ BLI_STR_UTF8_CPY(dst, src, maxncpy);
- return (size_t)(dst - r_dst);
+ return (size_t)(dst - r_dst);
}
char *BLI_strncat_utf8(char *__restrict dst, const char *__restrict src, size_t maxncpy)
{
- while (*dst && maxncpy > 0) {
- dst++;
- maxncpy--;
- }
+ while (*dst && maxncpy > 0) {
+ dst++;
+ maxncpy--;
+ }
#ifdef DEBUG_STRSIZE
- memset(dst, 0xff, sizeof(*dst) * maxncpy);
+ memset(dst, 0xff, sizeof(*dst) * maxncpy);
#endif
- BLI_STR_UTF8_CPY(dst, src, maxncpy);
+ BLI_STR_UTF8_CPY(dst, src, maxncpy);
- return dst;
+ return dst;
}
#undef BLI_STR_UTF8_CPY
@@ -268,89 +309,91 @@ char *BLI_strncat_utf8(char *__restrict dst, const char *__restrict src, size_t
/* --------------------------------------------------------------------------*/
/* wchar_t / utf8 functions */
-size_t BLI_strncpy_wchar_as_utf8(char *__restrict dst, const wchar_t *__restrict src, const size_t maxncpy)
+size_t BLI_strncpy_wchar_as_utf8(char *__restrict dst,
+ const wchar_t *__restrict src,
+ const size_t maxncpy)
{
- const size_t maxlen = maxncpy - 1;
- /* 6 is max utf8 length of an unicode char. */
- const int64_t maxlen_secured = (int64_t)maxlen - 6;
- size_t len = 0;
+ const size_t maxlen = maxncpy - 1;
+ /* 6 is max utf8 length of an unicode char. */
+ const int64_t maxlen_secured = (int64_t)maxlen - 6;
+ size_t len = 0;
- BLI_assert(maxncpy != 0);
+ BLI_assert(maxncpy != 0);
#ifdef DEBUG_STRSIZE
- memset(dst, 0xff, sizeof(*dst) * maxncpy);
+ memset(dst, 0xff, sizeof(*dst) * maxncpy);
#endif
- while (*src && len <= maxlen_secured) {
- len += BLI_str_utf8_from_unicode((uint)*src++, dst + len);
- }
-
- /* We have to be more careful for the last six bytes,
- * to avoid buffer overflow in case utf8-encoded char would be too long for our dst buffer. */
- while (*src) {
- char t[6];
- size_t l = BLI_str_utf8_from_unicode((uint)*src++, t);
- BLI_assert(l <= 6);
- if (len + l > maxlen) {
- break;
- }
- memcpy(dst + len, t, l);
- len += l;
- }
-
- dst[len] = '\0';
-
- return len;
+ while (*src && len <= maxlen_secured) {
+ len += BLI_str_utf8_from_unicode((uint)*src++, dst + len);
+ }
+
+ /* We have to be more careful for the last six bytes,
+ * to avoid buffer overflow in case utf8-encoded char would be too long for our dst buffer. */
+ while (*src) {
+ char t[6];
+ size_t l = BLI_str_utf8_from_unicode((uint)*src++, t);
+ BLI_assert(l <= 6);
+ if (len + l > maxlen) {
+ break;
+ }
+ memcpy(dst + len, t, l);
+ len += l;
+ }
+
+ dst[len] = '\0';
+
+ return len;
}
/* wchar len in utf8 */
size_t BLI_wstrlen_utf8(const wchar_t *src)
{
- size_t len = 0;
+ size_t len = 0;
- while (*src) {
- len += BLI_str_utf8_from_unicode((uint)*src++, NULL);
- }
+ while (*src) {
+ len += BLI_str_utf8_from_unicode((uint)*src++, NULL);
+ }
- return len;
+ return len;
}
size_t BLI_strlen_utf8_ex(const char *strc, size_t *r_len_bytes)
{
- size_t len;
- const char *strc_orig = strc;
+ size_t len;
+ const char *strc_orig = strc;
- for (len = 0; *strc; len++) {
- strc += BLI_str_utf8_size_safe(strc);
- }
+ for (len = 0; *strc; len++) {
+ strc += BLI_str_utf8_size_safe(strc);
+ }
- *r_len_bytes = (size_t)(strc - strc_orig);
- return len;
+ *r_len_bytes = (size_t)(strc - strc_orig);
+ return len;
}
size_t BLI_strlen_utf8(const char *strc)
{
- size_t len;
+ size_t len;
- for (len = 0; *strc; len++) {
- strc += BLI_str_utf8_size_safe(strc);
- }
+ for (len = 0; *strc; len++) {
+ strc += BLI_str_utf8_size_safe(strc);
+ }
- return len;
+ return len;
}
size_t BLI_strnlen_utf8_ex(const char *strc, const size_t maxlen, size_t *r_len_bytes)
{
- size_t len;
- const char *strc_orig = strc;
- const char *strc_end = strc + maxlen;
+ size_t len;
+ const char *strc_orig = strc;
+ const char *strc_end = strc + maxlen;
- for (len = 0; *strc && strc < strc_end; len++) {
- strc += BLI_str_utf8_size_safe(strc);
- }
+ for (len = 0; *strc && strc < strc_end; len++) {
+ strc += BLI_str_utf8_size_safe(strc);
+ }
- *r_len_bytes = (size_t)(strc - strc_orig);
- return len;
+ *r_len_bytes = (size_t)(strc - strc_orig);
+ return len;
}
/**
@@ -360,45 +403,47 @@ size_t BLI_strnlen_utf8_ex(const char *strc, const size_t maxlen, size_t *r_len_
*/
size_t BLI_strnlen_utf8(const char *strc, const size_t maxlen)
{
- size_t len;
- const char *strc_end = strc + maxlen;
+ size_t len;
+ const char *strc_end = strc + maxlen;
- for (len = 0; *strc && strc < strc_end; len++) {
- strc += BLI_str_utf8_size_safe(strc);
- }
+ for (len = 0; *strc && strc < strc_end; len++) {
+ strc += BLI_str_utf8_size_safe(strc);
+ }
- return len;
+ return len;
}
-size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst_w, const char *__restrict src_c, const size_t maxncpy)
+size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst_w,
+ const char *__restrict src_c,
+ const size_t maxncpy)
{
- const size_t maxlen = maxncpy - 1;
- size_t len = 0;
+ const size_t maxlen = maxncpy - 1;
+ size_t len = 0;
- BLI_assert(maxncpy != 0);
+ BLI_assert(maxncpy != 0);
#ifdef DEBUG_STRSIZE
- memset(dst_w, 0xff, sizeof(*dst_w) * maxncpy);
+ memset(dst_w, 0xff, sizeof(*dst_w) * maxncpy);
#endif
- while (*src_c && len != maxlen) {
- size_t step = 0;
- uint unicode = BLI_str_utf8_as_unicode_and_size(src_c, &step);
- if (unicode != BLI_UTF8_ERR) {
- *dst_w = (wchar_t)unicode;
- src_c += step;
- }
- else {
- *dst_w = '?';
- src_c = BLI_str_find_next_char_utf8(src_c, NULL);
- }
- dst_w++;
- len++;
- }
-
- *dst_w = 0;
-
- return len;
+ while (*src_c && len != maxlen) {
+ size_t step = 0;
+ uint unicode = BLI_str_utf8_as_unicode_and_size(src_c, &step);
+ if (unicode != BLI_UTF8_ERR) {
+ *dst_w = (wchar_t)unicode;
+ src_c += step;
+ }
+ else {
+ *dst_w = '?';
+ src_c = BLI_str_find_next_char_utf8(src_c, NULL);
+ }
+ dst_w++;
+ len++;
+ }
+
+ *dst_w = 0;
+
+ return len;
}
/* end wchar_t / utf8 functions */
@@ -408,36 +453,36 @@ size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst_w, const char *__rest
int BLI_wcwidth(wchar_t ucs)
{
- return mk_wcwidth(ucs);
+ return mk_wcwidth(ucs);
}
int BLI_wcswidth(const wchar_t *pwcs, size_t n)
{
- return mk_wcswidth(pwcs, n);
+ return mk_wcswidth(pwcs, n);
}
int BLI_str_utf8_char_width(const char *p)
{
- uint unicode = BLI_str_utf8_as_unicode(p);
- if (unicode == BLI_UTF8_ERR) {
- return -1;
- }
+ uint unicode = BLI_str_utf8_as_unicode(p);
+ if (unicode == BLI_UTF8_ERR) {
+ return -1;
+ }
- return BLI_wcwidth((wchar_t)unicode);
+ return BLI_wcwidth((wchar_t)unicode);
}
int BLI_str_utf8_char_width_safe(const char *p)
{
- int columns;
+ int columns;
- uint unicode = BLI_str_utf8_as_unicode(p);
- if (unicode == BLI_UTF8_ERR) {
- return 1;
- }
+ uint unicode = BLI_str_utf8_as_unicode(p);
+ if (unicode == BLI_UTF8_ERR) {
+ return 1;
+ }
- columns = BLI_wcwidth((wchar_t)unicode);
+ columns = BLI_wcwidth((wchar_t)unicode);
- return (columns < 0) ? 1 : columns;
+ return (columns < 0) ? 1 : columns;
}
/* --------------------------------------------------------------------------*/
@@ -447,73 +492,74 @@ int BLI_str_utf8_char_width_safe(const char *p)
/* note, glib uses uint for unicode, best we do the same,
* though we don't typedef it - campbell */
-#define UTF8_COMPUTE(Char, Mask, Len, Err) \
- if (Char < 128) { \
- Len = 1; \
- Mask = 0x7f; \
- } \
- else if ((Char & 0xe0) == 0xc0) { \
- Len = 2; \
- Mask = 0x1f; \
- } \
- else if ((Char & 0xf0) == 0xe0) { \
- Len = 3; \
- Mask = 0x0f; \
- } \
- else if ((Char & 0xf8) == 0xf0) { \
- Len = 4; \
- Mask = 0x07; \
- } \
- else if ((Char & 0xfc) == 0xf8) { \
- Len = 5; \
- Mask = 0x03; \
- } \
- else if ((Char & 0xfe) == 0xfc) { \
- Len = 6; \
- Mask = 0x01; \
- } \
- else { \
- Len = Err; /* -1 is the typical error value or 1 to skip */ \
- } (void)0
+#define UTF8_COMPUTE(Char, Mask, Len, Err) \
+ if (Char < 128) { \
+ Len = 1; \
+ Mask = 0x7f; \
+ } \
+ else if ((Char & 0xe0) == 0xc0) { \
+ Len = 2; \
+ Mask = 0x1f; \
+ } \
+ else if ((Char & 0xf0) == 0xe0) { \
+ Len = 3; \
+ Mask = 0x0f; \
+ } \
+ else if ((Char & 0xf8) == 0xf0) { \
+ Len = 4; \
+ Mask = 0x07; \
+ } \
+ else if ((Char & 0xfc) == 0xf8) { \
+ Len = 5; \
+ Mask = 0x03; \
+ } \
+ else if ((Char & 0xfe) == 0xfc) { \
+ Len = 6; \
+ Mask = 0x01; \
+ } \
+ else { \
+ Len = Err; /* -1 is the typical error value or 1 to skip */ \
+ } \
+ (void)0
/* same as glib define but added an 'Err' arg */
-#define UTF8_GET(Result, Chars, Count, Mask, Len, Err) \
- (Result) = (Chars)[0] & (Mask); \
- for ((Count) = 1; (Count) < (Len); ++(Count)) { \
- if (((Chars)[(Count)] & 0xc0) != 0x80) { \
- (Result) = Err; \
- break; \
- } \
- (Result) <<= 6; \
- (Result) |= ((Chars)[(Count)] & 0x3f); \
- } (void)0
-
+#define UTF8_GET(Result, Chars, Count, Mask, Len, Err) \
+ (Result) = (Chars)[0] & (Mask); \
+ for ((Count) = 1; (Count) < (Len); ++(Count)) { \
+ if (((Chars)[(Count)] & 0xc0) != 0x80) { \
+ (Result) = Err; \
+ break; \
+ } \
+ (Result) <<= 6; \
+ (Result) |= ((Chars)[(Count)] & 0x3f); \
+ } \
+ (void)0
/* uses glib functions but not from glib */
/* gets the size of a single utf8 char */
int BLI_str_utf8_size(const char *p)
{
- int mask = 0, len;
- const unsigned char c = (unsigned char) *p;
+ int mask = 0, len;
+ const unsigned char c = (unsigned char)*p;
- UTF8_COMPUTE(c, mask, len, -1);
+ UTF8_COMPUTE(c, mask, len, -1);
- (void)mask; /* quiet warning */
+ (void)mask; /* quiet warning */
- return len;
+ return len;
}
/* use when we want to skip errors */
int BLI_str_utf8_size_safe(const char *p)
{
- int mask = 0, len;
- const unsigned char c = (unsigned char) *p;
+ int mask = 0, len;
+ const unsigned char c = (unsigned char)*p;
- UTF8_COMPUTE(c, mask, len, 1);
+ UTF8_COMPUTE(c, mask, len, 1);
- (void)mask; /* quiet warning */
+ (void)mask; /* quiet warning */
- return len;
+ return len;
}
/* was g_utf8_get_char */
@@ -531,98 +577,98 @@ int BLI_str_utf8_size_safe(const char *p)
*/
uint BLI_str_utf8_as_unicode(const char *p)
{
- int i, len;
- uint mask = 0;
- uint result;
- const unsigned char c = (unsigned char) *p;
-
- UTF8_COMPUTE(c, mask, len, -1);
- if (UNLIKELY(len == -1)) {
- return BLI_UTF8_ERR;
- }
- UTF8_GET(result, p, i, mask, len, BLI_UTF8_ERR);
-
- return result;
+ int i, len;
+ uint mask = 0;
+ uint result;
+ const unsigned char c = (unsigned char)*p;
+
+ UTF8_COMPUTE(c, mask, len, -1);
+ if (UNLIKELY(len == -1)) {
+ return BLI_UTF8_ERR;
+ }
+ UTF8_GET(result, p, i, mask, len, BLI_UTF8_ERR);
+
+ return result;
}
/* variant that increments the length */
uint BLI_str_utf8_as_unicode_and_size(const char *__restrict p, size_t *__restrict index)
{
- int i, len;
- unsigned mask = 0;
- uint result;
- const unsigned char c = (unsigned char) *p;
-
- UTF8_COMPUTE(c, mask, len, -1);
- if (UNLIKELY(len == -1)) {
- return BLI_UTF8_ERR;
- }
- UTF8_GET(result, p, i, mask, len, BLI_UTF8_ERR);
- *index += (size_t)len;
- return result;
+ int i, len;
+ unsigned mask = 0;
+ uint result;
+ const unsigned char c = (unsigned char)*p;
+
+ UTF8_COMPUTE(c, mask, len, -1);
+ if (UNLIKELY(len == -1)) {
+ return BLI_UTF8_ERR;
+ }
+ UTF8_GET(result, p, i, mask, len, BLI_UTF8_ERR);
+ *index += (size_t)len;
+ return result;
}
uint BLI_str_utf8_as_unicode_and_size_safe(const char *__restrict p, size_t *__restrict index)
{
- int i, len;
- uint mask = 0;
- uint result;
- const unsigned char c = (unsigned char) *p;
-
- UTF8_COMPUTE(c, mask, len, -1);
- if (UNLIKELY(len == -1)) {
- *index += 1;
- return c;
- }
- UTF8_GET(result, p, i, mask, len, BLI_UTF8_ERR);
- *index += (size_t)len;
- return result;
+ int i, len;
+ uint mask = 0;
+ uint result;
+ const unsigned char c = (unsigned char)*p;
+
+ UTF8_COMPUTE(c, mask, len, -1);
+ if (UNLIKELY(len == -1)) {
+ *index += 1;
+ return c;
+ }
+ UTF8_GET(result, p, i, mask, len, BLI_UTF8_ERR);
+ *index += (size_t)len;
+ return result;
}
/* another variant that steps over the index,
* note, currently this also falls back to latin1 for text drawing. */
uint BLI_str_utf8_as_unicode_step(const char *__restrict p, size_t *__restrict index)
{
- int i, len;
- uint mask = 0;
- uint result;
- unsigned char c;
-
- p += *index;
- c = (unsigned char) *p;
-
- UTF8_COMPUTE(c, mask, len, -1);
- if (UNLIKELY(len == -1)) {
- /* when called with NULL end, result will never be NULL,
- * checks for a NULL character */
- const char *p_next = BLI_str_find_next_char_utf8(p, NULL);
- /* will never return the same pointer unless '\0',
- * eternal loop is prevented */
- *index += (size_t)(p_next - p);
- return BLI_UTF8_ERR;
- }
-
- /* this is tricky since there are a few ways we can bail out of bad unicode
- * values, 3 possible solutions. */
+ int i, len;
+ uint mask = 0;
+ uint result;
+ unsigned char c;
+
+ p += *index;
+ c = (unsigned char)*p;
+
+ UTF8_COMPUTE(c, mask, len, -1);
+ if (UNLIKELY(len == -1)) {
+ /* when called with NULL end, result will never be NULL,
+ * checks for a NULL character */
+ const char *p_next = BLI_str_find_next_char_utf8(p, NULL);
+ /* will never return the same pointer unless '\0',
+ * eternal loop is prevented */
+ *index += (size_t)(p_next - p);
+ return BLI_UTF8_ERR;
+ }
+
+ /* this is tricky since there are a few ways we can bail out of bad unicode
+ * values, 3 possible solutions. */
#if 0
- UTF8_GET(result, p, i, mask, len, BLI_UTF8_ERR);
+ UTF8_GET(result, p, i, mask, len, BLI_UTF8_ERR);
#elif 1
- /* WARNING: this is NOT part of glib, or supported by similar functions.
- * this is added for text drawing because some filepaths can have latin1
- * characters */
- UTF8_GET(result, p, i, mask, len, BLI_UTF8_ERR);
- if (result == BLI_UTF8_ERR) {
- len = 1;
- result = *p;
- }
- /* end warning! */
+ /* WARNING: this is NOT part of glib, or supported by similar functions.
+ * this is added for text drawing because some filepaths can have latin1
+ * characters */
+ UTF8_GET(result, p, i, mask, len, BLI_UTF8_ERR);
+ if (result == BLI_UTF8_ERR) {
+ len = 1;
+ result = *p;
+ }
+ /* end warning! */
#else
- /* without a fallback like '?', text drawing will stop on this value */
- UTF8_GET(result, p, i, mask, len, '?');
+ /* without a fallback like '?', text drawing will stop on this value */
+ UTF8_GET(result, p, i, mask, len, '?');
#endif
- *index += (size_t)len;
- return result;
+ *index += (size_t)len;
+ return result;
}
/* was g_unichar_to_utf8 */
@@ -639,45 +685,45 @@ uint BLI_str_utf8_as_unicode_step(const char *__restrict p, size_t *__restrict i
*/
size_t BLI_str_utf8_from_unicode(uint c, char *outbuf)
{
- /* If this gets modified, also update the copy in g_string_insert_unichar() */
- uint len = 0;
- uint first;
- uint i;
-
- if (c < 0x80) {
- first = 0;
- len = 1;
- }
- else if (c < 0x800) {
- first = 0xc0;
- len = 2;
- }
- else if (c < 0x10000) {
- first = 0xe0;
- len = 3;
- }
- else if (c < 0x200000) {
- first = 0xf0;
- len = 4;
- }
- else if (c < 0x4000000) {
- first = 0xf8;
- len = 5;
- }
- else {
- first = 0xfc;
- len = 6;
- }
-
- if (outbuf) {
- for (i = len - 1; i > 0; --i) {
- outbuf[i] = (c & 0x3f) | 0x80;
- c >>= 6;
- }
- outbuf[0] = c | first;
- }
-
- return len;
+ /* If this gets modified, also update the copy in g_string_insert_unichar() */
+ uint len = 0;
+ uint first;
+ uint i;
+
+ if (c < 0x80) {
+ first = 0;
+ len = 1;
+ }
+ else if (c < 0x800) {
+ first = 0xc0;
+ len = 2;
+ }
+ else if (c < 0x10000) {
+ first = 0xe0;
+ len = 3;
+ }
+ else if (c < 0x200000) {
+ first = 0xf0;
+ len = 4;
+ }
+ else if (c < 0x4000000) {
+ first = 0xf8;
+ len = 5;
+ }
+ else {
+ first = 0xfc;
+ len = 6;
+ }
+
+ if (outbuf) {
+ for (i = len - 1; i > 0; --i) {
+ outbuf[i] = (c & 0x3f) | 0x80;
+ c >>= 6;
+ }
+ outbuf[0] = c | first;
+ }
+
+ return len;
}
/* was g_utf8_find_prev_char */
@@ -698,12 +744,12 @@ size_t BLI_str_utf8_from_unicode(uint c, char *outbuf)
*/
char *BLI_str_find_prev_char_utf8(const char *str, const char *p)
{
- for (--p; p >= str; --p) {
- if ((*p & 0xc0) != 0x80) {
- return (char *)p;
- }
- }
- return NULL;
+ for (--p; p >= str; --p) {
+ if ((*p & 0xc0) != 0x80) {
+ return (char *)p;
+ }
+ }
+ return NULL;
}
/* was g_utf8_find_next_char */
@@ -723,19 +769,19 @@ char *BLI_str_find_prev_char_utf8(const char *str, const char *p)
*/
char *BLI_str_find_next_char_utf8(const char *p, const char *end)
{
- if (*p) {
- if (end) {
- for (++p; p < end && (*p & 0xc0) == 0x80; ++p) {
- /* do nothing */
- }
- }
- else {
- for (++p; (*p & 0xc0) == 0x80; ++p) {
- /* do nothing */
- }
- }
- }
- return (p == end) ? NULL : (char *)p;
+ if (*p) {
+ if (end) {
+ for (++p; p < end && (*p & 0xc0) == 0x80; ++p) {
+ /* do nothing */
+ }
+ }
+ else {
+ for (++p; (*p & 0xc0) == 0x80; ++p) {
+ /* do nothing */
+ }
+ }
+ }
+ return (p == end) ? NULL : (char *)p;
}
/* was g_utf8_prev_char */
@@ -754,61 +800,71 @@ char *BLI_str_find_next_char_utf8(const char *p, const char *end)
*/
char *BLI_str_prev_char_utf8(const char *p)
{
- while (1) {
- p--;
- if ((*p & 0xc0) != 0x80) {
- return (char *)p;
- }
- }
+ while (1) {
+ p--;
+ if ((*p & 0xc0) != 0x80) {
+ return (char *)p;
+ }
+ }
}
/* end glib copy */
-size_t BLI_str_partition_utf8(const char *str, const uint delim[], const char **sep, const char **suf)
+size_t BLI_str_partition_utf8(const char *str,
+ const uint delim[],
+ const char **sep,
+ const char **suf)
{
- return BLI_str_partition_ex_utf8(str, NULL, delim, sep, suf, false);
+ return BLI_str_partition_ex_utf8(str, NULL, delim, sep, suf, false);
}
-size_t BLI_str_rpartition_utf8(const char *str, const uint delim[], const char **sep, const char **suf)
+size_t BLI_str_rpartition_utf8(const char *str,
+ const uint delim[],
+ const char **sep,
+ const char **suf)
{
- return BLI_str_partition_ex_utf8(str, NULL, delim, sep, suf, true);
+ return BLI_str_partition_ex_utf8(str, NULL, delim, sep, suf, true);
}
-size_t BLI_str_partition_ex_utf8(
- const char *str, const char *end, const uint delim[], const char **sep, const char **suf, const bool from_right)
+size_t BLI_str_partition_ex_utf8(const char *str,
+ const char *end,
+ const uint delim[],
+ const char **sep,
+ const char **suf,
+ const bool from_right)
{
- const uint *d;
- const size_t str_len = end ? (size_t)(end - str) : strlen(str);
- size_t index;
-
- /* Note that here, we assume end points to a valid utf8 char! */
- BLI_assert(end == NULL || (end >= str && (BLI_str_utf8_as_unicode(end) != BLI_UTF8_ERR)));
-
- *suf = (char *)(str + str_len);
-
- for (*sep = (char *)(from_right ? BLI_str_find_prev_char_utf8(str, str + str_len) : str), index = 0;
- *sep >= str && (!end || *sep < end) && **sep != '\0';
- *sep = (char *)(from_right ? BLI_str_find_prev_char_utf8(str, *sep) : str + index))
- {
- const uint c = BLI_str_utf8_as_unicode_and_size(*sep, &index);
-
- if (c == BLI_UTF8_ERR) {
- *suf = *sep = NULL;
- break;
- }
-
- for (d = delim; *d != '\0'; ++d) {
- if (*d == c) {
- /* *suf is already correct in case from_right is true. */
- if (!from_right) {
- *suf = (char *)(str + index);
- }
- return (size_t)(*sep - str);
- }
- }
-
- *suf = *sep; /* Useful in 'from_right' case! */
- }
-
- *suf = *sep = NULL;
- return str_len;
+ const uint *d;
+ const size_t str_len = end ? (size_t)(end - str) : strlen(str);
+ size_t index;
+
+ /* Note that here, we assume end points to a valid utf8 char! */
+ BLI_assert(end == NULL || (end >= str && (BLI_str_utf8_as_unicode(end) != BLI_UTF8_ERR)));
+
+ *suf = (char *)(str + str_len);
+
+ for (*sep = (char *)(from_right ? BLI_str_find_prev_char_utf8(str, str + str_len) : str),
+ index = 0;
+ *sep >= str && (!end || *sep < end) && **sep != '\0';
+ *sep = (char *)(from_right ? BLI_str_find_prev_char_utf8(str, *sep) : str + index)) {
+ const uint c = BLI_str_utf8_as_unicode_and_size(*sep, &index);
+
+ if (c == BLI_UTF8_ERR) {
+ *suf = *sep = NULL;
+ break;
+ }
+
+ for (d = delim; *d != '\0'; ++d) {
+ if (*d == c) {
+ /* *suf is already correct in case from_right is true. */
+ if (!from_right) {
+ *suf = (char *)(str + index);
+ }
+ return (size_t)(*sep - str);
+ }
+ }
+
+ *suf = *sep; /* Useful in 'from_right' case! */
+ }
+
+ *suf = *sep = NULL;
+ return str_len;
}
diff --git a/source/blender/blenlib/intern/string_utils.c b/source/blender/blenlib/intern/string_utils.c
index 46472d8125d..9b6ffd85341 100644
--- a/source/blender/blenlib/intern/string_utils.c
+++ b/source/blender/blenlib/intern/string_utils.c
@@ -34,7 +34,6 @@
#include "DNA_listBase.h"
-
#ifdef __GNUC__
# pragma GCC diagnostic error "-Wsign-conversion"
#endif
@@ -55,37 +54,37 @@
*/
size_t BLI_split_name_num(char *left, int *nr, const char *name, const char delim)
{
- const size_t name_len = strlen(name);
-
- *nr = 0;
- memcpy(left, name, (name_len + 1) * sizeof(char));
-
- /* name doesn't end with a delimiter "foo." */
- if ((name_len > 1 && name[name_len - 1] == delim) == 0) {
- size_t a = name_len;
- while (a--) {
- if (name[a] == delim) {
- left[a] = '\0'; /* truncate left part here */
- *nr = atol(name + a + 1);
- /* casting down to an int, can overflow for large numbers */
- if (*nr < 0) {
- *nr = 0;
- }
- return a;
- }
- else if (isdigit(name[a]) == 0) {
- /* non-numeric suffix - give up */
- break;
- }
- }
- }
-
- return name_len;
+ const size_t name_len = strlen(name);
+
+ *nr = 0;
+ memcpy(left, name, (name_len + 1) * sizeof(char));
+
+ /* name doesn't end with a delimiter "foo." */
+ if ((name_len > 1 && name[name_len - 1] == delim) == 0) {
+ size_t a = name_len;
+ while (a--) {
+ if (name[a] == delim) {
+ left[a] = '\0'; /* truncate left part here */
+ *nr = atol(name + a + 1);
+ /* casting down to an int, can overflow for large numbers */
+ if (*nr < 0) {
+ *nr = 0;
+ }
+ return a;
+ }
+ else if (isdigit(name[a]) == 0) {
+ /* non-numeric suffix - give up */
+ break;
+ }
+ }
+ }
+
+ return name_len;
}
static bool is_char_sep(const char c)
{
- return ELEM(c, '.', ' ', '-', '_');
+ return ELEM(c, '.', ' ', '-', '_');
}
/**
@@ -94,20 +93,20 @@ static bool is_char_sep(const char c)
*/
void BLI_string_split_suffix(const char *string, char *r_body, char *r_suf, const size_t str_len)
{
- size_t len = BLI_strnlen(string, str_len);
- size_t i;
+ size_t len = BLI_strnlen(string, str_len);
+ size_t i;
- r_body[0] = r_suf[0] = '\0';
+ r_body[0] = r_suf[0] = '\0';
- for (i = len; i > 0; i--) {
- if (is_char_sep(string[i])) {
- BLI_strncpy(r_body, string, i + 1);
- BLI_strncpy(r_suf, string + i, (len + 1) - i);
- return;
- }
- }
+ for (i = len; i > 0; i--) {
+ if (is_char_sep(string[i])) {
+ BLI_strncpy(r_body, string, i + 1);
+ BLI_strncpy(r_suf, string + i, (len + 1) - i);
+ return;
+ }
+ }
- memcpy(r_body, string, len + 1);
+ memcpy(r_body, string, len + 1);
}
/**
@@ -115,21 +114,21 @@ void BLI_string_split_suffix(const char *string, char *r_body, char *r_suf, cons
*/
void BLI_string_split_prefix(const char *string, char *r_pre, char *r_body, const size_t str_len)
{
- size_t len = BLI_strnlen(string, str_len);
- size_t i;
+ size_t len = BLI_strnlen(string, str_len);
+ size_t i;
- r_body[0] = r_pre[0] = '\0';
+ r_body[0] = r_pre[0] = '\0';
- for (i = 1; i < len; i++) {
- if (is_char_sep(string[i])) {
- i++;
- BLI_strncpy(r_pre, string, i + 1);
- BLI_strncpy(r_body, string + i, (len + 1) - i);
- return;
- }
- }
+ for (i = 1; i < len; i++) {
+ if (is_char_sep(string[i])) {
+ i++;
+ BLI_strncpy(r_pre, string, i + 1);
+ BLI_strncpy(r_body, string + i, (len + 1) - i);
+ return;
+ }
+ }
- BLI_strncpy(r_body, string, len);
+ BLI_strncpy(r_body, string, len);
}
/**
@@ -139,129 +138,127 @@ void BLI_string_split_prefix(const char *string, char *r_pre, char *r_body, cons
* \param from_name: original name, assumed to be a pointer to a string of at least \a name_len size.
* \param strip_number: If set, remove number extensions.
*/
-void BLI_string_flip_side_name(char *r_name, const char *from_name, const bool strip_number, const size_t name_len)
+void BLI_string_flip_side_name(char *r_name,
+ const char *from_name,
+ const bool strip_number,
+ const size_t name_len)
{
- size_t len;
- char *prefix = alloca(name_len); /* The part before the facing */
- char *suffix = alloca(name_len); /* The part after the facing */
- char *replace = alloca(name_len); /* The replacement string */
- char *number = alloca(name_len); /* The number extension string */
- char *index = NULL;
- bool is_set = false;
-
- *prefix = *suffix = *replace = *number = '\0';
-
- /* always copy the name, since this can be called with an uninitialized string */
- BLI_strncpy(r_name, from_name, name_len);
-
- len = BLI_strnlen(from_name, name_len);
- if (len < 3) {
- /* we don't do names like .R or .L */
- return;
- }
-
- /* We first check the case with a .### extension, let's find the last period */
- if (isdigit(r_name[len - 1])) {
- index = strrchr(r_name, '.'); // last occurrence
- if (index && isdigit(index[1])) { // doesnt handle case bone.1abc2 correct..., whatever!
- if (strip_number == false) {
- BLI_strncpy(number, index, name_len);
- }
- *index = 0;
- len = BLI_strnlen(r_name, name_len);
- }
- }
-
- BLI_strncpy(prefix, r_name, name_len);
-
- /* first case; separator . - _ with extensions r R l L */
- if ((len > 1) && is_char_sep(r_name[len - 2])) {
- is_set = true;
- switch (r_name[len - 1]) {
- case 'l':
- prefix[len - 1] = 0;
- strcpy(replace, "r");
- break;
- case 'r':
- prefix[len - 1] = 0;
- strcpy(replace, "l");
- break;
- case 'L':
- prefix[len - 1] = 0;
- strcpy(replace, "R");
- break;
- case 'R':
- prefix[len - 1] = 0;
- strcpy(replace, "L");
- break;
- default:
- is_set = false;
- }
- }
-
- /* case; beginning with r R l L, with separator after it */
- if (!is_set && is_char_sep(r_name[1])) {
- is_set = true;
- switch (r_name[0]) {
- case 'l':
- strcpy(replace, "r");
- BLI_strncpy(suffix, r_name + 1, name_len);
- prefix[0] = 0;
- break;
- case 'r':
- strcpy(replace, "l");
- BLI_strncpy(suffix, r_name + 1, name_len);
- prefix[0] = 0;
- break;
- case 'L':
- strcpy(replace, "R");
- BLI_strncpy(suffix, r_name + 1, name_len);
- prefix[0] = 0;
- break;
- case 'R':
- strcpy(replace, "L");
- BLI_strncpy(suffix, r_name + 1, name_len);
- prefix[0] = 0;
- break;
- default:
- is_set = false;
- }
- }
-
- if (!is_set && len > 5) {
- /* hrms, why test for a separator? lets do the rule 'ultimate left or right' */
- if (((index = BLI_strcasestr(prefix, "right")) == prefix) ||
- (index == prefix + len - 5))
- {
- is_set = true;
- if (index[0] == 'r') {
- strcpy(replace, "left");
- }
- else {
- strcpy(replace, (index[1] == 'I') ? "LEFT" : "Left");
- }
- *index = 0;
- BLI_strncpy(suffix, index + 5, name_len);
- }
- else if (((index = BLI_strcasestr(prefix, "left")) == prefix) ||
- (index == prefix + len - 4))
- {
- is_set = true;
- if (index[0] == 'l') {
- strcpy(replace, "right");
- }
- else {
- strcpy(replace, (index[1] == 'E') ? "RIGHT" : "Right");
- }
- *index = 0;
- BLI_strncpy(suffix, index + 4, name_len);
- }
- }
-
- BLI_snprintf(r_name, name_len, "%s%s%s%s", prefix, replace, suffix, number);
+ size_t len;
+ char *prefix = alloca(name_len); /* The part before the facing */
+ char *suffix = alloca(name_len); /* The part after the facing */
+ char *replace = alloca(name_len); /* The replacement string */
+ char *number = alloca(name_len); /* The number extension string */
+ char *index = NULL;
+ bool is_set = false;
+
+ *prefix = *suffix = *replace = *number = '\0';
+
+ /* always copy the name, since this can be called with an uninitialized string */
+ BLI_strncpy(r_name, from_name, name_len);
+
+ len = BLI_strnlen(from_name, name_len);
+ if (len < 3) {
+ /* we don't do names like .R or .L */
+ return;
+ }
+
+ /* We first check the case with a .### extension, let's find the last period */
+ if (isdigit(r_name[len - 1])) {
+ index = strrchr(r_name, '.'); // last occurrence
+ if (index && isdigit(index[1])) { // doesnt handle case bone.1abc2 correct..., whatever!
+ if (strip_number == false) {
+ BLI_strncpy(number, index, name_len);
+ }
+ *index = 0;
+ len = BLI_strnlen(r_name, name_len);
+ }
+ }
+
+ BLI_strncpy(prefix, r_name, name_len);
+
+ /* first case; separator . - _ with extensions r R l L */
+ if ((len > 1) && is_char_sep(r_name[len - 2])) {
+ is_set = true;
+ switch (r_name[len - 1]) {
+ case 'l':
+ prefix[len - 1] = 0;
+ strcpy(replace, "r");
+ break;
+ case 'r':
+ prefix[len - 1] = 0;
+ strcpy(replace, "l");
+ break;
+ case 'L':
+ prefix[len - 1] = 0;
+ strcpy(replace, "R");
+ break;
+ case 'R':
+ prefix[len - 1] = 0;
+ strcpy(replace, "L");
+ break;
+ default:
+ is_set = false;
+ }
+ }
+
+ /* case; beginning with r R l L, with separator after it */
+ if (!is_set && is_char_sep(r_name[1])) {
+ is_set = true;
+ switch (r_name[0]) {
+ case 'l':
+ strcpy(replace, "r");
+ BLI_strncpy(suffix, r_name + 1, name_len);
+ prefix[0] = 0;
+ break;
+ case 'r':
+ strcpy(replace, "l");
+ BLI_strncpy(suffix, r_name + 1, name_len);
+ prefix[0] = 0;
+ break;
+ case 'L':
+ strcpy(replace, "R");
+ BLI_strncpy(suffix, r_name + 1, name_len);
+ prefix[0] = 0;
+ break;
+ case 'R':
+ strcpy(replace, "L");
+ BLI_strncpy(suffix, r_name + 1, name_len);
+ prefix[0] = 0;
+ break;
+ default:
+ is_set = false;
+ }
+ }
+
+ if (!is_set && len > 5) {
+ /* hrms, why test for a separator? lets do the rule 'ultimate left or right' */
+ if (((index = BLI_strcasestr(prefix, "right")) == prefix) || (index == prefix + len - 5)) {
+ is_set = true;
+ if (index[0] == 'r') {
+ strcpy(replace, "left");
+ }
+ else {
+ strcpy(replace, (index[1] == 'I') ? "LEFT" : "Left");
+ }
+ *index = 0;
+ BLI_strncpy(suffix, index + 5, name_len);
+ }
+ else if (((index = BLI_strcasestr(prefix, "left")) == prefix) || (index == prefix + len - 4)) {
+ is_set = true;
+ if (index[0] == 'l') {
+ strcpy(replace, "right");
+ }
+ else {
+ strcpy(replace, (index[1] == 'E') ? "RIGHT" : "Right");
+ }
+ *index = 0;
+ BLI_strncpy(suffix, index + 4, name_len);
+ }
+ }
+
+ BLI_snprintf(r_name, name_len, "%s%s%s%s", prefix, replace, suffix, number);
}
-
/* Unique name utils. */
/**
@@ -276,47 +273,51 @@ void BLI_string_flip_side_name(char *r_name, const char *from_name, const bool s
* \param name_len: Maximum length of name area
* \return true if there if the name was changed
*/
-bool BLI_uniquename_cb(
- UniquenameCheckCallback unique_check, void *arg, const char *defname, char delim, char *name, size_t name_len)
+bool BLI_uniquename_cb(UniquenameCheckCallback unique_check,
+ void *arg,
+ const char *defname,
+ char delim,
+ char *name,
+ size_t name_len)
{
- if (name[0] == '\0') {
- BLI_strncpy(name, defname, name_len);
- }
-
- if (unique_check(arg, name)) {
- char numstr[16];
- char *tempname = alloca(name_len);
- char *left = alloca(name_len);
- int number;
- size_t len = BLI_split_name_num(left, &number, name, delim);
- do {
- /* add 1 to account for \0 */
- const size_t numlen = BLI_snprintf(numstr, sizeof(numstr), "%c%03d", delim, ++number) + 1;
-
- /* highly unlikely the string only has enough room for the number
- * but support anyway */
- if ((len == 0) || (numlen >= name_len)) {
- /* number is know not to be utf-8 */
- BLI_strncpy(tempname, numstr, name_len);
- }
- else {
- char *tempname_buf;
- tempname_buf = tempname + BLI_strncpy_utf8_rlen(tempname, left, name_len - numlen);
- memcpy(tempname_buf, numstr, numlen);
- }
- } while (unique_check(arg, tempname));
-
- BLI_strncpy(name, tempname, name_len);
-
- return true;
- }
-
- return false;
+ if (name[0] == '\0') {
+ BLI_strncpy(name, defname, name_len);
+ }
+
+ if (unique_check(arg, name)) {
+ char numstr[16];
+ char *tempname = alloca(name_len);
+ char *left = alloca(name_len);
+ int number;
+ size_t len = BLI_split_name_num(left, &number, name, delim);
+ do {
+ /* add 1 to account for \0 */
+ const size_t numlen = BLI_snprintf(numstr, sizeof(numstr), "%c%03d", delim, ++number) + 1;
+
+ /* highly unlikely the string only has enough room for the number
+ * but support anyway */
+ if ((len == 0) || (numlen >= name_len)) {
+ /* number is know not to be utf-8 */
+ BLI_strncpy(tempname, numstr, name_len);
+ }
+ else {
+ char *tempname_buf;
+ tempname_buf = tempname + BLI_strncpy_utf8_rlen(tempname, left, name_len - numlen);
+ memcpy(tempname_buf, numstr, numlen);
+ }
+ } while (unique_check(arg, tempname));
+
+ BLI_strncpy(name, tempname, name_len);
+
+ return true;
+ }
+
+ return false;
}
/* little helper macro for BLI_uniquename */
#ifndef GIVE_STRADDR
-# define GIVE_STRADDR(data, offset) ( ((char *)data) + offset)
+# define GIVE_STRADDR(data, offset) (((char *)data) + offset)
#endif
/**
@@ -329,23 +330,27 @@ bool BLI_uniquename_cb(
*/
static bool uniquename_find_dupe(ListBase *list, void *vlink, const char *name, int name_offs)
{
- Link *link;
+ Link *link;
- for (link = list->first; link; link = link->next) {
- if (link != vlink) {
- if (STREQ(GIVE_STRADDR(link, name_offs), name)) {
- return true;
- }
- }
- }
+ for (link = list->first; link; link = link->next) {
+ if (link != vlink) {
+ if (STREQ(GIVE_STRADDR(link, name_offs), name)) {
+ return true;
+ }
+ }
+ }
- return false;
+ return false;
}
static bool uniquename_unique_check(void *arg, const char *name)
{
- struct {ListBase *lb; void *vlink; int name_offs; } *data = arg;
- return uniquename_find_dupe(data->lb, data->vlink, name, data->name_offs);
+ struct {
+ ListBase *lb;
+ void *vlink;
+ int name_offs;
+ } *data = arg;
+ return uniquename_find_dupe(data->lb, data->vlink, name, data->name_offs);
}
/**
@@ -359,21 +364,27 @@ static bool uniquename_unique_check(void *arg, const char *name)
* \param name_offs: Offset of name within block structure
* \param name_len: Maximum length of name area
*/
-bool BLI_uniquename(ListBase *list, void *vlink, const char *defname, char delim, int name_offs, size_t name_len)
+bool BLI_uniquename(
+ ListBase *list, void *vlink, const char *defname, char delim, int name_offs, size_t name_len)
{
- struct {ListBase *lb; void *vlink; int name_offs; } data;
- data.lb = list;
- data.vlink = vlink;
- data.name_offs = name_offs;
-
- BLI_assert(name_len > 1);
-
- /* See if we are given an empty string */
- if (ELEM(NULL, vlink, defname)) {
- return false;
- }
-
- return BLI_uniquename_cb(uniquename_unique_check, &data, defname, delim, GIVE_STRADDR(vlink, name_offs), name_len);
+ struct {
+ ListBase *lb;
+ void *vlink;
+ int name_offs;
+ } data;
+ data.lb = list;
+ data.vlink = vlink;
+ data.name_offs = name_offs;
+
+ BLI_assert(name_len > 1);
+
+ /* See if we are given an empty string */
+ if (ELEM(NULL, vlink, defname)) {
+ return false;
+ }
+
+ return BLI_uniquename_cb(
+ uniquename_unique_check, &data, defname, delim, GIVE_STRADDR(vlink, name_offs), name_len);
}
/* ------------------------------------------------------------------------- */
@@ -389,77 +400,77 @@ bool BLI_uniquename(ListBase *list, void *vlink, const char *defname, char delim
/**
* Join an array of strings into a newly allocated, null terminated string.
*/
-char *BLI_string_join_arrayN(
- const char *strings[], uint strings_len)
+char *BLI_string_join_arrayN(const char *strings[], uint strings_len)
{
- uint total_len = 1;
- for (uint i = 0; i < strings_len; i++) {
- total_len += strlen(strings[i]);
- }
- char *result = MEM_mallocN(sizeof(char) * total_len, __func__);
- char *c = result;
- for (uint i = 0; i < strings_len; i++) {
- c += BLI_strcpy_rlen(c, strings[i]);
- }
- return result;
+ uint total_len = 1;
+ for (uint i = 0; i < strings_len; i++) {
+ total_len += strlen(strings[i]);
+ }
+ char *result = MEM_mallocN(sizeof(char) * total_len, __func__);
+ char *c = result;
+ for (uint i = 0; i < strings_len; i++) {
+ c += BLI_strcpy_rlen(c, strings[i]);
+ }
+ return result;
}
/**
* A version of #BLI_string_joinN that takes a separator which can be any character including '\0'.
*/
-char *BLI_string_join_array_by_sep_charN(
- char sep, const char *strings[], uint strings_len)
+char *BLI_string_join_array_by_sep_charN(char sep, const char *strings[], uint strings_len)
{
- uint total_len = 0;
- for (uint i = 0; i < strings_len; i++) {
- total_len += strlen(strings[i]) + 1;
- }
- if (total_len == 0) {
- total_len = 1;
- }
-
- char *result = MEM_mallocN(sizeof(char) * total_len, __func__);
- char *c = result;
- if (strings_len != 0) {
- for (uint i = 0; i < strings_len; i++) {
- c += BLI_strcpy_rlen(c, strings[i]);
- *c = sep;
- c++;
- }
- c--;
- }
- *c = '\0';
- return result;
+ uint total_len = 0;
+ for (uint i = 0; i < strings_len; i++) {
+ total_len += strlen(strings[i]) + 1;
+ }
+ if (total_len == 0) {
+ total_len = 1;
+ }
+
+ char *result = MEM_mallocN(sizeof(char) * total_len, __func__);
+ char *c = result;
+ if (strings_len != 0) {
+ for (uint i = 0; i < strings_len; i++) {
+ c += BLI_strcpy_rlen(c, strings[i]);
+ *c = sep;
+ c++;
+ }
+ c--;
+ }
+ *c = '\0';
+ return result;
}
/**
* A version of #BLI_string_join_array_by_sep_charN that takes a table array.
* The new location of each string is written into this array.
*/
-char *BLI_string_join_array_by_sep_char_with_tableN(
- char sep, char *table[], const char *strings[], uint strings_len)
+char *BLI_string_join_array_by_sep_char_with_tableN(char sep,
+ char *table[],
+ const char *strings[],
+ uint strings_len)
{
- uint total_len = 0;
- for (uint i = 0; i < strings_len; i++) {
- total_len += strlen(strings[i]) + 1;
- }
- if (total_len == 0) {
- total_len = 1;
- }
-
- char *result = MEM_mallocN(sizeof(char) * total_len, __func__);
- char *c = result;
- if (strings_len != 0) {
- for (uint i = 0; i < strings_len; i++) {
- table[i] = c; /* <-- only difference to BLI_string_join_array_by_sep_charN. */
- c += BLI_strcpy_rlen(c, strings[i]);
- *c = sep;
- c++;
- }
- c--;
- }
- *c = '\0';
- return result;
+ uint total_len = 0;
+ for (uint i = 0; i < strings_len; i++) {
+ total_len += strlen(strings[i]) + 1;
+ }
+ if (total_len == 0) {
+ total_len = 1;
+ }
+
+ char *result = MEM_mallocN(sizeof(char) * total_len, __func__);
+ char *c = result;
+ if (strings_len != 0) {
+ for (uint i = 0; i < strings_len; i++) {
+ table[i] = c; /* <-- only difference to BLI_string_join_array_by_sep_charN. */
+ c += BLI_strcpy_rlen(c, strings[i]);
+ *c = sep;
+ c++;
+ }
+ c--;
+ }
+ *c = '\0';
+ return result;
}
/** \} */
diff --git a/source/blender/blenlib/intern/system.c b/source/blender/blenlib/intern/system.c
index 2b0dfd045ca..d23b45a3937 100644
--- a/source/blender/blenlib/intern/system.c
+++ b/source/blender/blenlib/intern/system.c
@@ -40,32 +40,32 @@
int BLI_cpu_support_sse2(void)
{
#if defined(__x86_64__) || defined(_M_X64)
- /* x86_64 always has SSE2 instructions */
- return 1;
+ /* x86_64 always has SSE2 instructions */
+ return 1;
#elif defined(__GNUC__) && defined(i386)
- /* for GCC x86 we check cpuid */
- unsigned int d;
- __asm__(
- "pushl %%ebx\n\t"
- "cpuid\n\t"
- "popl %%ebx\n\t"
- : "=d" (d)
- : "a" (1));
- return (d & 0x04000000) != 0;
+ /* for GCC x86 we check cpuid */
+ unsigned int d;
+ __asm__(
+ "pushl %%ebx\n\t"
+ "cpuid\n\t"
+ "popl %%ebx\n\t"
+ : "=d"(d)
+ : "a"(1));
+ return (d & 0x04000000) != 0;
#elif (defined(_MSC_VER) && defined(_M_IX86))
- /* also check cpuid for MSVC x86 */
- unsigned int d;
- __asm {
- xor eax, eax
- inc eax
- push ebx
- cpuid
- pop ebx
- mov d, edx
- }
- return (d & 0x04000000) != 0;
+ /* also check cpuid for MSVC x86 */
+ unsigned int d;
+ __asm {
+ xor eax, eax
+ inc eax
+ push ebx
+ cpuid
+ pop ebx
+ mov d, edx
+ }
+ return (d & 0x04000000) != 0;
#else
- return 0;
+ return 0;
#endif
}
@@ -74,67 +74,66 @@ int BLI_cpu_support_sse2(void)
*/
void BLI_system_backtrace(FILE *fp)
{
- /* ------------- */
- /* Linux / Apple */
+ /* ------------- */
+ /* 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 */
+# 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)
-#ifndef NDEBUG
-#define MAXSYMBOL 256
-#define SIZE 100
- 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
-#undef SIZE
-#else
- fprintf(fp, "Crash backtrace not supported on release builds\n");
-#endif /* NDEBUG */
-#else /* _MSC_VER */
- /* ------------------ */
- /* non msvc/osx/linux */
- (void)fp;
+# ifndef NDEBUG
+# define MAXSYMBOL 256
+# define SIZE 100
+ 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
+# undef SIZE
+# else
+ fprintf(fp, "Crash backtrace not supported on release builds\n");
+# endif /* NDEBUG */
+#else /* _MSC_VER */
+ /* ------------------ */
+ /* non msvc/osx/linux */
+ (void)fp;
#endif
-
}
/* end BLI_system_backtrace */
@@ -143,50 +142,50 @@ void BLI_system_backtrace(FILE *fp)
#if !defined(_WIN32) || defined(FREE_WINDOWS)
static void __cpuid(int data[4], int selector)
{
-#if defined(__x86_64__)
- asm("cpuid" : "=a" (data[0]), "=b" (data[1]), "=c" (data[2]), "=d" (data[3]) : "a"(selector));
-#elif defined(__i386__)
- asm("pushl %%ebx \n\t"
- "cpuid \n\t"
- "movl %%ebx, %1 \n\t"
- "popl %%ebx \n\t"
- : "=a" (data[0]), "=r" (data[1]), "=c" (data[2]), "=d" (data[3])
- : "a"(selector)
- : "ebx");
-#else
- data[0] = data[1] = data[2] = data[3] = 0;
-#endif
+# if defined(__x86_64__)
+ asm("cpuid" : "=a"(data[0]), "=b"(data[1]), "=c"(data[2]), "=d"(data[3]) : "a"(selector));
+# elif defined(__i386__)
+ asm("pushl %%ebx \n\t"
+ "cpuid \n\t"
+ "movl %%ebx, %1 \n\t"
+ "popl %%ebx \n\t"
+ : "=a"(data[0]), "=r"(data[1]), "=c"(data[2]), "=d"(data[3])
+ : "a"(selector)
+ : "ebx");
+# else
+ data[0] = data[1] = data[2] = data[3] = 0;
+# endif
}
#endif
char *BLI_cpu_brand_string(void)
{
- char buf[48] = { 0 };
- int result[4] = { 0 };
- __cpuid(result, 0x80000000);
- if (result[0] >= (int)0x80000004) {
- __cpuid((int *)(buf + 0), 0x80000002);
- __cpuid((int *)(buf + 16), 0x80000003);
- __cpuid((int *)(buf + 32), 0x80000004);
- char *brand = BLI_strdup(buf);
- /* TODO(sergey): Make it a bit more presentable by removing trademark. */
- return brand;
- }
- return NULL;
+ char buf[48] = {0};
+ int result[4] = {0};
+ __cpuid(result, 0x80000000);
+ if (result[0] >= (int)0x80000004) {
+ __cpuid((int *)(buf + 0), 0x80000002);
+ __cpuid((int *)(buf + 16), 0x80000003);
+ __cpuid((int *)(buf + 32), 0x80000004);
+ char *brand = BLI_strdup(buf);
+ /* TODO(sergey): Make it a bit more presentable by removing trademark. */
+ return brand;
+ }
+ return NULL;
}
void BLI_hostname_get(char *buffer, size_t bufsize)
{
#ifndef WIN32
- if (gethostname(buffer, bufsize - 1) < 0) {
- BLI_strncpy(buffer, "-unknown-", bufsize);
- }
- /* When gethostname() truncates, it doesn't guarantee the trailing \0. */
- buffer[bufsize - 1] = '\0';
+ if (gethostname(buffer, bufsize - 1) < 0) {
+ BLI_strncpy(buffer, "-unknown-", bufsize);
+ }
+ /* When gethostname() truncates, it doesn't guarantee the trailing \0. */
+ buffer[bufsize - 1] = '\0';
#else
- DWORD bufsize_inout = bufsize;
- if (!GetComputerName(buffer, &bufsize_inout)) {
- strncpy(buffer, "-unknown-", bufsize);
- }
+ DWORD bufsize_inout = bufsize;
+ if (!GetComputerName(buffer, &bufsize_inout)) {
+ strncpy(buffer, "-unknown-", bufsize);
+ }
#endif
}
diff --git a/source/blender/blenlib/intern/task.c b/source/blender/blenlib/intern/task.c
index 3a6613b2612..57ce4f16b1a 100644
--- a/source/blender/blenlib/intern/task.c
+++ b/source/blender/blenlib/intern/task.c
@@ -59,33 +59,33 @@
#define DELAYED_QUEUE_SIZE 4096
#ifndef NDEBUG
-# define ASSERT_THREAD_ID(scheduler, thread_id) \
- do { \
- if (!BLI_thread_is_main()) { \
- TaskThread *thread = pthread_getspecific(scheduler->tls_id_key); \
- if (thread == NULL) { \
- BLI_assert(thread_id == 0); \
- } \
- else { \
- BLI_assert(thread_id == thread->id); \
- } \
- } \
- else { \
- BLI_assert(thread_id == 0); \
- } \
- } while (false)
+# define ASSERT_THREAD_ID(scheduler, thread_id) \
+ do { \
+ if (!BLI_thread_is_main()) { \
+ TaskThread *thread = pthread_getspecific(scheduler->tls_id_key); \
+ if (thread == NULL) { \
+ BLI_assert(thread_id == 0); \
+ } \
+ else { \
+ BLI_assert(thread_id == thread->id); \
+ } \
+ } \
+ else { \
+ BLI_assert(thread_id == 0); \
+ } \
+ } while (false)
#else
# define ASSERT_THREAD_ID(scheduler, thread_id)
#endif
typedef struct Task {
- struct Task *next, *prev;
+ struct Task *next, *prev;
- TaskRunFunction run;
- void *taskdata;
- bool free_taskdata;
- TaskFreeFunction freedata;
- TaskPool *pool;
+ TaskRunFunction run;
+ void *taskdata;
+ bool free_taskdata;
+ TaskFreeFunction freedata;
+ TaskPool *pool;
} Task;
/* This is a per-thread storage of pre-allocated tasks.
@@ -115,471 +115,467 @@ typedef struct Task {
* pool which corresponds to a thread which handled the task.
*/
typedef struct TaskMemPool {
- /* Number of pre-allocated tasks in the pool. */
- int num_tasks;
- /* Pre-allocated task memory pointers. */
- Task *tasks[MEMPOOL_SIZE];
+ /* Number of pre-allocated tasks in the pool. */
+ int num_tasks;
+ /* Pre-allocated task memory pointers. */
+ Task *tasks[MEMPOOL_SIZE];
} TaskMemPool;
#ifdef DEBUG_STATS
typedef struct TaskMemPoolStats {
- /* Number of allocations. */
- int num_alloc;
- /* Number of avoided allocations (pointer was re-used from the pool). */
- int num_reuse;
- /* Number of discarded memory due to pool saturation, */
- int num_discard;
+ /* Number of allocations. */
+ int num_alloc;
+ /* Number of avoided allocations (pointer was re-used from the pool). */
+ int num_reuse;
+ /* Number of discarded memory due to pool saturation, */
+ int num_discard;
} TaskMemPoolStats;
#endif
typedef struct TaskThreadLocalStorage {
- /* Memory pool for faster task allocation.
- * The idea is to re-use memory of finished/discarded tasks by this thread.
- */
- TaskMemPool task_mempool;
-
- /* Local queue keeps thread alive by keeping small amount of tasks ready
- * to be picked up without causing global thread locks for synchronization.
- */
- int num_local_queue;
- Task *local_queue[LOCAL_QUEUE_SIZE];
-
- /* Thread can be marked for delayed tasks push. This is helpful when it's
- * know that lots of subsequent task pushed will happen from the same thread
- * without "interrupting" for task execution.
- *
- * We try to accumulate as much tasks as possible in a local queue without
- * any locks first, and then we push all of them into a scheduler's queue
- * from within a single mutex lock.
- */
- bool do_delayed_push;
- int num_delayed_queue;
- Task *delayed_queue[DELAYED_QUEUE_SIZE];
+ /* Memory pool for faster task allocation.
+ * The idea is to re-use memory of finished/discarded tasks by this thread.
+ */
+ TaskMemPool task_mempool;
+
+ /* Local queue keeps thread alive by keeping small amount of tasks ready
+ * to be picked up without causing global thread locks for synchronization.
+ */
+ int num_local_queue;
+ Task *local_queue[LOCAL_QUEUE_SIZE];
+
+ /* Thread can be marked for delayed tasks push. This is helpful when it's
+ * know that lots of subsequent task pushed will happen from the same thread
+ * without "interrupting" for task execution.
+ *
+ * We try to accumulate as much tasks as possible in a local queue without
+ * any locks first, and then we push all of them into a scheduler's queue
+ * from within a single mutex lock.
+ */
+ bool do_delayed_push;
+ int num_delayed_queue;
+ Task *delayed_queue[DELAYED_QUEUE_SIZE];
} TaskThreadLocalStorage;
struct TaskPool {
- TaskScheduler *scheduler;
-
- volatile size_t num;
- ThreadMutex num_mutex;
- ThreadCondition num_cond;
-
- void *userdata;
- ThreadMutex user_mutex;
-
- volatile bool do_cancel;
- volatile bool do_work;
-
- volatile bool is_suspended;
- bool start_suspended;
- ListBase suspended_queue;
- size_t num_suspended;
-
- /* If set, this pool may never be work_and_wait'ed, which means TaskScheduler
- * has to use its special background fallback thread in case we are in
- * single-threaded situation.
- */
- bool run_in_background;
-
- /* This is a task scheduler's ID of a thread at which pool was constructed.
- * It will be used to access task TLS.
- */
- int thread_id;
-
- /* For the pools which are created from non-main thread which is not a
- * scheduler worker thread we can't re-use any of scheduler's threads TLS
- * and have to use our own one.
- */
- bool use_local_tls;
- TaskThreadLocalStorage local_tls;
+ TaskScheduler *scheduler;
+
+ volatile size_t num;
+ ThreadMutex num_mutex;
+ ThreadCondition num_cond;
+
+ void *userdata;
+ ThreadMutex user_mutex;
+
+ volatile bool do_cancel;
+ volatile bool do_work;
+
+ volatile bool is_suspended;
+ bool start_suspended;
+ ListBase suspended_queue;
+ size_t num_suspended;
+
+ /* If set, this pool may never be work_and_wait'ed, which means TaskScheduler
+ * has to use its special background fallback thread in case we are in
+ * single-threaded situation.
+ */
+ bool run_in_background;
+
+ /* This is a task scheduler's ID of a thread at which pool was constructed.
+ * It will be used to access task TLS.
+ */
+ int thread_id;
+
+ /* For the pools which are created from non-main thread which is not a
+ * scheduler worker thread we can't re-use any of scheduler's threads TLS
+ * and have to use our own one.
+ */
+ bool use_local_tls;
+ TaskThreadLocalStorage local_tls;
#ifndef NDEBUG
- pthread_t creator_thread_id;
+ pthread_t creator_thread_id;
#endif
#ifdef DEBUG_STATS
- TaskMemPoolStats *mempool_stats;
+ TaskMemPoolStats *mempool_stats;
#endif
};
struct TaskScheduler {
- pthread_t *threads;
- struct TaskThread *task_threads;
- int num_threads;
- bool background_thread_only;
+ pthread_t *threads;
+ struct TaskThread *task_threads;
+ int num_threads;
+ bool background_thread_only;
- ListBase queue;
- ThreadMutex queue_mutex;
- ThreadCondition queue_cond;
+ ListBase queue;
+ ThreadMutex queue_mutex;
+ ThreadCondition queue_cond;
- volatile bool do_exit;
+ volatile bool do_exit;
- /* NOTE: In pthread's TLS we store the whole TaskThread structure. */
- pthread_key_t tls_id_key;
+ /* NOTE: In pthread's TLS we store the whole TaskThread structure. */
+ pthread_key_t tls_id_key;
};
typedef struct TaskThread {
- TaskScheduler *scheduler;
- int id;
- TaskThreadLocalStorage tls;
+ TaskScheduler *scheduler;
+ int id;
+ TaskThreadLocalStorage tls;
} TaskThread;
/* Helper */
BLI_INLINE void task_data_free(Task *task, const int thread_id)
{
- if (task->free_taskdata) {
- if (task->freedata) {
- task->freedata(task->pool, task->taskdata, thread_id);
- }
- else {
- MEM_freeN(task->taskdata);
- }
- }
+ if (task->free_taskdata) {
+ if (task->freedata) {
+ task->freedata(task->pool, task->taskdata, thread_id);
+ }
+ else {
+ MEM_freeN(task->taskdata);
+ }
+ }
}
BLI_INLINE void initialize_task_tls(TaskThreadLocalStorage *tls)
{
- memset(tls, 0, sizeof(TaskThreadLocalStorage));
+ memset(tls, 0, sizeof(TaskThreadLocalStorage));
}
-BLI_INLINE TaskThreadLocalStorage *get_task_tls(TaskPool *pool,
- const int thread_id)
+BLI_INLINE TaskThreadLocalStorage *get_task_tls(TaskPool *pool, const int thread_id)
{
- TaskScheduler *scheduler = pool->scheduler;
- BLI_assert(thread_id >= 0);
- BLI_assert(thread_id <= scheduler->num_threads);
- if (pool->use_local_tls && thread_id == 0) {
- BLI_assert(pool->thread_id == 0);
- BLI_assert(!BLI_thread_is_main());
- BLI_assert(pthread_equal(pthread_self(), pool->creator_thread_id));
- return &pool->local_tls;
- }
- if (thread_id == 0) {
- BLI_assert(BLI_thread_is_main());
- return &scheduler->task_threads[pool->thread_id].tls;
- }
- return &scheduler->task_threads[thread_id].tls;
+ TaskScheduler *scheduler = pool->scheduler;
+ BLI_assert(thread_id >= 0);
+ BLI_assert(thread_id <= scheduler->num_threads);
+ if (pool->use_local_tls && thread_id == 0) {
+ BLI_assert(pool->thread_id == 0);
+ BLI_assert(!BLI_thread_is_main());
+ BLI_assert(pthread_equal(pthread_self(), pool->creator_thread_id));
+ return &pool->local_tls;
+ }
+ if (thread_id == 0) {
+ BLI_assert(BLI_thread_is_main());
+ return &scheduler->task_threads[pool->thread_id].tls;
+ }
+ return &scheduler->task_threads[thread_id].tls;
}
BLI_INLINE void free_task_tls(TaskThreadLocalStorage *tls)
{
- TaskMemPool *task_mempool = &tls->task_mempool;
- for (int i = 0; i < task_mempool->num_tasks; ++i) {
- MEM_freeN(task_mempool->tasks[i]);
- }
+ TaskMemPool *task_mempool = &tls->task_mempool;
+ for (int i = 0; i < task_mempool->num_tasks; ++i) {
+ MEM_freeN(task_mempool->tasks[i]);
+ }
}
static Task *task_alloc(TaskPool *pool, const int thread_id)
{
- BLI_assert(thread_id <= pool->scheduler->num_threads);
- if (thread_id != -1) {
- BLI_assert(thread_id >= 0);
- BLI_assert(thread_id <= pool->scheduler->num_threads);
- TaskThreadLocalStorage *tls = get_task_tls(pool, thread_id);
- TaskMemPool *task_mempool = &tls->task_mempool;
- /* Try to re-use task memory from a thread local storage. */
- if (task_mempool->num_tasks > 0) {
- --task_mempool->num_tasks;
- /* Success! We've just avoided task allocation. */
+ BLI_assert(thread_id <= pool->scheduler->num_threads);
+ if (thread_id != -1) {
+ BLI_assert(thread_id >= 0);
+ BLI_assert(thread_id <= pool->scheduler->num_threads);
+ TaskThreadLocalStorage *tls = get_task_tls(pool, thread_id);
+ TaskMemPool *task_mempool = &tls->task_mempool;
+ /* Try to re-use task memory from a thread local storage. */
+ if (task_mempool->num_tasks > 0) {
+ --task_mempool->num_tasks;
+ /* Success! We've just avoided task allocation. */
#ifdef DEBUG_STATS
- pool->mempool_stats[thread_id].num_reuse++;
+ pool->mempool_stats[thread_id].num_reuse++;
#endif
- return task_mempool->tasks[task_mempool->num_tasks];
- }
- /* We are doomed to allocate new task data. */
+ return task_mempool->tasks[task_mempool->num_tasks];
+ }
+ /* We are doomed to allocate new task data. */
#ifdef DEBUG_STATS
- pool->mempool_stats[thread_id].num_alloc++;
+ pool->mempool_stats[thread_id].num_alloc++;
#endif
- }
- return MEM_mallocN(sizeof(Task), "New task");
+ }
+ return MEM_mallocN(sizeof(Task), "New task");
}
static void task_free(TaskPool *pool, Task *task, const int thread_id)
{
- task_data_free(task, thread_id);
- BLI_assert(thread_id >= 0);
- BLI_assert(thread_id <= pool->scheduler->num_threads);
- if (thread_id == 0) {
- BLI_assert(pool->use_local_tls || BLI_thread_is_main());
- }
- TaskThreadLocalStorage *tls = get_task_tls(pool, thread_id);
- TaskMemPool *task_mempool = &tls->task_mempool;
- if (task_mempool->num_tasks < MEMPOOL_SIZE - 1) {
- /* Successfully allowed the task to be re-used later. */
- task_mempool->tasks[task_mempool->num_tasks] = task;
- ++task_mempool->num_tasks;
- }
- else {
- /* Local storage saturated, no other way than just discard
- * the memory.
- *
- * TODO(sergey): We can perhaps store such pointer in a global
- * scheduler pool, maybe it'll be faster than discarding and
- * allocating again.
- */
- MEM_freeN(task);
+ task_data_free(task, thread_id);
+ BLI_assert(thread_id >= 0);
+ BLI_assert(thread_id <= pool->scheduler->num_threads);
+ if (thread_id == 0) {
+ BLI_assert(pool->use_local_tls || BLI_thread_is_main());
+ }
+ TaskThreadLocalStorage *tls = get_task_tls(pool, thread_id);
+ TaskMemPool *task_mempool = &tls->task_mempool;
+ if (task_mempool->num_tasks < MEMPOOL_SIZE - 1) {
+ /* Successfully allowed the task to be re-used later. */
+ task_mempool->tasks[task_mempool->num_tasks] = task;
+ ++task_mempool->num_tasks;
+ }
+ else {
+ /* Local storage saturated, no other way than just discard
+ * the memory.
+ *
+ * TODO(sergey): We can perhaps store such pointer in a global
+ * scheduler pool, maybe it'll be faster than discarding and
+ * allocating again.
+ */
+ MEM_freeN(task);
#ifdef DEBUG_STATS
- pool->mempool_stats[thread_id].num_discard++;
+ pool->mempool_stats[thread_id].num_discard++;
#endif
- }
+ }
}
/* Task Scheduler */
static void task_pool_num_decrease(TaskPool *pool, size_t done)
{
- BLI_mutex_lock(&pool->num_mutex);
+ BLI_mutex_lock(&pool->num_mutex);
- BLI_assert(pool->num >= done);
+ BLI_assert(pool->num >= done);
- pool->num -= done;
+ pool->num -= done;
- if (pool->num == 0) {
- BLI_condition_notify_all(&pool->num_cond);
- }
+ if (pool->num == 0) {
+ BLI_condition_notify_all(&pool->num_cond);
+ }
- BLI_mutex_unlock(&pool->num_mutex);
+ BLI_mutex_unlock(&pool->num_mutex);
}
static void task_pool_num_increase(TaskPool *pool, size_t new)
{
- BLI_mutex_lock(&pool->num_mutex);
+ BLI_mutex_lock(&pool->num_mutex);
- pool->num += new;
- BLI_condition_notify_all(&pool->num_cond);
+ pool->num += new;
+ BLI_condition_notify_all(&pool->num_cond);
- BLI_mutex_unlock(&pool->num_mutex);
+ BLI_mutex_unlock(&pool->num_mutex);
}
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);
- }
-
- do {
- Task *current_task;
-
- /* Assuming we can only have a void queue in 'exit' case here seems logical
- * (we should only be here after our worker thread has been woken up from a
- * condition_wait(), which only happens after a new task was added to the queue),
- * but it is wrong.
- * Waiting on condition may wake up the thread even if condition is not signaled
- * (spurious wake-ups), and some race condition may also empty the queue **after**
- * condition has been signaled, but **before** awoken thread reaches this point...
- * See http://stackoverflow.com/questions/8594591
- *
- * So we only abort here if do_exit is set.
- */
- if (scheduler->do_exit) {
- BLI_mutex_unlock(&scheduler->queue_mutex);
- return false;
- }
-
- for (current_task = scheduler->queue.first;
- current_task != NULL;
- current_task = current_task->next)
- {
- TaskPool *pool = current_task->pool;
-
- if (scheduler->background_thread_only && !pool->run_in_background) {
- continue;
- }
-
- *task = current_task;
- found_task = true;
- 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);
-
- return true;
+ 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);
+ }
+
+ do {
+ Task *current_task;
+
+ /* Assuming we can only have a void queue in 'exit' case here seems logical
+ * (we should only be here after our worker thread has been woken up from a
+ * condition_wait(), which only happens after a new task was added to the queue),
+ * but it is wrong.
+ * Waiting on condition may wake up the thread even if condition is not signaled
+ * (spurious wake-ups), and some race condition may also empty the queue **after**
+ * condition has been signaled, but **before** awoken thread reaches this point...
+ * See http://stackoverflow.com/questions/8594591
+ *
+ * So we only abort here if do_exit is set.
+ */
+ if (scheduler->do_exit) {
+ BLI_mutex_unlock(&scheduler->queue_mutex);
+ return false;
+ }
+
+ for (current_task = scheduler->queue.first; current_task != NULL;
+ current_task = current_task->next) {
+ TaskPool *pool = current_task->pool;
+
+ if (scheduler->background_thread_only && !pool->run_in_background) {
+ continue;
+ }
+
+ *task = current_task;
+ found_task = true;
+ 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);
+
+ return true;
}
-BLI_INLINE void handle_local_queue(TaskThreadLocalStorage *tls,
- const int thread_id)
+BLI_INLINE void handle_local_queue(TaskThreadLocalStorage *tls, const int thread_id)
{
- BLI_assert(!tls->do_delayed_push);
- while (tls->num_local_queue > 0) {
- /* We pop task from queue before handling it so handler of the task can
- * push next job to the local queue.
- */
- tls->num_local_queue--;
- Task *local_task = tls->local_queue[tls->num_local_queue];
- /* TODO(sergey): Double-check work_and_wait() doesn't handle other's
- * pool tasks.
- */
- TaskPool *local_pool = local_task->pool;
- local_task->run(local_pool, local_task->taskdata, thread_id);
- task_free(local_pool, local_task, thread_id);
- }
- BLI_assert(!tls->do_delayed_push);
+ BLI_assert(!tls->do_delayed_push);
+ while (tls->num_local_queue > 0) {
+ /* We pop task from queue before handling it so handler of the task can
+ * push next job to the local queue.
+ */
+ tls->num_local_queue--;
+ Task *local_task = tls->local_queue[tls->num_local_queue];
+ /* TODO(sergey): Double-check work_and_wait() doesn't handle other's
+ * pool tasks.
+ */
+ TaskPool *local_pool = local_task->pool;
+ local_task->run(local_pool, local_task->taskdata, thread_id);
+ task_free(local_pool, local_task, thread_id);
+ }
+ BLI_assert(!tls->do_delayed_push);
}
static void *task_scheduler_thread_run(void *thread_p)
{
- TaskThread *thread = (TaskThread *) thread_p;
- TaskThreadLocalStorage *tls = &thread->tls;
- TaskScheduler *scheduler = thread->scheduler;
- int thread_id = thread->id;
- Task *task;
+ TaskThread *thread = (TaskThread *)thread_p;
+ TaskThreadLocalStorage *tls = &thread->tls;
+ TaskScheduler *scheduler = thread->scheduler;
+ int thread_id = thread->id;
+ Task *task;
- pthread_setspecific(scheduler->tls_id_key, thread);
+ pthread_setspecific(scheduler->tls_id_key, thread);
- /* keep popping off tasks */
- while (task_scheduler_thread_wait_pop(scheduler, &task)) {
- TaskPool *pool = task->pool;
+ /* keep popping off tasks */
+ while (task_scheduler_thread_wait_pop(scheduler, &task)) {
+ TaskPool *pool = task->pool;
- /* run task */
- BLI_assert(!tls->do_delayed_push);
- task->run(pool, task->taskdata, thread_id);
- BLI_assert(!tls->do_delayed_push);
+ /* run task */
+ BLI_assert(!tls->do_delayed_push);
+ task->run(pool, task->taskdata, thread_id);
+ BLI_assert(!tls->do_delayed_push);
- /* delete task */
- task_free(pool, task, thread_id);
+ /* delete task */
+ task_free(pool, task, thread_id);
- /* Handle all tasks from local queue. */
- handle_local_queue(tls, thread_id);
+ /* Handle all tasks from local queue. */
+ handle_local_queue(tls, thread_id);
- /* notify pool task was done */
- task_pool_num_decrease(pool, 1);
- }
+ /* notify pool task was done */
+ task_pool_num_decrease(pool, 1);
+ }
- return NULL;
+ return NULL;
}
TaskScheduler *BLI_task_scheduler_create(int num_threads)
{
- TaskScheduler *scheduler = MEM_callocN(sizeof(TaskScheduler), "TaskScheduler");
+ TaskScheduler *scheduler = MEM_callocN(sizeof(TaskScheduler), "TaskScheduler");
- /* multiple places can use this task scheduler, sharing the same
- * threads, so we keep track of the number of users. */
- scheduler->do_exit = false;
+ /* multiple places can use this task scheduler, sharing the same
+ * threads, so we keep track of the number of users. */
+ scheduler->do_exit = false;
- BLI_listbase_clear(&scheduler->queue);
- BLI_mutex_init(&scheduler->queue_mutex);
- BLI_condition_init(&scheduler->queue_cond);
+ BLI_listbase_clear(&scheduler->queue);
+ BLI_mutex_init(&scheduler->queue_mutex);
+ BLI_condition_init(&scheduler->queue_cond);
- if (num_threads == 0) {
- /* automatic number of threads will be main thread + num cores */
- num_threads = BLI_system_thread_count();
- }
+ if (num_threads == 0) {
+ /* automatic number of threads will be main thread + num cores */
+ num_threads = BLI_system_thread_count();
+ }
- /* main thread will also work, so we count it too */
- num_threads -= 1;
+ /* main thread will also work, so we count it too */
+ num_threads -= 1;
- /* Add background-only thread if needed. */
- if (num_threads == 0) {
- scheduler->background_thread_only = true;
- num_threads = 1;
- }
+ /* Add background-only thread if needed. */
+ if (num_threads == 0) {
+ scheduler->background_thread_only = true;
+ num_threads = 1;
+ }
- scheduler->task_threads = MEM_mallocN(sizeof(TaskThread) * (num_threads + 1),
- "TaskScheduler task threads");
+ scheduler->task_threads = MEM_mallocN(sizeof(TaskThread) * (num_threads + 1),
+ "TaskScheduler task threads");
- /* Initialize TLS for main thread. */
- initialize_task_tls(&scheduler->task_threads[0].tls);
+ /* Initialize TLS for main thread. */
+ initialize_task_tls(&scheduler->task_threads[0].tls);
- pthread_key_create(&scheduler->tls_id_key, NULL);
+ pthread_key_create(&scheduler->tls_id_key, NULL);
- /* launch threads that will be waiting for work */
- if (num_threads > 0) {
- int i;
+ /* launch threads that will be waiting for work */
+ if (num_threads > 0) {
+ int i;
- scheduler->num_threads = num_threads;
- scheduler->threads = MEM_callocN(sizeof(pthread_t) * num_threads, "TaskScheduler threads");
+ scheduler->num_threads = num_threads;
+ scheduler->threads = MEM_callocN(sizeof(pthread_t) * num_threads, "TaskScheduler threads");
- for (i = 0; i < num_threads; i++) {
- TaskThread *thread = &scheduler->task_threads[i + 1];
- thread->scheduler = scheduler;
- thread->id = i + 1;
- initialize_task_tls(&thread->tls);
+ for (i = 0; i < num_threads; i++) {
+ TaskThread *thread = &scheduler->task_threads[i + 1];
+ thread->scheduler = scheduler;
+ thread->id = i + 1;
+ initialize_task_tls(&thread->tls);
- if (pthread_create(&scheduler->threads[i], NULL, task_scheduler_thread_run, thread) != 0) {
- fprintf(stderr, "TaskScheduler failed to launch thread %d/%d\n", i, num_threads);
- }
- }
- }
+ if (pthread_create(&scheduler->threads[i], NULL, task_scheduler_thread_run, thread) != 0) {
+ fprintf(stderr, "TaskScheduler failed to launch thread %d/%d\n", i, num_threads);
+ }
+ }
+ }
- return scheduler;
+ return scheduler;
}
void BLI_task_scheduler_free(TaskScheduler *scheduler)
{
- Task *task;
-
- /* stop all waiting threads */
- BLI_mutex_lock(&scheduler->queue_mutex);
- scheduler->do_exit = true;
- BLI_condition_notify_all(&scheduler->queue_cond);
- BLI_mutex_unlock(&scheduler->queue_mutex);
-
- pthread_key_delete(scheduler->tls_id_key);
-
- /* delete threads */
- if (scheduler->threads) {
- int i;
-
- for (i = 0; i < scheduler->num_threads; i++) {
- if (pthread_join(scheduler->threads[i], NULL) != 0) {
- fprintf(stderr, "TaskScheduler failed to join thread %d/%d\n", i, scheduler->num_threads);
- }
- }
-
- MEM_freeN(scheduler->threads);
- }
-
- /* Delete task thread data */
- if (scheduler->task_threads) {
- for (int i = 0; i < scheduler->num_threads + 1; ++i) {
- TaskThreadLocalStorage *tls = &scheduler->task_threads[i].tls;
- free_task_tls(tls);
- }
-
- MEM_freeN(scheduler->task_threads);
- }
-
- /* delete leftover tasks */
- for (task = scheduler->queue.first; task; task = task->next) {
- task_data_free(task, 0);
- }
- BLI_freelistN(&scheduler->queue);
-
- /* delete mutex/condition */
- BLI_mutex_end(&scheduler->queue_mutex);
- BLI_condition_end(&scheduler->queue_cond);
-
- MEM_freeN(scheduler);
+ Task *task;
+
+ /* stop all waiting threads */
+ BLI_mutex_lock(&scheduler->queue_mutex);
+ scheduler->do_exit = true;
+ BLI_condition_notify_all(&scheduler->queue_cond);
+ BLI_mutex_unlock(&scheduler->queue_mutex);
+
+ pthread_key_delete(scheduler->tls_id_key);
+
+ /* delete threads */
+ if (scheduler->threads) {
+ int i;
+
+ for (i = 0; i < scheduler->num_threads; i++) {
+ if (pthread_join(scheduler->threads[i], NULL) != 0) {
+ fprintf(stderr, "TaskScheduler failed to join thread %d/%d\n", i, scheduler->num_threads);
+ }
+ }
+
+ MEM_freeN(scheduler->threads);
+ }
+
+ /* Delete task thread data */
+ if (scheduler->task_threads) {
+ for (int i = 0; i < scheduler->num_threads + 1; ++i) {
+ TaskThreadLocalStorage *tls = &scheduler->task_threads[i].tls;
+ free_task_tls(tls);
+ }
+
+ MEM_freeN(scheduler->task_threads);
+ }
+
+ /* delete leftover tasks */
+ for (task = scheduler->queue.first; task; task = task->next) {
+ task_data_free(task, 0);
+ }
+ BLI_freelistN(&scheduler->queue);
+
+ /* delete mutex/condition */
+ BLI_mutex_end(&scheduler->queue_mutex);
+ BLI_condition_end(&scheduler->queue_cond);
+
+ MEM_freeN(scheduler);
}
int BLI_task_scheduler_num_threads(TaskScheduler *scheduler)
{
- return scheduler->num_threads + 1;
+ return scheduler->num_threads + 1;
}
static void task_scheduler_push(TaskScheduler *scheduler, Task *task, TaskPriority priority)
{
- task_pool_num_increase(task->pool, 1);
+ task_pool_num_increase(task->pool, 1);
- /* add task to queue */
- BLI_mutex_lock(&scheduler->queue_mutex);
+ /* add task to queue */
+ BLI_mutex_lock(&scheduler->queue_mutex);
- if (priority == TASK_PRIORITY_HIGH) {
- BLI_addhead(&scheduler->queue, task);
- }
- else {
- BLI_addtail(&scheduler->queue, task);
- }
+ if (priority == TASK_PRIORITY_HIGH) {
+ BLI_addhead(&scheduler->queue, task);
+ }
+ else {
+ BLI_addtail(&scheduler->queue, task);
+ }
- BLI_condition_notify_one(&scheduler->queue_cond);
- BLI_mutex_unlock(&scheduler->queue_mutex);
+ BLI_condition_notify_one(&scheduler->queue_cond);
+ BLI_mutex_unlock(&scheduler->queue_mutex);
}
static void task_scheduler_push_all(TaskScheduler *scheduler,
@@ -587,45 +583,45 @@ static void task_scheduler_push_all(TaskScheduler *scheduler,
Task **tasks,
int num_tasks)
{
- if (num_tasks == 0) {
- return;
- }
+ if (num_tasks == 0) {
+ return;
+ }
- task_pool_num_increase(pool, num_tasks);
+ task_pool_num_increase(pool, num_tasks);
- BLI_mutex_lock(&scheduler->queue_mutex);
+ BLI_mutex_lock(&scheduler->queue_mutex);
- for (int i = 0; i < num_tasks; i++) {
- BLI_addhead(&scheduler->queue, tasks[i]);
- }
+ for (int i = 0; i < num_tasks; i++) {
+ BLI_addhead(&scheduler->queue, tasks[i]);
+ }
- BLI_condition_notify_all(&scheduler->queue_cond);
- BLI_mutex_unlock(&scheduler->queue_mutex);
+ BLI_condition_notify_all(&scheduler->queue_cond);
+ BLI_mutex_unlock(&scheduler->queue_mutex);
}
static void task_scheduler_clear(TaskScheduler *scheduler, TaskPool *pool)
{
- Task *task, *nexttask;
- size_t done = 0;
+ Task *task, *nexttask;
+ size_t done = 0;
- BLI_mutex_lock(&scheduler->queue_mutex);
+ BLI_mutex_lock(&scheduler->queue_mutex);
- /* free all tasks from this pool from the queue */
- for (task = scheduler->queue.first; task; task = nexttask) {
- nexttask = task->next;
+ /* free all tasks from this pool from the queue */
+ for (task = scheduler->queue.first; task; task = nexttask) {
+ nexttask = task->next;
- if (task->pool == pool) {
- task_data_free(task, pool->thread_id);
- BLI_freelinkN(&scheduler->queue, task);
+ if (task->pool == pool) {
+ task_data_free(task, pool->thread_id);
+ BLI_freelinkN(&scheduler->queue, task);
- done++;
- }
- }
+ done++;
+ }
+ }
- BLI_mutex_unlock(&scheduler->queue_mutex);
+ BLI_mutex_unlock(&scheduler->queue_mutex);
- /* notify done */
- task_pool_num_decrease(pool, done);
+ /* notify done */
+ task_pool_num_decrease(pool, done);
}
/* Task Pool */
@@ -635,76 +631,75 @@ static TaskPool *task_pool_create_ex(TaskScheduler *scheduler,
const bool is_background,
const bool is_suspended)
{
- TaskPool *pool = MEM_mallocN(sizeof(TaskPool), "TaskPool");
+ TaskPool *pool = MEM_mallocN(sizeof(TaskPool), "TaskPool");
#ifndef NDEBUG
- /* Assert we do not try to create a background pool from some parent task -
- * those only work OK from main thread. */
- if (is_background) {
- const pthread_t thread_id = pthread_self();
- int i = scheduler->num_threads;
-
- while (i--) {
- BLI_assert(!pthread_equal(scheduler->threads[i], thread_id));
- }
- }
+ /* Assert we do not try to create a background pool from some parent task -
+ * those only work OK from main thread. */
+ if (is_background) {
+ const pthread_t thread_id = pthread_self();
+ int i = scheduler->num_threads;
+
+ while (i--) {
+ BLI_assert(!pthread_equal(scheduler->threads[i], thread_id));
+ }
+ }
#endif
- pool->scheduler = scheduler;
- pool->num = 0;
- pool->do_cancel = false;
- pool->do_work = false;
- pool->is_suspended = is_suspended;
- pool->start_suspended = is_suspended;
- pool->num_suspended = 0;
- pool->suspended_queue.first = pool->suspended_queue.last = NULL;
- pool->run_in_background = is_background;
- pool->use_local_tls = false;
-
- BLI_mutex_init(&pool->num_mutex);
- BLI_condition_init(&pool->num_cond);
-
- pool->userdata = userdata;
- BLI_mutex_init(&pool->user_mutex);
-
- if (BLI_thread_is_main()) {
- pool->thread_id = 0;
- }
- else {
- TaskThread *thread = pthread_getspecific(scheduler->tls_id_key);
- if (thread == NULL) {
- /* NOTE: Task pool is created from non-main thread which is not
- * managed by the task scheduler. We identify ourselves as thread ID
- * 0 but we do not use scheduler's TLS storage and use our own
- * instead to avoid any possible threading conflicts.
- */
- pool->thread_id = 0;
- pool->use_local_tls = true;
+ pool->scheduler = scheduler;
+ pool->num = 0;
+ pool->do_cancel = false;
+ pool->do_work = false;
+ pool->is_suspended = is_suspended;
+ pool->start_suspended = is_suspended;
+ pool->num_suspended = 0;
+ pool->suspended_queue.first = pool->suspended_queue.last = NULL;
+ pool->run_in_background = is_background;
+ pool->use_local_tls = false;
+
+ BLI_mutex_init(&pool->num_mutex);
+ BLI_condition_init(&pool->num_cond);
+
+ pool->userdata = userdata;
+ BLI_mutex_init(&pool->user_mutex);
+
+ if (BLI_thread_is_main()) {
+ pool->thread_id = 0;
+ }
+ else {
+ TaskThread *thread = pthread_getspecific(scheduler->tls_id_key);
+ if (thread == NULL) {
+ /* NOTE: Task pool is created from non-main thread which is not
+ * managed by the task scheduler. We identify ourselves as thread ID
+ * 0 but we do not use scheduler's TLS storage and use our own
+ * instead to avoid any possible threading conflicts.
+ */
+ pool->thread_id = 0;
+ pool->use_local_tls = true;
#ifndef NDEBUG
- pool->creator_thread_id = pthread_self();
+ pool->creator_thread_id = pthread_self();
#endif
- initialize_task_tls(&pool->local_tls);
- }
- else {
- pool->thread_id = thread->id;
- }
- }
+ initialize_task_tls(&pool->local_tls);
+ }
+ else {
+ pool->thread_id = thread->id;
+ }
+ }
#ifdef DEBUG_STATS
- pool->mempool_stats =
- MEM_callocN(sizeof(*pool->mempool_stats) * (scheduler->num_threads + 1),
- "per-taskpool mempool stats");
+ pool->mempool_stats = MEM_callocN(sizeof(*pool->mempool_stats) * (scheduler->num_threads + 1),
+ "per-taskpool mempool stats");
#endif
- /* Ensure malloc will go fine from threads,
- *
- * This is needed because we could be in main thread here
- * and malloc could be non-thread safe at this point because
- * no other jobs are running.
- */
- BLI_threaded_malloc_begin();
+ /* Ensure malloc will go fine from threads,
+ *
+ * This is needed because we could be in main thread here
+ * and malloc could be non-thread safe at this point because
+ * no other jobs are running.
+ */
+ BLI_threaded_malloc_begin();
- return pool;
+ return pool;
}
/**
@@ -714,7 +709,7 @@ static TaskPool *task_pool_create_ex(TaskScheduler *scheduler,
*/
TaskPool *BLI_task_pool_create(TaskScheduler *scheduler, void *userdata)
{
- return task_pool_create_ex(scheduler, userdata, false, false);
+ return task_pool_create_ex(scheduler, userdata, false, false);
}
/**
@@ -729,7 +724,7 @@ TaskPool *BLI_task_pool_create(TaskScheduler *scheduler, void *userdata)
*/
TaskPool *BLI_task_pool_create_background(TaskScheduler *scheduler, void *userdata)
{
- return task_pool_create_ex(scheduler, userdata, true, false);
+ return task_pool_create_ex(scheduler, userdata, true, false);
}
/**
@@ -739,256 +734,263 @@ TaskPool *BLI_task_pool_create_background(TaskScheduler *scheduler, void *userda
*/
TaskPool *BLI_task_pool_create_suspended(TaskScheduler *scheduler, void *userdata)
{
- return task_pool_create_ex(scheduler, userdata, false, true);
+ return task_pool_create_ex(scheduler, userdata, false, true);
}
void BLI_task_pool_free(TaskPool *pool)
{
- BLI_task_pool_cancel(pool);
+ BLI_task_pool_cancel(pool);
- BLI_mutex_end(&pool->num_mutex);
- BLI_condition_end(&pool->num_cond);
+ BLI_mutex_end(&pool->num_mutex);
+ BLI_condition_end(&pool->num_cond);
- BLI_mutex_end(&pool->user_mutex);
+ BLI_mutex_end(&pool->user_mutex);
#ifdef DEBUG_STATS
- printf("Thread ID Allocated Reused Discarded\n");
- for (int i = 0; i < pool->scheduler->num_threads + 1; ++i) {
- printf("%02d %05d %05d %05d\n",
- i,
- pool->mempool_stats[i].num_alloc,
- pool->mempool_stats[i].num_reuse,
- pool->mempool_stats[i].num_discard);
- }
- MEM_freeN(pool->mempool_stats);
+ printf("Thread ID Allocated Reused Discarded\n");
+ for (int i = 0; i < pool->scheduler->num_threads + 1; ++i) {
+ printf("%02d %05d %05d %05d\n",
+ i,
+ pool->mempool_stats[i].num_alloc,
+ pool->mempool_stats[i].num_reuse,
+ pool->mempool_stats[i].num_discard);
+ }
+ MEM_freeN(pool->mempool_stats);
#endif
- if (pool->use_local_tls) {
- free_task_tls(&pool->local_tls);
- }
+ if (pool->use_local_tls) {
+ free_task_tls(&pool->local_tls);
+ }
- MEM_freeN(pool);
+ MEM_freeN(pool);
- BLI_threaded_malloc_end();
+ BLI_threaded_malloc_end();
}
BLI_INLINE bool task_can_use_local_queues(TaskPool *pool, int thread_id)
{
- return (thread_id != -1 && (thread_id != pool->thread_id || pool->do_work));
+ return (thread_id != -1 && (thread_id != pool->thread_id || pool->do_work));
}
-static void task_pool_push(
- TaskPool *pool, TaskRunFunction run, void *taskdata,
- bool free_taskdata, TaskFreeFunction freedata, TaskPriority priority,
- int thread_id)
+static void task_pool_push(TaskPool *pool,
+ TaskRunFunction run,
+ void *taskdata,
+ bool free_taskdata,
+ TaskFreeFunction freedata,
+ TaskPriority priority,
+ int thread_id)
{
- /* Allocate task and fill it's properties. */
- Task *task = task_alloc(pool, thread_id);
- task->run = run;
- task->taskdata = taskdata;
- task->free_taskdata = free_taskdata;
- task->freedata = freedata;
- task->pool = pool;
- /* For suspended pools we put everything yo a global queue first
- * and exit as soon as possible.
- *
- * This tasks will be moved to actual execution when pool is
- * activated by work_and_wait().
- */
- if (pool->is_suspended) {
- BLI_addhead(&pool->suspended_queue, task);
- atomic_fetch_and_add_z(&pool->num_suspended, 1);
- return;
- }
- /* Populate to any local queue first, this is cheapest push ever. */
- if (task_can_use_local_queues(pool, thread_id)) {
- ASSERT_THREAD_ID(pool->scheduler, thread_id);
- TaskThreadLocalStorage *tls = get_task_tls(pool, thread_id);
- /* Try to push to a local execution queue.
- * These tasks will be picked up next.
- */
- if (tls->num_local_queue < LOCAL_QUEUE_SIZE) {
- tls->local_queue[tls->num_local_queue] = task;
- tls->num_local_queue++;
- return;
- }
- /* If we are in the delayed tasks push mode, we push tasks to a
- * temporary local queue first without any locks, and then move them
- * to global execution queue with a single lock.
- */
- if (tls->do_delayed_push && tls->num_delayed_queue < DELAYED_QUEUE_SIZE) {
- tls->delayed_queue[tls->num_delayed_queue] = task;
- tls->num_delayed_queue++;
- return;
- }
- }
- /* Do push to a global execution pool, slowest possible method,
- * causes quite reasonable amount of threading overhead.
- */
- task_scheduler_push(pool->scheduler, task, priority);
+ /* Allocate task and fill it's properties. */
+ Task *task = task_alloc(pool, thread_id);
+ task->run = run;
+ task->taskdata = taskdata;
+ task->free_taskdata = free_taskdata;
+ task->freedata = freedata;
+ task->pool = pool;
+ /* For suspended pools we put everything yo a global queue first
+ * and exit as soon as possible.
+ *
+ * This tasks will be moved to actual execution when pool is
+ * activated by work_and_wait().
+ */
+ if (pool->is_suspended) {
+ BLI_addhead(&pool->suspended_queue, task);
+ atomic_fetch_and_add_z(&pool->num_suspended, 1);
+ return;
+ }
+ /* Populate to any local queue first, this is cheapest push ever. */
+ if (task_can_use_local_queues(pool, thread_id)) {
+ ASSERT_THREAD_ID(pool->scheduler, thread_id);
+ TaskThreadLocalStorage *tls = get_task_tls(pool, thread_id);
+ /* Try to push to a local execution queue.
+ * These tasks will be picked up next.
+ */
+ if (tls->num_local_queue < LOCAL_QUEUE_SIZE) {
+ tls->local_queue[tls->num_local_queue] = task;
+ tls->num_local_queue++;
+ return;
+ }
+ /* If we are in the delayed tasks push mode, we push tasks to a
+ * temporary local queue first without any locks, and then move them
+ * to global execution queue with a single lock.
+ */
+ if (tls->do_delayed_push && tls->num_delayed_queue < DELAYED_QUEUE_SIZE) {
+ tls->delayed_queue[tls->num_delayed_queue] = task;
+ tls->num_delayed_queue++;
+ return;
+ }
+ }
+ /* Do push to a global execution pool, slowest possible method,
+ * causes quite reasonable amount of threading overhead.
+ */
+ task_scheduler_push(pool->scheduler, task, priority);
}
-void BLI_task_pool_push_ex(
- TaskPool *pool, TaskRunFunction run, void *taskdata,
- bool free_taskdata, TaskFreeFunction freedata, TaskPriority priority)
+void BLI_task_pool_push_ex(TaskPool *pool,
+ TaskRunFunction run,
+ void *taskdata,
+ bool free_taskdata,
+ TaskFreeFunction freedata,
+ TaskPriority priority)
{
- task_pool_push(pool, run, taskdata, free_taskdata, freedata, priority, -1);
+ task_pool_push(pool, run, taskdata, free_taskdata, freedata, priority, -1);
}
void BLI_task_pool_push(
- TaskPool *pool, TaskRunFunction run, void *taskdata, bool free_taskdata, TaskPriority priority)
+ TaskPool *pool, TaskRunFunction run, void *taskdata, bool free_taskdata, TaskPriority priority)
{
- BLI_task_pool_push_ex(pool, run, taskdata, free_taskdata, NULL, priority);
+ BLI_task_pool_push_ex(pool, run, taskdata, free_taskdata, NULL, priority);
}
-void BLI_task_pool_push_from_thread(TaskPool *pool, TaskRunFunction run,
- void *taskdata, bool free_taskdata, TaskPriority priority, int thread_id)
+void BLI_task_pool_push_from_thread(TaskPool *pool,
+ TaskRunFunction run,
+ void *taskdata,
+ bool free_taskdata,
+ TaskPriority priority,
+ int thread_id)
{
- task_pool_push(pool, run, taskdata, free_taskdata, NULL, priority, thread_id);
+ task_pool_push(pool, run, taskdata, free_taskdata, NULL, priority, thread_id);
}
void BLI_task_pool_work_and_wait(TaskPool *pool)
{
- TaskThreadLocalStorage *tls = get_task_tls(pool, pool->thread_id);
- TaskScheduler *scheduler = pool->scheduler;
+ TaskThreadLocalStorage *tls = get_task_tls(pool, pool->thread_id);
+ TaskScheduler *scheduler = pool->scheduler;
- if (atomic_fetch_and_and_uint8((uint8_t *)&pool->is_suspended, 0)) {
- if (pool->num_suspended) {
- task_pool_num_increase(pool, pool->num_suspended);
- BLI_mutex_lock(&scheduler->queue_mutex);
+ if (atomic_fetch_and_and_uint8((uint8_t *)&pool->is_suspended, 0)) {
+ if (pool->num_suspended) {
+ task_pool_num_increase(pool, pool->num_suspended);
+ BLI_mutex_lock(&scheduler->queue_mutex);
- BLI_movelisttolist(&scheduler->queue, &pool->suspended_queue);
+ BLI_movelisttolist(&scheduler->queue, &pool->suspended_queue);
- BLI_condition_notify_all(&scheduler->queue_cond);
- BLI_mutex_unlock(&scheduler->queue_mutex);
+ BLI_condition_notify_all(&scheduler->queue_cond);
+ BLI_mutex_unlock(&scheduler->queue_mutex);
- pool->num_suspended = 0;
- }
- }
+ pool->num_suspended = 0;
+ }
+ }
- pool->do_work = true;
+ pool->do_work = true;
- ASSERT_THREAD_ID(pool->scheduler, pool->thread_id);
+ ASSERT_THREAD_ID(pool->scheduler, pool->thread_id);
- handle_local_queue(tls, pool->thread_id);
+ handle_local_queue(tls, pool->thread_id);
- BLI_mutex_lock(&pool->num_mutex);
+ BLI_mutex_lock(&pool->num_mutex);
- while (pool->num != 0) {
- Task *task, *work_task = NULL;
- bool found_task = false;
+ while (pool->num != 0) {
+ Task *task, *work_task = NULL;
+ bool found_task = false;
- BLI_mutex_unlock(&pool->num_mutex);
+ BLI_mutex_unlock(&pool->num_mutex);
- BLI_mutex_lock(&scheduler->queue_mutex);
+ BLI_mutex_lock(&scheduler->queue_mutex);
- /* find task from this pool. if we get a task from another pool,
- * we can get into deadlock */
+ /* 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;
- }
- }
+ 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;
+ }
+ }
- BLI_mutex_unlock(&scheduler->queue_mutex);
+ BLI_mutex_unlock(&scheduler->queue_mutex);
- /* if found task, do it, otherwise wait until other tasks are done */
- if (found_task) {
- /* run task */
- BLI_assert(!tls->do_delayed_push);
- work_task->run(pool, work_task->taskdata, pool->thread_id);
- BLI_assert(!tls->do_delayed_push);
+ /* if found task, do it, otherwise wait until other tasks are done */
+ if (found_task) {
+ /* run task */
+ BLI_assert(!tls->do_delayed_push);
+ work_task->run(pool, work_task->taskdata, pool->thread_id);
+ BLI_assert(!tls->do_delayed_push);
- /* delete task */
- task_free(pool, task, pool->thread_id);
+ /* delete task */
+ task_free(pool, task, pool->thread_id);
- /* Handle all tasks from local queue. */
- handle_local_queue(tls, pool->thread_id);
+ /* Handle all tasks from local queue. */
+ handle_local_queue(tls, pool->thread_id);
- /* notify pool task was done */
- task_pool_num_decrease(pool, 1);
- }
+ /* notify pool task was done */
+ task_pool_num_decrease(pool, 1);
+ }
- BLI_mutex_lock(&pool->num_mutex);
- if (pool->num == 0) {
- break;
- }
+ BLI_mutex_lock(&pool->num_mutex);
+ if (pool->num == 0) {
+ break;
+ }
- if (!found_task) {
- BLI_condition_wait(&pool->num_cond, &pool->num_mutex);
- }
- }
+ if (!found_task) {
+ BLI_condition_wait(&pool->num_cond, &pool->num_mutex);
+ }
+ }
- BLI_mutex_unlock(&pool->num_mutex);
+ BLI_mutex_unlock(&pool->num_mutex);
- BLI_assert(tls->num_local_queue == 0);
+ BLI_assert(tls->num_local_queue == 0);
}
void BLI_task_pool_work_wait_and_reset(TaskPool *pool)
{
- BLI_task_pool_work_and_wait(pool);
+ BLI_task_pool_work_and_wait(pool);
- pool->do_work = false;
- pool->is_suspended = pool->start_suspended;
+ pool->do_work = false;
+ pool->is_suspended = pool->start_suspended;
}
void BLI_task_pool_cancel(TaskPool *pool)
{
- pool->do_cancel = true;
+ pool->do_cancel = true;
- task_scheduler_clear(pool->scheduler, pool);
+ task_scheduler_clear(pool->scheduler, pool);
- /* wait until all entries are cleared */
- BLI_mutex_lock(&pool->num_mutex);
- while (pool->num) {
- BLI_condition_wait(&pool->num_cond, &pool->num_mutex);
- }
- BLI_mutex_unlock(&pool->num_mutex);
+ /* wait until all entries are cleared */
+ BLI_mutex_lock(&pool->num_mutex);
+ while (pool->num) {
+ BLI_condition_wait(&pool->num_cond, &pool->num_mutex);
+ }
+ BLI_mutex_unlock(&pool->num_mutex);
- pool->do_cancel = false;
+ pool->do_cancel = false;
}
bool BLI_task_pool_canceled(TaskPool *pool)
{
- return pool->do_cancel;
+ return pool->do_cancel;
}
void *BLI_task_pool_userdata(TaskPool *pool)
{
- return pool->userdata;
+ return pool->userdata;
}
ThreadMutex *BLI_task_pool_user_mutex(TaskPool *pool)
{
- return &pool->user_mutex;
+ return &pool->user_mutex;
}
void BLI_task_pool_delayed_push_begin(TaskPool *pool, int thread_id)
{
- if (task_can_use_local_queues(pool, thread_id)) {
- ASSERT_THREAD_ID(pool->scheduler, thread_id);
- TaskThreadLocalStorage *tls = get_task_tls(pool, thread_id);
- tls->do_delayed_push = true;
- }
+ if (task_can_use_local_queues(pool, thread_id)) {
+ ASSERT_THREAD_ID(pool->scheduler, thread_id);
+ TaskThreadLocalStorage *tls = get_task_tls(pool, thread_id);
+ tls->do_delayed_push = true;
+ }
}
void BLI_task_pool_delayed_push_end(TaskPool *pool, int thread_id)
{
- if (task_can_use_local_queues(pool, thread_id)) {
- ASSERT_THREAD_ID(pool->scheduler, thread_id);
- TaskThreadLocalStorage *tls = get_task_tls(pool, thread_id);
- BLI_assert(tls->do_delayed_push);
- task_scheduler_push_all(pool->scheduler,
- pool,
- tls->delayed_queue,
- tls->num_delayed_queue);
- tls->do_delayed_push = false;
- tls->num_delayed_queue = 0;
- }
+ if (task_can_use_local_queues(pool, thread_id)) {
+ ASSERT_THREAD_ID(pool->scheduler, thread_id);
+ TaskThreadLocalStorage *tls = get_task_tls(pool, thread_id);
+ BLI_assert(tls->do_delayed_push);
+ task_scheduler_push_all(pool->scheduler, pool, tls->delayed_queue, tls->num_delayed_queue);
+ tls->do_delayed_push = false;
+ tls->num_delayed_queue = 0;
+ }
}
/* Parallel range routines */
@@ -1007,72 +1009,72 @@ void BLI_task_pool_delayed_push_end(TaskPool *pool, int thread_id)
/* Allows to avoid using malloc for userdata_chunk in tasks, when small enough. */
#define MALLOCA(_size) ((_size) <= 8192) ? alloca((_size)) : MEM_mallocN((_size), __func__)
-#define MALLOCA_FREE(_mem, _size) if (((_mem) != NULL) && ((_size) > 8192)) MEM_freeN((_mem))
+#define MALLOCA_FREE(_mem, _size) \
+ if (((_mem) != NULL) && ((_size) > 8192)) \
+ MEM_freeN((_mem))
typedef struct ParallelRangeState {
- int start, stop;
- void *userdata;
+ int start, stop;
+ void *userdata;
- TaskParallelRangeFunc func;
+ TaskParallelRangeFunc func;
- int iter;
- int chunk_size;
+ int iter;
+ int chunk_size;
} ParallelRangeState;
-BLI_INLINE bool parallel_range_next_iter_get(
- ParallelRangeState * __restrict state,
- int * __restrict iter, int * __restrict count)
+BLI_INLINE bool parallel_range_next_iter_get(ParallelRangeState *__restrict state,
+ int *__restrict iter,
+ int *__restrict count)
{
- int previter = atomic_fetch_and_add_int32(&state->iter, state->chunk_size);
+ int previter = atomic_fetch_and_add_int32(&state->iter, state->chunk_size);
- *iter = previter;
- *count = max_ii(0, min_ii(state->chunk_size, state->stop - previter));
+ *iter = previter;
+ *count = max_ii(0, min_ii(state->chunk_size, state->stop - previter));
- return (previter < state->stop);
+ return (previter < state->stop);
}
-static void parallel_range_func(
- TaskPool * __restrict pool,
- void *userdata_chunk,
- int thread_id)
+static void parallel_range_func(TaskPool *__restrict pool, void *userdata_chunk, int thread_id)
{
- ParallelRangeState * __restrict state = BLI_task_pool_userdata(pool);
- ParallelRangeTLS tls = {
- .thread_id = thread_id,
- .userdata_chunk = userdata_chunk,
- };
- int iter, count;
- while (parallel_range_next_iter_get(state, &iter, &count)) {
- for (int i = 0; i < count; ++i) {
- state->func(state->userdata, iter + i, &tls);
- }
- }
+ ParallelRangeState *__restrict state = BLI_task_pool_userdata(pool);
+ ParallelRangeTLS tls = {
+ .thread_id = thread_id,
+ .userdata_chunk = userdata_chunk,
+ };
+ int iter, count;
+ while (parallel_range_next_iter_get(state, &iter, &count)) {
+ for (int i = 0; i < count; ++i) {
+ state->func(state->userdata, iter + i, &tls);
+ }
+ }
}
-static void parallel_range_single_thread(const int start, int const stop,
+static void parallel_range_single_thread(const int start,
+ int const stop,
void *userdata,
TaskParallelRangeFunc func,
const ParallelRangeSettings *settings)
{
- void *userdata_chunk = settings->userdata_chunk;
- const size_t userdata_chunk_size = settings->userdata_chunk_size;
- void *userdata_chunk_local = NULL;
- const bool use_userdata_chunk = (userdata_chunk_size != 0) && (userdata_chunk != NULL);
- if (use_userdata_chunk) {
- userdata_chunk_local = MALLOCA(userdata_chunk_size);
- memcpy(userdata_chunk_local, userdata_chunk, userdata_chunk_size);
- }
- ParallelRangeTLS tls = {
- .thread_id = 0,
- .userdata_chunk = userdata_chunk_local,
- };
- for (int i = start; i < stop; ++i) {
- func(userdata, i, &tls);
- }
- if (settings->func_finalize != NULL) {
- settings->func_finalize(userdata, userdata_chunk_local);
- }
- MALLOCA_FREE(userdata_chunk_local, userdata_chunk_size);
+ void *userdata_chunk = settings->userdata_chunk;
+ const size_t userdata_chunk_size = settings->userdata_chunk_size;
+ void *userdata_chunk_local = NULL;
+ const bool use_userdata_chunk = (userdata_chunk_size != 0) && (userdata_chunk != NULL);
+ if (use_userdata_chunk) {
+ userdata_chunk_local = MALLOCA(userdata_chunk_size);
+ memcpy(userdata_chunk_local, userdata_chunk, userdata_chunk_size);
+ }
+ ParallelRangeTLS tls = {
+ .thread_id = 0,
+ .userdata_chunk = userdata_chunk_local,
+ };
+ for (int i = start; i < stop; ++i) {
+ func(userdata, i, &tls);
+ }
+ if (settings->func_finalize != NULL) {
+ settings->func_finalize(userdata, userdata_chunk_local);
+ }
+ MALLOCA_FREE(userdata_chunk_local, userdata_chunk_size);
}
/**
@@ -1080,176 +1082,166 @@ static void parallel_range_single_thread(const int start, int const stop,
*
* See public API doc of ParallelRangeSettings for description of all settings.
*/
-void BLI_task_parallel_range(const int start, const int stop,
+void BLI_task_parallel_range(const int start,
+ const int stop,
void *userdata,
TaskParallelRangeFunc func,
const ParallelRangeSettings *settings)
{
- TaskScheduler *task_scheduler;
- TaskPool *task_pool;
- ParallelRangeState state;
- int i, num_threads, num_tasks;
-
- void *userdata_chunk = settings->userdata_chunk;
- const size_t userdata_chunk_size = settings->userdata_chunk_size;
- void *userdata_chunk_local = NULL;
- void *userdata_chunk_array = NULL;
- const bool use_userdata_chunk = (userdata_chunk_size != 0) && (userdata_chunk != NULL);
-
- if (start == stop) {
- return;
- }
-
- BLI_assert(start < stop);
- if (userdata_chunk_size != 0) {
- BLI_assert(userdata_chunk != NULL);
- }
-
- /* If it's not enough data to be crunched, don't bother with tasks at all,
- * do everything from the main thread.
- */
- if (!settings->use_threading) {
- parallel_range_single_thread(start, stop,
- userdata,
- func,
- settings);
- return;
- }
-
- task_scheduler = BLI_task_scheduler_get();
- 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.
- */
- num_tasks = num_threads + 2;
-
- state.start = start;
- state.stop = stop;
- state.userdata = userdata;
- state.func = func;
- state.iter = start;
- switch (settings->scheduling_mode) {
- case TASK_SCHEDULING_STATIC:
- state.chunk_size = max_ii(
- settings->min_iter_per_thread,
- (stop - start) / (num_tasks));
- break;
- case TASK_SCHEDULING_DYNAMIC:
- /* TODO(sergey): Make it configurable from min_iter_per_thread. */
- state.chunk_size = 32;
- break;
- }
-
- num_tasks = min_ii(num_tasks,
- max_ii(1, (stop - start) / state.chunk_size));
-
- if (num_tasks == 1) {
- parallel_range_single_thread(start, stop,
- userdata,
- func,
- settings);
- return;
- }
-
- task_pool = BLI_task_pool_create_suspended(task_scheduler, &state);
-
- /* NOTE: This way we are adding a memory barrier and ensure all worker
- * threads can read and modify the value, without any locks. */
- atomic_fetch_and_add_int32(&state.iter, 0);
-
- if (use_userdata_chunk) {
- userdata_chunk_array = MALLOCA(userdata_chunk_size * num_tasks);
- }
-
- for (i = 0; i < num_tasks; i++) {
- if (use_userdata_chunk) {
- userdata_chunk_local = (char *)userdata_chunk_array + (userdata_chunk_size * i);
- memcpy(userdata_chunk_local, userdata_chunk, userdata_chunk_size);
- }
- /* Use this pool's pre-allocated tasks. */
- BLI_task_pool_push_from_thread(task_pool,
- parallel_range_func,
- userdata_chunk_local, false,
- TASK_PRIORITY_HIGH,
- task_pool->thread_id);
- }
-
- BLI_task_pool_work_and_wait(task_pool);
- BLI_task_pool_free(task_pool);
-
- if (use_userdata_chunk) {
- if (settings->func_finalize != NULL) {
- for (i = 0; i < num_tasks; i++) {
- userdata_chunk_local = (char *)userdata_chunk_array + (userdata_chunk_size * i);
- settings->func_finalize(userdata, userdata_chunk_local);
- }
- }
- MALLOCA_FREE(userdata_chunk_array, userdata_chunk_size * num_tasks);
- }
+ TaskScheduler *task_scheduler;
+ TaskPool *task_pool;
+ ParallelRangeState state;
+ int i, num_threads, num_tasks;
+
+ void *userdata_chunk = settings->userdata_chunk;
+ const size_t userdata_chunk_size = settings->userdata_chunk_size;
+ void *userdata_chunk_local = NULL;
+ void *userdata_chunk_array = NULL;
+ const bool use_userdata_chunk = (userdata_chunk_size != 0) && (userdata_chunk != NULL);
+
+ if (start == stop) {
+ return;
+ }
+
+ BLI_assert(start < stop);
+ if (userdata_chunk_size != 0) {
+ BLI_assert(userdata_chunk != NULL);
+ }
+
+ /* If it's not enough data to be crunched, don't bother with tasks at all,
+ * do everything from the main thread.
+ */
+ if (!settings->use_threading) {
+ parallel_range_single_thread(start, stop, userdata, func, settings);
+ return;
+ }
+
+ task_scheduler = BLI_task_scheduler_get();
+ 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.
+ */
+ num_tasks = num_threads + 2;
+
+ state.start = start;
+ state.stop = stop;
+ state.userdata = userdata;
+ state.func = func;
+ state.iter = start;
+ switch (settings->scheduling_mode) {
+ case TASK_SCHEDULING_STATIC:
+ state.chunk_size = max_ii(settings->min_iter_per_thread, (stop - start) / (num_tasks));
+ break;
+ case TASK_SCHEDULING_DYNAMIC:
+ /* TODO(sergey): Make it configurable from min_iter_per_thread. */
+ state.chunk_size = 32;
+ break;
+ }
+
+ num_tasks = min_ii(num_tasks, max_ii(1, (stop - start) / state.chunk_size));
+
+ if (num_tasks == 1) {
+ parallel_range_single_thread(start, stop, userdata, func, settings);
+ return;
+ }
+
+ task_pool = BLI_task_pool_create_suspended(task_scheduler, &state);
+
+ /* NOTE: This way we are adding a memory barrier and ensure all worker
+ * threads can read and modify the value, without any locks. */
+ atomic_fetch_and_add_int32(&state.iter, 0);
+
+ if (use_userdata_chunk) {
+ userdata_chunk_array = MALLOCA(userdata_chunk_size * num_tasks);
+ }
+
+ for (i = 0; i < num_tasks; i++) {
+ if (use_userdata_chunk) {
+ userdata_chunk_local = (char *)userdata_chunk_array + (userdata_chunk_size * i);
+ memcpy(userdata_chunk_local, userdata_chunk, userdata_chunk_size);
+ }
+ /* Use this pool's pre-allocated tasks. */
+ BLI_task_pool_push_from_thread(task_pool,
+ parallel_range_func,
+ userdata_chunk_local,
+ false,
+ TASK_PRIORITY_HIGH,
+ task_pool->thread_id);
+ }
+
+ BLI_task_pool_work_and_wait(task_pool);
+ BLI_task_pool_free(task_pool);
+
+ if (use_userdata_chunk) {
+ if (settings->func_finalize != NULL) {
+ for (i = 0; i < num_tasks; i++) {
+ userdata_chunk_local = (char *)userdata_chunk_array + (userdata_chunk_size * i);
+ settings->func_finalize(userdata, userdata_chunk_local);
+ }
+ }
+ MALLOCA_FREE(userdata_chunk_array, userdata_chunk_size * num_tasks);
+ }
}
#undef MALLOCA
#undef MALLOCA_FREE
typedef struct ParallelListbaseState {
- void *userdata;
- TaskParallelListbaseFunc func;
+ void *userdata;
+ TaskParallelListbaseFunc func;
- int chunk_size;
- int index;
- Link *link;
- SpinLock lock;
+ int chunk_size;
+ int index;
+ Link *link;
+ SpinLock lock;
} ParallelListState;
-BLI_INLINE Link *parallel_listbase_next_iter_get(
- ParallelListState * __restrict state,
- int * __restrict index,
- int * __restrict count)
+BLI_INLINE Link *parallel_listbase_next_iter_get(ParallelListState *__restrict state,
+ int *__restrict index,
+ int *__restrict count)
{
- int task_count = 0;
- BLI_spin_lock(&state->lock);
- Link *result = state->link;
- if (LIKELY(result != NULL)) {
- *index = state->index;
- while (state->link != NULL && task_count < state->chunk_size) {
- ++task_count;
- state->link = state->link->next;
- }
- state->index += task_count;
- }
- BLI_spin_unlock(&state->lock);
- *count = task_count;
- return result;
+ int task_count = 0;
+ BLI_spin_lock(&state->lock);
+ Link *result = state->link;
+ if (LIKELY(result != NULL)) {
+ *index = state->index;
+ while (state->link != NULL && task_count < state->chunk_size) {
+ ++task_count;
+ state->link = state->link->next;
+ }
+ state->index += task_count;
+ }
+ BLI_spin_unlock(&state->lock);
+ *count = task_count;
+ return result;
}
-static void parallel_listbase_func(
- TaskPool * __restrict pool,
- void *UNUSED(taskdata),
- int UNUSED(threadid))
+static void parallel_listbase_func(TaskPool *__restrict pool,
+ void *UNUSED(taskdata),
+ int UNUSED(threadid))
{
- ParallelListState * __restrict state = BLI_task_pool_userdata(pool);
- Link *link;
- int index, count;
-
- while ((link = parallel_listbase_next_iter_get(state, &index, &count)) != NULL) {
- for (int i = 0; i < count; ++i) {
- state->func(state->userdata, link, index + i);
- link = link->next;
- }
- }
+ ParallelListState *__restrict state = BLI_task_pool_userdata(pool);
+ Link *link;
+ int index, count;
+
+ while ((link = parallel_listbase_next_iter_get(state, &index, &count)) != NULL) {
+ for (int i = 0; i < count; ++i) {
+ state->func(state->userdata, link, index + i);
+ link = link->next;
+ }
+ }
}
-static void task_parallel_listbase_no_threads(
- struct ListBase *listbase,
- void *userdata,
- TaskParallelListbaseFunc func)
+static void task_parallel_listbase_no_threads(struct ListBase *listbase,
+ void *userdata,
+ TaskParallelListbaseFunc func)
{
- int i = 0;
- for (Link *link = listbase->first; link != NULL; link = link->next, ++i) {
- func(userdata, link, i);
- }
+ int i = 0;
+ for (Link *link = listbase->first; link != NULL; link = link->next, ++i) {
+ func(userdata, link, i);
+ }
}
/* NOTE: The idea here is to compensate for rather measurable threading
@@ -1257,13 +1249,13 @@ static void task_parallel_listbase_no_threads(
* to spend too much time in those overheads. */
BLI_INLINE int task_parallel_listbasecalc_chunk_size(const int num_threads)
{
- if (num_threads > 32) {
- return 128;
- }
- else if (num_threads > 16) {
- return 64;
- }
- return 32;
+ if (num_threads > 32) {
+ return 128;
+ }
+ else if (num_threads > 16) {
+ return 64;
+ }
+ return 32;
}
/**
@@ -1277,75 +1269,65 @@ BLI_INLINE int task_parallel_listbasecalc_chunk_size(const int num_threads)
*
* \note There is no static scheduling here, since it would need another full loop over items to count them...
*/
-void BLI_task_parallel_listbase(
- struct ListBase *listbase,
- void *userdata,
- TaskParallelListbaseFunc func,
- const bool use_threading)
+void BLI_task_parallel_listbase(struct ListBase *listbase,
+ void *userdata,
+ TaskParallelListbaseFunc func,
+ const bool use_threading)
{
- if (BLI_listbase_is_empty(listbase)) {
- return;
- }
- if (!use_threading) {
- task_parallel_listbase_no_threads(listbase, userdata, func);
- return;
- }
- TaskScheduler *task_scheduler = BLI_task_scheduler_get();
- const int num_threads = BLI_task_scheduler_num_threads(task_scheduler);
- /* TODO(sergey): Consider making chunk size configurable. */
- const int chunk_size = task_parallel_listbasecalc_chunk_size(num_threads);
- const int num_tasks = min_ii(
- num_threads,
- BLI_listbase_count(listbase) / chunk_size);
- if (num_tasks <= 1) {
- task_parallel_listbase_no_threads(listbase, userdata, func);
- return;
- }
-
- ParallelListState state;
- TaskPool *task_pool = BLI_task_pool_create_suspended(task_scheduler, &state);
-
- state.index = 0;
- state.link = listbase->first;
- state.userdata = userdata;
- state.func = func;
- state.chunk_size = chunk_size;
- BLI_spin_init(&state.lock);
-
- BLI_assert(num_tasks > 0);
- for (int i = 0; i < num_tasks; i++) {
- /* Use this pool's pre-allocated tasks. */
- BLI_task_pool_push_from_thread(task_pool,
- parallel_listbase_func,
- NULL, false,
- TASK_PRIORITY_HIGH,
- task_pool->thread_id);
- }
-
- BLI_task_pool_work_and_wait(task_pool);
- BLI_task_pool_free(task_pool);
-
- BLI_spin_end(&state.lock);
+ if (BLI_listbase_is_empty(listbase)) {
+ return;
+ }
+ if (!use_threading) {
+ task_parallel_listbase_no_threads(listbase, userdata, func);
+ return;
+ }
+ TaskScheduler *task_scheduler = BLI_task_scheduler_get();
+ const int num_threads = BLI_task_scheduler_num_threads(task_scheduler);
+ /* TODO(sergey): Consider making chunk size configurable. */
+ const int chunk_size = task_parallel_listbasecalc_chunk_size(num_threads);
+ const int num_tasks = min_ii(num_threads, BLI_listbase_count(listbase) / chunk_size);
+ if (num_tasks <= 1) {
+ task_parallel_listbase_no_threads(listbase, userdata, func);
+ return;
+ }
+
+ ParallelListState state;
+ TaskPool *task_pool = BLI_task_pool_create_suspended(task_scheduler, &state);
+
+ state.index = 0;
+ state.link = listbase->first;
+ state.userdata = userdata;
+ state.func = func;
+ state.chunk_size = chunk_size;
+ BLI_spin_init(&state.lock);
+
+ BLI_assert(num_tasks > 0);
+ for (int i = 0; i < num_tasks; i++) {
+ /* Use this pool's pre-allocated tasks. */
+ BLI_task_pool_push_from_thread(
+ task_pool, parallel_listbase_func, NULL, false, TASK_PRIORITY_HIGH, task_pool->thread_id);
+ }
+
+ BLI_task_pool_work_and_wait(task_pool);
+ BLI_task_pool_free(task_pool);
+
+ BLI_spin_end(&state.lock);
}
-
typedef struct ParallelMempoolState {
- void *userdata;
- TaskParallelMempoolFunc func;
+ void *userdata;
+ TaskParallelMempoolFunc func;
} ParallelMempoolState;
-static void parallel_mempool_func(
- TaskPool * __restrict pool,
- void *taskdata,
- int UNUSED(threadid))
+static void parallel_mempool_func(TaskPool *__restrict pool, void *taskdata, int UNUSED(threadid))
{
- ParallelMempoolState * __restrict state = BLI_task_pool_userdata(pool);
- BLI_mempool_iter *iter = taskdata;
- MempoolIterData *item;
+ ParallelMempoolState *__restrict state = BLI_task_pool_userdata(pool);
+ BLI_mempool_iter *iter = taskdata;
+ MempoolIterData *item;
- while ((item = BLI_mempool_iterstep(iter)) != NULL) {
- state->func(state->userdata, item);
- }
+ while ((item = BLI_mempool_iterstep(iter)) != NULL) {
+ state->func(state->userdata, item);
+ }
}
/**
@@ -1359,57 +1341,59 @@ static void parallel_mempool_func(
*
* \note There is no static scheduling here.
*/
-void BLI_task_parallel_mempool(
- BLI_mempool *mempool,
- void *userdata,
- TaskParallelMempoolFunc func,
- const bool use_threading)
+void BLI_task_parallel_mempool(BLI_mempool *mempool,
+ void *userdata,
+ TaskParallelMempoolFunc func,
+ const bool use_threading)
{
- TaskScheduler *task_scheduler;
- TaskPool *task_pool;
- ParallelMempoolState state;
- int i, num_threads, num_tasks;
-
- if (BLI_mempool_len(mempool) == 0) {
- return;
- }
-
- if (!use_threading) {
- BLI_mempool_iter iter;
- BLI_mempool_iternew(mempool, &iter);
-
- for (void *item = BLI_mempool_iterstep(&iter); item != NULL; item = BLI_mempool_iterstep(&iter)) {
- func(userdata, item);
- }
- return;
- }
-
- task_scheduler = BLI_task_scheduler_get();
- task_pool = BLI_task_pool_create_suspended(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 item to be crunched using the threaded-aware BLI_mempool_iter.
- */
- num_tasks = num_threads + 2;
-
- state.userdata = userdata;
- state.func = func;
-
- BLI_mempool_iter *mempool_iterators = BLI_mempool_iter_threadsafe_create(mempool, (size_t)num_tasks);
-
- for (i = 0; i < num_tasks; i++) {
- /* Use this pool's pre-allocated tasks. */
- BLI_task_pool_push_from_thread(task_pool,
- parallel_mempool_func,
- &mempool_iterators[i], false,
- TASK_PRIORITY_HIGH,
- task_pool->thread_id);
- }
-
- BLI_task_pool_work_and_wait(task_pool);
- BLI_task_pool_free(task_pool);
-
- BLI_mempool_iter_threadsafe_free(mempool_iterators);
+ TaskScheduler *task_scheduler;
+ TaskPool *task_pool;
+ ParallelMempoolState state;
+ int i, num_threads, num_tasks;
+
+ if (BLI_mempool_len(mempool) == 0) {
+ return;
+ }
+
+ if (!use_threading) {
+ BLI_mempool_iter iter;
+ BLI_mempool_iternew(mempool, &iter);
+
+ for (void *item = BLI_mempool_iterstep(&iter); item != NULL;
+ item = BLI_mempool_iterstep(&iter)) {
+ func(userdata, item);
+ }
+ return;
+ }
+
+ task_scheduler = BLI_task_scheduler_get();
+ task_pool = BLI_task_pool_create_suspended(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 item to be crunched using the threaded-aware BLI_mempool_iter.
+ */
+ num_tasks = num_threads + 2;
+
+ state.userdata = userdata;
+ state.func = func;
+
+ BLI_mempool_iter *mempool_iterators = BLI_mempool_iter_threadsafe_create(mempool,
+ (size_t)num_tasks);
+
+ for (i = 0; i < num_tasks; i++) {
+ /* Use this pool's pre-allocated tasks. */
+ BLI_task_pool_push_from_thread(task_pool,
+ parallel_mempool_func,
+ &mempool_iterators[i],
+ false,
+ TASK_PRIORITY_HIGH,
+ task_pool->thread_id);
+ }
+
+ BLI_task_pool_work_and_wait(task_pool);
+ BLI_task_pool_free(task_pool);
+
+ BLI_mempool_iter_threadsafe_free(mempool_iterators);
}
diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c
index 0758af03193..abd59dac891 100644
--- a/source/blender/blenlib/intern/threads.c
+++ b/source/blender/blenlib/intern/threads.c
@@ -50,7 +50,8 @@
#include "atomic_ops.h"
#include "numaapi.h"
-#if defined(__APPLE__) && defined(_OPENMP) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 2) && !defined(__clang__)
+#if defined(__APPLE__) && defined(_OPENMP) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 2) && \
+ !defined(__clang__)
# define USE_APPLE_OMP_FIX
#endif
@@ -122,60 +123,60 @@ static pthread_mutex_t _fftw_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t _view3d_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_t mainid;
static bool is_numa_available = false;
-static unsigned int thread_levels = 0; /* threads can be invoked inside threads */
+static unsigned int thread_levels = 0; /* threads can be invoked inside threads */
static int num_threads_override = 0;
/* just a max for security reasons */
#define RE_MAX_THREAD BLENDER_MAX_THREADS
typedef struct ThreadSlot {
- struct ThreadSlot *next, *prev;
- void *(*do_thread)(void *);
- void *callerdata;
- pthread_t pthread;
- int avail;
+ struct ThreadSlot *next, *prev;
+ void *(*do_thread)(void *);
+ void *callerdata;
+ pthread_t pthread;
+ int avail;
} ThreadSlot;
static void BLI_lock_malloc_thread(void)
{
- BLI_spin_lock(&_malloc_lock);
+ BLI_spin_lock(&_malloc_lock);
}
static void BLI_unlock_malloc_thread(void)
{
- BLI_spin_unlock(&_malloc_lock);
+ BLI_spin_unlock(&_malloc_lock);
}
void BLI_threadapi_init(void)
{
- mainid = pthread_self();
+ mainid = pthread_self();
- BLI_spin_init(&_malloc_lock);
- if (numaAPI_Initialize() == NUMAAPI_SUCCESS) {
- is_numa_available = true;
- }
+ BLI_spin_init(&_malloc_lock);
+ if (numaAPI_Initialize() == NUMAAPI_SUCCESS) {
+ is_numa_available = true;
+ }
}
void BLI_threadapi_exit(void)
{
- if (task_scheduler) {
- BLI_task_scheduler_free(task_scheduler);
- }
- BLI_spin_end(&_malloc_lock);
+ if (task_scheduler) {
+ BLI_task_scheduler_free(task_scheduler);
+ }
+ BLI_spin_end(&_malloc_lock);
}
TaskScheduler *BLI_task_scheduler_get(void)
{
- if (task_scheduler == NULL) {
- int tot_thread = BLI_system_thread_count();
+ if (task_scheduler == NULL) {
+ int tot_thread = BLI_system_thread_count();
- /* Do a lazy initialization, so it happens after
- * command line arguments parsing
- */
- task_scheduler = BLI_task_scheduler_create(tot_thread);
- }
+ /* Do a lazy initialization, so it happens after
+ * command line arguments parsing
+ */
+ task_scheduler = BLI_task_scheduler_create(tot_thread);
+ }
- return task_scheduler;
+ return task_scheduler;
}
/* tot = 0 only initializes malloc mutex in a safe way (see sequence.c)
@@ -184,161 +185,161 @@ TaskScheduler *BLI_task_scheduler_get(void)
void BLI_threadpool_init(ListBase *threadbase, void *(*do_thread)(void *), int tot)
{
- int a;
+ int a;
- if (threadbase != NULL && tot > 0) {
- BLI_listbase_clear(threadbase);
+ if (threadbase != NULL && tot > 0) {
+ BLI_listbase_clear(threadbase);
- if (tot > RE_MAX_THREAD) {
- tot = RE_MAX_THREAD;
- }
- else if (tot < 1) {
- tot = 1;
- }
+ if (tot > RE_MAX_THREAD) {
+ tot = RE_MAX_THREAD;
+ }
+ else if (tot < 1) {
+ tot = 1;
+ }
- for (a = 0; a < tot; a++) {
- ThreadSlot *tslot = MEM_callocN(sizeof(ThreadSlot), "threadslot");
- BLI_addtail(threadbase, tslot);
- tslot->do_thread = do_thread;
- tslot->avail = 1;
- }
- }
+ for (a = 0; a < tot; a++) {
+ ThreadSlot *tslot = MEM_callocN(sizeof(ThreadSlot), "threadslot");
+ BLI_addtail(threadbase, tslot);
+ tslot->do_thread = do_thread;
+ tslot->avail = 1;
+ }
+ }
- unsigned int level = atomic_fetch_and_add_u(&thread_levels, 1);
- if (level == 0) {
- MEM_set_lock_callback(BLI_lock_malloc_thread, BLI_unlock_malloc_thread);
+ unsigned int level = atomic_fetch_and_add_u(&thread_levels, 1);
+ if (level == 0) {
+ MEM_set_lock_callback(BLI_lock_malloc_thread, BLI_unlock_malloc_thread);
#ifdef USE_APPLE_OMP_FIX
- /* workaround for Apple gcc 4.2.1 omp vs background thread bug,
- * we copy gomp thread local storage pointer to setting it again
- * inside the thread that we start */
- thread_tls_data = pthread_getspecific(gomp_tls_key);
+ /* workaround for Apple gcc 4.2.1 omp vs background thread bug,
+ * we copy gomp thread local storage pointer to setting it again
+ * inside the thread that we start */
+ thread_tls_data = pthread_getspecific(gomp_tls_key);
#endif
- }
+ }
}
/* amount of available threads */
int BLI_available_threads(ListBase *threadbase)
{
- ThreadSlot *tslot;
- int counter = 0;
+ ThreadSlot *tslot;
+ int counter = 0;
- for (tslot = threadbase->first; tslot; tslot = tslot->next) {
- if (tslot->avail) {
- counter++;
- }
- }
- return counter;
+ for (tslot = threadbase->first; tslot; tslot = tslot->next) {
+ if (tslot->avail) {
+ counter++;
+ }
+ }
+ return counter;
}
/* returns thread number, for sample patterns or threadsafe tables */
int BLI_threadpool_available_thread_index(ListBase *threadbase)
{
- ThreadSlot *tslot;
- int counter = 0;
+ ThreadSlot *tslot;
+ int counter = 0;
- for (tslot = threadbase->first; tslot; tslot = tslot->next, counter++) {
- if (tslot->avail) {
- return counter;
- }
- }
- return 0;
+ for (tslot = threadbase->first; tslot; tslot = tslot->next, counter++) {
+ if (tslot->avail) {
+ return counter;
+ }
+ }
+ return 0;
}
static void *tslot_thread_start(void *tslot_p)
{
- ThreadSlot *tslot = (ThreadSlot *)tslot_p;
+ ThreadSlot *tslot = (ThreadSlot *)tslot_p;
#ifdef USE_APPLE_OMP_FIX
- /* workaround for Apple gcc 4.2.1 omp vs background thread bug,
- * set gomp thread local storage pointer which was copied beforehand */
- pthread_setspecific(gomp_tls_key, thread_tls_data);
+ /* workaround for Apple gcc 4.2.1 omp vs background thread bug,
+ * set gomp thread local storage pointer which was copied beforehand */
+ pthread_setspecific(gomp_tls_key, thread_tls_data);
#endif
- return tslot->do_thread(tslot->callerdata);
+ return tslot->do_thread(tslot->callerdata);
}
int BLI_thread_is_main(void)
{
- return pthread_equal(pthread_self(), mainid);
+ return pthread_equal(pthread_self(), mainid);
}
void BLI_threadpool_insert(ListBase *threadbase, void *callerdata)
{
- ThreadSlot *tslot;
+ ThreadSlot *tslot;
- for (tslot = threadbase->first; tslot; tslot = tslot->next) {
- if (tslot->avail) {
- tslot->avail = 0;
- tslot->callerdata = callerdata;
- pthread_create(&tslot->pthread, NULL, tslot_thread_start, tslot);
- return;
- }
- }
- printf("ERROR: could not insert thread slot\n");
+ for (tslot = threadbase->first; tslot; tslot = tslot->next) {
+ if (tslot->avail) {
+ tslot->avail = 0;
+ tslot->callerdata = callerdata;
+ pthread_create(&tslot->pthread, NULL, tslot_thread_start, tslot);
+ return;
+ }
+ }
+ printf("ERROR: could not insert thread slot\n");
}
void BLI_threadpool_remove(ListBase *threadbase, void *callerdata)
{
- ThreadSlot *tslot;
+ ThreadSlot *tslot;
- for (tslot = threadbase->first; tslot; tslot = tslot->next) {
- if (tslot->callerdata == callerdata) {
- pthread_join(tslot->pthread, NULL);
- tslot->callerdata = NULL;
- tslot->avail = 1;
- }
- }
+ for (tslot = threadbase->first; tslot; tslot = tslot->next) {
+ if (tslot->callerdata == callerdata) {
+ pthread_join(tslot->pthread, NULL);
+ tslot->callerdata = NULL;
+ tslot->avail = 1;
+ }
+ }
}
void BLI_threadpool_remove_index(ListBase *threadbase, int index)
{
- ThreadSlot *tslot;
- int counter = 0;
+ ThreadSlot *tslot;
+ int counter = 0;
- for (tslot = threadbase->first; tslot; tslot = tslot->next, counter++) {
- if (counter == index && tslot->avail == 0) {
- pthread_join(tslot->pthread, NULL);
- tslot->callerdata = NULL;
- tslot->avail = 1;
- break;
- }
- }
+ for (tslot = threadbase->first; tslot; tslot = tslot->next, counter++) {
+ if (counter == index && tslot->avail == 0) {
+ pthread_join(tslot->pthread, NULL);
+ tslot->callerdata = NULL;
+ tslot->avail = 1;
+ break;
+ }
+ }
}
void BLI_threadpool_clear(ListBase *threadbase)
{
- ThreadSlot *tslot;
+ ThreadSlot *tslot;
- for (tslot = threadbase->first; tslot; tslot = tslot->next) {
- if (tslot->avail == 0) {
- pthread_join(tslot->pthread, NULL);
- tslot->callerdata = NULL;
- tslot->avail = 1;
- }
- }
+ for (tslot = threadbase->first; tslot; tslot = tslot->next) {
+ if (tslot->avail == 0) {
+ pthread_join(tslot->pthread, NULL);
+ tslot->callerdata = NULL;
+ tslot->avail = 1;
+ }
+ }
}
void BLI_threadpool_end(ListBase *threadbase)
{
- ThreadSlot *tslot;
+ ThreadSlot *tslot;
- /* only needed if there's actually some stuff to end
- * this way we don't end up decrementing thread_levels on an empty threadbase
- * */
- if (threadbase && (BLI_listbase_is_empty(threadbase) == false)) {
- for (tslot = threadbase->first; tslot; tslot = tslot->next) {
- if (tslot->avail == 0) {
- pthread_join(tslot->pthread, NULL);
- }
- }
- BLI_freelistN(threadbase);
- }
+ /* only needed if there's actually some stuff to end
+ * this way we don't end up decrementing thread_levels on an empty threadbase
+ * */
+ if (threadbase && (BLI_listbase_is_empty(threadbase) == false)) {
+ for (tslot = threadbase->first; tslot; tslot = tslot->next) {
+ if (tslot->avail == 0) {
+ pthread_join(tslot->pthread, NULL);
+ }
+ }
+ BLI_freelistN(threadbase);
+ }
- unsigned int level = atomic_sub_and_fetch_u(&thread_levels, 1);
- if (level == 0) {
- MEM_set_lock_callback(NULL, NULL);
- }
+ unsigned int level = atomic_sub_and_fetch_u(&thread_levels, 1);
+ if (level == 0) {
+ MEM_set_lock_callback(NULL, NULL);
+ }
}
/* System Information */
@@ -346,131 +347,131 @@ void BLI_threadpool_end(ListBase *threadbase)
/* how many threads are native on this system? */
int BLI_system_thread_count(void)
{
- static int t = -1;
+ static int t = -1;
- if (num_threads_override != 0) {
- return num_threads_override;
- }
- else if (LIKELY(t != -1)) {
- return t;
- }
+ if (num_threads_override != 0) {
+ return num_threads_override;
+ }
+ else if (LIKELY(t != -1)) {
+ return t;
+ }
- {
+ {
#ifdef WIN32
- SYSTEM_INFO info;
- GetSystemInfo(&info);
- t = (int) info.dwNumberOfProcessors;
+ SYSTEM_INFO info;
+ GetSystemInfo(&info);
+ t = (int)info.dwNumberOfProcessors;
#else
-# ifdef __APPLE__
- int mib[2];
- size_t len;
-
- mib[0] = CTL_HW;
- mib[1] = HW_NCPU;
- len = sizeof(t);
- sysctl(mib, 2, &t, &len, NULL, 0);
-# else
- t = (int)sysconf(_SC_NPROCESSORS_ONLN);
-# endif
+# ifdef __APPLE__
+ int mib[2];
+ size_t len;
+
+ mib[0] = CTL_HW;
+ mib[1] = HW_NCPU;
+ len = sizeof(t);
+ sysctl(mib, 2, &t, &len, NULL, 0);
+# else
+ t = (int)sysconf(_SC_NPROCESSORS_ONLN);
+# endif
#endif
- }
+ }
- CLAMP(t, 1, RE_MAX_THREAD);
+ CLAMP(t, 1, RE_MAX_THREAD);
- return t;
+ return t;
}
void BLI_system_num_threads_override_set(int num)
{
- num_threads_override = num;
+ num_threads_override = num;
}
int BLI_system_num_threads_override_get(void)
{
- return num_threads_override;
+ return num_threads_override;
}
/* Global Mutex Locks */
static ThreadMutex *global_mutex_from_type(const int type)
{
- switch (type) {
- case LOCK_IMAGE:
- return &_image_lock;
- case LOCK_DRAW_IMAGE:
- return &_image_draw_lock;
- case LOCK_VIEWER:
- return &_viewer_lock;
- case LOCK_CUSTOM1:
- return &_custom1_lock;
- case LOCK_RCACHE:
- return &_rcache_lock;
- case LOCK_OPENGL:
- return &_opengl_lock;
- case LOCK_NODES:
- return &_nodes_lock;
- case LOCK_MOVIECLIP:
- return &_movieclip_lock;
- case LOCK_COLORMANAGE:
- return &_colormanage_lock;
- case LOCK_FFTW:
- return &_fftw_lock;
- case LOCK_VIEW3D:
- return &_view3d_lock;
- default:
- BLI_assert(0);
- return NULL;
- }
+ switch (type) {
+ case LOCK_IMAGE:
+ return &_image_lock;
+ case LOCK_DRAW_IMAGE:
+ return &_image_draw_lock;
+ case LOCK_VIEWER:
+ return &_viewer_lock;
+ case LOCK_CUSTOM1:
+ return &_custom1_lock;
+ case LOCK_RCACHE:
+ return &_rcache_lock;
+ case LOCK_OPENGL:
+ return &_opengl_lock;
+ case LOCK_NODES:
+ return &_nodes_lock;
+ case LOCK_MOVIECLIP:
+ return &_movieclip_lock;
+ case LOCK_COLORMANAGE:
+ return &_colormanage_lock;
+ case LOCK_FFTW:
+ return &_fftw_lock;
+ case LOCK_VIEW3D:
+ return &_view3d_lock;
+ default:
+ BLI_assert(0);
+ return NULL;
+ }
}
void BLI_thread_lock(int type)
{
- pthread_mutex_lock(global_mutex_from_type(type));
+ pthread_mutex_lock(global_mutex_from_type(type));
}
void BLI_thread_unlock(int type)
{
- pthread_mutex_unlock(global_mutex_from_type(type));
+ pthread_mutex_unlock(global_mutex_from_type(type));
}
/* Mutex Locks */
void BLI_mutex_init(ThreadMutex *mutex)
{
- pthread_mutex_init(mutex, NULL);
+ pthread_mutex_init(mutex, NULL);
}
void BLI_mutex_lock(ThreadMutex *mutex)
{
- pthread_mutex_lock(mutex);
+ pthread_mutex_lock(mutex);
}
void BLI_mutex_unlock(ThreadMutex *mutex)
{
- pthread_mutex_unlock(mutex);
+ pthread_mutex_unlock(mutex);
}
bool BLI_mutex_trylock(ThreadMutex *mutex)
{
- return (pthread_mutex_trylock(mutex) == 0);
+ return (pthread_mutex_trylock(mutex) == 0);
}
void BLI_mutex_end(ThreadMutex *mutex)
{
- pthread_mutex_destroy(mutex);
+ pthread_mutex_destroy(mutex);
}
ThreadMutex *BLI_mutex_alloc(void)
{
- ThreadMutex *mutex = MEM_callocN(sizeof(ThreadMutex), "ThreadMutex");
- BLI_mutex_init(mutex);
- return mutex;
+ ThreadMutex *mutex = MEM_callocN(sizeof(ThreadMutex), "ThreadMutex");
+ BLI_mutex_init(mutex);
+ return mutex;
}
void BLI_mutex_free(ThreadMutex *mutex)
{
- BLI_mutex_end(mutex);
- MEM_freeN(mutex);
+ BLI_mutex_end(mutex);
+ MEM_freeN(mutex);
}
/* Spin Locks */
@@ -478,39 +479,39 @@ void BLI_mutex_free(ThreadMutex *mutex)
void BLI_spin_init(SpinLock *spin)
{
#if defined(__APPLE__)
- *spin = OS_SPINLOCK_INIT;
+ *spin = OS_SPINLOCK_INIT;
#elif defined(_MSC_VER)
- *spin = 0;
+ *spin = 0;
#else
- pthread_spin_init(spin, 0);
+ pthread_spin_init(spin, 0);
#endif
}
void BLI_spin_lock(SpinLock *spin)
{
#if defined(__APPLE__)
- OSSpinLockLock(spin);
+ OSSpinLockLock(spin);
#elif defined(_MSC_VER)
- while (InterlockedExchangeAcquire(spin, 1)) {
- while (*spin) {
- /* Spinlock hint for processors with hyperthreading. */
- YieldProcessor();
- }
- }
+ while (InterlockedExchangeAcquire(spin, 1)) {
+ while (*spin) {
+ /* Spinlock hint for processors with hyperthreading. */
+ YieldProcessor();
+ }
+ }
#else
- pthread_spin_lock(spin);
+ pthread_spin_lock(spin);
#endif
}
void BLI_spin_unlock(SpinLock *spin)
{
#if defined(__APPLE__)
- OSSpinLockUnlock(spin);
+ OSSpinLockUnlock(spin);
#elif defined(_MSC_VER)
- _ReadWriteBarrier();
- *spin = 0;
+ _ReadWriteBarrier();
+ *spin = 0;
#else
- pthread_spin_unlock(spin);
+ pthread_spin_unlock(spin);
#endif
}
@@ -521,7 +522,7 @@ void BLI_spin_end(SpinLock *UNUSED(spin))
#else
void BLI_spin_end(SpinLock *spin)
{
- pthread_spin_destroy(spin);
+ pthread_spin_destroy(spin);
}
#endif
@@ -529,87 +530,87 @@ void BLI_spin_end(SpinLock *spin)
void BLI_rw_mutex_init(ThreadRWMutex *mutex)
{
- pthread_rwlock_init(mutex, NULL);
+ pthread_rwlock_init(mutex, NULL);
}
void BLI_rw_mutex_lock(ThreadRWMutex *mutex, int mode)
{
- if (mode == THREAD_LOCK_READ) {
- pthread_rwlock_rdlock(mutex);
- }
- else {
- pthread_rwlock_wrlock(mutex);
- }
+ if (mode == THREAD_LOCK_READ) {
+ pthread_rwlock_rdlock(mutex);
+ }
+ else {
+ pthread_rwlock_wrlock(mutex);
+ }
}
void BLI_rw_mutex_unlock(ThreadRWMutex *mutex)
{
- pthread_rwlock_unlock(mutex);
+ pthread_rwlock_unlock(mutex);
}
void BLI_rw_mutex_end(ThreadRWMutex *mutex)
{
- pthread_rwlock_destroy(mutex);
+ pthread_rwlock_destroy(mutex);
}
ThreadRWMutex *BLI_rw_mutex_alloc(void)
{
- ThreadRWMutex *mutex = MEM_callocN(sizeof(ThreadRWMutex), "ThreadRWMutex");
- BLI_rw_mutex_init(mutex);
- return mutex;
+ ThreadRWMutex *mutex = MEM_callocN(sizeof(ThreadRWMutex), "ThreadRWMutex");
+ BLI_rw_mutex_init(mutex);
+ return mutex;
}
void BLI_rw_mutex_free(ThreadRWMutex *mutex)
{
- BLI_rw_mutex_end(mutex);
- MEM_freeN(mutex);
+ BLI_rw_mutex_end(mutex);
+ MEM_freeN(mutex);
}
/* Ticket Mutex Lock */
struct TicketMutex {
- pthread_cond_t cond;
- pthread_mutex_t mutex;
- unsigned int queue_head, queue_tail;
+ pthread_cond_t cond;
+ pthread_mutex_t mutex;
+ unsigned int queue_head, queue_tail;
};
TicketMutex *BLI_ticket_mutex_alloc(void)
{
- TicketMutex *ticket = MEM_callocN(sizeof(TicketMutex), "TicketMutex");
+ TicketMutex *ticket = MEM_callocN(sizeof(TicketMutex), "TicketMutex");
- pthread_cond_init(&ticket->cond, NULL);
- pthread_mutex_init(&ticket->mutex, NULL);
+ pthread_cond_init(&ticket->cond, NULL);
+ pthread_mutex_init(&ticket->mutex, NULL);
- return ticket;
+ return ticket;
}
void BLI_ticket_mutex_free(TicketMutex *ticket)
{
- pthread_mutex_destroy(&ticket->mutex);
- pthread_cond_destroy(&ticket->cond);
- MEM_freeN(ticket);
+ pthread_mutex_destroy(&ticket->mutex);
+ pthread_cond_destroy(&ticket->cond);
+ MEM_freeN(ticket);
}
void BLI_ticket_mutex_lock(TicketMutex *ticket)
{
- unsigned int queue_me;
+ unsigned int queue_me;
- pthread_mutex_lock(&ticket->mutex);
- queue_me = ticket->queue_tail++;
+ pthread_mutex_lock(&ticket->mutex);
+ queue_me = ticket->queue_tail++;
- while (queue_me != ticket->queue_head) {
- pthread_cond_wait(&ticket->cond, &ticket->mutex);
- }
+ while (queue_me != ticket->queue_head) {
+ pthread_cond_wait(&ticket->cond, &ticket->mutex);
+ }
- pthread_mutex_unlock(&ticket->mutex);
+ pthread_mutex_unlock(&ticket->mutex);
}
void BLI_ticket_mutex_unlock(TicketMutex *ticket)
{
- pthread_mutex_lock(&ticket->mutex);
- ticket->queue_head++;
- pthread_cond_broadcast(&ticket->cond);
- pthread_mutex_unlock(&ticket->mutex);
+ pthread_mutex_lock(&ticket->mutex);
+ ticket->queue_head++;
+ pthread_cond_broadcast(&ticket->cond);
+ pthread_mutex_unlock(&ticket->mutex);
}
/* ************************************************ */
@@ -618,241 +619,241 @@ void BLI_ticket_mutex_unlock(TicketMutex *ticket)
void BLI_condition_init(ThreadCondition *cond)
{
- pthread_cond_init(cond, NULL);
+ pthread_cond_init(cond, NULL);
}
void BLI_condition_wait(ThreadCondition *cond, ThreadMutex *mutex)
{
- pthread_cond_wait(cond, mutex);
+ pthread_cond_wait(cond, mutex);
}
void BLI_condition_wait_global_mutex(ThreadCondition *cond, const int type)
{
- pthread_cond_wait(cond, global_mutex_from_type(type));
+ pthread_cond_wait(cond, global_mutex_from_type(type));
}
void BLI_condition_notify_one(ThreadCondition *cond)
{
- pthread_cond_signal(cond);
+ pthread_cond_signal(cond);
}
void BLI_condition_notify_all(ThreadCondition *cond)
{
- pthread_cond_broadcast(cond);
+ pthread_cond_broadcast(cond);
}
void BLI_condition_end(ThreadCondition *cond)
{
- pthread_cond_destroy(cond);
+ pthread_cond_destroy(cond);
}
/* ************************************************ */
struct ThreadQueue {
- GSQueue *queue;
- pthread_mutex_t mutex;
- pthread_cond_t push_cond;
- pthread_cond_t finish_cond;
- volatile int nowait;
- volatile int canceled;
+ GSQueue *queue;
+ pthread_mutex_t mutex;
+ pthread_cond_t push_cond;
+ pthread_cond_t finish_cond;
+ volatile int nowait;
+ volatile int canceled;
};
ThreadQueue *BLI_thread_queue_init(void)
{
- ThreadQueue *queue;
+ ThreadQueue *queue;
- queue = MEM_callocN(sizeof(ThreadQueue), "ThreadQueue");
- queue->queue = BLI_gsqueue_new(sizeof(void *));
+ queue = MEM_callocN(sizeof(ThreadQueue), "ThreadQueue");
+ queue->queue = BLI_gsqueue_new(sizeof(void *));
- pthread_mutex_init(&queue->mutex, NULL);
- pthread_cond_init(&queue->push_cond, NULL);
- pthread_cond_init(&queue->finish_cond, NULL);
+ pthread_mutex_init(&queue->mutex, NULL);
+ pthread_cond_init(&queue->push_cond, NULL);
+ pthread_cond_init(&queue->finish_cond, NULL);
- return queue;
+ return queue;
}
void BLI_thread_queue_free(ThreadQueue *queue)
{
- /* destroy everything, assumes no one is using queue anymore */
- pthread_cond_destroy(&queue->finish_cond);
- pthread_cond_destroy(&queue->push_cond);
- pthread_mutex_destroy(&queue->mutex);
+ /* destroy everything, assumes no one is using queue anymore */
+ pthread_cond_destroy(&queue->finish_cond);
+ pthread_cond_destroy(&queue->push_cond);
+ pthread_mutex_destroy(&queue->mutex);
- BLI_gsqueue_free(queue->queue);
+ BLI_gsqueue_free(queue->queue);
- MEM_freeN(queue);
+ MEM_freeN(queue);
}
void BLI_thread_queue_push(ThreadQueue *queue, void *work)
{
- pthread_mutex_lock(&queue->mutex);
+ pthread_mutex_lock(&queue->mutex);
- BLI_gsqueue_push(queue->queue, &work);
+ BLI_gsqueue_push(queue->queue, &work);
- /* signal threads waiting to pop */
- pthread_cond_signal(&queue->push_cond);
- pthread_mutex_unlock(&queue->mutex);
+ /* signal threads waiting to pop */
+ pthread_cond_signal(&queue->push_cond);
+ pthread_mutex_unlock(&queue->mutex);
}
void *BLI_thread_queue_pop(ThreadQueue *queue)
{
- void *work = NULL;
+ void *work = NULL;
- /* wait until there is work */
- pthread_mutex_lock(&queue->mutex);
- while (BLI_gsqueue_is_empty(queue->queue) && !queue->nowait) {
- pthread_cond_wait(&queue->push_cond, &queue->mutex);
- }
+ /* wait until there is work */
+ pthread_mutex_lock(&queue->mutex);
+ while (BLI_gsqueue_is_empty(queue->queue) && !queue->nowait) {
+ pthread_cond_wait(&queue->push_cond, &queue->mutex);
+ }
- /* if we have something, pop it */
- if (!BLI_gsqueue_is_empty(queue->queue)) {
- BLI_gsqueue_pop(queue->queue, &work);
+ /* if we have something, pop it */
+ if (!BLI_gsqueue_is_empty(queue->queue)) {
+ BLI_gsqueue_pop(queue->queue, &work);
- if (BLI_gsqueue_is_empty(queue->queue)) {
- pthread_cond_broadcast(&queue->finish_cond);
- }
- }
+ if (BLI_gsqueue_is_empty(queue->queue)) {
+ pthread_cond_broadcast(&queue->finish_cond);
+ }
+ }
- pthread_mutex_unlock(&queue->mutex);
+ pthread_mutex_unlock(&queue->mutex);
- return work;
+ return work;
}
static void wait_timeout(struct timespec *timeout, int ms)
{
- ldiv_t div_result;
- long sec, usec, x;
+ ldiv_t div_result;
+ long sec, usec, x;
#ifdef WIN32
- {
- struct _timeb now;
- _ftime(&now);
- sec = now.time;
- usec = now.millitm * 1000; /* microsecond precision would be better */
- }
+ {
+ struct _timeb now;
+ _ftime(&now);
+ sec = now.time;
+ usec = now.millitm * 1000; /* microsecond precision would be better */
+ }
#else
- {
- struct timeval now;
- gettimeofday(&now, NULL);
- sec = now.tv_sec;
- usec = now.tv_usec;
- }
+ {
+ struct timeval now;
+ gettimeofday(&now, NULL);
+ sec = now.tv_sec;
+ usec = now.tv_usec;
+ }
#endif
- /* add current time + millisecond offset */
- div_result = ldiv(ms, 1000);
- timeout->tv_sec = sec + div_result.quot;
+ /* add current time + millisecond offset */
+ div_result = ldiv(ms, 1000);
+ timeout->tv_sec = sec + div_result.quot;
- x = usec + (div_result.rem * 1000);
+ x = usec + (div_result.rem * 1000);
- if (x >= 1000000) {
- timeout->tv_sec++;
- x -= 1000000;
- }
+ if (x >= 1000000) {
+ timeout->tv_sec++;
+ x -= 1000000;
+ }
- timeout->tv_nsec = x * 1000;
+ timeout->tv_nsec = x * 1000;
}
void *BLI_thread_queue_pop_timeout(ThreadQueue *queue, int ms)
{
- double t;
- void *work = NULL;
- struct timespec timeout;
+ double t;
+ void *work = NULL;
+ struct timespec timeout;
- t = PIL_check_seconds_timer();
- wait_timeout(&timeout, ms);
+ t = PIL_check_seconds_timer();
+ wait_timeout(&timeout, ms);
- /* wait until there is work */
- pthread_mutex_lock(&queue->mutex);
- while (BLI_gsqueue_is_empty(queue->queue) && !queue->nowait) {
- if (pthread_cond_timedwait(&queue->push_cond, &queue->mutex, &timeout) == ETIMEDOUT) {
- break;
- }
- else if (PIL_check_seconds_timer() - t >= ms * 0.001) {
- break;
- }
- }
+ /* wait until there is work */
+ pthread_mutex_lock(&queue->mutex);
+ while (BLI_gsqueue_is_empty(queue->queue) && !queue->nowait) {
+ if (pthread_cond_timedwait(&queue->push_cond, &queue->mutex, &timeout) == ETIMEDOUT) {
+ break;
+ }
+ else if (PIL_check_seconds_timer() - t >= ms * 0.001) {
+ break;
+ }
+ }
- /* if we have something, pop it */
- if (!BLI_gsqueue_is_empty(queue->queue)) {
- BLI_gsqueue_pop(queue->queue, &work);
+ /* if we have something, pop it */
+ if (!BLI_gsqueue_is_empty(queue->queue)) {
+ BLI_gsqueue_pop(queue->queue, &work);
- if (BLI_gsqueue_is_empty(queue->queue)) {
- pthread_cond_broadcast(&queue->finish_cond);
- }
- }
+ if (BLI_gsqueue_is_empty(queue->queue)) {
+ pthread_cond_broadcast(&queue->finish_cond);
+ }
+ }
- pthread_mutex_unlock(&queue->mutex);
+ pthread_mutex_unlock(&queue->mutex);
- return work;
+ return work;
}
int BLI_thread_queue_len(ThreadQueue *queue)
{
- int size;
+ int size;
- pthread_mutex_lock(&queue->mutex);
- size = BLI_gsqueue_len(queue->queue);
- pthread_mutex_unlock(&queue->mutex);
+ pthread_mutex_lock(&queue->mutex);
+ size = BLI_gsqueue_len(queue->queue);
+ pthread_mutex_unlock(&queue->mutex);
- return size;
+ return size;
}
bool BLI_thread_queue_is_empty(ThreadQueue *queue)
{
- bool is_empty;
+ bool is_empty;
- pthread_mutex_lock(&queue->mutex);
- is_empty = BLI_gsqueue_is_empty(queue->queue);
- pthread_mutex_unlock(&queue->mutex);
+ pthread_mutex_lock(&queue->mutex);
+ is_empty = BLI_gsqueue_is_empty(queue->queue);
+ pthread_mutex_unlock(&queue->mutex);
- return is_empty;
+ return is_empty;
}
void BLI_thread_queue_nowait(ThreadQueue *queue)
{
- pthread_mutex_lock(&queue->mutex);
+ pthread_mutex_lock(&queue->mutex);
- queue->nowait = 1;
+ queue->nowait = 1;
- /* signal threads waiting to pop */
- pthread_cond_broadcast(&queue->push_cond);
- pthread_mutex_unlock(&queue->mutex);
+ /* signal threads waiting to pop */
+ pthread_cond_broadcast(&queue->push_cond);
+ pthread_mutex_unlock(&queue->mutex);
}
void BLI_thread_queue_wait_finish(ThreadQueue *queue)
{
- /* wait for finish condition */
- pthread_mutex_lock(&queue->mutex);
+ /* wait for finish condition */
+ pthread_mutex_lock(&queue->mutex);
- while (!BLI_gsqueue_is_empty(queue->queue)) {
- pthread_cond_wait(&queue->finish_cond, &queue->mutex);
- }
+ while (!BLI_gsqueue_is_empty(queue->queue)) {
+ pthread_cond_wait(&queue->finish_cond, &queue->mutex);
+ }
- pthread_mutex_unlock(&queue->mutex);
+ pthread_mutex_unlock(&queue->mutex);
}
/* ************************************************ */
void BLI_threaded_malloc_begin(void)
{
- unsigned int level = atomic_fetch_and_add_u(&thread_levels, 1);
- if (level == 0) {
- MEM_set_lock_callback(BLI_lock_malloc_thread, BLI_unlock_malloc_thread);
- /* There is a little chance that two threads will need to access to a
- * scheduler which was not yet created from main thread. which could
- * cause scheduler created multiple times.
- */
- BLI_task_scheduler_get();
- }
+ unsigned int level = atomic_fetch_and_add_u(&thread_levels, 1);
+ if (level == 0) {
+ MEM_set_lock_callback(BLI_lock_malloc_thread, BLI_unlock_malloc_thread);
+ /* There is a little chance that two threads will need to access to a
+ * scheduler which was not yet created from main thread. which could
+ * cause scheduler created multiple times.
+ */
+ BLI_task_scheduler_get();
+ }
}
void BLI_threaded_malloc_end(void)
{
- unsigned int level = atomic_sub_and_fetch_u(&thread_levels, 1);
- if (level == 0) {
- MEM_set_lock_callback(NULL, NULL);
- }
+ unsigned int level = atomic_sub_and_fetch_u(&thread_levels, 1);
+ if (level == 0) {
+ MEM_set_lock_callback(NULL, NULL);
+ }
}
/* **** Special functions to help performance on crazy NUMA setups. **** */
@@ -860,107 +861,107 @@ void BLI_threaded_malloc_end(void)
#if 0 /* UNUSED */
static bool check_is_threadripper2_alike_topology(void)
{
- /* NOTE: We hope operating system does not support CPU hotswap to
- * a different brand. And that SMP of different types is also not
- * encouraged by the system. */
- static bool is_initialized = false;
- static bool is_threadripper2 = false;
- if (is_initialized) {
- return is_threadripper2;
- }
- is_initialized = true;
- char *cpu_brand = BLI_cpu_brand_string();
- if (cpu_brand == NULL) {
- return false;
- }
- if (strstr(cpu_brand, "Threadripper")) {
- /* NOTE: We consider all Thread-rippers having similar topology to
- * the second one. This is because we are trying to utilize NUMA node
- * 0 as much as possible. This node does exist on earlier versions of
- * thread-ripper and setting affinity to it should not have negative
- * effect.
- * This allows us to avoid per-model check, making the code more
- * reliable for the CPUs which are not yet released.
- */
- if (strstr(cpu_brand, "2990WX") || strstr(cpu_brand, "2950X")) {
- is_threadripper2 = true;
- }
- }
- /* NOTE: While all dies of EPYC has memory controller, only two f them
- * has access to a lower-indexed DDR slots. Those dies are same as on
- * Threadripper2 with the memory controller.
- * Now, it is rather likely that reasonable amount of users don't max
- * up their DR slots, making it only two dies connected to a DDR slot
- * with actual memory in it. */
- if (strstr(cpu_brand, "EPYC")) {
- /* NOTE: Similarly to Thread-ripper we do not do model check. */
- is_threadripper2 = true;
- }
- MEM_freeN(cpu_brand);
- return is_threadripper2;
+ /* NOTE: We hope operating system does not support CPU hotswap to
+ * a different brand. And that SMP of different types is also not
+ * encouraged by the system. */
+ static bool is_initialized = false;
+ static bool is_threadripper2 = false;
+ if (is_initialized) {
+ return is_threadripper2;
+ }
+ is_initialized = true;
+ char *cpu_brand = BLI_cpu_brand_string();
+ if (cpu_brand == NULL) {
+ return false;
+ }
+ if (strstr(cpu_brand, "Threadripper")) {
+ /* NOTE: We consider all Thread-rippers having similar topology to
+ * the second one. This is because we are trying to utilize NUMA node
+ * 0 as much as possible. This node does exist on earlier versions of
+ * thread-ripper and setting affinity to it should not have negative
+ * effect.
+ * This allows us to avoid per-model check, making the code more
+ * reliable for the CPUs which are not yet released.
+ */
+ if (strstr(cpu_brand, "2990WX") || strstr(cpu_brand, "2950X")) {
+ is_threadripper2 = true;
+ }
+ }
+ /* NOTE: While all dies of EPYC has memory controller, only two f them
+ * has access to a lower-indexed DDR slots. Those dies are same as on
+ * Threadripper2 with the memory controller.
+ * Now, it is rather likely that reasonable amount of users don't max
+ * up their DR slots, making it only two dies connected to a DDR slot
+ * with actual memory in it. */
+ if (strstr(cpu_brand, "EPYC")) {
+ /* NOTE: Similarly to Thread-ripper we do not do model check. */
+ is_threadripper2 = true;
+ }
+ MEM_freeN(cpu_brand);
+ return is_threadripper2;
}
static void threadripper_put_process_on_fast_node(void)
{
- if (!is_numa_available) {
- return;
- }
- /* NOTE: Technically, we can use NUMA nodes 0 and 2 and using both of
- * them in the affinity mask will allow OS to schedule threads more
- * flexible,possibly increasing overall performance when multiple apps
- * are crunching numbers.
- *
- * However, if scene fits into memory adjacent to a single die we don't
- * want OS to re-schedule the process to another die since that will make
- * it further away from memory allocated for .blend file. */
- /* NOTE: Even if NUMA is available in the API but is disabled in BIOS on
- * this workstation we still process here. If NUMA is disabled it will be a
- * single node, so our action is no-visible-changes, but allows to keep
- * things simple and unified. */
- numaAPI_RunProcessOnNode(0);
+ if (!is_numa_available) {
+ return;
+ }
+ /* NOTE: Technically, we can use NUMA nodes 0 and 2 and using both of
+ * them in the affinity mask will allow OS to schedule threads more
+ * flexible,possibly increasing overall performance when multiple apps
+ * are crunching numbers.
+ *
+ * However, if scene fits into memory adjacent to a single die we don't
+ * want OS to re-schedule the process to another die since that will make
+ * it further away from memory allocated for .blend file. */
+ /* NOTE: Even if NUMA is available in the API but is disabled in BIOS on
+ * this workstation we still process here. If NUMA is disabled it will be a
+ * single node, so our action is no-visible-changes, but allows to keep
+ * things simple and unified. */
+ numaAPI_RunProcessOnNode(0);
}
static void threadripper_put_thread_on_fast_node(void)
{
- if (!is_numa_available) {
- return;
- }
- /* NOTE: This is where things becomes more interesting. On the one hand
- * we can use nodes 0 and 2 and allow operating system to do balancing
- * of processes/threads for the maximum performance when multiple apps
- * are running.
- * On another hand, however, we probably want to use same node as the
- * main thread since that's where the memory of .blend file is likely
- * to be allocated.
- * Since the main thread is currently on node 0, we also put thread on
- * same node. */
- /* See additional note about NUMA disabled in BIOS above. */
- numaAPI_RunThreadOnNode(0);
-}
-#endif /* UNUSED */
+ if (!is_numa_available) {
+ return;
+ }
+ /* NOTE: This is where things becomes more interesting. On the one hand
+ * we can use nodes 0 and 2 and allow operating system to do balancing
+ * of processes/threads for the maximum performance when multiple apps
+ * are running.
+ * On another hand, however, we probably want to use same node as the
+ * main thread since that's where the memory of .blend file is likely
+ * to be allocated.
+ * Since the main thread is currently on node 0, we also put thread on
+ * same node. */
+ /* See additional note about NUMA disabled in BIOS above. */
+ numaAPI_RunThreadOnNode(0);
+}
+#endif /* UNUSED */
void BLI_thread_put_process_on_fast_node(void)
{
- /* Disabled for now since this causes only 16 threads to be used on a
- * thread-ripper for computations like sculpting and fluid sim. The problem
- * is that all threads created as children from this thread will inherit
- * the NUMA node and so will end up on the same node. This can be fixed
- * case-by-case by assigning the NUMA node for every child thread, however
- * this is difficult for external libraries and OpenMP, and out of our
- * control for plugins like external renderers. */
+ /* Disabled for now since this causes only 16 threads to be used on a
+ * thread-ripper for computations like sculpting and fluid sim. The problem
+ * is that all threads created as children from this thread will inherit
+ * the NUMA node and so will end up on the same node. This can be fixed
+ * case-by-case by assigning the NUMA node for every child thread, however
+ * this is difficult for external libraries and OpenMP, and out of our
+ * control for plugins like external renderers. */
#if 0
- if (check_is_threadripper2_alike_topology()) {
- threadripper_put_process_on_fast_node();
- }
+ if (check_is_threadripper2_alike_topology()) {
+ threadripper_put_process_on_fast_node();
+ }
#endif
}
void BLI_thread_put_thread_on_fast_node(void)
{
- /* Disabled for now, see comment above. */
+ /* Disabled for now, see comment above. */
#if 0
- if (check_is_threadripper2_alike_topology()) {
- threadripper_put_thread_on_fast_node();
- }
+ if (check_is_threadripper2_alike_topology()) {
+ threadripper_put_thread_on_fast_node();
+ }
#endif
}
diff --git a/source/blender/blenlib/intern/time.c b/source/blender/blenlib/intern/time.c
index ee90e74ea52..f7bcf303b4b 100644
--- a/source/blender/blenlib/intern/time.c
+++ b/source/blender/blenlib/intern/time.c
@@ -21,94 +21,93 @@
* \ingroup bli
*/
-
#include "PIL_time.h"
#ifdef WIN32
-#ifndef _WIN32_WINNT
-#define _WIN32_WINNT 0x501 /* Windows XP or newer */
-#endif
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
+# ifndef _WIN32_WINNT
+# define _WIN32_WINNT 0x501 /* Windows XP or newer */
+# endif
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
double PIL_check_seconds_timer(void)
{
- static int hasperfcounter = -1; /* (-1 == unknown) */
- static double perffreq;
-
- if (hasperfcounter == -1) {
- __int64 ifreq;
- hasperfcounter = QueryPerformanceFrequency((LARGE_INTEGER *) &ifreq);
- perffreq = (double) ifreq;
- }
-
- if (hasperfcounter) {
- __int64 count;
-
- QueryPerformanceCounter((LARGE_INTEGER *) &count);
-
- return count / perffreq;
- }
- else {
- static double accum = 0.0;
- static int ltick = 0;
- int ntick = GetTickCount();
-
- if (ntick < ltick) {
- accum += (0xFFFFFFFF - ltick + ntick) / 1000.0;
- }
- else {
- accum += (ntick - ltick) / 1000.0;
- }
-
- ltick = ntick;
- return accum;
- }
+ static int hasperfcounter = -1; /* (-1 == unknown) */
+ static double perffreq;
+
+ if (hasperfcounter == -1) {
+ __int64 ifreq;
+ hasperfcounter = QueryPerformanceFrequency((LARGE_INTEGER *)&ifreq);
+ perffreq = (double)ifreq;
+ }
+
+ if (hasperfcounter) {
+ __int64 count;
+
+ QueryPerformanceCounter((LARGE_INTEGER *)&count);
+
+ return count / perffreq;
+ }
+ else {
+ static double accum = 0.0;
+ static int ltick = 0;
+ int ntick = GetTickCount();
+
+ if (ntick < ltick) {
+ accum += (0xFFFFFFFF - ltick + ntick) / 1000.0;
+ }
+ else {
+ accum += (ntick - ltick) / 1000.0;
+ }
+
+ ltick = ntick;
+ return accum;
+ }
}
long int PIL_check_seconds_timer_i(void)
{
- return (long int)PIL_check_seconds_timer();
+ return (long int)PIL_check_seconds_timer();
}
void PIL_sleep_ms(int ms)
{
- Sleep(ms);
+ Sleep(ms);
}
#else
-#include <unistd.h>
-#include <sys/time.h>
+# include <unistd.h>
+# include <sys/time.h>
double PIL_check_seconds_timer(void)
{
- struct timeval tv;
- struct timezone tz;
+ struct timeval tv;
+ struct timezone tz;
- gettimeofday(&tv, &tz);
+ gettimeofday(&tv, &tz);
- return ((double) tv.tv_sec + tv.tv_usec / 1000000.0);
+ return ((double)tv.tv_sec + tv.tv_usec / 1000000.0);
}
long int PIL_check_seconds_timer_i(void)
{
- struct timeval tv;
- struct timezone tz;
+ struct timeval tv;
+ struct timezone tz;
- gettimeofday(&tv, &tz);
+ gettimeofday(&tv, &tz);
- return tv.tv_sec;
+ return tv.tv_sec;
}
void PIL_sleep_ms(int ms)
{
- if (ms >= 1000) {
- sleep(ms / 1000);
- ms = (ms % 1000);
- }
+ if (ms >= 1000) {
+ sleep(ms / 1000);
+ ms = (ms % 1000);
+ }
- usleep(ms * 1000);
+ usleep(ms * 1000);
}
#endif
diff --git a/source/blender/blenlib/intern/timecode.c b/source/blender/blenlib/intern/timecode.c
index 53d0347d088..9b6ed00c704 100644
--- a/source/blender/blenlib/intern/timecode.c
+++ b/source/blender/blenlib/intern/timecode.c
@@ -25,14 +25,13 @@
#include <stdio.h>
-
#include "BLI_utildefines.h"
#include "BLI_string.h"
#include "BLI_math.h"
-#include "BLI_timecode.h" /* own include */
+#include "BLI_timecode.h" /* own include */
-#include "DNA_userdef_types.h" /* for eTimecodeStyles only */
+#include "DNA_userdef_types.h" /* for eTimecodeStyles only */
#include "BLI_strict_flags.h"
@@ -49,149 +48,151 @@
* \return length of \a str
*/
-size_t BLI_timecode_string_from_time(
- char *str, const size_t maxncpy, const int brevity_level, const float time_seconds,
- const double fps, const short timecode_style)
+size_t BLI_timecode_string_from_time(char *str,
+ const size_t maxncpy,
+ const int brevity_level,
+ const float time_seconds,
+ const double fps,
+ const short timecode_style)
{
- int hours = 0, minutes = 0, seconds = 0, frames = 0;
- float time = time_seconds;
- char neg[2] = {'\0'};
- size_t rlen;
-
- /* get cframes */
- if (time < 0) {
- /* correction for negative cfraues */
- neg[0] = '-';
- time = -time;
- }
-
- if (time >= 3600.0f) {
- /* hours */
- /* XXX should we only display a single digit for hours since clips are
- * VERY UNLIKELY to be more than 1-2 hours max? However, that would
- * go against conventions...
- */
- hours = (int)time / 3600;
- time = fmodf(time, 3600);
- }
-
- if (time >= 60.0f) {
- /* minutes */
- minutes = (int)time / 60;
- time = fmodf(time, 60);
- }
-
- if (brevity_level <= 0) {
- /* seconds + frames
- * Frames are derived from 'fraction' of second. We need to perform some additional rounding
- * to cope with 'half' frames, etc., which should be fine in most cases
- */
- seconds = (int)time;
- frames = round_fl_to_int((float)(((double)time - (double)seconds) * fps));
- }
- else {
- /* seconds (with pixel offset rounding) */
- seconds = round_fl_to_int(time);
- }
-
- switch (timecode_style) {
- case USER_TIMECODE_MINIMAL:
- {
- /* - In general, minutes and seconds should be shown, as most clips will be
- * within this length. Hours will only be included if relevant.
- * - Only show frames when zoomed in enough for them to be relevant
- * (using separator of '+' for frames).
- * When showing frames, use slightly different display to avoid confusion with mm:ss format
- */
- if (brevity_level <= 0) {
- /* include "frames" in display */
- if (hours) {
- rlen = BLI_snprintf_rlen(str, maxncpy, "%s%02d:%02d:%02d+%02d", neg, hours, minutes, seconds, frames);
- }
- else if (minutes) {
- rlen = BLI_snprintf_rlen(str, maxncpy, "%s%02d:%02d+%02d", neg, minutes, seconds, frames);
- }
- else {
- rlen = BLI_snprintf_rlen(str, maxncpy, "%s%d+%02d", neg, seconds, frames);
- }
- }
- else {
- /* don't include 'frames' in display */
- if (hours) {
- rlen = BLI_snprintf_rlen(str, maxncpy, "%s%02d:%02d:%02d", neg, hours, minutes, seconds);
- }
- else {
- rlen = BLI_snprintf_rlen(str, maxncpy, "%s%02d:%02d", neg, minutes, seconds);
- }
- }
- break;
- }
- case USER_TIMECODE_SMPTE_MSF:
- {
- /* reduced SMPTE format that always shows minutes, seconds, frames.
- * Hours only shown as needed. */
- if (hours) {
- rlen = BLI_snprintf_rlen(str, maxncpy, "%s%02d:%02d:%02d:%02d", neg, hours, minutes, seconds, frames);
- }
- else {
- rlen = BLI_snprintf_rlen(str, maxncpy, "%s%02d:%02d:%02d", neg, minutes, seconds, frames);
- }
- break;
- }
- case USER_TIMECODE_MILLISECONDS:
- {
- /* reduced SMPTE. Instead of frames, milliseconds are shown */
-
- /* precision of decimal part */
- const int ms_dp = (brevity_level <= 0) ? (1 - brevity_level) : 1;
-
- /* to get 2 digit whole-number part for seconds display
- * (i.e. 3 is for 2 digits + radix, on top of full length) */
- const int s_pad = ms_dp + 3;
-
- if (hours) {
- rlen = BLI_snprintf_rlen(str, maxncpy, "%s%02d:%02d:%0*.*f", neg, hours, minutes, s_pad, ms_dp, time);
- }
- else {
- rlen = BLI_snprintf_rlen(str, maxncpy, "%s%02d:%0*.*f", neg, minutes, s_pad, ms_dp, time);
- }
- break;
- }
- case USER_TIMECODE_SUBRIP:
- {
- /* SubRip, like SMPTE milliseconds but seconds and milliseconds
- * are separated by a comma, not a dot... */
-
- /* precision of decimal part */
- const int ms_dp = (brevity_level <= 0) ? (1 - brevity_level) : 1;
- const int ms = round_fl_to_int((time - (float)seconds) * 1000.0f);
-
- rlen = BLI_snprintf_rlen(
- str, maxncpy, "%s%02d:%02d:%02d,%0*d", neg, hours, minutes, seconds, ms_dp, ms);
- break;
- }
- case USER_TIMECODE_SECONDS_ONLY:
- {
- /* only show the original seconds display */
- /* round to whole numbers if brevity_level is >= 1 (i.e. scale is coarse) */
- if (brevity_level <= 0) {
- rlen = BLI_snprintf_rlen(str, maxncpy, "%.*f", 1 - brevity_level, time_seconds);
- }
- else {
- rlen = BLI_snprintf_rlen(str, maxncpy, "%d", round_fl_to_int(time_seconds));
- }
- break;
- }
- case USER_TIMECODE_SMPTE_FULL:
- default:
- {
- /* full SMPTE format */
- rlen = BLI_snprintf_rlen(str, maxncpy, "%s%02d:%02d:%02d:%02d", neg, hours, minutes, seconds, frames);
- break;
- }
- }
-
- return rlen;
+ int hours = 0, minutes = 0, seconds = 0, frames = 0;
+ float time = time_seconds;
+ char neg[2] = {'\0'};
+ size_t rlen;
+
+ /* get cframes */
+ if (time < 0) {
+ /* correction for negative cfraues */
+ neg[0] = '-';
+ time = -time;
+ }
+
+ if (time >= 3600.0f) {
+ /* hours */
+ /* XXX should we only display a single digit for hours since clips are
+ * VERY UNLIKELY to be more than 1-2 hours max? However, that would
+ * go against conventions...
+ */
+ hours = (int)time / 3600;
+ time = fmodf(time, 3600);
+ }
+
+ if (time >= 60.0f) {
+ /* minutes */
+ minutes = (int)time / 60;
+ time = fmodf(time, 60);
+ }
+
+ if (brevity_level <= 0) {
+ /* seconds + frames
+ * Frames are derived from 'fraction' of second. We need to perform some additional rounding
+ * to cope with 'half' frames, etc., which should be fine in most cases
+ */
+ seconds = (int)time;
+ frames = round_fl_to_int((float)(((double)time - (double)seconds) * fps));
+ }
+ else {
+ /* seconds (with pixel offset rounding) */
+ seconds = round_fl_to_int(time);
+ }
+
+ switch (timecode_style) {
+ case USER_TIMECODE_MINIMAL: {
+ /* - In general, minutes and seconds should be shown, as most clips will be
+ * within this length. Hours will only be included if relevant.
+ * - Only show frames when zoomed in enough for them to be relevant
+ * (using separator of '+' for frames).
+ * When showing frames, use slightly different display to avoid confusion with mm:ss format
+ */
+ if (brevity_level <= 0) {
+ /* include "frames" in display */
+ if (hours) {
+ rlen = BLI_snprintf_rlen(
+ str, maxncpy, "%s%02d:%02d:%02d+%02d", neg, hours, minutes, seconds, frames);
+ }
+ else if (minutes) {
+ rlen = BLI_snprintf_rlen(
+ str, maxncpy, "%s%02d:%02d+%02d", neg, minutes, seconds, frames);
+ }
+ else {
+ rlen = BLI_snprintf_rlen(str, maxncpy, "%s%d+%02d", neg, seconds, frames);
+ }
+ }
+ else {
+ /* don't include 'frames' in display */
+ if (hours) {
+ rlen = BLI_snprintf_rlen(str, maxncpy, "%s%02d:%02d:%02d", neg, hours, minutes, seconds);
+ }
+ else {
+ rlen = BLI_snprintf_rlen(str, maxncpy, "%s%02d:%02d", neg, minutes, seconds);
+ }
+ }
+ break;
+ }
+ case USER_TIMECODE_SMPTE_MSF: {
+ /* reduced SMPTE format that always shows minutes, seconds, frames.
+ * Hours only shown as needed. */
+ if (hours) {
+ rlen = BLI_snprintf_rlen(
+ str, maxncpy, "%s%02d:%02d:%02d:%02d", neg, hours, minutes, seconds, frames);
+ }
+ else {
+ rlen = BLI_snprintf_rlen(str, maxncpy, "%s%02d:%02d:%02d", neg, minutes, seconds, frames);
+ }
+ break;
+ }
+ case USER_TIMECODE_MILLISECONDS: {
+ /* reduced SMPTE. Instead of frames, milliseconds are shown */
+
+ /* precision of decimal part */
+ const int ms_dp = (brevity_level <= 0) ? (1 - brevity_level) : 1;
+
+ /* to get 2 digit whole-number part for seconds display
+ * (i.e. 3 is for 2 digits + radix, on top of full length) */
+ const int s_pad = ms_dp + 3;
+
+ if (hours) {
+ rlen = BLI_snprintf_rlen(
+ str, maxncpy, "%s%02d:%02d:%0*.*f", neg, hours, minutes, s_pad, ms_dp, time);
+ }
+ else {
+ rlen = BLI_snprintf_rlen(str, maxncpy, "%s%02d:%0*.*f", neg, minutes, s_pad, ms_dp, time);
+ }
+ break;
+ }
+ case USER_TIMECODE_SUBRIP: {
+ /* SubRip, like SMPTE milliseconds but seconds and milliseconds
+ * are separated by a comma, not a dot... */
+
+ /* precision of decimal part */
+ const int ms_dp = (brevity_level <= 0) ? (1 - brevity_level) : 1;
+ const int ms = round_fl_to_int((time - (float)seconds) * 1000.0f);
+
+ rlen = BLI_snprintf_rlen(
+ str, maxncpy, "%s%02d:%02d:%02d,%0*d", neg, hours, minutes, seconds, ms_dp, ms);
+ break;
+ }
+ case USER_TIMECODE_SECONDS_ONLY: {
+ /* only show the original seconds display */
+ /* round to whole numbers if brevity_level is >= 1 (i.e. scale is coarse) */
+ if (brevity_level <= 0) {
+ rlen = BLI_snprintf_rlen(str, maxncpy, "%.*f", 1 - brevity_level, time_seconds);
+ }
+ else {
+ rlen = BLI_snprintf_rlen(str, maxncpy, "%d", round_fl_to_int(time_seconds));
+ }
+ break;
+ }
+ case USER_TIMECODE_SMPTE_FULL:
+ default: {
+ /* full SMPTE format */
+ rlen = BLI_snprintf_rlen(
+ str, maxncpy, "%s%02d:%02d:%02d:%02d", neg, hours, minutes, seconds, frames);
+ break;
+ }
+ }
+
+ return rlen;
}
/**
@@ -202,25 +203,26 @@ size_t BLI_timecode_string_from_time(
* \param time_seconds: time total time in seconds
* \return length of \a str
*/
-size_t BLI_timecode_string_from_time_simple(
- char *str, const size_t maxncpy, const double time_seconds)
+size_t BLI_timecode_string_from_time_simple(char *str,
+ const size_t maxncpy,
+ const double time_seconds)
{
- size_t rlen;
-
- /* format 00:00:00.00 (hr:min:sec) string has to be 12 long */
- const int hr = ( (int) time_seconds) / (60 * 60);
- const int min = (((int) time_seconds) / 60 ) % 60;
- const int sec = ( (int) time_seconds) % 60;
- const int hun = ( (int) (time_seconds * 100.0)) % 100;
-
- if (hr) {
- rlen = BLI_snprintf(str, maxncpy, "%.2d:%.2d:%.2d.%.2d", hr, min, sec, hun);
- }
- else {
- rlen = BLI_snprintf(str, maxncpy, "%.2d:%.2d.%.2d", min, sec, hun);
- }
-
- return rlen;
+ size_t rlen;
+
+ /* format 00:00:00.00 (hr:min:sec) string has to be 12 long */
+ const int hr = ((int)time_seconds) / (60 * 60);
+ const int min = (((int)time_seconds) / 60) % 60;
+ const int sec = ((int)time_seconds) % 60;
+ const int hun = ((int)(time_seconds * 100.0)) % 100;
+
+ if (hr) {
+ rlen = BLI_snprintf(str, maxncpy, "%.2d:%.2d:%.2d.%.2d", hr, min, sec, hun);
+ }
+ else {
+ rlen = BLI_snprintf(str, maxncpy, "%.2d:%.2d.%.2d", min, sec, hun);
+ }
+
+ return rlen;
}
/**
@@ -235,18 +237,20 @@ size_t BLI_timecode_string_from_time_simple(
*
* \note in some cases this is used to print non-seconds values.
*/
-size_t BLI_timecode_string_from_time_seconds(
- char *str, const size_t maxncpy, const int brevity_level, const float time_seconds)
+size_t BLI_timecode_string_from_time_seconds(char *str,
+ const size_t maxncpy,
+ const int brevity_level,
+ const float time_seconds)
{
- size_t rlen;
+ size_t rlen;
- /* round to whole numbers if brevity_level is >= 1 (i.e. scale is coarse) */
- if (brevity_level <= 0) {
- rlen = BLI_snprintf_rlen(str, maxncpy, "%.*f", 1 - brevity_level, time_seconds);
- }
- else {
- rlen = BLI_snprintf_rlen(str, maxncpy, "%d", round_fl_to_int(time_seconds));
- }
+ /* round to whole numbers if brevity_level is >= 1 (i.e. scale is coarse) */
+ if (brevity_level <= 0) {
+ rlen = BLI_snprintf_rlen(str, maxncpy, "%.*f", 1 - brevity_level, time_seconds);
+ }
+ else {
+ rlen = BLI_snprintf_rlen(str, maxncpy, "%d", round_fl_to_int(time_seconds));
+ }
- return rlen;
+ return rlen;
}
diff --git a/source/blender/blenlib/intern/uvproject.c b/source/blender/blenlib/intern/uvproject.c
index c08f0d5e32b..a34c551767a 100644
--- a/source/blender/blenlib/intern/uvproject.c
+++ b/source/blender/blenlib/intern/uvproject.c
@@ -29,168 +29,173 @@
#include "BLI_uvproject.h"
typedef struct ProjCameraInfo {
- float camangle;
- float camsize;
- float xasp, yasp;
- float shiftx, shifty;
- float rotmat[4][4];
- float caminv[4][4];
- bool do_persp, do_pano, do_rotmat;
+ float camangle;
+ float camsize;
+ float xasp, yasp;
+ float shiftx, shifty;
+ float rotmat[4][4];
+ float caminv[4][4];
+ bool do_persp, do_pano, do_rotmat;
} ProjCameraInfo;
void BLI_uvproject_from_camera(float target[2], float source[3], ProjCameraInfo *uci)
{
- float pv4[4];
-
- copy_v3_v3(pv4, source);
- pv4[3] = 1.0;
-
- /* rotmat is the object matrix in this case */
- if (uci->do_rotmat) {
- mul_m4_v4(uci->rotmat, pv4);
- }
-
- /* caminv is the inverse camera matrix */
- mul_m4_v4(uci->caminv, pv4);
-
- if (uci->do_pano) {
- float angle = atan2f(pv4[0], -pv4[2]) / ((float)M_PI * 2.0f); /* angle around the camera */
- if (uci->do_persp == false) {
- target[0] = angle; /* no correct method here, just map to 0-1 */
- target[1] = pv4[1] / uci->camsize;
- }
- else {
- float vec2d[2]; /* 2D position from the camera */
- vec2d[0] = pv4[0];
- vec2d[1] = pv4[2];
- target[0] = angle * ((float)M_PI / uci->camangle);
- target[1] = pv4[1] / (len_v2(vec2d) * (uci->camsize * 2.0f));
- }
- }
- else {
- if (pv4[2] == 0.0f) {
- pv4[2] = 0.00001f; /* don't allow div by 0 */
- }
-
- if (uci->do_persp == false) {
- target[0] = (pv4[0] / uci->camsize);
- target[1] = (pv4[1] / uci->camsize);
- }
- else {
- target[0] = (-pv4[0] * ((1.0f / uci->camsize) / pv4[2])) / 2.0f;
- target[1] = (-pv4[1] * ((1.0f / uci->camsize) / pv4[2])) / 2.0f;
- }
- }
-
- target[0] *= uci->xasp;
- target[1] *= uci->yasp;
-
- /* adds camera shift + 0.5 */
- target[0] += uci->shiftx;
- target[1] += uci->shifty;
+ float pv4[4];
+
+ copy_v3_v3(pv4, source);
+ pv4[3] = 1.0;
+
+ /* rotmat is the object matrix in this case */
+ if (uci->do_rotmat) {
+ mul_m4_v4(uci->rotmat, pv4);
+ }
+
+ /* caminv is the inverse camera matrix */
+ mul_m4_v4(uci->caminv, pv4);
+
+ if (uci->do_pano) {
+ float angle = atan2f(pv4[0], -pv4[2]) / ((float)M_PI * 2.0f); /* angle around the camera */
+ if (uci->do_persp == false) {
+ target[0] = angle; /* no correct method here, just map to 0-1 */
+ target[1] = pv4[1] / uci->camsize;
+ }
+ else {
+ float vec2d[2]; /* 2D position from the camera */
+ vec2d[0] = pv4[0];
+ vec2d[1] = pv4[2];
+ target[0] = angle * ((float)M_PI / uci->camangle);
+ target[1] = pv4[1] / (len_v2(vec2d) * (uci->camsize * 2.0f));
+ }
+ }
+ else {
+ if (pv4[2] == 0.0f) {
+ pv4[2] = 0.00001f; /* don't allow div by 0 */
+ }
+
+ if (uci->do_persp == false) {
+ target[0] = (pv4[0] / uci->camsize);
+ target[1] = (pv4[1] / uci->camsize);
+ }
+ else {
+ target[0] = (-pv4[0] * ((1.0f / uci->camsize) / pv4[2])) / 2.0f;
+ target[1] = (-pv4[1] * ((1.0f / uci->camsize) / pv4[2])) / 2.0f;
+ }
+ }
+
+ target[0] *= uci->xasp;
+ target[1] *= uci->yasp;
+
+ /* adds camera shift + 0.5 */
+ target[0] += uci->shiftx;
+ target[1] += uci->shifty;
}
/* could rv3d->persmat */
-void BLI_uvproject_from_view(float target[2], float source[3], float persmat[4][4], float rotmat[4][4], float winx, float winy)
+void BLI_uvproject_from_view(float target[2],
+ float source[3],
+ float persmat[4][4],
+ float rotmat[4][4],
+ float winx,
+ float winy)
{
- float pv4[4], x = 0.0, y = 0.0;
-
- copy_v3_v3(pv4, source);
- pv4[3] = 1.0;
-
- /* rotmat is the object matrix in this case */
- mul_m4_v4(rotmat, pv4);
-
- /* almost ED_view3d_project_short */
- mul_m4_v4(persmat, pv4);
- if (fabsf(pv4[3]) > 0.00001f) { /* avoid division by zero */
- target[0] = winx / 2.0f + (winx / 2.0f) * pv4[0] / pv4[3];
- target[1] = winy / 2.0f + (winy / 2.0f) * pv4[1] / pv4[3];
- }
- else {
- /* scaling is lost but give a valid result */
- target[0] = winx / 2.0f + (winx / 2.0f) * pv4[0];
- target[1] = winy / 2.0f + (winy / 2.0f) * pv4[1];
- }
-
- /* v3d->persmat seems to do this funky scaling */
- if (winx > winy) {
- y = (winx - winy) / 2.0f;
- winy = winx;
- }
- else {
- x = (winy - winx) / 2.0f;
- winx = winy;
- }
-
- target[0] = (x + target[0]) / winx;
- target[1] = (y + target[1]) / winy;
+ float pv4[4], x = 0.0, y = 0.0;
+
+ copy_v3_v3(pv4, source);
+ pv4[3] = 1.0;
+
+ /* rotmat is the object matrix in this case */
+ mul_m4_v4(rotmat, pv4);
+
+ /* almost ED_view3d_project_short */
+ mul_m4_v4(persmat, pv4);
+ if (fabsf(pv4[3]) > 0.00001f) { /* avoid division by zero */
+ target[0] = winx / 2.0f + (winx / 2.0f) * pv4[0] / pv4[3];
+ target[1] = winy / 2.0f + (winy / 2.0f) * pv4[1] / pv4[3];
+ }
+ else {
+ /* scaling is lost but give a valid result */
+ target[0] = winx / 2.0f + (winx / 2.0f) * pv4[0];
+ target[1] = winy / 2.0f + (winy / 2.0f) * pv4[1];
+ }
+
+ /* v3d->persmat seems to do this funky scaling */
+ if (winx > winy) {
+ y = (winx - winy) / 2.0f;
+ winy = winx;
+ }
+ else {
+ x = (winy - winx) / 2.0f;
+ winx = winy;
+ }
+
+ target[0] = (x + target[0]) / winx;
+ target[1] = (y + target[1]) / winy;
}
/* 'rotmat' can be obedit->obmat when uv project is used.
* 'winx' and 'winy' can be from scene->r.xsch/ysch */
-ProjCameraInfo *BLI_uvproject_camera_info(Object *ob, float(*rotmat)[4], float winx, float winy)
+ProjCameraInfo *BLI_uvproject_camera_info(Object *ob, float (*rotmat)[4], float winx, float winy)
{
- ProjCameraInfo uci;
- Camera *camera = ob->data;
-
- uci.do_pano = (camera->type == CAM_PANO);
- uci.do_persp = (camera->type == CAM_PERSP);
-
- uci.camangle = focallength_to_fov(camera->lens, camera->sensor_x) / 2.0f;
- uci.camsize = uci.do_persp ? tanf(uci.camangle) : camera->ortho_scale;
-
- /* account for scaled cameras */
- copy_m4_m4(uci.caminv, ob->obmat);
- normalize_m4(uci.caminv);
-
- if (invert_m4(uci.caminv)) {
- ProjCameraInfo *uci_pt;
-
- /* normal projection */
- if (rotmat) {
- copy_m4_m4(uci.rotmat, rotmat);
- uci.do_rotmat = true;
- }
- else {
- uci.do_rotmat = false;
- }
-
- /* also make aspect ratio adjustment factors */
- if (winx > winy) {
- uci.xasp = 1.0f;
- uci.yasp = winx / winy;
- }
- else {
- uci.xasp = winy / winx;
- uci.yasp = 1.0f;
- }
-
- /* include 0.5f here to move the UVs into the center */
- uci.shiftx = 0.5f - (camera->shiftx * uci.xasp);
- uci.shifty = 0.5f - (camera->shifty * uci.yasp);
-
- uci_pt = MEM_mallocN(sizeof(ProjCameraInfo), "ProjCameraInfo");
- *uci_pt = uci;
- return uci_pt;
- }
-
- return NULL;
+ ProjCameraInfo uci;
+ Camera *camera = ob->data;
+
+ uci.do_pano = (camera->type == CAM_PANO);
+ uci.do_persp = (camera->type == CAM_PERSP);
+
+ uci.camangle = focallength_to_fov(camera->lens, camera->sensor_x) / 2.0f;
+ uci.camsize = uci.do_persp ? tanf(uci.camangle) : camera->ortho_scale;
+
+ /* account for scaled cameras */
+ copy_m4_m4(uci.caminv, ob->obmat);
+ normalize_m4(uci.caminv);
+
+ if (invert_m4(uci.caminv)) {
+ ProjCameraInfo *uci_pt;
+
+ /* normal projection */
+ if (rotmat) {
+ copy_m4_m4(uci.rotmat, rotmat);
+ uci.do_rotmat = true;
+ }
+ else {
+ uci.do_rotmat = false;
+ }
+
+ /* also make aspect ratio adjustment factors */
+ if (winx > winy) {
+ uci.xasp = 1.0f;
+ uci.yasp = winx / winy;
+ }
+ else {
+ uci.xasp = winy / winx;
+ uci.yasp = 1.0f;
+ }
+
+ /* include 0.5f here to move the UVs into the center */
+ uci.shiftx = 0.5f - (camera->shiftx * uci.xasp);
+ uci.shifty = 0.5f - (camera->shifty * uci.yasp);
+
+ uci_pt = MEM_mallocN(sizeof(ProjCameraInfo), "ProjCameraInfo");
+ *uci_pt = uci;
+ return uci_pt;
+ }
+
+ return NULL;
}
void BLI_uvproject_from_view_ortho(float target[2], float source[3], float rotmat[4][4])
{
- float pv[3];
+ float pv[3];
- mul_v3_m4v3(pv, rotmat, source);
+ mul_v3_m4v3(pv, rotmat, source);
- /* ortho projection */
- target[0] = -pv[0];
- target[1] = pv[2];
+ /* ortho projection */
+ target[0] = -pv[0];
+ target[1] = pv[2];
}
void BLI_uvproject_camera_info_scale(ProjCameraInfo *uci, float scale_x, float scale_y)
{
- uci->xasp *= scale_x;
- uci->yasp *= scale_y;
+ uci->xasp *= scale_x;
+ uci->yasp *= scale_y;
}
diff --git a/source/blender/blenlib/intern/voronoi_2d.c b/source/blender/blenlib/intern/voronoi_2d.c
index 248e07eae35..29beb93159a 100644
--- a/source/blender/blenlib/intern/voronoi_2d.c
+++ b/source/blender/blenlib/intern/voronoi_2d.c
@@ -34,823 +34,829 @@
#define VORONOI_EPS 1e-2f
enum {
- voronoiEventType_Site = 0,
- voronoiEventType_Circle = 1,
+ voronoiEventType_Site = 0,
+ voronoiEventType_Circle = 1,
};
typedef struct VoronoiEvent {
- struct VoronoiEvent *next, *prev;
+ struct VoronoiEvent *next, *prev;
- int type; /* type of event (site or circle) */
- float site[2]; /* site for which event was generated */
+ int type; /* type of event (site or circle) */
+ float site[2]; /* site for which event was generated */
- struct VoronoiParabola *parabola; /* parabola for which event was generated */
+ struct VoronoiParabola *parabola; /* parabola for which event was generated */
} VoronoiEvent;
typedef struct VoronoiParabola {
- struct VoronoiParabola *left, *right, *parent;
- VoronoiEvent *event;
- VoronoiEdge *edge;
- float site[2];
- bool is_leaf;
+ struct VoronoiParabola *left, *right, *parent;
+ VoronoiEvent *event;
+ VoronoiEdge *edge;
+ float site[2];
+ bool is_leaf;
} VoronoiParabola;
typedef struct VoronoiProcess {
- ListBase queue, edges;
- VoronoiParabola *root;
- int width, height;
- float current_y;
+ ListBase queue, edges;
+ VoronoiParabola *root;
+ int width, height;
+ float current_y;
} VoronoiProcess;
/* event */
static void voronoi_insertEvent(VoronoiProcess *process, VoronoiEvent *event)
{
- VoronoiEvent *current_event = process->queue.first;
+ VoronoiEvent *current_event = process->queue.first;
- while (current_event) {
- if (current_event->site[1] < event->site[1]) {
- break;
- }
- if (current_event->site[1] == event->site[1]) {
- event->site[1] -= VORONOI_EPS;
- }
+ while (current_event) {
+ if (current_event->site[1] < event->site[1]) {
+ break;
+ }
+ if (current_event->site[1] == event->site[1]) {
+ event->site[1] -= VORONOI_EPS;
+ }
- current_event = current_event->next;
- }
+ current_event = current_event->next;
+ }
- BLI_insertlinkbefore(&process->queue, current_event, event);
+ BLI_insertlinkbefore(&process->queue, current_event, event);
}
/* edge */
static VoronoiEdge *voronoiEdge_new(float start[2], float left[2], float right[2])
{
- VoronoiEdge *edge = MEM_callocN(sizeof(VoronoiEdge), "voronoi edge");
+ VoronoiEdge *edge = MEM_callocN(sizeof(VoronoiEdge), "voronoi edge");
- copy_v2_v2(edge->start, start);
- copy_v2_v2(edge->left, left);
- copy_v2_v2(edge->right, right);
+ copy_v2_v2(edge->start, start);
+ copy_v2_v2(edge->left, left);
+ copy_v2_v2(edge->right, right);
- edge->neighbor = NULL;
- edge->end[0] = 0;
- edge->end[1] = 0;
+ edge->neighbor = NULL;
+ edge->end[0] = 0;
+ edge->end[1] = 0;
- edge->f = (right[0] - left[0]) / (left[1] - right[1]);
- edge->g = start[1] - edge->f * start[0];
+ edge->f = (right[0] - left[0]) / (left[1] - right[1]);
+ edge->g = start[1] - edge->f * start[0];
- edge->direction[0] = right[1] - left[1];
- edge->direction[1] = -(right[0] - left[0]);
+ edge->direction[0] = right[1] - left[1];
+ edge->direction[1] = -(right[0] - left[0]);
- return edge;
+ return edge;
}
/* parabola */
static VoronoiParabola *voronoiParabola_new(void)
{
- VoronoiParabola *parabola = MEM_callocN(sizeof(VoronoiParabola), "voronoi parabola");
+ VoronoiParabola *parabola = MEM_callocN(sizeof(VoronoiParabola), "voronoi parabola");
- parabola->is_leaf = false;
- parabola->event = NULL;
- parabola->edge = NULL;
- parabola->parent = NULL;
+ parabola->is_leaf = false;
+ parabola->event = NULL;
+ parabola->edge = NULL;
+ parabola->parent = NULL;
- return parabola;
+ return parabola;
}
static VoronoiParabola *voronoiParabola_newSite(float site[2])
{
- VoronoiParabola *parabola = MEM_callocN(sizeof(VoronoiParabola), "voronoi parabola site");
+ VoronoiParabola *parabola = MEM_callocN(sizeof(VoronoiParabola), "voronoi parabola site");
- copy_v2_v2(parabola->site, site);
- parabola->is_leaf = true;
- parabola->event = NULL;
- parabola->edge = NULL;
- parabola->parent = NULL;
+ copy_v2_v2(parabola->site, site);
+ parabola->is_leaf = true;
+ parabola->event = NULL;
+ parabola->edge = NULL;
+ parabola->parent = NULL;
- return parabola;
+ return parabola;
}
/* returns the closest leave which is on the left of current node */
static VoronoiParabola *voronoiParabola_getLeftChild(VoronoiParabola *parabola)
{
- VoronoiParabola *current_parabola;
+ VoronoiParabola *current_parabola;
- if (!parabola) {
- return NULL;
- }
+ if (!parabola) {
+ return NULL;
+ }
- current_parabola = parabola->left;
- while (!current_parabola->is_leaf) {
- current_parabola = current_parabola->right;
- }
+ current_parabola = parabola->left;
+ while (!current_parabola->is_leaf) {
+ current_parabola = current_parabola->right;
+ }
- return current_parabola;
+ return current_parabola;
}
/* returns the closest leave which is on the right of current node */
static VoronoiParabola *voronoiParabola_getRightChild(VoronoiParabola *parabola)
{
- VoronoiParabola *current_parabola;
+ VoronoiParabola *current_parabola;
- if (!parabola) {
- return NULL;
- }
+ if (!parabola) {
+ return NULL;
+ }
- current_parabola = parabola->right;
- while (!current_parabola->is_leaf) {
- current_parabola = current_parabola->left;
- }
+ current_parabola = parabola->right;
+ while (!current_parabola->is_leaf) {
+ current_parabola = current_parabola->left;
+ }
- return current_parabola;
+ return current_parabola;
}
/* returns the closest parent which is on the left */
static VoronoiParabola *voronoiParabola_getLeftParent(VoronoiParabola *parabola)
{
- VoronoiParabola *current_par = parabola->parent;
- VoronoiParabola *last_parabola = parabola;
+ VoronoiParabola *current_par = parabola->parent;
+ VoronoiParabola *last_parabola = parabola;
- while (current_par->left == last_parabola) {
- if (!current_par->parent) {
- return NULL;
- }
+ while (current_par->left == last_parabola) {
+ if (!current_par->parent) {
+ return NULL;
+ }
- last_parabola = current_par;
- current_par = current_par->parent;
- }
+ last_parabola = current_par;
+ current_par = current_par->parent;
+ }
- return current_par;
+ return current_par;
}
/* returns the closest parent which is on the right */
static VoronoiParabola *voronoiParabola_getRightParent(VoronoiParabola *parabola)
{
- VoronoiParabola *current_parabola = parabola->parent;
- VoronoiParabola *last_parabola = parabola;
+ VoronoiParabola *current_parabola = parabola->parent;
+ VoronoiParabola *last_parabola = parabola;
- while (current_parabola->right == last_parabola) {
- if (!current_parabola->parent) {
- return NULL;
- }
+ while (current_parabola->right == last_parabola) {
+ if (!current_parabola->parent) {
+ return NULL;
+ }
- last_parabola = current_parabola;
- current_parabola = current_parabola->parent;
- }
+ last_parabola = current_parabola;
+ current_parabola = current_parabola->parent;
+ }
- return current_parabola;
+ return current_parabola;
}
static void voronoiParabola_setLeft(VoronoiParabola *parabola, VoronoiParabola *left)
{
- parabola->left = left;
- left->parent = parabola;
+ parabola->left = left;
+ left->parent = parabola;
}
static void voronoiParabola_setRight(VoronoiParabola *parabola, VoronoiParabola *right)
{
- parabola->right = right;
- right->parent = parabola;
+ parabola->right = right;
+ right->parent = parabola;
}
static float voronoi_getY(VoronoiProcess *process, float p[2], float x)
{
- float ly = process->current_y;
+ float ly = process->current_y;
- float dp = 2 * (p[1] - ly);
- float a1 = 1 / dp;
- float b1 = -2 * p[0] / dp;
- float c1 = ly + dp / 4 + p[0] * p[0] / dp;
+ float dp = 2 * (p[1] - ly);
+ float a1 = 1 / dp;
+ float b1 = -2 * p[0] / dp;
+ float c1 = ly + dp / 4 + p[0] * p[0] / dp;
- return a1 * x * x + b1 * x + c1;
+ return a1 * x * x + b1 * x + c1;
}
static float voronoi_getXOfEdge(VoronoiProcess *process, VoronoiParabola *par, float y)
{
- VoronoiParabola *left = voronoiParabola_getLeftChild(par);
- VoronoiParabola *right = voronoiParabola_getRightChild(par);
- float p[2], r[2];
- float dp, a1, b1, c1, a2, b2, c2, a, b, c, disc, ry, x1, x2;
- float ly = process->current_y;
-
- copy_v2_v2(p, left->site);
- copy_v2_v2(r, right->site);
-
- dp = 2.0f * (p[1] - y);
- a1 = 1.0f / dp;
- b1 = -2.0f * p[0] / dp;
- c1 = y + dp / 4 + p[0] * p[0] / dp;
-
- dp = 2.0f * (r[1] - y);
- a2 = 1.0f / dp;
- b2 = -2.0f * r[0] / dp;
- c2 = ly + dp / 4 + r[0] * r[0] / dp;
-
- a = a1 - a2;
- b = b1 - b2;
- c = c1 - c2;
-
- disc = b * b - 4 * a * c;
- x1 = (-b + sqrtf(disc)) / (2 * a);
- x2 = (-b - sqrtf(disc)) / (2 * a);
-
- if (p[1] < r[1]) {
- ry = max_ff(x1, x2);
- }
- else {
- ry = min_ff(x1, x2);
- }
-
- return ry;
+ VoronoiParabola *left = voronoiParabola_getLeftChild(par);
+ VoronoiParabola *right = voronoiParabola_getRightChild(par);
+ float p[2], r[2];
+ float dp, a1, b1, c1, a2, b2, c2, a, b, c, disc, ry, x1, x2;
+ float ly = process->current_y;
+
+ copy_v2_v2(p, left->site);
+ copy_v2_v2(r, right->site);
+
+ dp = 2.0f * (p[1] - y);
+ a1 = 1.0f / dp;
+ b1 = -2.0f * p[0] / dp;
+ c1 = y + dp / 4 + p[0] * p[0] / dp;
+
+ dp = 2.0f * (r[1] - y);
+ a2 = 1.0f / dp;
+ b2 = -2.0f * r[0] / dp;
+ c2 = ly + dp / 4 + r[0] * r[0] / dp;
+
+ a = a1 - a2;
+ b = b1 - b2;
+ c = c1 - c2;
+
+ disc = b * b - 4 * a * c;
+ x1 = (-b + sqrtf(disc)) / (2 * a);
+ x2 = (-b - sqrtf(disc)) / (2 * a);
+
+ if (p[1] < r[1]) {
+ ry = max_ff(x1, x2);
+ }
+ else {
+ ry = min_ff(x1, x2);
+ }
+
+ return ry;
}
static VoronoiParabola *voronoi_getParabolaByX(VoronoiProcess *process, float xx)
{
- VoronoiParabola *par = process->root;
- float x = 0.0f;
- float ly = process->current_y;
-
- while (!par->is_leaf) {
- x = voronoi_getXOfEdge(process, par, ly);
-
- if (x > xx) {
- par = par->left;
- }
- else {
- par = par->right;
- }
- }
-
- return par;
+ VoronoiParabola *par = process->root;
+ float x = 0.0f;
+ float ly = process->current_y;
+
+ while (!par->is_leaf) {
+ x = voronoi_getXOfEdge(process, par, ly);
+
+ if (x > xx) {
+ par = par->left;
+ }
+ else {
+ par = par->right;
+ }
+ }
+
+ return par;
}
static int voronoi_getEdgeIntersection(VoronoiEdge *a, VoronoiEdge *b, float p[2])
{
- float x = (b->g - a->g) / (a->f - b->f);
- float y = a->f * x + a->g;
+ float x = (b->g - a->g) / (a->f - b->f);
+ float y = a->f * x + a->g;
- if ((x - a->start[0]) / a->direction[0] < 0) {
- return 0;
- }
+ if ((x - a->start[0]) / a->direction[0] < 0) {
+ return 0;
+ }
- if ((y - a->start[1]) / a->direction[1] < 0) {
- return 0;
- }
+ if ((y - a->start[1]) / a->direction[1] < 0) {
+ return 0;
+ }
- if ((x - b->start[0]) / b->direction[0] < 0) {
- return 0;
- }
+ if ((x - b->start[0]) / b->direction[0] < 0) {
+ return 0;
+ }
- if ((y - b->start[1]) / b->direction[1] < 0) {
- return 0;
- }
+ if ((y - b->start[1]) / b->direction[1] < 0) {
+ return 0;
+ }
- p[0] = x;
- p[1] = y;
+ p[0] = x;
+ p[1] = y;
- return 1;
+ return 1;
}
static void voronoi_checkCircle(VoronoiProcess *process, VoronoiParabola *b)
{
- VoronoiParabola *lp = voronoiParabola_getLeftParent(b);
- VoronoiParabola *rp = voronoiParabola_getRightParent(b);
+ VoronoiParabola *lp = voronoiParabola_getLeftParent(b);
+ VoronoiParabola *rp = voronoiParabola_getRightParent(b);
- VoronoiParabola *a = voronoiParabola_getLeftChild(lp);
- VoronoiParabola *c = voronoiParabola_getRightChild(rp);
+ VoronoiParabola *a = voronoiParabola_getLeftChild(lp);
+ VoronoiParabola *c = voronoiParabola_getRightChild(rp);
- VoronoiEvent *event;
+ VoronoiEvent *event;
- float ly = process->current_y;
- float s[2], dx, dy, d;
+ float ly = process->current_y;
+ float s[2], dx, dy, d;
- if (!a || !c || len_squared_v2v2(a->site, c->site) < VORONOI_EPS) {
- return;
- }
+ if (!a || !c || len_squared_v2v2(a->site, c->site) < VORONOI_EPS) {
+ return;
+ }
- if (!voronoi_getEdgeIntersection(lp->edge, rp->edge, s)) {
- return;
- }
+ if (!voronoi_getEdgeIntersection(lp->edge, rp->edge, s)) {
+ return;
+ }
- dx = a->site[0] - s[0];
- dy = a->site[1] - s[1];
+ dx = a->site[0] - s[0];
+ dy = a->site[1] - s[1];
- d = sqrtf((dx * dx) + (dy * dy));
+ d = sqrtf((dx * dx) + (dy * dy));
- if (s[1] - d >= ly) {
- return;
- }
+ if (s[1] - d >= ly) {
+ return;
+ }
- event = MEM_callocN(sizeof(VoronoiEvent), "voronoi circle event");
+ event = MEM_callocN(sizeof(VoronoiEvent), "voronoi circle event");
- event->type = voronoiEventType_Circle;
+ event->type = voronoiEventType_Circle;
- event->site[0] = s[0];
- event->site[1] = s[1] - d;
+ event->site[0] = s[0];
+ event->site[1] = s[1] - d;
- b->event = event;
- event->parabola = b;
+ b->event = event;
+ event->parabola = b;
- voronoi_insertEvent(process, event);
+ voronoi_insertEvent(process, event);
}
static void voronoi_addParabola(VoronoiProcess *process, float site[2])
{
- VoronoiParabola *root = process->root;
- VoronoiParabola *par, *p0, *p1, *p2;
- VoronoiEdge *el, *er;
- float start[2];
+ VoronoiParabola *root = process->root;
+ VoronoiParabola *par, *p0, *p1, *p2;
+ VoronoiEdge *el, *er;
+ float start[2];
- if (!process->root) {
- process->root = voronoiParabola_newSite(site);
+ if (!process->root) {
+ process->root = voronoiParabola_newSite(site);
- return;
- }
+ return;
+ }
- if (root->is_leaf && root->site[1] - site[1] < 0) {
- float *fp = root->site;
- float s[2];
+ if (root->is_leaf && root->site[1] - site[1] < 0) {
+ float *fp = root->site;
+ float s[2];
- root->is_leaf = false;
- voronoiParabola_setLeft(root, voronoiParabola_newSite(fp));
- voronoiParabola_setRight(root, voronoiParabola_newSite(site));
+ root->is_leaf = false;
+ voronoiParabola_setLeft(root, voronoiParabola_newSite(fp));
+ voronoiParabola_setRight(root, voronoiParabola_newSite(site));
- s[0] = (site[0] + fp[0]) / 2.0f;
- s[1] = process->height;
+ s[0] = (site[0] + fp[0]) / 2.0f;
+ s[1] = process->height;
- if (site[0] > fp[0]) {
- root->edge = voronoiEdge_new(s, fp, site);
- }
- else {
- root->edge = voronoiEdge_new(s, site, fp);
- }
+ if (site[0] > fp[0]) {
+ root->edge = voronoiEdge_new(s, fp, site);
+ }
+ else {
+ root->edge = voronoiEdge_new(s, site, fp);
+ }
- BLI_addtail(&process->edges, root->edge);
+ BLI_addtail(&process->edges, root->edge);
- return;
- }
+ return;
+ }
- par = voronoi_getParabolaByX(process, site[0]);
+ par = voronoi_getParabolaByX(process, site[0]);
- if (par->event) {
- BLI_freelinkN(&process->queue, par->event);
+ if (par->event) {
+ BLI_freelinkN(&process->queue, par->event);
- par->event = NULL;
- }
+ par->event = NULL;
+ }
- start[0] = site[0];
- start[1] = voronoi_getY(process, par->site, site[0]);
+ start[0] = site[0];
+ start[1] = voronoi_getY(process, par->site, site[0]);
- el = voronoiEdge_new(start, par->site, site);
- er = voronoiEdge_new(start, site, par->site);
+ el = voronoiEdge_new(start, par->site, site);
+ er = voronoiEdge_new(start, site, par->site);
- el->neighbor = er;
- BLI_addtail(&process->edges, el);
+ el->neighbor = er;
+ BLI_addtail(&process->edges, el);
- par->edge = er;
- par->is_leaf = false;
+ par->edge = er;
+ par->is_leaf = false;
- p0 = voronoiParabola_newSite(par->site);
- p1 = voronoiParabola_newSite(site);
- p2 = voronoiParabola_newSite(par->site);
+ p0 = voronoiParabola_newSite(par->site);
+ p1 = voronoiParabola_newSite(site);
+ p2 = voronoiParabola_newSite(par->site);
- voronoiParabola_setRight(par, p2);
- voronoiParabola_setLeft(par, voronoiParabola_new());
- par->left->edge = el;
+ voronoiParabola_setRight(par, p2);
+ voronoiParabola_setLeft(par, voronoiParabola_new());
+ par->left->edge = el;
- voronoiParabola_setLeft(par->left, p0);
- voronoiParabola_setRight(par->left, p1);
+ voronoiParabola_setLeft(par->left, p0);
+ voronoiParabola_setRight(par->left, p1);
- voronoi_checkCircle(process, p0);
- voronoi_checkCircle(process, p2);
+ voronoi_checkCircle(process, p0);
+ voronoi_checkCircle(process, p2);
}
static void voronoi_removeParabola(VoronoiProcess *process, VoronoiEvent *event)
{
- VoronoiParabola *p1 = event->parabola;
-
- VoronoiParabola *xl = voronoiParabola_getLeftParent(p1);
- VoronoiParabola *xr = voronoiParabola_getRightParent(p1);
-
- VoronoiParabola *p0 = voronoiParabola_getLeftChild(xl);
- VoronoiParabola *p2 = voronoiParabola_getRightChild(xr);
-
- VoronoiParabola *higher = NULL, *par, *gparent;
-
- float p[2];
-
- if (p0->event) {
- BLI_freelinkN(&process->queue, p0->event);
- p0->event = NULL;
- }
-
- if (p2->event) {
- BLI_freelinkN(&process->queue, p2->event);
- p2->event = NULL;
- }
-
- p[0] = event->site[0];
- p[1] = voronoi_getY(process, p1->site, event->site[0]);
-
- copy_v2_v2(xl->edge->end, p);
- copy_v2_v2(xr->edge->end, p);
-
- par = p1;
- while (par != process->root) {
- par = par->parent;
-
- if (par == xl) {
- higher = xl;
- }
- if (par == xr) {
- higher = xr;
- }
- }
-
- higher->edge = voronoiEdge_new(p, p0->site, p2->site);
- BLI_addtail(&process->edges, higher->edge);
-
- gparent = p1->parent->parent;
- if (p1->parent->left == p1) {
- if (gparent->left == p1->parent) {
- voronoiParabola_setLeft(gparent, p1->parent->right);
- }
- if (gparent->right == p1->parent) {
- voronoiParabola_setRight(gparent, p1->parent->right);
- }
- }
- else {
- if (gparent->left == p1->parent) {
- voronoiParabola_setLeft(gparent, p1->parent->left);
- }
- if (gparent->right == p1->parent) {
- voronoiParabola_setRight(gparent, p1->parent->left);
- }
- }
-
- MEM_freeN(p1->parent);
- MEM_freeN(p1);
-
- voronoi_checkCircle(process, p0);
- voronoi_checkCircle(process, p2);
+ VoronoiParabola *p1 = event->parabola;
+
+ VoronoiParabola *xl = voronoiParabola_getLeftParent(p1);
+ VoronoiParabola *xr = voronoiParabola_getRightParent(p1);
+
+ VoronoiParabola *p0 = voronoiParabola_getLeftChild(xl);
+ VoronoiParabola *p2 = voronoiParabola_getRightChild(xr);
+
+ VoronoiParabola *higher = NULL, *par, *gparent;
+
+ float p[2];
+
+ if (p0->event) {
+ BLI_freelinkN(&process->queue, p0->event);
+ p0->event = NULL;
+ }
+
+ if (p2->event) {
+ BLI_freelinkN(&process->queue, p2->event);
+ p2->event = NULL;
+ }
+
+ p[0] = event->site[0];
+ p[1] = voronoi_getY(process, p1->site, event->site[0]);
+
+ copy_v2_v2(xl->edge->end, p);
+ copy_v2_v2(xr->edge->end, p);
+
+ par = p1;
+ while (par != process->root) {
+ par = par->parent;
+
+ if (par == xl) {
+ higher = xl;
+ }
+ if (par == xr) {
+ higher = xr;
+ }
+ }
+
+ higher->edge = voronoiEdge_new(p, p0->site, p2->site);
+ BLI_addtail(&process->edges, higher->edge);
+
+ gparent = p1->parent->parent;
+ if (p1->parent->left == p1) {
+ if (gparent->left == p1->parent) {
+ voronoiParabola_setLeft(gparent, p1->parent->right);
+ }
+ if (gparent->right == p1->parent) {
+ voronoiParabola_setRight(gparent, p1->parent->right);
+ }
+ }
+ else {
+ if (gparent->left == p1->parent) {
+ voronoiParabola_setLeft(gparent, p1->parent->left);
+ }
+ if (gparent->right == p1->parent) {
+ voronoiParabola_setRight(gparent, p1->parent->left);
+ }
+ }
+
+ MEM_freeN(p1->parent);
+ MEM_freeN(p1);
+
+ voronoi_checkCircle(process, p0);
+ voronoi_checkCircle(process, p2);
}
static void voronoi_finishEdge(VoronoiProcess *process, VoronoiParabola *parabola)
{
- float mx;
+ float mx;
- if (parabola->is_leaf) {
- MEM_freeN(parabola);
- return;
- }
+ if (parabola->is_leaf) {
+ MEM_freeN(parabola);
+ return;
+ }
- if (parabola->edge->direction[0] > 0.0f) {
- mx = max_ff(process->width, parabola->edge->start[0] + 10);
- }
- else {
- mx = min_ff(0.0f, parabola->edge->start[0] - 10.0f);
- }
+ if (parabola->edge->direction[0] > 0.0f) {
+ mx = max_ff(process->width, parabola->edge->start[0] + 10);
+ }
+ else {
+ mx = min_ff(0.0f, parabola->edge->start[0] - 10.0f);
+ }
- parabola->edge->end[0] = mx;
- parabola->edge->end[1] = mx * parabola->edge->f + parabola->edge->g;
+ parabola->edge->end[0] = mx;
+ parabola->edge->end[1] = mx * parabola->edge->f + parabola->edge->g;
- voronoi_finishEdge(process, parabola->left);
- voronoi_finishEdge(process, parabola->right);
+ voronoi_finishEdge(process, parabola->left);
+ voronoi_finishEdge(process, parabola->right);
- MEM_freeN(parabola);
+ MEM_freeN(parabola);
}
static void voronoi_clampEdgeVertex(int width, int height, float *coord, float *other_coord)
{
- const float corners[4][2] = {{0.0f, 0.0f},
- {width - 1, 0.0f},
- {width - 1, height - 1},
- {0.0f, height - 1}};
- int i;
-
- if (IN_RANGE_INCL(coord[0], 0, width - 1) && IN_RANGE_INCL(coord[1], 0, height - 1)) {
- return;
- }
-
- for (i = 0; i < 4; i++) {
- float v1[2], v2[2];
- float p[2];
-
- copy_v2_v2(v1, corners[i]);
-
- if (i == 3) {
- copy_v2_v2(v2, corners[0]);
- }
- else {
- copy_v2_v2(v2, corners[i + 1]);
- }
-
- if (isect_seg_seg_v2_point(v1, v2, coord, other_coord, p) == 1) {
- if (i == 0 && coord[1] > p[1]) {
- continue;
- }
- if (i == 1 && coord[0] < p[0]) {
- continue;
- }
- if (i == 2 && coord[1] < p[1]) {
- continue;
- }
- if (i == 3 && coord[0] > p[0]) {
- continue;
- }
-
- copy_v2_v2(coord, p);
- }
- }
+ const float corners[4][2] = {
+ {0.0f, 0.0f}, {width - 1, 0.0f}, {width - 1, height - 1}, {0.0f, height - 1}};
+ int i;
+
+ if (IN_RANGE_INCL(coord[0], 0, width - 1) && IN_RANGE_INCL(coord[1], 0, height - 1)) {
+ return;
+ }
+
+ for (i = 0; i < 4; i++) {
+ float v1[2], v2[2];
+ float p[2];
+
+ copy_v2_v2(v1, corners[i]);
+
+ if (i == 3) {
+ copy_v2_v2(v2, corners[0]);
+ }
+ else {
+ copy_v2_v2(v2, corners[i + 1]);
+ }
+
+ if (isect_seg_seg_v2_point(v1, v2, coord, other_coord, p) == 1) {
+ if (i == 0 && coord[1] > p[1]) {
+ continue;
+ }
+ if (i == 1 && coord[0] < p[0]) {
+ continue;
+ }
+ if (i == 2 && coord[1] < p[1]) {
+ continue;
+ }
+ if (i == 3 && coord[0] > p[0]) {
+ continue;
+ }
+
+ copy_v2_v2(coord, p);
+ }
+ }
}
static void voronoi_clampEdges(ListBase *edges, int width, int height, ListBase *clamped_edges)
{
- VoronoiEdge *edge;
+ VoronoiEdge *edge;
- edge = edges->first;
- while (edge) {
- VoronoiEdge *new_edge = MEM_callocN(sizeof(VoronoiEdge), "clamped edge");
+ edge = edges->first;
+ while (edge) {
+ VoronoiEdge *new_edge = MEM_callocN(sizeof(VoronoiEdge), "clamped edge");
- *new_edge = *edge;
- BLI_addtail(clamped_edges, new_edge);
+ *new_edge = *edge;
+ BLI_addtail(clamped_edges, new_edge);
- voronoi_clampEdgeVertex(width, height, new_edge->start, new_edge->end);
- voronoi_clampEdgeVertex(width, height, new_edge->end, new_edge->start);
+ voronoi_clampEdgeVertex(width, height, new_edge->start, new_edge->end);
+ voronoi_clampEdgeVertex(width, height, new_edge->end, new_edge->start);
- edge = edge->next;
- }
+ edge = edge->next;
+ }
}
-static int voronoi_getNextSideCoord(ListBase *edges, float coord[2], int dim, int dir, float next_coord[2])
+static int voronoi_getNextSideCoord(
+ ListBase *edges, float coord[2], int dim, int dir, float next_coord[2])
{
- VoronoiEdge *edge = edges->first;
- float distance = FLT_MAX;
- int other_dim = dim ? 0 : 1;
-
- while (edge) {
- bool ok = false;
- float co[2], cur_distance;
-
- if (fabsf(edge->start[other_dim] - coord[other_dim]) < VORONOI_EPS &&
- len_squared_v2v2(coord, edge->start) > VORONOI_EPS)
- {
- copy_v2_v2(co, edge->start);
- ok = true;
- }
-
- if (fabsf(edge->end[other_dim] - coord[other_dim]) < VORONOI_EPS &&
- len_squared_v2v2(coord, edge->end) > VORONOI_EPS)
- {
- copy_v2_v2(co, edge->end);
- ok = true;
- }
-
- if (ok) {
- if (dir > 0 && coord[dim] > co[dim]) {
- ok = false;
- }
- else if (dir < 0 && coord[dim] < co[dim]) {
- ok = false;
- }
- }
-
- if (ok) {
- cur_distance = len_squared_v2v2(coord, co);
- if (cur_distance < distance) {
- copy_v2_v2(next_coord, co);
- distance = cur_distance;
- }
- }
-
- edge = edge->next;
- }
-
- return distance < FLT_MAX;
+ VoronoiEdge *edge = edges->first;
+ float distance = FLT_MAX;
+ int other_dim = dim ? 0 : 1;
+
+ while (edge) {
+ bool ok = false;
+ float co[2], cur_distance;
+
+ if (fabsf(edge->start[other_dim] - coord[other_dim]) < VORONOI_EPS &&
+ len_squared_v2v2(coord, edge->start) > VORONOI_EPS) {
+ copy_v2_v2(co, edge->start);
+ ok = true;
+ }
+
+ if (fabsf(edge->end[other_dim] - coord[other_dim]) < VORONOI_EPS &&
+ len_squared_v2v2(coord, edge->end) > VORONOI_EPS) {
+ copy_v2_v2(co, edge->end);
+ ok = true;
+ }
+
+ if (ok) {
+ if (dir > 0 && coord[dim] > co[dim]) {
+ ok = false;
+ }
+ else if (dir < 0 && coord[dim] < co[dim]) {
+ ok = false;
+ }
+ }
+
+ if (ok) {
+ cur_distance = len_squared_v2v2(coord, co);
+ if (cur_distance < distance) {
+ copy_v2_v2(next_coord, co);
+ distance = cur_distance;
+ }
+ }
+
+ edge = edge->next;
+ }
+
+ return distance < FLT_MAX;
}
static void voronoi_createBoundaryEdges(ListBase *edges, int width, int height)
{
- const float corners[4][2] = {{width - 1, 0.0f},
- {width - 1, height - 1},
- {0.0f, height - 1},
- {0.0f, 0.0f}};
- int i, dim = 0, dir = 1;
-
- float coord[2] = {0.0f, 0.0f};
- float next_coord[2] = {0.0f, 0.0f};
-
- for (i = 0; i < 4; i++) {
- while (voronoi_getNextSideCoord(edges, coord, dim, dir, next_coord)) {
- VoronoiEdge *edge = MEM_callocN(sizeof(VoronoiEdge), "boundary edge");
-
- copy_v2_v2(edge->start, coord);
- copy_v2_v2(edge->end, next_coord);
- BLI_addtail(edges, edge);
-
- copy_v2_v2(coord, next_coord);
- }
-
- if (len_squared_v2v2(coord, corners[i]) > VORONOI_EPS) {
- VoronoiEdge *edge = MEM_callocN(sizeof(VoronoiEdge), "boundary edge");
-
- copy_v2_v2(edge->start, coord);
- copy_v2_v2(edge->end, corners[i]);
- BLI_addtail(edges, edge);
- copy_v2_v2(coord, corners[i]);
- }
-
- dim = dim ? 0 : 1;
- if (i == 1) {
- dir = -1;
- }
- }
+ const float corners[4][2] = {
+ {width - 1, 0.0f}, {width - 1, height - 1}, {0.0f, height - 1}, {0.0f, 0.0f}};
+ int i, dim = 0, dir = 1;
+
+ float coord[2] = {0.0f, 0.0f};
+ float next_coord[2] = {0.0f, 0.0f};
+
+ for (i = 0; i < 4; i++) {
+ while (voronoi_getNextSideCoord(edges, coord, dim, dir, next_coord)) {
+ VoronoiEdge *edge = MEM_callocN(sizeof(VoronoiEdge), "boundary edge");
+
+ copy_v2_v2(edge->start, coord);
+ copy_v2_v2(edge->end, next_coord);
+ BLI_addtail(edges, edge);
+
+ copy_v2_v2(coord, next_coord);
+ }
+
+ if (len_squared_v2v2(coord, corners[i]) > VORONOI_EPS) {
+ VoronoiEdge *edge = MEM_callocN(sizeof(VoronoiEdge), "boundary edge");
+
+ copy_v2_v2(edge->start, coord);
+ copy_v2_v2(edge->end, corners[i]);
+ BLI_addtail(edges, edge);
+ copy_v2_v2(coord, corners[i]);
+ }
+
+ dim = dim ? 0 : 1;
+ if (i == 1) {
+ dir = -1;
+ }
+ }
}
-void BLI_voronoi_compute(const VoronoiSite *sites, int sites_total, int width, int height, ListBase *edges)
+void BLI_voronoi_compute(
+ const VoronoiSite *sites, int sites_total, int width, int height, ListBase *edges)
{
- VoronoiProcess process;
- VoronoiEdge *edge;
- int i;
+ VoronoiProcess process;
+ VoronoiEdge *edge;
+ int i;
- memset(&process, 0, sizeof(VoronoiProcess));
+ memset(&process, 0, sizeof(VoronoiProcess));
- process.width = width;
- process.height = height;
+ process.width = width;
+ process.height = height;
- for (i = 0; i < sites_total; i++) {
- VoronoiEvent *event = MEM_callocN(sizeof(VoronoiEvent), "voronoi site event");
+ for (i = 0; i < sites_total; i++) {
+ VoronoiEvent *event = MEM_callocN(sizeof(VoronoiEvent), "voronoi site event");
- event->type = voronoiEventType_Site;
- copy_v2_v2(event->site, sites[i].co);
+ event->type = voronoiEventType_Site;
+ copy_v2_v2(event->site, sites[i].co);
- voronoi_insertEvent(&process, event);
- }
+ voronoi_insertEvent(&process, event);
+ }
- while (process.queue.first) {
- VoronoiEvent *event = process.queue.first;
+ while (process.queue.first) {
+ VoronoiEvent *event = process.queue.first;
- process.current_y = event->site[1];
+ process.current_y = event->site[1];
- if (event->type == voronoiEventType_Site) {
- voronoi_addParabola(&process, event->site);
- }
- else {
- voronoi_removeParabola(&process, event);
- }
+ if (event->type == voronoiEventType_Site) {
+ voronoi_addParabola(&process, event->site);
+ }
+ else {
+ voronoi_removeParabola(&process, event);
+ }
- BLI_freelinkN(&process.queue, event);
- }
+ BLI_freelinkN(&process.queue, event);
+ }
- voronoi_finishEdge(&process, process.root);
+ voronoi_finishEdge(&process, process.root);
- edge = process.edges.first;
- while (edge) {
- if (edge->neighbor) {
- copy_v2_v2(edge->start, edge->neighbor->end);
- MEM_freeN(edge->neighbor);
- }
+ edge = process.edges.first;
+ while (edge) {
+ if (edge->neighbor) {
+ copy_v2_v2(edge->start, edge->neighbor->end);
+ MEM_freeN(edge->neighbor);
+ }
- edge = edge->next;
- }
+ edge = edge->next;
+ }
- BLI_movelisttolist(edges, &process.edges);
+ BLI_movelisttolist(edges, &process.edges);
}
static bool testVoronoiEdge(const float site[2], const float point[2], const VoronoiEdge *edge)
{
- float p[2];
+ float p[2];
- if (isect_seg_seg_v2_point(site, point, edge->start, edge->end, p) == 1) {
- if (len_squared_v2v2(p, edge->start) > VORONOI_EPS &&
- len_squared_v2v2(p, edge->end) > VORONOI_EPS)
- {
- return false;
- }
- }
+ if (isect_seg_seg_v2_point(site, point, edge->start, edge->end, p) == 1) {
+ if (len_squared_v2v2(p, edge->start) > VORONOI_EPS &&
+ len_squared_v2v2(p, edge->end) > VORONOI_EPS) {
+ return false;
+ }
+ }
- return true;
+ return true;
}
-static int voronoi_addTriangulationPoint(const float coord[2], const float color[3],
+static int voronoi_addTriangulationPoint(const float coord[2],
+ const float color[3],
VoronoiTriangulationPoint **triangulated_points,
int *triangulated_points_total)
{
- VoronoiTriangulationPoint *triangulation_point;
- int i;
+ VoronoiTriangulationPoint *triangulation_point;
+ int i;
- for (i = 0; i < *triangulated_points_total; i++) {
- if (equals_v2v2(coord, (*triangulated_points)[i].co)) {
- triangulation_point = &(*triangulated_points)[i];
+ for (i = 0; i < *triangulated_points_total; i++) {
+ if (equals_v2v2(coord, (*triangulated_points)[i].co)) {
+ triangulation_point = &(*triangulated_points)[i];
- add_v3_v3(triangulation_point->color, color);
- triangulation_point->power++;
+ add_v3_v3(triangulation_point->color, color);
+ triangulation_point->power++;
- return i;
- }
- }
+ return i;
+ }
+ }
- if (*triangulated_points) {
- *triangulated_points = MEM_reallocN(*triangulated_points,
- sizeof(VoronoiTriangulationPoint) * (*triangulated_points_total + 1));
- }
- else {
- *triangulated_points = MEM_callocN(sizeof(VoronoiTriangulationPoint), "triangulation points");
- }
+ if (*triangulated_points) {
+ *triangulated_points = MEM_reallocN(*triangulated_points,
+ sizeof(VoronoiTriangulationPoint) *
+ (*triangulated_points_total + 1));
+ }
+ else {
+ *triangulated_points = MEM_callocN(sizeof(VoronoiTriangulationPoint), "triangulation points");
+ }
- triangulation_point = &(*triangulated_points)[(*triangulated_points_total)];
- copy_v2_v2(triangulation_point->co, coord);
- copy_v3_v3(triangulation_point->color, color);
+ triangulation_point = &(*triangulated_points)[(*triangulated_points_total)];
+ copy_v2_v2(triangulation_point->co, coord);
+ copy_v3_v3(triangulation_point->color, color);
- triangulation_point->power = 1;
+ triangulation_point->power = 1;
- (*triangulated_points_total)++;
+ (*triangulated_points_total)++;
- return (*triangulated_points_total) - 1;
+ return (*triangulated_points_total) - 1;
}
static void voronoi_addTriangle(int v1, int v2, int v3, int (**triangles)[3], int *triangles_total)
{
- int *triangle;
+ int *triangle;
- if (*triangles) {
- *triangles = MEM_reallocN(*triangles, sizeof(int[3]) * (*triangles_total + 1));
- }
- else {
- *triangles = MEM_callocN(sizeof(int[3]), "trianglulation triangles");
- }
+ if (*triangles) {
+ *triangles = MEM_reallocN(*triangles, sizeof(int[3]) * (*triangles_total + 1));
+ }
+ else {
+ *triangles = MEM_callocN(sizeof(int[3]), "trianglulation triangles");
+ }
- triangle = (int *)&(*triangles)[(*triangles_total)];
+ triangle = (int *)&(*triangles)[(*triangles_total)];
- triangle[0] = v1;
- triangle[1] = v2;
- triangle[2] = v3;
+ triangle[0] = v1;
+ triangle[1] = v2;
+ triangle[2] = v3;
- (*triangles_total)++;
+ (*triangles_total)++;
}
-void BLI_voronoi_triangulate(const VoronoiSite *sites, int sites_total, ListBase *edges, int width, int height,
- VoronoiTriangulationPoint **triangulated_points_r, int *triangulated_points_total_r,
- int (**triangles_r)[3], int *triangles_total_r)
+void BLI_voronoi_triangulate(const VoronoiSite *sites,
+ int sites_total,
+ ListBase *edges,
+ int width,
+ int height,
+ VoronoiTriangulationPoint **triangulated_points_r,
+ int *triangulated_points_total_r,
+ int (**triangles_r)[3],
+ int *triangles_total_r)
{
- VoronoiTriangulationPoint *triangulated_points = NULL;
- int (*triangles)[3] = NULL;
- int triangulated_points_total = 0, triangles_total = 0;
- int i;
- ListBase boundary_edges = {NULL, NULL};
+ VoronoiTriangulationPoint *triangulated_points = NULL;
+ int(*triangles)[3] = NULL;
+ int triangulated_points_total = 0, triangles_total = 0;
+ int i;
+ ListBase boundary_edges = {NULL, NULL};
- voronoi_clampEdges(edges, width, height, &boundary_edges);
- voronoi_createBoundaryEdges(&boundary_edges, width, height);
+ voronoi_clampEdges(edges, width, height, &boundary_edges);
+ voronoi_createBoundaryEdges(&boundary_edges, width, height);
- for (i = 0; i < sites_total; i++) {
- VoronoiEdge *edge;
- int v1;
+ for (i = 0; i < sites_total; i++) {
+ VoronoiEdge *edge;
+ int v1;
- v1 = voronoi_addTriangulationPoint(sites[i].co, sites[i].color, &triangulated_points, &triangulated_points_total);
+ v1 = voronoi_addTriangulationPoint(
+ sites[i].co, sites[i].color, &triangulated_points, &triangulated_points_total);
- edge = boundary_edges.first;
- while (edge) {
- VoronoiEdge *test_edge = boundary_edges.first;
- bool ok_start = true, ok_end = true;
+ edge = boundary_edges.first;
+ while (edge) {
+ VoronoiEdge *test_edge = boundary_edges.first;
+ bool ok_start = true, ok_end = true;
- while (test_edge) {
- if (ok_start && !testVoronoiEdge(sites[i].co, edge->start, test_edge)) {
- ok_start = false;
- break;
- }
+ while (test_edge) {
+ if (ok_start && !testVoronoiEdge(sites[i].co, edge->start, test_edge)) {
+ ok_start = false;
+ break;
+ }
- if (ok_end && !testVoronoiEdge(sites[i].co, edge->end, test_edge)) {
- ok_end = false;
- break;
- }
+ if (ok_end && !testVoronoiEdge(sites[i].co, edge->end, test_edge)) {
+ ok_end = false;
+ break;
+ }
- test_edge = test_edge->next;
- }
+ test_edge = test_edge->next;
+ }
- if (ok_start && ok_end) {
- int v2, v3;
+ if (ok_start && ok_end) {
+ int v2, v3;
- v2 = voronoi_addTriangulationPoint(edge->start, sites[i].color, &triangulated_points, &triangulated_points_total);
- v3 = voronoi_addTriangulationPoint(edge->end, sites[i].color, &triangulated_points, &triangulated_points_total);
+ v2 = voronoi_addTriangulationPoint(
+ edge->start, sites[i].color, &triangulated_points, &triangulated_points_total);
+ v3 = voronoi_addTriangulationPoint(
+ edge->end, sites[i].color, &triangulated_points, &triangulated_points_total);
- voronoi_addTriangle(v1, v2, v3, &triangles, &triangles_total);
- }
+ voronoi_addTriangle(v1, v2, v3, &triangles, &triangles_total);
+ }
- edge = edge->next;
- }
- }
+ edge = edge->next;
+ }
+ }
- for (i = 0; i < triangulated_points_total; i++) {
- VoronoiTriangulationPoint *triangulation_point = &triangulated_points[i];
+ for (i = 0; i < triangulated_points_total; i++) {
+ VoronoiTriangulationPoint *triangulation_point = &triangulated_points[i];
- mul_v3_fl(triangulation_point->color, 1.0f / triangulation_point->power);
- }
+ mul_v3_fl(triangulation_point->color, 1.0f / triangulation_point->power);
+ }
- *triangulated_points_r = triangulated_points;
- *triangulated_points_total_r = triangulated_points_total;
+ *triangulated_points_r = triangulated_points;
+ *triangulated_points_total_r = triangulated_points_total;
- *triangles_r = triangles;
- *triangles_total_r = triangles_total;
+ *triangles_r = triangles;
+ *triangles_total_r = triangles_total;
- BLI_freelistN(&boundary_edges);
+ BLI_freelistN(&boundary_edges);
}
diff --git a/source/blender/blenlib/intern/voxel.c b/source/blender/blenlib/intern/voxel.c
index fbd6fb74ab5..c7c794957c2 100644
--- a/source/blender/blenlib/intern/voxel.c
+++ b/source/blender/blenlib/intern/voxel.c
@@ -26,33 +26,32 @@
#include "BLI_strict_flags.h"
-
BLI_INLINE float D(float *data, const int res[3], int x, int y, int z)
{
- CLAMP(x, 0, res[0] - 1);
- CLAMP(y, 0, res[1] - 1);
- CLAMP(z, 0, res[2] - 1);
- return data[BLI_VOXEL_INDEX(x, y, z, res)];
+ CLAMP(x, 0, res[0] - 1);
+ CLAMP(y, 0, res[1] - 1);
+ CLAMP(z, 0, res[2] - 1);
+ return data[BLI_VOXEL_INDEX(x, y, z, res)];
}
/* *** nearest neighbor *** */
/* input coordinates must be in bounding box 0.0 - 1.0 */
float BLI_voxel_sample_nearest(float *data, const int res[3], const float co[3])
{
- int xi, yi, zi;
+ int xi, yi, zi;
- xi = (int)(co[0] * (float)res[0]);
- yi = (int)(co[1] * (float)res[1]);
- zi = (int)(co[2] * (float)res[2]);
+ xi = (int)(co[0] * (float)res[0]);
+ yi = (int)(co[1] * (float)res[1]);
+ zi = (int)(co[2] * (float)res[2]);
- return D(data, res, xi, yi, zi);
+ return D(data, res, xi, yi, zi);
}
/* returns highest integer <= x as integer (slightly faster than floor()) */
BLI_INLINE int FLOORI(float x)
{
- const int r = (int)x;
- return ((x >= 0.f) || (float)r == x) ? r : (r - 1);
+ const int r = (int)x;
+ return ((x >= 0.f) || (float)r == x) ? r : (r - 1);
}
/* clamp function, cannot use the CLAMPIS macro,
@@ -63,169 +62,200 @@ BLI_INLINE int FLOORI(float x)
* x + 2 should wrap around to -2147483647 so the test < 0 should return true, which it doesn't) */
BLI_INLINE int64_t _clamp(int a, int b, int c)
{
- return (a < b) ? b : ((a > c) ? c : a);
+ return (a < b) ? b : ((a > c) ? c : a);
}
float BLI_voxel_sample_trilinear(float *data, const int res[3], const float co[3])
{
- if (data) {
-
- const float xf = co[0] * (float)res[0] - 0.5f;
- const float yf = co[1] * (float)res[1] - 0.5f;
- const float zf = co[2] * (float)res[2] - 0.5f;
-
- const int x = FLOORI(xf), y = FLOORI(yf), z = FLOORI(zf);
-
- const int64_t xc[2] = {
- _clamp(x, 0, res[0] - 1),
- _clamp(x + 1, 0, res[0] - 1),
- };
- const int64_t yc[2] = {
- _clamp(y, 0, res[1] - 1) * res[0],
- _clamp(y + 1, 0, res[1] - 1) * res[0],
- };
- const int64_t zc[2] = {
- _clamp(z, 0, res[2] - 1) * res[0] * res[1],
- _clamp(z + 1, 0, res[2] - 1) * res[0] * res[1],
- };
-
- const float dx = xf - (float)x;
- const float dy = yf - (float)y;
- const float dz = zf - (float)z;
-
- const float u[2] = {1.f - dx, dx};
- const float v[2] = {1.f - dy, dy};
- const float w[2] = {1.f - dz, dz};
-
- return w[0] * ( v[0] * ( u[0] * data[xc[0] + yc[0] + zc[0]] + u[1] * data[xc[1] + yc[0] + zc[0]] )
- + v[1] * ( u[0] * data[xc[0] + yc[1] + zc[0]] + u[1] * data[xc[1] + yc[1] + zc[0]] ) )
- + w[1] * ( v[0] * ( u[0] * data[xc[0] + yc[0] + zc[1]] + u[1] * data[xc[1] + yc[0] + zc[1]] )
- + v[1] * ( u[0] * data[xc[0] + yc[1] + zc[1]] + u[1] * data[xc[1] + yc[1] + zc[1]] ) );
-
- }
- return 0.f;
+ if (data) {
+
+ const float xf = co[0] * (float)res[0] - 0.5f;
+ const float yf = co[1] * (float)res[1] - 0.5f;
+ const float zf = co[2] * (float)res[2] - 0.5f;
+
+ const int x = FLOORI(xf), y = FLOORI(yf), z = FLOORI(zf);
+
+ const int64_t xc[2] = {
+ _clamp(x, 0, res[0] - 1),
+ _clamp(x + 1, 0, res[0] - 1),
+ };
+ const int64_t yc[2] = {
+ _clamp(y, 0, res[1] - 1) * res[0],
+ _clamp(y + 1, 0, res[1] - 1) * res[0],
+ };
+ const int64_t zc[2] = {
+ _clamp(z, 0, res[2] - 1) * res[0] * res[1],
+ _clamp(z + 1, 0, res[2] - 1) * res[0] * res[1],
+ };
+
+ const float dx = xf - (float)x;
+ const float dy = yf - (float)y;
+ const float dz = zf - (float)z;
+
+ const float u[2] = {1.f - dx, dx};
+ const float v[2] = {1.f - dy, dy};
+ const float w[2] = {1.f - dz, dz};
+
+ return w[0] *
+ (v[0] * (u[0] * data[xc[0] + yc[0] + zc[0]] + u[1] * data[xc[1] + yc[0] + zc[0]]) +
+ v[1] * (u[0] * data[xc[0] + yc[1] + zc[0]] + u[1] * data[xc[1] + yc[1] + zc[0]])) +
+ w[1] *
+ (v[0] * (u[0] * data[xc[0] + yc[0] + zc[1]] + u[1] * data[xc[1] + yc[0] + zc[1]]) +
+ v[1] * (u[0] * data[xc[0] + yc[1] + zc[1]] + u[1] * data[xc[1] + yc[1] + zc[1]]));
+ }
+ return 0.f;
}
float BLI_voxel_sample_triquadratic(float *data, const int res[3], const float co[3])
{
- if (data) {
-
- const float xf = co[0] * (float)res[0];
- const float yf = co[1] * (float)res[1];
- const float zf = co[2] * (float)res[2];
- const int x = FLOORI(xf), y = FLOORI(yf), z = FLOORI(zf);
-
- const int64_t xc[3] = {
- _clamp(x - 1, 0, res[0] - 1),
- _clamp(x, 0, res[0] - 1),
- _clamp(x + 1, 0, res[0] - 1),
- };
- const int64_t yc[3] = {
- _clamp(y - 1, 0, res[1] - 1) * res[0],
- _clamp(y, 0, res[1] - 1) * res[0],
- _clamp(y + 1, 0, res[1] - 1) * res[0],
- };
- const int64_t zc[3] = {
- _clamp(z - 1, 0, res[2] - 1) * res[0] * res[1],
- _clamp(z, 0, res[2] - 1) * res[0] * res[1],
- _clamp(z + 1, 0, res[2] - 1) * res[0] * res[1],
- };
-
- const float dx = xf - (float)x, dy = yf - (float)y, dz = zf - (float)z;
- const float u[3] = {dx * (0.5f * dx - 1.f) + 0.5f, dx * (1.0f - dx) + 0.5f, 0.5f * dx * dx};
- const float v[3] = {dy * (0.5f * dy - 1.f) + 0.5f, dy * (1.0f - dy) + 0.5f, 0.5f * dy * dy};
- const float w[3] = {dz * (0.5f * dz - 1.f) + 0.5f, dz * (1.0f - dz) + 0.5f, 0.5f * dz * dz};
-
- return w[0] * ( v[0] * ( u[0] * data[xc[0] + yc[0] + zc[0]] + u[1] * data[xc[1] + yc[0] + zc[0]] + u[2] * data[xc[2] + yc[0] + zc[0]] )
- + v[1] * ( u[0] * data[xc[0] + yc[1] + zc[0]] + u[1] * data[xc[1] + yc[1] + zc[0]] + u[2] * data[xc[2] + yc[1] + zc[0]] )
- + v[2] * ( u[0] * data[xc[0] + yc[2] + zc[0]] + u[1] * data[xc[1] + yc[2] + zc[0]] + u[2] * data[xc[2] + yc[2] + zc[0]] ) )
- + w[1] * ( v[0] * ( u[0] * data[xc[0] + yc[0] + zc[1]] + u[1] * data[xc[1] + yc[0] + zc[1]] + u[2] * data[xc[2] + yc[0] + zc[1]] )
- + v[1] * ( u[0] * data[xc[0] + yc[1] + zc[1]] + u[1] * data[xc[1] + yc[1] + zc[1]] + u[2] * data[xc[2] + yc[1] + zc[1]] )
- + v[2] * ( u[0] * data[xc[0] + yc[2] + zc[1]] + u[1] * data[xc[1] + yc[2] + zc[1]] + u[2] * data[xc[2] + yc[2] + zc[1]] ) )
- + w[2] * ( v[0] * ( u[0] * data[xc[0] + yc[0] + zc[2]] + u[1] * data[xc[1] + yc[0] + zc[2]] + u[2] * data[xc[2] + yc[0] + zc[2]] )
- + v[1] * ( u[0] * data[xc[0] + yc[1] + zc[2]] + u[1] * data[xc[1] + yc[1] + zc[2]] + u[2] * data[xc[2] + yc[1] + zc[2]] )
- + v[2] * ( u[0] * data[xc[0] + yc[2] + zc[2]] + u[1] * data[xc[1] + yc[2] + zc[2]] + u[2] * data[xc[2] + yc[2] + zc[2]] ) );
-
- }
- return 0.f;
+ if (data) {
+
+ const float xf = co[0] * (float)res[0];
+ const float yf = co[1] * (float)res[1];
+ const float zf = co[2] * (float)res[2];
+ const int x = FLOORI(xf), y = FLOORI(yf), z = FLOORI(zf);
+
+ const int64_t xc[3] = {
+ _clamp(x - 1, 0, res[0] - 1),
+ _clamp(x, 0, res[0] - 1),
+ _clamp(x + 1, 0, res[0] - 1),
+ };
+ const int64_t yc[3] = {
+ _clamp(y - 1, 0, res[1] - 1) * res[0],
+ _clamp(y, 0, res[1] - 1) * res[0],
+ _clamp(y + 1, 0, res[1] - 1) * res[0],
+ };
+ const int64_t zc[3] = {
+ _clamp(z - 1, 0, res[2] - 1) * res[0] * res[1],
+ _clamp(z, 0, res[2] - 1) * res[0] * res[1],
+ _clamp(z + 1, 0, res[2] - 1) * res[0] * res[1],
+ };
+
+ const float dx = xf - (float)x, dy = yf - (float)y, dz = zf - (float)z;
+ const float u[3] = {dx * (0.5f * dx - 1.f) + 0.5f, dx * (1.0f - dx) + 0.5f, 0.5f * dx * dx};
+ const float v[3] = {dy * (0.5f * dy - 1.f) + 0.5f, dy * (1.0f - dy) + 0.5f, 0.5f * dy * dy};
+ const float w[3] = {dz * (0.5f * dz - 1.f) + 0.5f, dz * (1.0f - dz) + 0.5f, 0.5f * dz * dz};
+
+ return w[0] *
+ (v[0] * (u[0] * data[xc[0] + yc[0] + zc[0]] + u[1] * data[xc[1] + yc[0] + zc[0]] +
+ u[2] * data[xc[2] + yc[0] + zc[0]]) +
+ v[1] * (u[0] * data[xc[0] + yc[1] + zc[0]] + u[1] * data[xc[1] + yc[1] + zc[0]] +
+ u[2] * data[xc[2] + yc[1] + zc[0]]) +
+ v[2] * (u[0] * data[xc[0] + yc[2] + zc[0]] + u[1] * data[xc[1] + yc[2] + zc[0]] +
+ u[2] * data[xc[2] + yc[2] + zc[0]])) +
+ w[1] *
+ (v[0] * (u[0] * data[xc[0] + yc[0] + zc[1]] + u[1] * data[xc[1] + yc[0] + zc[1]] +
+ u[2] * data[xc[2] + yc[0] + zc[1]]) +
+ v[1] * (u[0] * data[xc[0] + yc[1] + zc[1]] + u[1] * data[xc[1] + yc[1] + zc[1]] +
+ u[2] * data[xc[2] + yc[1] + zc[1]]) +
+ v[2] * (u[0] * data[xc[0] + yc[2] + zc[1]] + u[1] * data[xc[1] + yc[2] + zc[1]] +
+ u[2] * data[xc[2] + yc[2] + zc[1]])) +
+ w[2] *
+ (v[0] * (u[0] * data[xc[0] + yc[0] + zc[2]] + u[1] * data[xc[1] + yc[0] + zc[2]] +
+ u[2] * data[xc[2] + yc[0] + zc[2]]) +
+ v[1] * (u[0] * data[xc[0] + yc[1] + zc[2]] + u[1] * data[xc[1] + yc[1] + zc[2]] +
+ u[2] * data[xc[2] + yc[1] + zc[2]]) +
+ v[2] * (u[0] * data[xc[0] + yc[2] + zc[2]] + u[1] * data[xc[1] + yc[2] + zc[2]] +
+ u[2] * data[xc[2] + yc[2] + zc[2]]));
+ }
+ return 0.f;
}
float BLI_voxel_sample_tricubic(float *data, const int res[3], const float co[3], int bspline)
{
- if (data) {
-
- const float xf = co[0] * (float)res[0] - 0.5f;
- const float yf = co[1] * (float)res[1] - 0.5f;
- const float zf = co[2] * (float)res[2] - 0.5f;
- const int x = FLOORI(xf), y = FLOORI(yf), z = FLOORI(zf);
-
- const int64_t xc[4] = {
- _clamp(x - 1, 0, res[0] - 1),
- _clamp(x, 0, res[0] - 1),
- _clamp(x + 1, 0, res[0] - 1),
- _clamp(x + 2, 0, res[0] - 1),
- };
- const int64_t yc[4] = {
- _clamp(y - 1, 0, res[1] - 1) * res[0],
- _clamp(y, 0, res[1] - 1) * res[0],
- _clamp(y + 1, 0, res[1] - 1) * res[0],
- _clamp(y + 2, 0, res[1] - 1) * res[0],
- };
- const int64_t zc[4] = {
- _clamp(z - 1, 0, res[2] - 1) * res[0] * res[1],
- _clamp(z, 0, res[2] - 1) * res[0] * res[1],
- _clamp(z + 1, 0, res[2] - 1) * res[0] * res[1],
- _clamp(z + 2, 0, res[2] - 1) * res[0] * res[1],
- };
- const float dx = xf - (float)x, dy = yf - (float)y, dz = zf - (float)z;
-
- float u[4], v[4], w[4];
- if (bspline) { // B-Spline
- u[0] = (((-1.f/6.f)*dx + 0.5f)*dx - 0.5f)*dx + (1.f/6.f);
- u[1] = (( 0.5f*dx - 1.f )*dx )*dx + (2.f/3.f);
- u[2] = (( -0.5f*dx + 0.5f)*dx + 0.5f)*dx + (1.f/6.f);
- u[3] = ( 1.f/6.f)*dx*dx*dx;
- v[0] = (((-1.f/6.f)*dy + 0.5f)*dy - 0.5f)*dy + (1.f/6.f);
- v[1] = (( 0.5f*dy - 1.f )*dy )*dy + (2.f/3.f);
- v[2] = (( -0.5f*dy + 0.5f)*dy + 0.5f)*dy + (1.f/6.f);
- v[3] = ( 1.f/6.f)*dy*dy*dy;
- w[0] = (((-1.f/6.f)*dz + 0.5f)*dz - 0.5f)*dz + (1.f/6.f);
- w[1] = (( 0.5f*dz - 1.f )*dz )*dz + (2.f/3.f);
- w[2] = (( -0.5f*dz + 0.5f)*dz + 0.5f)*dz + (1.f/6.f);
- w[3] = ( 1.f/6.f)*dz*dz*dz;
- }
- else { // Catmull-Rom
- u[0] = ((-0.5f*dx + 1.0f)*dx - 0.5f)*dx;
- u[1] = (( 1.5f*dx - 2.5f)*dx )*dx + 1.0f;
- u[2] = ((-1.5f*dx + 2.0f)*dx + 0.5f)*dx;
- u[3] = (( 0.5f*dx - 0.5f)*dx )*dx;
- v[0] = ((-0.5f*dy + 1.0f)*dy - 0.5f)*dy;
- v[1] = (( 1.5f*dy - 2.5f)*dy )*dy + 1.0f;
- v[2] = ((-1.5f*dy + 2.0f)*dy + 0.5f)*dy;
- v[3] = (( 0.5f*dy - 0.5f)*dy )*dy;
- w[0] = ((-0.5f*dz + 1.0f)*dz - 0.5f)*dz;
- w[1] = (( 1.5f*dz - 2.5f)*dz )*dz + 1.0f;
- w[2] = ((-1.5f*dz + 2.0f)*dz + 0.5f)*dz;
- w[3] = (( 0.5f*dz - 0.5f)*dz )*dz;
- }
-
- return w[0] * ( v[0] * ( u[0] * data[xc[0] + yc[0] + zc[0]] + u[1] * data[xc[1] + yc[0] + zc[0]] + u[2] * data[xc[2] + yc[0] + zc[0]] + u[3] * data[xc[3] + yc[0] + zc[0]] )
- + v[1] * ( u[0] * data[xc[0] + yc[1] + zc[0]] + u[1] * data[xc[1] + yc[1] + zc[0]] + u[2] * data[xc[2] + yc[1] + zc[0]] + u[3] * data[xc[3] + yc[1] + zc[0]] )
- + v[2] * ( u[0] * data[xc[0] + yc[2] + zc[0]] + u[1] * data[xc[1] + yc[2] + zc[0]] + u[2] * data[xc[2] + yc[2] + zc[0]] + u[3] * data[xc[3] + yc[2] + zc[0]] )
- + v[3] * ( u[0] * data[xc[0] + yc[3] + zc[0]] + u[1] * data[xc[1] + yc[3] + zc[0]] + u[2] * data[xc[2] + yc[3] + zc[0]] + u[3] * data[xc[3] + yc[3] + zc[0]] ) )
- + w[1] * ( v[0] * ( u[0] * data[xc[0] + yc[0] + zc[1]] + u[1] * data[xc[1] + yc[0] + zc[1]] + u[2] * data[xc[2] + yc[0] + zc[1]] + u[3] * data[xc[3] + yc[0] + zc[1]] )
- + v[1] * ( u[0] * data[xc[0] + yc[1] + zc[1]] + u[1] * data[xc[1] + yc[1] + zc[1]] + u[2] * data[xc[2] + yc[1] + zc[1]] + u[3] * data[xc[3] + yc[1] + zc[1]] )
- + v[2] * ( u[0] * data[xc[0] + yc[2] + zc[1]] + u[1] * data[xc[1] + yc[2] + zc[1]] + u[2] * data[xc[2] + yc[2] + zc[1]] + u[3] * data[xc[3] + yc[2] + zc[1]] )
- + v[3] * ( u[0] * data[xc[0] + yc[3] + zc[1]] + u[1] * data[xc[1] + yc[3] + zc[1]] + u[2] * data[xc[2] + yc[3] + zc[1]] + u[3] * data[xc[3] + yc[3] + zc[1]] ) )
- + w[2] * ( v[0] * ( u[0] * data[xc[0] + yc[0] + zc[2]] + u[1] * data[xc[1] + yc[0] + zc[2]] + u[2] * data[xc[2] + yc[0] + zc[2]] + u[3] * data[xc[3] + yc[0] + zc[2]] )
- + v[1] * ( u[0] * data[xc[0] + yc[1] + zc[2]] + u[1] * data[xc[1] + yc[1] + zc[2]] + u[2] * data[xc[2] + yc[1] + zc[2]] + u[3] * data[xc[3] + yc[1] + zc[2]] )
- + v[2] * ( u[0] * data[xc[0] + yc[2] + zc[2]] + u[1] * data[xc[1] + yc[2] + zc[2]] + u[2] * data[xc[2] + yc[2] + zc[2]] + u[3] * data[xc[3] + yc[2] + zc[2]] )
- + v[3] * ( u[0] * data[xc[0] + yc[3] + zc[2]] + u[1] * data[xc[1] + yc[3] + zc[2]] + u[2] * data[xc[2] + yc[3] + zc[2]] + u[3] * data[xc[3] + yc[3] + zc[2]] ) )
- + w[3] * ( v[0] * ( u[0] * data[xc[0] + yc[0] + zc[3]] + u[1] * data[xc[1] + yc[0] + zc[3]] + u[2] * data[xc[2] + yc[0] + zc[3]] + u[3] * data[xc[3] + yc[0] + zc[3]] )
- + v[1] * ( u[0] * data[xc[0] + yc[1] + zc[3]] + u[1] * data[xc[1] + yc[1] + zc[3]] + u[2] * data[xc[2] + yc[1] + zc[3]] + u[3] * data[xc[3] + yc[1] + zc[3]] )
- + v[2] * ( u[0] * data[xc[0] + yc[2] + zc[3]] + u[1] * data[xc[1] + yc[2] + zc[3]] + u[2] * data[xc[2] + yc[2] + zc[3]] + u[3] * data[xc[3] + yc[2] + zc[3]] )
- + v[3] * ( u[0] * data[xc[0] + yc[3] + zc[3]] + u[1] * data[xc[1] + yc[3] + zc[3]] + u[2] * data[xc[2] + yc[3] + zc[3]] + u[3] * data[xc[3] + yc[3] + zc[3]] ) );
-
- }
- return 0.f;
+ if (data) {
+
+ const float xf = co[0] * (float)res[0] - 0.5f;
+ const float yf = co[1] * (float)res[1] - 0.5f;
+ const float zf = co[2] * (float)res[2] - 0.5f;
+ const int x = FLOORI(xf), y = FLOORI(yf), z = FLOORI(zf);
+
+ const int64_t xc[4] = {
+ _clamp(x - 1, 0, res[0] - 1),
+ _clamp(x, 0, res[0] - 1),
+ _clamp(x + 1, 0, res[0] - 1),
+ _clamp(x + 2, 0, res[0] - 1),
+ };
+ const int64_t yc[4] = {
+ _clamp(y - 1, 0, res[1] - 1) * res[0],
+ _clamp(y, 0, res[1] - 1) * res[0],
+ _clamp(y + 1, 0, res[1] - 1) * res[0],
+ _clamp(y + 2, 0, res[1] - 1) * res[0],
+ };
+ const int64_t zc[4] = {
+ _clamp(z - 1, 0, res[2] - 1) * res[0] * res[1],
+ _clamp(z, 0, res[2] - 1) * res[0] * res[1],
+ _clamp(z + 1, 0, res[2] - 1) * res[0] * res[1],
+ _clamp(z + 2, 0, res[2] - 1) * res[0] * res[1],
+ };
+ const float dx = xf - (float)x, dy = yf - (float)y, dz = zf - (float)z;
+
+ float u[4], v[4], w[4];
+ if (bspline) { // B-Spline
+ u[0] = (((-1.f / 6.f) * dx + 0.5f) * dx - 0.5f) * dx + (1.f / 6.f);
+ u[1] = ((0.5f * dx - 1.f) * dx) * dx + (2.f / 3.f);
+ u[2] = ((-0.5f * dx + 0.5f) * dx + 0.5f) * dx + (1.f / 6.f);
+ u[3] = (1.f / 6.f) * dx * dx * dx;
+ v[0] = (((-1.f / 6.f) * dy + 0.5f) * dy - 0.5f) * dy + (1.f / 6.f);
+ v[1] = ((0.5f * dy - 1.f) * dy) * dy + (2.f / 3.f);
+ v[2] = ((-0.5f * dy + 0.5f) * dy + 0.5f) * dy + (1.f / 6.f);
+ v[3] = (1.f / 6.f) * dy * dy * dy;
+ w[0] = (((-1.f / 6.f) * dz + 0.5f) * dz - 0.5f) * dz + (1.f / 6.f);
+ w[1] = ((0.5f * dz - 1.f) * dz) * dz + (2.f / 3.f);
+ w[2] = ((-0.5f * dz + 0.5f) * dz + 0.5f) * dz + (1.f / 6.f);
+ w[3] = (1.f / 6.f) * dz * dz * dz;
+ }
+ else { // Catmull-Rom
+ u[0] = ((-0.5f * dx + 1.0f) * dx - 0.5f) * dx;
+ u[1] = ((1.5f * dx - 2.5f) * dx) * dx + 1.0f;
+ u[2] = ((-1.5f * dx + 2.0f) * dx + 0.5f) * dx;
+ u[3] = ((0.5f * dx - 0.5f) * dx) * dx;
+ v[0] = ((-0.5f * dy + 1.0f) * dy - 0.5f) * dy;
+ v[1] = ((1.5f * dy - 2.5f) * dy) * dy + 1.0f;
+ v[2] = ((-1.5f * dy + 2.0f) * dy + 0.5f) * dy;
+ v[3] = ((0.5f * dy - 0.5f) * dy) * dy;
+ w[0] = ((-0.5f * dz + 1.0f) * dz - 0.5f) * dz;
+ w[1] = ((1.5f * dz - 2.5f) * dz) * dz + 1.0f;
+ w[2] = ((-1.5f * dz + 2.0f) * dz + 0.5f) * dz;
+ w[3] = ((0.5f * dz - 0.5f) * dz) * dz;
+ }
+
+ return w[0] *
+ (v[0] * (u[0] * data[xc[0] + yc[0] + zc[0]] + u[1] * data[xc[1] + yc[0] + zc[0]] +
+ u[2] * data[xc[2] + yc[0] + zc[0]] + u[3] * data[xc[3] + yc[0] + zc[0]]) +
+ v[1] * (u[0] * data[xc[0] + yc[1] + zc[0]] + u[1] * data[xc[1] + yc[1] + zc[0]] +
+ u[2] * data[xc[2] + yc[1] + zc[0]] + u[3] * data[xc[3] + yc[1] + zc[0]]) +
+ v[2] * (u[0] * data[xc[0] + yc[2] + zc[0]] + u[1] * data[xc[1] + yc[2] + zc[0]] +
+ u[2] * data[xc[2] + yc[2] + zc[0]] + u[3] * data[xc[3] + yc[2] + zc[0]]) +
+ v[3] * (u[0] * data[xc[0] + yc[3] + zc[0]] + u[1] * data[xc[1] + yc[3] + zc[0]] +
+ u[2] * data[xc[2] + yc[3] + zc[0]] + u[3] * data[xc[3] + yc[3] + zc[0]])) +
+ w[1] *
+ (v[0] * (u[0] * data[xc[0] + yc[0] + zc[1]] + u[1] * data[xc[1] + yc[0] + zc[1]] +
+ u[2] * data[xc[2] + yc[0] + zc[1]] + u[3] * data[xc[3] + yc[0] + zc[1]]) +
+ v[1] * (u[0] * data[xc[0] + yc[1] + zc[1]] + u[1] * data[xc[1] + yc[1] + zc[1]] +
+ u[2] * data[xc[2] + yc[1] + zc[1]] + u[3] * data[xc[3] + yc[1] + zc[1]]) +
+ v[2] * (u[0] * data[xc[0] + yc[2] + zc[1]] + u[1] * data[xc[1] + yc[2] + zc[1]] +
+ u[2] * data[xc[2] + yc[2] + zc[1]] + u[3] * data[xc[3] + yc[2] + zc[1]]) +
+ v[3] * (u[0] * data[xc[0] + yc[3] + zc[1]] + u[1] * data[xc[1] + yc[3] + zc[1]] +
+ u[2] * data[xc[2] + yc[3] + zc[1]] + u[3] * data[xc[3] + yc[3] + zc[1]])) +
+ w[2] *
+ (v[0] * (u[0] * data[xc[0] + yc[0] + zc[2]] + u[1] * data[xc[1] + yc[0] + zc[2]] +
+ u[2] * data[xc[2] + yc[0] + zc[2]] + u[3] * data[xc[3] + yc[0] + zc[2]]) +
+ v[1] * (u[0] * data[xc[0] + yc[1] + zc[2]] + u[1] * data[xc[1] + yc[1] + zc[2]] +
+ u[2] * data[xc[2] + yc[1] + zc[2]] + u[3] * data[xc[3] + yc[1] + zc[2]]) +
+ v[2] * (u[0] * data[xc[0] + yc[2] + zc[2]] + u[1] * data[xc[1] + yc[2] + zc[2]] +
+ u[2] * data[xc[2] + yc[2] + zc[2]] + u[3] * data[xc[3] + yc[2] + zc[2]]) +
+ v[3] * (u[0] * data[xc[0] + yc[3] + zc[2]] + u[1] * data[xc[1] + yc[3] + zc[2]] +
+ u[2] * data[xc[2] + yc[3] + zc[2]] + u[3] * data[xc[3] + yc[3] + zc[2]])) +
+ w[3] *
+ (v[0] * (u[0] * data[xc[0] + yc[0] + zc[3]] + u[1] * data[xc[1] + yc[0] + zc[3]] +
+ u[2] * data[xc[2] + yc[0] + zc[3]] + u[3] * data[xc[3] + yc[0] + zc[3]]) +
+ v[1] * (u[0] * data[xc[0] + yc[1] + zc[3]] + u[1] * data[xc[1] + yc[1] + zc[3]] +
+ u[2] * data[xc[2] + yc[1] + zc[3]] + u[3] * data[xc[3] + yc[1] + zc[3]]) +
+ v[2] * (u[0] * data[xc[0] + yc[2] + zc[3]] + u[1] * data[xc[1] + yc[2] + zc[3]] +
+ u[2] * data[xc[2] + yc[2] + zc[3]] + u[3] * data[xc[3] + yc[2] + zc[3]]) +
+ v[3] * (u[0] * data[xc[0] + yc[3] + zc[3]] + u[1] * data[xc[1] + yc[3] + zc[3]] +
+ u[2] * data[xc[2] + yc[3] + zc[3]] + u[3] * data[xc[3] + yc[3] + zc[3]]));
+ }
+ return 0.f;
}
diff --git a/source/blender/blenlib/intern/winstuff.c b/source/blender/blenlib/intern/winstuff.c
index 483351801f4..9e6ea0bb6ee 100644
--- a/source/blender/blenlib/intern/winstuff.c
+++ b/source/blender/blenlib/intern/winstuff.c
@@ -22,244 +22,263 @@
* \ingroup bli
*/
-
#ifdef WIN32
-#include <stdlib.h>
-#include <stdio.h>
-#include <conio.h>
+# include <stdlib.h>
+# include <stdio.h>
+# include <conio.h>
-#include "MEM_guardedalloc.h"
+# include "MEM_guardedalloc.h"
-#define WIN32_SKIP_HKEY_PROTECTION // need to use HKEY
-#include "BLI_winstuff.h"
-#include "BLI_utildefines.h"
-#include "BLI_path_util.h"
-#include "BLI_string.h"
+# define WIN32_SKIP_HKEY_PROTECTION // need to use HKEY
+# include "BLI_winstuff.h"
+# include "BLI_utildefines.h"
+# include "BLI_path_util.h"
+# include "BLI_string.h"
-#include "../blenkernel/BKE_global.h" /* G.background, bad level include (no function calls) */
+# include "../blenkernel/BKE_global.h" /* G.background, bad level include (no function calls) */
-#include "utf_winfunc.h"
-#include "utfconv.h"
+# include "utf_winfunc.h"
+# include "utfconv.h"
/* FILE_MAXDIR + FILE_MAXFILE */
int BLI_getInstallationDir(char *str)
{
- char dir[FILE_MAXDIR];
- int a;
- /*change to utf support*/
- GetModuleFileName(NULL, str, FILE_MAX);
- BLI_split_dir_part(str, dir, sizeof(dir)); /* shouldn't be relative */
- a = strlen(dir);
- if (dir[a - 1] == '\\') {
- dir[a - 1] = 0;
- }
+ char dir[FILE_MAXDIR];
+ int a;
+ /*change to utf support*/
+ GetModuleFileName(NULL, str, FILE_MAX);
+ BLI_split_dir_part(str, dir, sizeof(dir)); /* shouldn't be relative */
+ a = strlen(dir);
+ if (dir[a - 1] == '\\') {
+ dir[a - 1] = 0;
+ }
- strcpy(str, dir);
+ strcpy(str, dir);
- return 1;
+ return 1;
}
static void RegisterBlendExtension_Fail(HKEY root)
{
- printf("failed\n");
- if (root) {
- RegCloseKey(root);
- }
- if (!G.background) {
- MessageBox(0, "Could not register file extension.", "Blender error", MB_OK | MB_ICONERROR);
- }
- TerminateProcess(GetCurrentProcess(), 1);
+ printf("failed\n");
+ if (root) {
+ RegCloseKey(root);
+ }
+ if (!G.background) {
+ MessageBox(0, "Could not register file extension.", "Blender error", MB_OK | MB_ICONERROR);
+ }
+ TerminateProcess(GetCurrentProcess(), 1);
}
void RegisterBlendExtension(void)
{
- LONG lresult;
- HKEY hkey = 0;
- HKEY root = 0;
- BOOL usr_mode = false;
- DWORD dwd = 0;
- char buffer[256];
+ LONG lresult;
+ HKEY hkey = 0;
+ HKEY root = 0;
+ BOOL usr_mode = false;
+ DWORD dwd = 0;
+ char buffer[256];
- char BlPath[MAX_PATH];
- char InstallDir[FILE_MAXDIR];
- char SysDir[FILE_MAXDIR];
- const char *ThumbHandlerDLL;
- char RegCmd[MAX_PATH * 2];
- char MBox[256];
- char *blender_app;
-#ifndef _WIN64
- BOOL IsWOW64;
-#endif
+ char BlPath[MAX_PATH];
+ char InstallDir[FILE_MAXDIR];
+ char SysDir[FILE_MAXDIR];
+ const char *ThumbHandlerDLL;
+ char RegCmd[MAX_PATH * 2];
+ char MBox[256];
+ char *blender_app;
+# ifndef _WIN64
+ BOOL IsWOW64;
+# endif
- printf("Registering file extension...");
- GetModuleFileName(0, BlPath, MAX_PATH);
+ printf("Registering file extension...");
+ GetModuleFileName(0, BlPath, MAX_PATH);
- /* Replace the actual app name with the wrapper. */
- blender_app = strstr(BlPath, "blender-app.exe");
- if (blender_app != NULL) {
- strcpy(blender_app, "blender.exe");
- }
+ /* Replace the actual app name with the wrapper. */
+ blender_app = strstr(BlPath, "blender-app.exe");
+ if (blender_app != NULL) {
+ strcpy(blender_app, "blender.exe");
+ }
- /* root is HKLM by default */
- lresult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Classes", 0, KEY_ALL_ACCESS, &root);
- if (lresult != ERROR_SUCCESS) {
- /* try HKCU on failure */
- usr_mode = true;
- lresult = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Classes", 0, KEY_ALL_ACCESS, &root);
- if (lresult != ERROR_SUCCESS) {
- RegisterBlendExtension_Fail(0);
- }
- }
+ /* root is HKLM by default */
+ lresult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Classes", 0, KEY_ALL_ACCESS, &root);
+ if (lresult != ERROR_SUCCESS) {
+ /* try HKCU on failure */
+ usr_mode = true;
+ lresult = RegOpenKeyEx(HKEY_CURRENT_USER, "Software\\Classes", 0, KEY_ALL_ACCESS, &root);
+ if (lresult != ERROR_SUCCESS) {
+ RegisterBlendExtension_Fail(0);
+ }
+ }
- lresult = RegCreateKeyEx(root, "blendfile", 0,
- NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwd);
- if (lresult == ERROR_SUCCESS) {
- strcpy(buffer, "Blender File");
- lresult = RegSetValueEx(hkey, NULL, 0, REG_SZ, (BYTE *)buffer, strlen(buffer) + 1);
- RegCloseKey(hkey);
- }
- if (lresult != ERROR_SUCCESS) {
- RegisterBlendExtension_Fail(root);
- }
+ lresult = RegCreateKeyEx(
+ root, "blendfile", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwd);
+ if (lresult == ERROR_SUCCESS) {
+ strcpy(buffer, "Blender File");
+ lresult = RegSetValueEx(hkey, NULL, 0, REG_SZ, (BYTE *)buffer, strlen(buffer) + 1);
+ RegCloseKey(hkey);
+ }
+ if (lresult != ERROR_SUCCESS) {
+ RegisterBlendExtension_Fail(root);
+ }
- lresult = RegCreateKeyEx(root, "blendfile\\shell\\open\\command", 0,
- NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwd);
- if (lresult == ERROR_SUCCESS) {
- sprintf(buffer, "\"%s\" \"%%1\"", BlPath);
- lresult = RegSetValueEx(hkey, NULL, 0, REG_SZ, (BYTE *)buffer, strlen(buffer) + 1);
- RegCloseKey(hkey);
- }
- if (lresult != ERROR_SUCCESS) {
- RegisterBlendExtension_Fail(root);
- }
+ lresult = RegCreateKeyEx(root,
+ "blendfile\\shell\\open\\command",
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_ALL_ACCESS,
+ NULL,
+ &hkey,
+ &dwd);
+ if (lresult == ERROR_SUCCESS) {
+ sprintf(buffer, "\"%s\" \"%%1\"", BlPath);
+ lresult = RegSetValueEx(hkey, NULL, 0, REG_SZ, (BYTE *)buffer, strlen(buffer) + 1);
+ RegCloseKey(hkey);
+ }
+ if (lresult != ERROR_SUCCESS) {
+ RegisterBlendExtension_Fail(root);
+ }
- lresult = RegCreateKeyEx(root, "blendfile\\DefaultIcon", 0,
- NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwd);
- if (lresult == ERROR_SUCCESS) {
- sprintf(buffer, "\"%s\", 1", BlPath);
- lresult = RegSetValueEx(hkey, NULL, 0, REG_SZ, (BYTE *)buffer, strlen(buffer) + 1);
- RegCloseKey(hkey);
- }
- if (lresult != ERROR_SUCCESS) {
- RegisterBlendExtension_Fail(root);
- }
+ lresult = RegCreateKeyEx(root,
+ "blendfile\\DefaultIcon",
+ 0,
+ NULL,
+ REG_OPTION_NON_VOLATILE,
+ KEY_ALL_ACCESS,
+ NULL,
+ &hkey,
+ &dwd);
+ if (lresult == ERROR_SUCCESS) {
+ sprintf(buffer, "\"%s\", 1", BlPath);
+ lresult = RegSetValueEx(hkey, NULL, 0, REG_SZ, (BYTE *)buffer, strlen(buffer) + 1);
+ RegCloseKey(hkey);
+ }
+ if (lresult != ERROR_SUCCESS) {
+ RegisterBlendExtension_Fail(root);
+ }
- lresult = RegCreateKeyEx(root, ".blend", 0,
- NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwd);
- if (lresult == ERROR_SUCCESS) {
- strcpy(buffer, "blendfile");
- lresult = RegSetValueEx(hkey, NULL, 0, REG_SZ, (BYTE *)buffer, strlen(buffer) + 1);
- RegCloseKey(hkey);
- }
- if (lresult != ERROR_SUCCESS) {
- RegisterBlendExtension_Fail(root);
- }
+ lresult = RegCreateKeyEx(
+ root, ".blend", 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwd);
+ if (lresult == ERROR_SUCCESS) {
+ strcpy(buffer, "blendfile");
+ lresult = RegSetValueEx(hkey, NULL, 0, REG_SZ, (BYTE *)buffer, strlen(buffer) + 1);
+ RegCloseKey(hkey);
+ }
+ if (lresult != ERROR_SUCCESS) {
+ RegisterBlendExtension_Fail(root);
+ }
- BLI_getInstallationDir(InstallDir);
- GetSystemDirectory(SysDir, FILE_MAXDIR);
-#ifdef _WIN64
- ThumbHandlerDLL = "BlendThumb64.dll";
-#else
- IsWow64Process(GetCurrentProcess(), &IsWOW64);
- if (IsWOW64 == true) {
- ThumbHandlerDLL = "BlendThumb64.dll";
- }
- else {
- ThumbHandlerDLL = "BlendThumb.dll";
- }
-#endif
- snprintf(RegCmd, MAX_PATH * 2, "%s\\regsvr32 /s \"%s\\%s\"", SysDir, InstallDir, ThumbHandlerDLL);
- system(RegCmd);
+ BLI_getInstallationDir(InstallDir);
+ GetSystemDirectory(SysDir, FILE_MAXDIR);
+# ifdef _WIN64
+ ThumbHandlerDLL = "BlendThumb64.dll";
+# else
+ IsWow64Process(GetCurrentProcess(), &IsWOW64);
+ if (IsWOW64 == true) {
+ ThumbHandlerDLL = "BlendThumb64.dll";
+ }
+ else {
+ ThumbHandlerDLL = "BlendThumb.dll";
+ }
+# endif
+ snprintf(
+ RegCmd, MAX_PATH * 2, "%s\\regsvr32 /s \"%s\\%s\"", SysDir, InstallDir, ThumbHandlerDLL);
+ system(RegCmd);
- RegCloseKey(root);
- printf("success (%s)\n", usr_mode ? "user" : "system");
- if (!G.background) {
- sprintf(MBox, "File extension registered for %s.", usr_mode ? "the current user. To register for all users, run as an administrator" : "all users");
- MessageBox(0, MBox, "Blender", MB_OK | MB_ICONINFORMATION);
- }
- TerminateProcess(GetCurrentProcess(), 0);
+ RegCloseKey(root);
+ printf("success (%s)\n", usr_mode ? "user" : "system");
+ if (!G.background) {
+ sprintf(MBox,
+ "File extension registered for %s.",
+ usr_mode ? "the current user. To register for all users, run as an administrator" :
+ "all users");
+ MessageBox(0, MBox, "Blender", MB_OK | MB_ICONINFORMATION);
+ }
+ TerminateProcess(GetCurrentProcess(), 0);
}
void get_default_root(char *root)
{
- char str[MAX_PATH + 1];
+ char str[MAX_PATH + 1];
- /* the default drive to resolve a directory without a specified drive
- * should be the Windows installation drive, since this was what the OS
- * assumes. */
- if (GetWindowsDirectory(str, MAX_PATH + 1)) {
- root[0] = str[0];
- root[1] = ':';
- root[2] = '\\';
- root[3] = '\0';
- }
- else {
- /* if GetWindowsDirectory fails, something has probably gone wrong,
- * we are trying the blender install dir though */
- if (GetModuleFileName(NULL, str, MAX_PATH + 1)) {
- printf("Error! Could not get the Windows Directory - "
- "Defaulting to Blender installation Dir!\n");
- root[0] = str[0];
- root[1] = ':';
- root[2] = '\\';
- root[3] = '\0';
- }
- else {
- DWORD tmp;
- int i;
- int rc = 0;
- /* now something has gone really wrong - still trying our best guess */
- printf("Error! Could not get the Windows Directory - "
- "Defaulting to first valid drive! Path might be invalid!\n");
- tmp = GetLogicalDrives();
- for (i = 2; i < 26; i++) {
- if ((tmp >> i) & 1) {
- root[0] = 'a' + i;
- root[1] = ':';
- root[2] = '\\';
- root[3] = '\0';
- if (GetFileAttributes(root) != 0xFFFFFFFF) {
- rc = i;
- break;
- }
- }
- }
- if (0 == rc) {
- printf("ERROR in 'get_default_root': can't find a valid drive!\n");
- root[0] = 'C';
- root[1] = ':';
- root[2] = '\\';
- root[3] = '\0';
- }
- }
- }
+ /* the default drive to resolve a directory without a specified drive
+ * should be the Windows installation drive, since this was what the OS
+ * assumes. */
+ if (GetWindowsDirectory(str, MAX_PATH + 1)) {
+ root[0] = str[0];
+ root[1] = ':';
+ root[2] = '\\';
+ root[3] = '\0';
+ }
+ else {
+ /* if GetWindowsDirectory fails, something has probably gone wrong,
+ * we are trying the blender install dir though */
+ if (GetModuleFileName(NULL, str, MAX_PATH + 1)) {
+ printf(
+ "Error! Could not get the Windows Directory - "
+ "Defaulting to Blender installation Dir!\n");
+ root[0] = str[0];
+ root[1] = ':';
+ root[2] = '\\';
+ root[3] = '\0';
+ }
+ else {
+ DWORD tmp;
+ int i;
+ int rc = 0;
+ /* now something has gone really wrong - still trying our best guess */
+ printf(
+ "Error! Could not get the Windows Directory - "
+ "Defaulting to first valid drive! Path might be invalid!\n");
+ tmp = GetLogicalDrives();
+ for (i = 2; i < 26; i++) {
+ if ((tmp >> i) & 1) {
+ root[0] = 'a' + i;
+ root[1] = ':';
+ root[2] = '\\';
+ root[3] = '\0';
+ if (GetFileAttributes(root) != 0xFFFFFFFF) {
+ rc = i;
+ break;
+ }
+ }
+ }
+ if (0 == rc) {
+ printf("ERROR in 'get_default_root': can't find a valid drive!\n");
+ root[0] = 'C';
+ root[1] = ':';
+ root[2] = '\\';
+ root[3] = '\0';
+ }
+ }
+ }
}
/* UNUSED */
-#if 0
+# if 0
int check_file_chars(char *filename)
{
- char *p = filename;
- while (*p) {
- switch (*p) {
- case ':':
- case '?':
- case '*':
- case '|':
- case '\\':
- case '/':
- case '\"':
- return 0;
- break;
- }
+ char *p = filename;
+ while (*p) {
+ switch (*p) {
+ case ':':
+ case '?':
+ case '*':
+ case '|':
+ case '\\':
+ case '/':
+ case '\"':
+ return 0;
+ break;
+ }
- p++;
- }
- return 1;
+ p++;
+ }
+ return 1;
}
-#endif
+# endif
#else
diff --git a/source/blender/blenlib/intern/winstuff_dir.c b/source/blender/blenlib/intern/winstuff_dir.c
index 9c1a51f9be7..1e5a0db678e 100644
--- a/source/blender/blenlib/intern/winstuff_dir.c
+++ b/source/blender/blenlib/intern/winstuff_dir.c
@@ -33,25 +33,25 @@
# include "MEM_guardedalloc.h"
# endif
-#define WIN32_SKIP_HKEY_PROTECTION // need to use HKEY
-#include "BLI_winstuff.h"
-#include "BLI_utildefines.h"
-#include "utfconv.h"
+# define WIN32_SKIP_HKEY_PROTECTION // need to use HKEY
+# include "BLI_winstuff.h"
+# include "BLI_utildefines.h"
+# include "utfconv.h"
-#define PATH_SUFFIX "\\*"
-#define PATH_SUFFIX_LEN 2
+# define PATH_SUFFIX "\\*"
+# define PATH_SUFFIX_LEN 2
/* keep local to this file */
struct __dirstream {
- HANDLE handle;
- WIN32_FIND_DATAW data;
- char path[MAX_PATH + PATH_SUFFIX_LEN];
- long dd_loc;
- long dd_size;
- char dd_buf[4096];
- void *dd_direct;
-
- struct dirent direntry;
+ HANDLE handle;
+ WIN32_FIND_DATAW data;
+ char path[MAX_PATH + PATH_SUFFIX_LEN];
+ long dd_loc;
+ long dd_size;
+ char dd_buf[4096];
+ void *dd_direct;
+
+ struct dirent direntry;
};
/**
@@ -64,95 +64,92 @@ struct __dirstream {
DIR *opendir(const char *path)
{
- wchar_t *path_16 = alloc_utf16_from_8(path, 0);
- int path_len;
- DIR *newd = NULL;
-
- if ((GetFileAttributesW(path_16) & FILE_ATTRIBUTE_DIRECTORY) &&
- ((path_len = strlen(path)) < (sizeof(newd->path) - PATH_SUFFIX_LEN)))
- {
- newd = MEM_mallocN(sizeof(DIR), "opendir");
- newd->handle = INVALID_HANDLE_VALUE;
- memcpy(newd->path, path, path_len);
- memcpy(newd->path + path_len, PATH_SUFFIX, PATH_SUFFIX_LEN + 1);
-
- newd->direntry.d_ino = 0;
- newd->direntry.d_off = 0;
- newd->direntry.d_reclen = 0;
- newd->direntry.d_name = NULL;
- }
-
- free(path_16);
- return newd;
+ wchar_t *path_16 = alloc_utf16_from_8(path, 0);
+ int path_len;
+ DIR *newd = NULL;
+
+ if ((GetFileAttributesW(path_16) & FILE_ATTRIBUTE_DIRECTORY) &&
+ ((path_len = strlen(path)) < (sizeof(newd->path) - PATH_SUFFIX_LEN))) {
+ newd = MEM_mallocN(sizeof(DIR), "opendir");
+ newd->handle = INVALID_HANDLE_VALUE;
+ memcpy(newd->path, path, path_len);
+ memcpy(newd->path + path_len, PATH_SUFFIX, PATH_SUFFIX_LEN + 1);
+
+ newd->direntry.d_ino = 0;
+ newd->direntry.d_off = 0;
+ newd->direntry.d_reclen = 0;
+ newd->direntry.d_name = NULL;
+ }
+
+ free(path_16);
+ return newd;
}
static char *BLI_alloc_utf_8_from_16(wchar_t *in16, size_t add)
{
- size_t bsize = count_utf_8_from_16(in16);
- char *out8 = NULL;
- if (!bsize) {
- return NULL;
- }
- out8 = (char *)MEM_mallocN(sizeof(char) * (bsize + add), "UTF-8 String");
- conv_utf_16_to_8(in16, out8, bsize);
- return out8;
+ size_t bsize = count_utf_8_from_16(in16);
+ char *out8 = NULL;
+ if (!bsize) {
+ return NULL;
+ }
+ out8 = (char *)MEM_mallocN(sizeof(char) * (bsize + add), "UTF-8 String");
+ conv_utf_16_to_8(in16, out8, bsize);
+ return out8;
}
-static wchar_t *UNUSED_FUNCTION(BLI_alloc_utf16_from_8) (char *in8, size_t add)
+static wchar_t *UNUSED_FUNCTION(BLI_alloc_utf16_from_8)(char *in8, size_t add)
{
- size_t bsize = count_utf_16_from_8(in8);
- wchar_t *out16 = NULL;
- if (!bsize) {
- return NULL;
- }
- out16 = (wchar_t *) MEM_mallocN(sizeof(wchar_t) * (bsize + add), "UTF-16 String");
- conv_utf_8_to_16(in8, out16, bsize);
- return out16;
+ size_t bsize = count_utf_16_from_8(in8);
+ wchar_t *out16 = NULL;
+ if (!bsize) {
+ return NULL;
+ }
+ out16 = (wchar_t *)MEM_mallocN(sizeof(wchar_t) * (bsize + add), "UTF-16 String");
+ conv_utf_8_to_16(in8, out16, bsize);
+ return out16;
}
-
-
struct dirent *readdir(DIR *dp)
{
- if (dp->direntry.d_name) {
- MEM_freeN(dp->direntry.d_name);
- dp->direntry.d_name = NULL;
- }
-
- if (dp->handle == INVALID_HANDLE_VALUE) {
- wchar_t *path_16 = alloc_utf16_from_8(dp->path, 0);
- dp->handle = FindFirstFileW(path_16, &(dp->data));
- free(path_16);
- if (dp->handle == INVALID_HANDLE_VALUE) {
- return NULL;
- }
-
- dp->direntry.d_name = BLI_alloc_utf_8_from_16(dp->data.cFileName, 0);
-
- return &dp->direntry;
- }
- else if (FindNextFileW(dp->handle, &(dp->data))) {
- dp->direntry.d_name = BLI_alloc_utf_8_from_16(dp->data.cFileName, 0);
-
- return &dp->direntry;
- }
- else {
- return NULL;
- }
+ if (dp->direntry.d_name) {
+ MEM_freeN(dp->direntry.d_name);
+ dp->direntry.d_name = NULL;
+ }
+
+ if (dp->handle == INVALID_HANDLE_VALUE) {
+ wchar_t *path_16 = alloc_utf16_from_8(dp->path, 0);
+ dp->handle = FindFirstFileW(path_16, &(dp->data));
+ free(path_16);
+ if (dp->handle == INVALID_HANDLE_VALUE) {
+ return NULL;
+ }
+
+ dp->direntry.d_name = BLI_alloc_utf_8_from_16(dp->data.cFileName, 0);
+
+ return &dp->direntry;
+ }
+ else if (FindNextFileW(dp->handle, &(dp->data))) {
+ dp->direntry.d_name = BLI_alloc_utf_8_from_16(dp->data.cFileName, 0);
+
+ return &dp->direntry;
+ }
+ else {
+ return NULL;
+ }
}
int closedir(DIR *dp)
{
- if (dp->direntry.d_name) {
- MEM_freeN(dp->direntry.d_name);
- }
- if (dp->handle != INVALID_HANDLE_VALUE) {
- FindClose(dp->handle);
- }
+ if (dp->direntry.d_name) {
+ MEM_freeN(dp->direntry.d_name);
+ }
+ if (dp->handle != INVALID_HANDLE_VALUE) {
+ FindClose(dp->handle);
+ }
- MEM_freeN(dp);
+ MEM_freeN(dp);
- return 0;
+ return 0;
}
/* End of copied part */