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:
authorJoseph Eagar <joeedh@gmail.com>2010-07-19 08:44:37 +0400
committerJoseph Eagar <joeedh@gmail.com>2010-07-19 08:44:37 +0400
commitc11c196efadf5ef52293d782638497f86a209722 (patch)
tree43abcd60b2400d28db8686f4dbea68f17475ef58 /source/blender/blenlib/intern
parentf54aa7811029c90b6071ccc9e27e57a758e5884d (diff)
parent7f083c45bee15f7540e2a35a725efe28fc962239 (diff)
part 1 of merge from trunk at r30358; it compiles, but doesn't link quite yet :)
Diffstat (limited to 'source/blender/blenlib/intern')
-rw-r--r--source/blender/blenlib/intern/BLI_args.c100
-rw-r--r--source/blender/blenlib/intern/BLI_bfile.c357
-rw-r--r--source/blender/blenlib/intern/BLI_dynstr.c2
-rw-r--r--source/blender/blenlib/intern/BLI_ghash.c19
-rw-r--r--source/blender/blenlib/intern/BLI_heap.c3
-rw-r--r--source/blender/blenlib/intern/BLI_kdopbvh.c8
-rw-r--r--source/blender/blenlib/intern/BLI_kdtree.c3
-rw-r--r--source/blender/blenlib/intern/BLI_linklist.c51
-rw-r--r--source/blender/blenlib/intern/BLI_memarena.c14
-rw-r--r--source/blender/blenlib/intern/boxpack2d.c24
-rw-r--r--source/blender/blenlib/intern/bpath.c46
-rw-r--r--source/blender/blenlib/intern/cpu.c57
-rw-r--r--source/blender/blenlib/intern/dynamiclist.c265
-rw-r--r--source/blender/blenlib/intern/dynlib.c8
-rw-r--r--source/blender/blenlib/intern/edgehash.c2
-rw-r--r--source/blender/blenlib/intern/fileops.c45
-rw-r--r--source/blender/blenlib/intern/fnmatch.c150
-rw-r--r--source/blender/blenlib/intern/freetypefont.c74
-rw-r--r--source/blender/blenlib/intern/graph.c8
-rw-r--r--source/blender/blenlib/intern/gsqueue.c4
-rw-r--r--source/blender/blenlib/intern/jitter.c3
-rw-r--r--source/blender/blenlib/intern/listbase.c11
-rw-r--r--source/blender/blenlib/intern/math_base.c16
-rw-r--r--source/blender/blenlib/intern/math_base_inline.c1
-rw-r--r--source/blender/blenlib/intern/math_color.c77
-rw-r--r--source/blender/blenlib/intern/math_geom.c650
-rw-r--r--source/blender/blenlib/intern/math_geom_inline.c138
-rw-r--r--source/blender/blenlib/intern/math_matrix.c627
-rw-r--r--source/blender/blenlib/intern/math_rotation.c42
-rw-r--r--source/blender/blenlib/intern/math_vector.c22
-rw-r--r--source/blender/blenlib/intern/math_vector_inline.c66
-rw-r--r--source/blender/blenlib/intern/noise.c28
-rw-r--r--source/blender/blenlib/intern/path_util.c635
-rw-r--r--source/blender/blenlib/intern/pbvh.c468
-rw-r--r--source/blender/blenlib/intern/rand.c4
-rw-r--r--source/blender/blenlib/intern/rct.c26
-rw-r--r--source/blender/blenlib/intern/scanfill.c14
-rw-r--r--source/blender/blenlib/intern/storage.c89
-rw-r--r--source/blender/blenlib/intern/string.c11
-rw-r--r--source/blender/blenlib/intern/threads.c85
-rw-r--r--source/blender/blenlib/intern/time.c7
-rw-r--r--source/blender/blenlib/intern/uvproject.c191
-rw-r--r--source/blender/blenlib/intern/voxel.c64
-rw-r--r--source/blender/blenlib/intern/winstuff.c34
44 files changed, 2979 insertions, 1570 deletions
diff --git a/source/blender/blenlib/intern/BLI_args.c b/source/blender/blenlib/intern/BLI_args.c
index cd876023830..8d72311f80b 100644
--- a/source/blender/blenlib/intern/BLI_args.c
+++ b/source/blender/blenlib/intern/BLI_args.c
@@ -1,7 +1,7 @@
/**
* A general argument parsing module
*
- * $Id:
+ * $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
@@ -33,10 +33,22 @@
#include "MEM_guardedalloc.h"
+#include "BLI_listbase.h"
#include "BLI_string.h"
#include "BLI_args.h"
#include "BLI_ghash.h"
+char NO_DOCS[] = "NO DOCUMENTATION SPECIFIED";
+
+struct bArgDoc;
+typedef struct bArgDoc {
+ struct bArgDoc *next, *prev;
+ char *short_arg;
+ char *long_arg;
+ char *documentation;
+ int done;
+} bArgDoc;
+
typedef struct bAKey {
char *arg;
uintptr_t pass; /* cast easier */
@@ -47,9 +59,11 @@ typedef struct bArgument {
bAKey *key;
BA_ArgCallback func;
void *data;
+ bArgDoc *doc;
} bArgument;
struct bArgs {
+ ListBase docs;
GHash *items;
int argc;
char **argv;
@@ -70,7 +84,7 @@ static unsigned int case_strhash(void *ptr) {
static unsigned int keyhash(void *ptr)
{
bAKey *k = ptr;
- return case_strhash(k->arg) ^ BLI_ghashutil_inthash((void*)k->pass);
+ return case_strhash(k->arg); // ^ BLI_ghashutil_inthash((void*)k->pass);
}
static int keycmp(void *a, void *b)
@@ -102,7 +116,8 @@ bArgs *BLI_argsInit(int argc, 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);
+ ba->items = BLI_ghash_new(keyhash, keycmp, "bArgs passes gh");
+ ba->docs.first = ba->docs.last = NULL;
ba->argc = argc;
ba->argv = argv;
@@ -118,6 +133,7 @@ void BLI_argsFree(struct bArgs *ba)
{
BLI_ghash_free(ba->items, freeItem, freeItem);
MEM_freeN(ba->passes);
+ BLI_freelistN(&ba->docs);
MEM_freeN(ba);
}
@@ -134,7 +150,25 @@ char **BLI_argsArgv(struct bArgs *ba)
return ba->argv;
}
-static void internalAdd(struct bArgs *ba, char *arg, int pass, int case_str, BA_ArgCallback cb, void *data)
+static bArgDoc *internalDocs(struct bArgs *ba, char *short_arg, char *long_arg, char *doc)
+{
+ bArgDoc *d;
+
+ d = MEM_callocN(sizeof(bArgDoc), "bArgDoc");
+
+ if (doc == NULL)
+ doc = NO_DOCS;
+
+ d->short_arg = short_arg;
+ d->long_arg = long_arg;
+ d->documentation = doc;
+
+ BLI_addtail(&ba->docs, d);
+
+ return d;
+}
+
+static void internalAdd(struct bArgs *ba, char *arg, int pass, int case_str, BA_ArgCallback cb, void *data, bArgDoc *d)
{
bArgument *a;
bAKey *key;
@@ -157,20 +191,67 @@ static void internalAdd(struct bArgs *ba, char *arg, int pass, int case_str, BA_
a->key = key;
a->func = cb;
a->data = data;
+ a->doc = d;
BLI_ghash_insert(ba->items, key, a);
}
-void BLI_argsAdd(struct bArgs *ba, char *arg, int pass, BA_ArgCallback cb, void *data)
+void BLI_argsAddCase(struct bArgs *ba, int pass, char *short_arg, int short_case, char *long_arg, int long_case, char *doc, BA_ArgCallback cb, void *data)
{
- internalAdd(ba, arg, pass, 0, cb, data);
+ bArgDoc *d = internalDocs(ba, short_arg, long_arg, doc);
+
+ 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);
+
+
}
-void BLI_argsAddCase(struct bArgs *ba, char *arg, int pass, BA_ArgCallback cb, void *data)
+void BLI_argsAdd(struct bArgs *ba, int pass, char *short_arg, char *long_arg, char *doc, BA_ArgCallback cb, void *data)
{
- internalAdd(ba, arg, pass, 1, 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);
+}
+
+void BLI_argsPrintArgDoc(struct bArgs *ba, char *arg)
+{
+ bArgument *a = lookUp(ba, arg, -1, -1);
+
+ if (a)
+ {
+ bArgDoc *d = a->doc;
+
+ internalDocPrint(d);
+
+ d->done = 1;
+ }
+}
+
+void BLI_argsPrintOtherDoc(struct bArgs *ba)
+{
+ bArgDoc *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)
{
@@ -203,7 +284,8 @@ void BLI_argsParse(struct bArgs *ba, int pass, BA_ArgCallback default_cb, void *
}
i += retval;
} else if (retval == -1){
- ba->passes[i] = pass;
+ if (a->key->pass != -1)
+ ba->passes[i] = pass;
break;
}
}
diff --git a/source/blender/blenlib/intern/BLI_bfile.c b/source/blender/blenlib/intern/BLI_bfile.c
index 3306283ad3f..b9ac6875b20 100644
--- a/source/blender/blenlib/intern/BLI_bfile.c
+++ b/source/blender/blenlib/intern/BLI_bfile.c
@@ -1,4 +1,5 @@
-/*
+/* -*- indent-tabs-mode:t; tab-width:4; -*-
+ *
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
@@ -33,6 +34,7 @@
#else
#include <io.h>
#include "BLI_winstuff.h"
+ static char* find_in_pathlist(char* filename, char* pathlist);
#endif
#include <sys/types.h>
#include <sys/stat.h>
@@ -46,8 +48,6 @@
#include "BLI_storage.h"
#include "BLI_bfile.h"
-#include "GHOST_C-api.h"
-
/* Internal bfile classification flags */
#define BCF_OPEN (0)
#define BCF_FOPEN (1<<0)
@@ -62,17 +62,14 @@
/* Declaration of internal functions */
-void chomp(char* line);
-void expand_envvars(char* src, char* dst);
-void fill_paths(BFILE *bfile, const char *path);
-char* find_in_pathlist(char* filename, char* pathlist);
-void init_vars_from_file(const char* path);
-void setup_temp();
+static void fill_paths(BFILE *bfile, const char *path, const char *relpath);
+static void free_paths(BFILE* bfile);
+
/*** Exported functions ***/
BFILE *BLI_bfile_fopen(const char *path, const char *mode, int bflags,
- BEnvVarFam envvars)
+ const char *relpath)
{
BFILE *bfile;
@@ -88,50 +85,85 @@ BFILE *BLI_bfile_fopen(const char *path, const char *mode, int bflags,
a BCF_AT_END | BCF_WRITE
a+ BCF_AT_END | BCF_WRITE | BCF_READ
*/
- if(strchr(mode, 'r'))
+ if (strchr(mode, 'r'))
bfile->classf |= BCF_READ;
- if(strchr(mode, 'w'))
+ if (strchr(mode, 'w'))
bfile->classf |= (BCF_DISCARD | BCF_WRITE);
- if(strchr(mode, 'a'))
+ if (strchr(mode, 'a'))
bfile->classf |= (BCF_AT_END | BCF_WRITE);
- if(strchr(mode, '+'))
+ if (strchr(mode, '+'))
bfile->classf |= (BCF_READ | BCF_WRITE);
- fill_paths(bfile, path);
+ fill_paths(bfile, path, relpath);
bfile->stream = fopen(bfile->tpath, mode);
- // detect failed fopen
+ if (!(bfile->stream)) {
+ free_paths(bfile);
+ MEM_freeN(bfile);
+ return NULL;
+ }
+
bfile->fd = fileno(bfile->stream);
+
return bfile;
}
BFILE *BLI_bfile_open(const char *pathname, int flags, int bflags,
- BEnvVarFam envvars)
+ const char *relpath)
{
BFILE *bfile;
+ char fopen_mode[3];
bfile = MEM_mallocN(sizeof(BFILE), "bfile-open");
bfile->classf = BCF_OPEN;
bfile->uflags = bflags;
/* Easy mapping for open() */
- if(flags & O_RDONLY)
+ if (flags & O_RDONLY)
bfile->classf |= BCF_READ;
- if(flags & O_WRONLY)
+ if (flags & O_WRONLY)
bfile->classf |= BCF_WRITE;
- if(flags & O_RDWR)
+ if (flags & O_RDWR)
bfile->classf |= (BCF_READ | BCF_WRITE);
- if(flags & O_APPEND)
+ if (flags & O_APPEND)
bfile->classf |= BCF_AT_END;
- if(flags & O_TRUNC)
+ if (flags & O_TRUNC)
bfile->classf |= BCF_DISCARD;
- fill_paths(bfile, pathname);
+ fill_paths(bfile, pathname, relpath);
bfile->fd = open(bfile->tpath, flags);
- // detect failed open
-// bfile->stream = fdopen(bfile->fd, XXX); /* MSWindows _fdopen? */
+ if (bfile->fd == -1) {
+ free_paths(bfile);
+ MEM_freeN(bfile);
+ return NULL;
+ }
+
+ fopen_mode[0] = 'r';
+ fopen_mode[1] = '\0';
+ fopen_mode[2] = '\0';
+ if (bfile->classf & BCF_DISCARD) {
+ fopen_mode[0] = 'w';
+ if (bfile->classf & BCF_READ) {
+ fopen_mode[1] = '+';
+ }
+ } else if (bfile->classf & BCF_AT_END) {
+ fopen_mode[0] = 'a';
+ if (bfile->classf & BCF_READ) {
+ fopen_mode[1] = '+';
+ }
+ } else if (bfile->classf & BCF_WRITE) {
+ fopen_mode[1] = '+';
+ }
+
+ bfile->stream = fdopen(bfile->fd, fopen_mode); /* MSWindows _fdopen? */
+ if (!(bfile->stream)) {
+ free_paths(bfile);
+ MEM_freeN(bfile);
+ return NULL;
+ }
+
return bfile;
}
@@ -175,8 +207,11 @@ size_t BLI_bfile_fwrite(const void *ptr, size_t size, size_t nmemb,
{
size_t ret;
+ if (f == NULL)
+ return 0;
+
ret = fwrite(ptr, size, nmemb, f->stream);
- if (ret < 0) {
+ if (ret <= 0) {
f->error = 1;
}
@@ -187,8 +222,11 @@ size_t BLI_bfile_fwrite(const void *ptr, size_t size, size_t nmemb,
size_t BLI_bfile_fread(void *ptr, size_t size, size_t nmemb, BFILE *f) {
size_t ret;
+ if (f == NULL)
+ return 0;
+
ret = fread(ptr, size, nmemb, f->stream);
- if ((ret < 0) && ferror(f->stream)) {
+ if ((ret <= 0) && ferror(f->stream)) {
f->error = 1;
}
@@ -197,21 +235,23 @@ size_t BLI_bfile_fread(void *ptr, size_t size, size_t nmemb, BFILE *f) {
void BLI_bfile_close(BFILE *bfile) {
- if((bfile->classf | BCF_WRITE) &&
- !(bfile->uflags | BFILE_RAW)) {
+ if ((bfile->classf | BCF_WRITE) &&
+ !(bfile->uflags | BFILE_RAW)) {
+ int error;
/* Make sure data is on disk */
+ error = fsync(bfile->fd);
+ /* fsync the directory too? */
/* Move to final name if no errors */
+ if (!(bfile->error) && !error) {
+ rename(bfile->tpath, bfile->fpath);
+ }
}
/* Normal close */
/* Cleanup */
- if(bfile->fpath) {
- MEM_freeN(bfile->fpath);
- }
- if(bfile->tpath) {
- MEM_freeN(bfile->tpath);
- }
+ free_paths(bfile);
+ MEM_freeN(bfile);
}
@@ -228,197 +268,9 @@ void BLI_bfile_set_error(BFILE *bfile, int error) {
}
-void BLI_bfile_init_vars() {
- char file[MAXPATHLEN];
- char temp[MAXPATHLEN];
- extern char bprogname[];
- FILE* fp;
-
- /* This one is unconditional */
- sprintf(temp, "%d", BLENDER_VERSION);
- BLI_setenv("BLENDER_VERSION", temp);
-
- /* Is this unpack&run? */
- sprintf(temp, "%s/%d/environment", dirname(bprogname), BLENDER_VERSION);
- if(BLI_exist(temp)) {
- BLI_setenv_if_new("BLENDER_SHARE", dirname(bprogname));
- } else {
- BLI_setenv_if_new("BLENDER_SHARE", (const char*)GHOST_getSystemDir());
- }
-
- strcpy(file, (const char*)GHOST_getUserDir());
- BLI_add_slash(file);
- strcat(file, LAST_SESSION_FILE);
- fp = fopen(file, "r");
- /* 1st line, read previous version */
- if (fp && (fscanf(fp, "%3c\n", temp) == 1)) {
- temp[3] = '\0';
- BLI_setenv("BLENDER_VERSION_PREV", temp);
- /* 2nd line, read previous session path if needed */
- if(!getenv("BLENDER_TEMP")) {
- if ((fgets(temp, MAXPATHLEN, fp) != NULL)) {
- /* Clean any \n */
- chomp(temp);
- /* Check the dir is still there or generate new one */
- if(!BLI_exist(temp)) {
- setup_temp();
- }
- } else {
- /* We have to generate it for sure */
- setup_temp();
- }
- }
- } else {
- /* Probably new user, or only <=249 before */
- BLI_setenv("BLENDER_VERSION_PREV", "0");
- setup_temp();
- }
-
- if(fp) {
- fclose(fp);
- }
-
- /* Load vars from user and system files */
- strcpy(file, (const char *)GHOST_getUserDir());
- BLI_add_slash(file);
- strcat(file, ENVIRONMENT_FILE);
- init_vars_from_file(file);
- sprintf(temp, "/%d/environment", BLENDER_VERSION);
- BLI_make_file_string("/", file, getenv("BLENDER_SHARE"), temp);
- init_vars_from_file(file);
-}
-
-
/*** Internal functions ***/
/**
- Eliminate trailing EOL by writing a \0 over it.
- Name taken from Perl.
- */
-void chomp(char* line) {
- int len = strlen(line);
-#ifndef WIN32
- if (line[len - 1] == '\n') {
- line[len - 1] = '\0';
- }
-#else
- if ((line[len - 2] == '\r' ) && ((line[len - 1] == '\n'))) {
- line[len - 2] = '\0';
- }
-#endif /* WIN32 */
-}
-
-
-/**
- Parse a file with lines like FOO=bar (comment lines have # as first
- character) assigning to envvar FOO the value bar if FOO does not
- exist yet.
- Any white space before FOO, around the = or trailing will be used,
- so beware.
- */
-#define MAX_LINE 4096
-#define ENV_VAR 256
-#define VAR_LEN 8192
-void init_vars_from_file(const char* path) {
- char line[MAX_LINE];
- char name[ENV_VAR];
- FILE *fp;
- char* separator;
- char expanded[VAR_LEN];
-
- fp = fopen(path, "r");
- if (!fp) return;
-
- while (fgets(line, MAX_LINE, fp) != NULL) {
- /* Ignore comment lines */
- if (line[0] == '#')
- continue;
-
- /* Split into envvar name and contents */
- separator = strchr(line, '=');
- if(separator && ((separator - line) < ENV_VAR)) {
- /* First remove EOL */
- chomp(line);
- strncpy(name, line, separator - line);
- name[separator - line] = '\0';
- expand_envvars(separator + 1, expanded);
- BLI_setenv_if_new(name, expanded);
- }
- }
- fclose(fp);
-}
-
-
-/**
- Look for ${} (or %%) env vars in src and expand if the var
- exists (even if empty value). If not exist, the name is left as is.
- The process is done all over src, and nested ${${}} is not supported.
- src must be \0 terminated, and dst must be big enough.
-*/
-#ifndef WIN32
- #define ENVVAR_PREFFIX "${"
- #define ENVVAR_P_SIZE 2
- #define ENVVAR_SUFFIX "}"
- #define ENVVAR_S_SIZE 1
-#else
- #define ENVVAR_PREFFIX "%"
- #define ENVVAR_P_SIZE 1
- #define ENVVAR_SUFFIX "%"
- #define ENVVAR_S_SIZE 1
-#endif /* WIN32 */
-void expand_envvars(char* src, char* dst) {
- char* hit1;
- char* hit2;
- char name[ENV_VAR];
- char* value;
- int prevlen;
- int done = 0;
- char* source = src;
-
- dst[0] = '\0';
- while (!done) {
- hit1 = strstr(source, ENVVAR_PREFFIX);
- if (hit1) {
- hit2 = strstr(hit1 + ENVVAR_P_SIZE, ENVVAR_SUFFIX);
- if (hit2) {
- /* "Copy" the leading part, if any */
- if (hit1 != source) {
- prevlen = strlen(dst);
- strncat(dst, source, hit1 - source);
- dst[prevlen + (hit1 - source)] = '\0';
- }
- /* Figure the name of the env var we just found */
- strncpy(name, hit1 + ENVVAR_P_SIZE,
- hit2 - (hit1 + ENVVAR_P_SIZE));
- name[hit2 - (hit1 + ENVVAR_P_SIZE)] = '\0';
- /* See if we can get something with that name */
- value = getenv(name);
- if (value) {
- /* Push the var value */
- strcat(dst, value);
- } else {
- /* Leave the var name, so it is clear that it failed */
- strcat(dst, ENVVAR_PREFFIX);
- strcat(dst, name);
- strcat(dst, ENVVAR_SUFFIX);
- }
- /* Continue after closing mark, like a new string */
- source = hit2 + ENVVAR_S_SIZE;
- } else {
- /* Non terminated var so "copy as is" and finish */
- strcat(dst, source);
- done = 1;
- }
- } else {
- /* "Copy" whatever is left */
- strcat(dst, source);
- done = 1;
- }
- }
-}
-
-
-/**
Return a full path if the filename exists when combined
with any item from pathlist. Or NULL otherwise.
*/
@@ -427,7 +279,9 @@ void expand_envvars(char* src, char* dst) {
#else
#define SEPARATOR ':'
#endif
-char* find_in_pathlist(char* filename, char* pathlist) {
+
+#ifdef WIN32
+static char* find_in_pathlist(char* filename, char* pathlist) {
char first[FILE_MAX + 10];
char* rest = NULL;
@@ -445,51 +299,58 @@ char* find_in_pathlist(char* filename, char* pathlist) {
/* Check if combination exists */
BLI_add_slash(first);
strcat(first, filename);
- if(BLI_exist(first)) {
+ if (BLI_exist(first)) {
return strdup(first);
}
/* First path failed, try with rest of paths if possible */
- if(rest) {
+ if (rest) {
return find_in_pathlist(filename, rest);
} else {
return NULL;
}
}
-
+#endif
/**
Setup fpath and tpath based in the needs of the bfile.
*/
-void fill_paths(BFILE *bfile, const char *path) {
+static void fill_paths(BFILE *bfile, const char *path, const char *relpath) {
char* source_path = NULL;
char* temp_path = NULL;
int bflags = bfile->uflags;
- if(bflags & BFILE_NORMAL || bflags & BFILE_RAW) {
+ if (bflags & BFILE_NORMAL || bflags & BFILE_RAW) {
// bfile->fpath is path with // replaced
}
- if(bflags & BFILE_TEMP) {
+ if (bflags & BFILE_TEMP) {
temp_path = MEM_mallocN(MAXPATHLEN, "bfile-fpath-1");
snprintf(temp_path, MAXPATHLEN, "%s/%s", getenv("BLENDER_TEMP"), path);
bfile->fpath = temp_path;
}
- if(bflags & BFILE_CONFIG) {
+ if (bflags & (BFILE_CONFIG_BASE | BFILE_CONFIG_DATAFILES |
+ BFILE_CONFIG_PYTHON | BFILE_CONFIG_PLUGINS)) {
+// evars
// bfile->fpath is userdir+version+path
// source_path is first hit in (if using fallback to older versions)
// userdir+curversion+path (... userdir+limitversion+path) sysdir+path
// (limitversion is based in path, using some kind of regex or "tables")
}
- if(bfile->classf & BCF_WRITE && !(bflags & BFILE_RAW)) {
- /* Generate temp path */
+ if (bfile->classf & BCF_WRITE && !(bflags & BFILE_RAW)) {
+ /* Generate random named path */
temp_path = MEM_mallocN(MAXPATHLEN, "bfile-fpath-2");
snprintf(temp_path, MAXPATHLEN, "%s.XXXXXX", path);
- bfile->tpath = mkdtemp(temp_path);
- if(!(bfile->classf & BCF_DISCARD)) {
- /* Copy data to tpath */
- if(source_path) {
- // copy it from older version or sys version
+ bfile->fd = mkstemp(temp_path);
+ bfile->tpath = temp_path;
+ /* It will be reopened in upper levels, later */
+ close(bfile->fd);
+ if (!(bfile->classf & BCF_DISCARD)) {
+ /* Copy original data into temp location */
+ if (source_path) {
+ BLI_copy_fileops(source_path, bfile->tpath);
+ } else {
+ BLI_copy_fileops(bfile->fpath, bfile->tpath);
}
}
} else {
@@ -499,19 +360,13 @@ void fill_paths(BFILE *bfile, const char *path) {
/**
- Create a temp directory in safe and multiuser way.
+ Free memory used for path strings.
*/
-void setup_temp() {
- char template[MAXPATHLEN];
- char* tempdir;
-
- if(getenv("TMPDIR")) {
- sprintf(template, "%s/blender-XXXXXX", getenv("TMPDIR"));
- } else {
- sprintf(template, "/tmp/blender-XXXXXX");
-// MacOSX NSTemporaryDirectory and WIN32 ???
+static void free_paths(BFILE* bfile) {
+ if (bfile->fpath) {
+ MEM_freeN(bfile->fpath);
+ }
+ if (bfile->tpath) {
+ MEM_freeN(bfile->tpath);
}
- tempdir = mkdtemp(template);
- BLI_setenv("BLENDER_TEMP", tempdir);
}
-
diff --git a/source/blender/blenlib/intern/BLI_dynstr.c b/source/blender/blenlib/intern/BLI_dynstr.c
index 4b7b61e64d9..5b61a86305b 100644
--- a/source/blender/blenlib/intern/BLI_dynstr.c
+++ b/source/blender/blenlib/intern/BLI_dynstr.c
@@ -29,8 +29,6 @@
*/
#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
#include <string.h>
#include "MEM_guardedalloc.h"
diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c
index 6ef8d9e5f19..456872d6612 100644
--- a/source/blender/blenlib/intern/BLI_ghash.c
+++ b/source/blender/blenlib/intern/BLI_ghash.c
@@ -28,21 +28,10 @@
* A general (pointer -> pointer) hash table ADT
*/
-#include <stdlib.h>
-#include <string.h>
-#include "MEM_guardedalloc.h"
#include "BLI_ghash.h"
-#include "BLI_mempool.h"
-
#include "BLO_sys_types.h" // for intptr_t support
-#include "BKE_utildefines.h"
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
/***/
unsigned int hashsizes[]= {
@@ -56,8 +45,8 @@ unsigned int hashsizes[]= {
/***/
-GHash *BLI_ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp) {
- GHash *gh= MEM_mallocN(sizeof(*gh), "GHash");
+GHash *BLI_ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp, const char *info) {
+ GHash *gh= MEM_mallocN(sizeof(*gh), info);
gh->hashfp= hashfp;
gh->cmpfp= cmpfp;
gh->entrypool = BLI_mempool_create(sizeof(Entry), 64, 64, 1, 0);
@@ -145,7 +134,7 @@ void *BLI_ghashIterator_getValue(GHashIterator *ghi) {
void BLI_ghashIterator_step(GHashIterator *ghi) {
if (ghi->curEntry) {
- ghi->curEntry= ghi->curEntry->next;
+ ghi->curEntry= ghi->curEntry->next;
while (!ghi->curEntry) {
ghi->curBucket++;
if (ghi->curBucket==ghi->gh->nbuckets)
@@ -180,7 +169,7 @@ unsigned int BLI_ghashutil_inthash(void *ptr) {
key += ~(key << 9);
key ^= (key >> 17);
- return (unsigned int)(key & 0xffffffff);
+ return (unsigned int)(key & 0xffffffff);
}
int BLI_ghashutil_intcmp(void *a, void *b) {
diff --git a/source/blender/blenlib/intern/BLI_heap.c b/source/blender/blenlib/intern/BLI_heap.c
index 196c9ed284c..f6616ecb06b 100644
--- a/source/blender/blenlib/intern/BLI_heap.c
+++ b/source/blender/blenlib/intern/BLI_heap.c
@@ -28,7 +28,6 @@
* A heap / priority queue ADT.
*/
-#include <stdlib.h>
#include <string.h>
#include "MEM_guardedalloc.h"
@@ -70,7 +69,7 @@ Heap *BLI_heap_new()
Heap *heap = (Heap*)MEM_callocN(sizeof(Heap), "BLIHeap");
heap->bufsize = 1;
heap->tree = (HeapNode**)MEM_mallocN(sizeof(HeapNode*), "BLIHeapTree");
- heap->arena = BLI_memarena_new(1<<16);
+ heap->arena = BLI_memarena_new(1<<16, "heap arena");
return heap;
}
diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c
index 7118b804cad..4d64f4a50ff 100644
--- a/source/blender/blenlib/intern/BLI_kdopbvh.c
+++ b/source/blender/blenlib/intern/BLI_kdopbvh.c
@@ -26,10 +26,6 @@
* ***** END GPL LICENSE BLOCK *****
*/
-#include "math.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
#include <assert.h>
#include "MEM_guardedalloc.h"
@@ -1494,7 +1490,7 @@ static float fast_ray_nearest_hit(const BVHRayCastData *data, const BVHNode *nod
dist = t1x;
if (t1y > dist) dist = t1y;
- if (t1z > dist) dist = t1z;
+ if (t1z > dist) dist = t1z;
return dist;
}
@@ -1617,7 +1613,7 @@ int BLI_bvhtree_ray_cast(BVHTree *tree, const float *co, const float *dir, float
{
dfs_raycast(&data, root);
// iterative_raycast(&data, root);
- }
+ }
if(hit)
diff --git a/source/blender/blenlib/intern/BLI_kdtree.c b/source/blender/blenlib/intern/BLI_kdtree.c
index 38b4d7a54d2..cf94a0c9ffe 100644
--- a/source/blender/blenlib/intern/BLI_kdtree.c
+++ b/source/blender/blenlib/intern/BLI_kdtree.c
@@ -28,9 +28,6 @@
* ***** END GPL LICENSE BLOCK *****
*/
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
#include "MEM_guardedalloc.h"
diff --git a/source/blender/blenlib/intern/BLI_linklist.c b/source/blender/blenlib/intern/BLI_linklist.c
index 4631d9e6bf2..c903e66057e 100644
--- a/source/blender/blenlib/intern/BLI_linklist.c
+++ b/source/blender/blenlib/intern/BLI_linklist.c
@@ -29,14 +29,9 @@
*/
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
#include "BLI_linklist.h"
#include "BLI_memarena.h"
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
int BLI_linklist_length(LinkNode *list) {
if (0) {
return list?(1+BLI_linklist_length(list->next)):0;
@@ -50,18 +45,28 @@ int BLI_linklist_length(LinkNode *list) {
}
}
-int BLI_linklist_index(struct LinkNode *list, void *ptr)
+int BLI_linklist_index(LinkNode *list, void *ptr)
{
int index;
- for (index = 0; list; list= list->next, index++) {
+ for (index = 0; list; list= list->next, index++)
if (list->link == ptr)
return index;
- }
return -1;
}
+LinkNode *BLI_linklist_find(LinkNode *list, int index)
+{
+ int i;
+
+ for (i = 0; list; list= list->next, i++)
+ if (i == index)
+ return list;
+
+ return NULL;
+}
+
void BLI_linklist_reverse(LinkNode **listp) {
LinkNode *rhead= NULL, *cur= *listp;
@@ -93,13 +98,13 @@ void BLI_linklist_append(LinkNode **listp, void *ptr) {
nlink->next = NULL;
if(node == NULL){
- *listp = nlink;
- } else {
- while(node->next != NULL){
- node = node->next;
- }
- node->next = nlink;
- }
+ *listp = nlink;
+ } else {
+ while(node->next != NULL){
+ node = node->next;
+ }
+ node->next = nlink;
+ }
}
void BLI_linklist_prepend_arena(LinkNode **listp, void *ptr, MemArena *ma) {
@@ -110,6 +115,22 @@ void BLI_linklist_prepend_arena(LinkNode **listp, void *ptr, MemArena *ma) {
*listp= nlink;
}
+void BLI_linklist_insert_after(LinkNode **listp, void *ptr) {
+ LinkNode *nlink= MEM_mallocN(sizeof(*nlink), "nlink");
+ 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;
diff --git a/source/blender/blenlib/intern/BLI_memarena.c b/source/blender/blenlib/intern/BLI_memarena.c
index 6c87f0914f9..de2a73e065f 100644
--- a/source/blender/blenlib/intern/BLI_memarena.c
+++ b/source/blender/blenlib/intern/BLI_memarena.c
@@ -28,21 +28,16 @@
* Efficient memory allocation for lots of similar small chunks.
*/
-#include <stdlib.h>
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
#include "BLI_memarena.h"
#include "BLI_linklist.h"
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
struct MemArena {
unsigned char *curbuf;
int bufsize, cursize;
+ const char *name;
int use_calloc;
int align;
@@ -50,10 +45,11 @@ struct MemArena {
LinkNode *bufs;
};
-MemArena *BLI_memarena_new(int bufsize) {
+MemArena *BLI_memarena_new(int bufsize, const char *name) {
MemArena *ma= MEM_callocN(sizeof(*ma), "memarena");
ma->bufsize= bufsize;
ma->align = 8;
+ ma->name= name;
return ma;
}
@@ -96,9 +92,9 @@ void *BLI_memarena_alloc(MemArena *ma, int size) {
else ma->cursize = ma->bufsize;
if(ma->use_calloc)
- ma->curbuf= MEM_callocN(ma->cursize, "memarena calloc");
+ ma->curbuf= MEM_callocN(ma->cursize, ma->name);
else
- ma->curbuf= MEM_mallocN(ma->cursize, "memarena malloc");
+ ma->curbuf= MEM_mallocN(ma->cursize, ma->name);
BLI_linklist_prepend(&ma->bufs, ma->curbuf);
diff --git a/source/blender/blenlib/intern/boxpack2d.c b/source/blender/blenlib/intern/boxpack2d.c
index eebffd6bd6e..1c910dbb519 100644
--- a/source/blender/blenlib/intern/boxpack2d.c
+++ b/source/blender/blenlib/intern/boxpack2d.c
@@ -240,17 +240,17 @@ void boxPack2D(boxPack *boxarray, int len, float *tot_width, float *tot_height)
if (vert->free & quad_flags[j]) {
switch (j) {
case BL:
- SET_BOXRIGHT(box, vert->x);
- SET_BOXTOP(box, vert->y);
- break;
+ SET_BOXRIGHT(box, vert->x);
+ SET_BOXTOP(box, vert->y);
+ break;
case TR:
- SET_BOXLEFT(box, vert->x);
- SET_BOXBOTTOM(box, vert->y);
- break;
+ SET_BOXLEFT(box, vert->x);
+ SET_BOXBOTTOM(box, vert->y);
+ break;
case TL:
- SET_BOXRIGHT(box, vert->x);
- SET_BOXBOTTOM(box, vert->y);
- break;
+ SET_BOXRIGHT(box, vert->x);
+ SET_BOXBOTTOM(box, vert->y);
+ break;
case BR:
SET_BOXLEFT(box, vert->x);
SET_BOXTOP(box, vert->y);
@@ -302,11 +302,11 @@ void boxPack2D(boxPack *boxarray, int len, float *tot_width, float *tot_height)
case TR:
box->v[BL]= vert;
vert->trb = box;
- break;
+ break;
case TL:
box->v[BR]= vert;
vert->tlb = box;
- break;
+ break;
case BR:
box->v[TL]= vert;
vert->brb = box;
@@ -314,7 +314,7 @@ void boxPack2D(boxPack *boxarray, int len, float *tot_width, float *tot_height)
case BL:
box->v[TR]= vert;
vert->blb = box;
- break;
+ break;
}
/* Mask free flags for verts that are
diff --git a/source/blender/blenlib/intern/bpath.c b/source/blender/blenlib/intern/bpath.c
index 8d3d807ba1b..fbe71019379 100644
--- a/source/blender/blenlib/intern/bpath.c
+++ b/source/blender/blenlib/intern/bpath.c
@@ -27,12 +27,7 @@
*/
#include <sys/stat.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
#include <string.h>
/* path/file handeling stuff */
@@ -46,13 +41,9 @@
#include "MEM_guardedalloc.h"
-#include "DNA_ID.h" /* Library */
-#include "DNA_customdata_types.h"
-#include "DNA_image_types.h"
#include "DNA_mesh_types.h"
#include "DNA_scene_types.h" /* to get the current frame */
#include "DNA_sequence_types.h"
-#include "DNA_sound_types.h"
#include "DNA_vfont_types.h"
#include "DNA_windowmanager_types.h"
@@ -71,9 +62,6 @@
/* for sequence */
//XXX #include "BSE_sequence.h"
//XXX define below from BSE_sequence.h - otherwise potentially odd behaviour
-#define SEQ_HAS_PATH(seq) (seq->type==SEQ_MOVIE || seq->type==SEQ_IMAGE)
-
-
#define FILE_MAX 240
@@ -86,7 +74,7 @@ enum BPathTypes {
BPATH_SEQ,
BPATH_CDATA,
- BPATH_DONE
+ BPATH_DONE
};
void BLI_bpathIterator_init( struct BPathIterator *bpi, char *base_path ) {
@@ -137,10 +125,11 @@ void BLI_bpathIterator_getPathExpanded( struct BPathIterator *bpi, char *path_ex
libpath = BLI_bpathIterator_getLib(bpi);
if (libpath) { /* check the files location relative to its library path */
- BLI_convertstringcode(path_expanded, libpath);
+ BLI_path_abs(path_expanded, libpath);
} else { /* local data, use the blend files path */
- BLI_convertstringcode(path_expanded, bpi->base_path);
+ BLI_path_abs(path_expanded, bpi->base_path);
}
+ BLI_cleanup_file(NULL, path_expanded);
}
char* BLI_bpathIterator_getLib( struct BPathIterator *bpi) {
return bpi->lib;
@@ -270,7 +259,7 @@ static void seq_getpath(struct BPathIterator *bpi, char *path) {
path[0] = '\0'; /* incase we cant get the path */
if (seq==NULL) return;
if (SEQ_HAS_PATH(seq)) {
- if (seq->type == SEQ_IMAGE || seq->type == SEQ_MOVIE) {
+ if (ELEM3(seq->type, SEQ_IMAGE, SEQ_MOVIE, SEQ_SOUND)) {
BLI_strncpy(path, seq->strip->dir, FILE_MAX);
BLI_add_slash(path); /* incase its missing */
if (seq->strip->stripdata) { /* should always be true! */
@@ -289,8 +278,8 @@ static void seq_setpath(struct BPathIterator *bpi, char *path) {
if (seq==NULL) return;
if (SEQ_HAS_PATH(seq)) {
- if (seq->type == SEQ_IMAGE || seq->type == SEQ_MOVIE) {
- BLI_split_dirfile_basic(path, seq->strip->dir, seq->strip->stripdata->name);
+ if (ELEM3(seq->type, SEQ_IMAGE, SEQ_MOVIE, SEQ_SOUND)) {
+ BLI_split_dirfile(path, seq->strip->dir, seq->strip->stripdata->name);
} else {
/* simple case */
BLI_strncpy(seq->strip->dir, path, sizeof(seq->strip->dir));
@@ -343,7 +332,7 @@ void BLI_bpathIterator_step( struct BPathIterator *bpi) {
/* get the path info from this datatype */
Image *ima = (Image *)bpi->data;
- bpi->lib = ima->id.lib ? ima->id.lib->filename : NULL;
+ bpi->lib = ima->id.lib ? ima->id.lib->filepath : NULL;
bpi->path = ima->name;
bpi->name = ima->id.name+2;
bpi->len = sizeof(ima->name);
@@ -364,7 +353,7 @@ void BLI_bpathIterator_step( struct BPathIterator *bpi) {
/* get the path info from this datatype */
bSound *snd = (bSound *)bpi->data;
- bpi->lib = snd->id.lib ? snd->id.lib->filename : NULL;
+ bpi->lib = snd->id.lib ? snd->id.lib->filepath : NULL;
bpi->path = snd->name;
bpi->name = snd->id.name+2;
bpi->len = sizeof(snd->name);
@@ -385,7 +374,7 @@ void BLI_bpathIterator_step( struct BPathIterator *bpi) {
/* get the path info from this datatype */
VFont *vf = (VFont *)bpi->data;
- bpi->lib = vf->id.lib ? vf->id.lib->filename : NULL;
+ bpi->lib = vf->id.lib ? vf->id.lib->filepath : NULL;
bpi->path = vf->name;
bpi->name = vf->id.name+2;
bpi->len = sizeof(vf->name);
@@ -432,7 +421,7 @@ void BLI_bpathIterator_step( struct BPathIterator *bpi) {
if (bpi->data) {
Mesh *me = (Mesh *)bpi->data;
- bpi->lib = me->id.lib ? me->id.lib->filename : NULL;
+ bpi->lib = me->id.lib ? me->id.lib->filepath : NULL;
bpi->path = me->fdata.external->filename;
bpi->name = me->id.name+2;
bpi->len = sizeof(me->fdata.external->filename);
@@ -533,7 +522,7 @@ void makeFilesRelative(char *basepath, ReportList *reports) {
/* Important BLI_cleanup_dir runs before the path is made relative
* because it wont work for paths that start with "//../" */
BLI_cleanup_file(bpi.base_path, filepath_relative); /* fix any /foo/../foo/ */
- BLI_makestringcode(bpi.base_path, filepath_relative);
+ BLI_path_rel(filepath_relative, bpi.base_path);
/* be safe and check the length */
if (BLI_bpathIterator_getPathMaxLen(&bpi) <= strlen(filepath_relative)) {
bpath_as_report(&bpi, "couldn't make path relative (too long)", reports);
@@ -631,7 +620,7 @@ static int findFileRecursive(char *filename_new, const char *dirname, const char
while ((de = readdir(dir)) != NULL) {
- if (strncmp(".", de->d_name, 2)==0 || strncmp("..", de->d_name, 3)==0)
+ if (strcmp(".", de->d_name)==0 || strcmp("..", de->d_name)==0)
continue;
BLI_join_dirfile(path, dirname, de->d_name);
@@ -669,11 +658,11 @@ void findMissingFiles(char *basepath, char *str) {
char filepath[FILE_MAX], *libpath;
int filesize, recur_depth;
- char dirname[FILE_MAX], filename[FILE_MAX], filename_new[FILE_MAX];
+ char dirname[FILE_MAX], filename_new[FILE_MAX];
//XXX waitcursor( 1 );
- BLI_split_dirfile_basic(str, dirname, NULL);
+ BLI_split_dirfile(str, dirname, NULL);
BLI_bpathIterator_init(&bpi, basepath);
@@ -694,9 +683,8 @@ void findMissingFiles(char *basepath, char *str) {
/* can the dir be opened? */
filesize = -1;
recur_depth = 0;
- BLI_split_dirfile_basic(filepath, NULL, filename); /* the file to find */
- findFileRecursive(filename_new, dirname, filename, &filesize, &recur_depth);
+ findFileRecursive(filename_new, dirname, BLI_path_basename(filepath), &filesize, &recur_depth);
if (filesize == -1) { /* could not open dir */
printf("Could not open dir \"%s\"\n", dirname);
return;
@@ -709,7 +697,7 @@ void findMissingFiles(char *basepath, char *str) {
} else {
/* copy the found path into the old one */
if (G.relbase_valid)
- BLI_makestringcode(bpi.base_path, filename_new);
+ BLI_path_rel(filename_new, bpi.base_path);
BLI_bpathIterator_setPath( &bpi, filename_new );
}
diff --git a/source/blender/blenlib/intern/cpu.c b/source/blender/blenlib/intern/cpu.c
new file mode 100644
index 00000000000..65e6b34488c
--- /dev/null
+++ b/source/blender/blenlib/intern/cpu.c
@@ -0,0 +1,57 @@
+/**
+ *
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "BLI_cpu.h"
+
+int BLI_cpu_support_sse2(void)
+{
+#if defined(__x86_64__) || defined(_M_X64)
+ /* 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;
+#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;
+#endif
+
+ return 0;
+}
+
diff --git a/source/blender/blenlib/intern/dynamiclist.c b/source/blender/blenlib/intern/dynamiclist.c
deleted file mode 100644
index 4bcccab4b18..00000000000
--- a/source/blender/blenlib/intern/dynamiclist.c
+++ /dev/null
@@ -1,265 +0,0 @@
-/* util.c
- *
- * various string, file, list operations.
- *
- *
- * $Id$
- *
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- *
- */
-
-#include "MEM_guardedalloc.h"
-
-#include "DNA_listBase.h"
-
-#include "BLI_listbase.h"
-#include "BLI_dynamiclist.h"
-
-#define PAGE_SIZE 4
-
-/*=====================================================================================*/
-/* Methods for access array (realloc) */
-/*=====================================================================================*/
-
-/* remove item with index */
-static void rem_array_item(struct DynamicArray *da, unsigned int index)
-{
- da->items[index]=NULL;
- da->count--;
- if(index==da->last_item_index){
- while((!da->items[da->last_item_index]) && (da->last_item_index>0)){
- da->last_item_index--;
- }
- }
-}
-
-/* add array (if needed, then realloc) */
-static void add_array_item(struct DynamicArray *da, void *item, unsigned int index)
-{
- /* realloc of access array */
- if(da->max_item_index < index){
- unsigned int i, max = da->max_item_index;
- void **nitems;
-
- do {
- da->max_item_index += PAGE_SIZE; /* OS can allocate only PAGE_SIZE Bytes */
- } while(da->max_item_index<=index);
-
- nitems = (void**)MEM_mallocN(sizeof(void*)*(da->max_item_index+1), "dlist access array");
- for(i=0;i<=max;i++)
- nitems[i] = da->items[i];
-
- /* set rest pointers to the NULL */
- for(i=max+1; i<=da->max_item_index; i++)
- nitems[i]=NULL;
-
- MEM_freeN(da->items); /* free old access array */
- da->items = nitems;
- }
-
- da->items[index] = item;
- da->count++;
- if(index > da->last_item_index) da->last_item_index = index;
-}
-
-/* free access array */
-static void destroy_array(DynamicArray *da)
-{
- da->count=0;
- da->last_item_index=0;
- da->max_item_index=0;
- MEM_freeN(da->items);
- da->items = NULL;
-}
-
-/* initialize dynamic array */
-static void init_array(DynamicArray *da)
-{
- unsigned int i;
-
- da->count=0;
- da->last_item_index=0;
- da->max_item_index = PAGE_SIZE-1;
- da->items = (void*)MEM_mallocN(sizeof(void*)*(da->max_item_index+1), "dlist access array");
- for(i=0; i<=da->max_item_index; i++) da->items[i]=NULL;
-}
-
-/* reinitialize dynamic array */
-static void reinit_array(DynamicArray *da)
-{
- destroy_array(da);
- init_array(da);
-}
-
-/*=====================================================================================*/
-/* Methods for two way dynamic list with access array */
-/*=====================================================================================*/
-
-/* create new two way dynamic list with access array from two way dynamic list
- * it doesn't copy any items to new array or something like this It is strongly
- * recomended to use BLI_dlist_ methods for adding/removing items from dynamic list
- * unless you can end with inconsistence system !!! */
-DynamicList *BLI_dlist_from_listbase(ListBase *lb)
-{
- DynamicList *dlist;
- Link *item;
- int i=0, count;
-
- if(!lb) return NULL;
-
- count = BLI_countlist(lb);
-
- dlist = MEM_mallocN(sizeof(DynamicList), "temp dynamic list");
- /* ListBase stuff */
- dlist->lb.first = lb->first;
- dlist->lb.last = lb->last;
- /* access array stuff */
- dlist->da.count=count;
- dlist->da.max_item_index = count-1;
- dlist->da.last_item_index = count -1;
- dlist->da.items = (void*)MEM_mallocN(sizeof(void*)*count, "temp dlist access array");
-
- item = (Link*)lb->first;
- while(item){
- dlist->da.items[i] = (void*)item;
- item = item->next;
- i++;
- }
-
- /* to prevent you of using original ListBase :-) */
- lb->first = lb->last = NULL;
-
- return dlist;
-}
-
-/* take out ListBase from DynamicList and destroy all temporary structures of DynamicList */
-ListBase *BLI_listbase_from_dlist(DynamicList *dlist, ListBase *lb)
-{
- if(!dlist) return NULL;
-
- if(!lb) lb = (ListBase*)MEM_mallocN(sizeof(ListBase), "ListBase");
-
- lb->first = dlist->lb.first;
- lb->last = dlist->lb.last;
-
- /* free all items of access array */
- MEM_freeN(dlist->da.items);
- /* free DynamicList*/
- MEM_freeN(dlist);
-
- return lb;
-}
-
-/* return pointer at item from th dynamic list with access array */
-void *BLI_dlist_find_link(DynamicList *dlist, unsigned int index)
-{
- if(!dlist || !dlist->da.items) return NULL;
-
- if((index <= dlist->da.last_item_index) && (index >= 0) && (dlist->da.count>0)){
- return dlist->da.items[index];
- }
- else {
- return NULL;
- }
-}
-
-/* return count of items in the dynamic list with access array */
-unsigned int BLI_count_items(DynamicList *dlist)
-{
- if(!dlist) return 0;
-
- return dlist->da.count;
-}
-
-/* free item from the dynamic list with access array */
-void BLI_dlist_free_item(DynamicList *dlist, unsigned int index)
-{
- if(!dlist || !dlist->da.items) return;
-
- if((index <= dlist->da.last_item_index) && (dlist->da.items[index])){
- BLI_freelinkN(&(dlist->lb), dlist->da.items[index]);
- rem_array_item(&(dlist->da), index);
- }
-}
-
-/* remove item from the dynamic list with access array */
-void BLI_dlist_rem_item(DynamicList *dlist, unsigned int index)
-{
- if(!dlist || !dlist->da.items) return;
-
- if((index <= dlist->da.last_item_index) && (dlist->da.items[index])){
- BLI_remlink(&(dlist->lb), dlist->da.items[index]);
- rem_array_item(&(dlist->da), index);
- }
-}
-
-/* add item to the dynamic list with access array (index) */
-void* BLI_dlist_add_item_index(DynamicList *dlist, void *item, unsigned int index)
-{
- if(!dlist || !dlist->da.items) return NULL;
-
- if((index <= dlist->da.max_item_index) && (dlist->da.items[index])) {
- /* you can't place item at used index */
- return NULL;
- }
- else {
- add_array_item(&(dlist->da), item, index);
- BLI_addtail(&(dlist->lb), item);
- return item;
- }
-}
-
-/* destroy dynamic list with access array */
-void BLI_dlist_destroy(DynamicList *dlist)
-{
- if(!dlist) return;
-
- BLI_freelistN(&(dlist->lb));
- destroy_array(&(dlist->da));
-}
-
-/* initialize dynamic list with access array */
-void BLI_dlist_init(DynamicList *dlist)
-{
- if(!dlist) return;
-
- dlist->lb.first = NULL;
- dlist->lb.last = NULL;
-
- init_array(&(dlist->da));
-}
-
-/* reinitialize dynamic list with acces array */
-void BLI_dlist_reinit(DynamicList *dlist)
-{
- if(!dlist) return;
-
- BLI_freelistN(&(dlist->lb));
- reinit_array(&(dlist->da));
-}
-
-/*=====================================================================================*/
diff --git a/source/blender/blenlib/intern/dynlib.c b/source/blender/blenlib/intern/dynlib.c
index eb41916c619..f42b342e326 100644
--- a/source/blender/blenlib/intern/dynlib.c
+++ b/source/blender/blenlib/intern/dynlib.c
@@ -28,15 +28,9 @@
*/
#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
#include "../PIL_dynlib.h"
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
#if !defined(CHAR_MAX)
#define CHAR_MAX 255
#endif
@@ -47,6 +41,8 @@
*/
#ifdef WIN32
+#include <string.h>
+#include <stdio.h>
#include <windows.h>
diff --git a/source/blender/blenlib/intern/edgehash.c b/source/blender/blenlib/intern/edgehash.c
index 1f70a34329f..44abd13c3fd 100644
--- a/source/blender/blenlib/intern/edgehash.c
+++ b/source/blender/blenlib/intern/edgehash.c
@@ -125,7 +125,7 @@ void BLI_edgehashIterator_setValue(EdgeHashIterator *ehi, void *val) {
void BLI_edgehashIterator_step(EdgeHashIterator *ehi) {
if (ehi->curEntry) {
- ehi->curEntry= ehi->curEntry->next;
+ ehi->curEntry= ehi->curEntry->next;
while (!ehi->curEntry) {
ehi->curBucket++;
if (ehi->curBucket==ehi->eh->nbuckets)
diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c
index 3503164ea56..7a24d9b36b1 100644
--- a/source/blender/blenlib/intern/fileops.c
+++ b/source/blender/blenlib/intern/fileops.c
@@ -29,7 +29,6 @@
#include <string.h>
#include <stdio.h>
-#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -49,9 +48,6 @@
#include "BLI_blenlib.h"
-#include "BLI_storage.h"
-#include "BLI_fileops.h"
-#include "BLI_callbacks.h"
#include "BKE_utildefines.h"
@@ -84,31 +80,6 @@ char *BLI_last_slash(const char *string) {
else return lfslash;
}
-static const char *last_slash_len(const char *string, int len) {
- int a;
-
- for(a=len-1; a>=0; a--)
- if(string[a] == '/' || string[a] == '\\')
- return &string[a];
-
- return NULL;
-}
-
-const char *BLI_short_filename(const char *string) {
- const char *ls, *lls;
-
- ls= last_slash_len(string, strlen(string));
- if(!ls)
- return string;
-
- lls= last_slash_len(string, ls-string);
-
- if(lls)
- return lls+1;
- else
- return ls+1;
-}
-
/* adds a slash if there isnt one there alredy */
int BLI_add_slash(char *string) {
int len = strlen(string);
@@ -234,6 +205,10 @@ int BLI_touch(const char *file)
return 0;
}
+int BLI_exists(char *file) {
+ return BLI_exist(file);
+}
+
#ifdef WIN32
static char str[MAXPATHLEN+12];
@@ -311,10 +286,6 @@ int BLI_link(char *file, char *to) {
return 1;
}
-int BLI_exists(char *file) {
- return (GetFileAttributes(file) != 0xFFFFFFFF);
-}
-
void BLI_recurdir_fileops(char *dirname) {
char *lslash;
char tmp[MAXPATHLEN];
@@ -355,10 +326,10 @@ int BLI_rename(char *from, char *to) {
return rename(from, to);
}
-#else /* The sane UNIX world */
+#else /* The weirdo UNIX world */
/*
- * but the sane UNIX world is tied to the interface, and the system
+ * but the UNIX world is tied to the interface, and the system
* timer, and... We implement a callback mechanism. The system will
* have to initialise the callback before the functions will work!
* */
@@ -403,10 +374,6 @@ int BLI_link(char *file, char *to) {
return system(str);
}
-int BLI_exists(char *file) {
- return BLI_exist(file);
-}
-
void BLI_recurdir_fileops(char *dirname) {
char *lslash;
char tmp[MAXPATHLEN];
diff --git a/source/blender/blenlib/intern/fnmatch.c b/source/blender/blenlib/intern/fnmatch.c
index ccb6fa72ea8..c44ee754110 100644
--- a/source/blender/blenlib/intern/fnmatch.c
+++ b/source/blender/blenlib/intern/fnmatch.c
@@ -16,10 +16,6 @@
#ifdef WIN32
-#if HAVE_CONFIG_H
-# include <config.h>
-#endif
-
/* Enable GNU extensions in fnmatch.h. */
#ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
@@ -66,97 +62,97 @@ 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);
+ {
+ c = FOLD (c);
- switch (c)
+ switch (c)
{
case '?':
if (*n == '\0')
- return FNM_NOMATCH;
+ return FNM_NOMATCH;
else if ((flags & FNM_FILE_NAME) && *n == '/')
- return FNM_NOMATCH;
+ return FNM_NOMATCH;
else if ((flags & FNM_PERIOD) && *n == '.' &&
(n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
- return FNM_NOMATCH;
+ return FNM_NOMATCH;
break;
case '\\':
if (!(flags & FNM_NOESCAPE))
- {
- c = *p++;
- if (c == '\0')
+ {
+ c = *p++;
+ if (c == '\0')
/* Trailing \ loses. */
return FNM_NOMATCH;
- c = FOLD (c);
- }
+ c = FOLD (c);
+ }
if (FOLD (*n) != c)
- return FNM_NOMATCH;
+ return FNM_NOMATCH;
break;
case '*':
if ((flags & FNM_PERIOD) && *n == '.' &&
- (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
- return FNM_NOMATCH;
+ (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+ return FNM_NOMATCH;
for (c = *p++; c == '?' || c == '*'; c = *p++)
- {
- if ((flags & FNM_FILE_NAME) && *n == '/')
+ {
+ if ((flags & FNM_FILE_NAME) && *n == '/')
/* A slash does not match a wildcard under FNM_FILE_NAME. */
return FNM_NOMATCH;
- else if (c == '?')
+ else if (c == '?')
{
/* A ? needs to match one character. */
if (*n == '\0')
- /* There isn't another character; no match. */
- return FNM_NOMATCH;
+ /* 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;
+ /* 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;
+ return 0;
{
- char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
- c1 = FOLD (c1);
- for (--p; *n != '\0'; ++n)
- if ((c == '[' || FOLD (*n) == c1) &&
+ 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;
+ return FNM_NOMATCH;
}
case '[':
{
- /* Nonzero if the sense of the character class is inverted. */
- register int not;
+ /* Nonzero if the sense of the character class is inverted. */
+ register int not;
- if (*n == '\0')
- return FNM_NOMATCH;
+ if (*n == '\0')
+ return FNM_NOMATCH;
- if ((flags & FNM_PERIOD) && *n == '.' &&
+ if ((flags & FNM_PERIOD) && *n == '.' &&
(n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
- return FNM_NOMATCH;
+ return FNM_NOMATCH;
- not = (*p == '!' || *p == '^');
- if (not)
- ++p;
+ not = (*p == '!' || *p == '^');
+ if (not)
+ ++p;
- c = *p++;
- for (;;)
- {
+ c = *p++;
+ for (;;)
+ {
register char cstart = c, cend = c;
if (!(flags & FNM_NOESCAPE) && c == '\\')
{
- if (*p == '\0')
- return FNM_NOMATCH;
- cstart = cend = *p++;
+ if (*p == '\0')
+ return FNM_NOMATCH;
+ cstart = cend = *p++;
}
cstart = cend = FOLD (cstart);
@@ -174,14 +170,14 @@ fnmatch (const char *pattern, const char *string, int flags)
if (c == '-' && *p != ']')
{
- cend = *p++;
- if (!(flags & FNM_NOESCAPE) && cend == '\\')
- cend = *p++;
- if (cend == '\0')
- return FNM_NOMATCH;
- cend = FOLD (cend);
-
- 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)
@@ -189,15 +185,15 @@ fnmatch (const char *pattern, const char *string, int flags)
if (c == ']')
break;
- }
- if (!not)
- return FNM_NOMATCH;
- break;
+ }
+ if (!not)
+ return FNM_NOMATCH;
+ break;
matched:;
- /* Skip the rest of the [...] that already matched. */
- while (c != ']')
- {
+ /* Skip the rest of the [...] that already matched. */
+ while (c != ']')
+ {
if (c == '\0')
/* [... (unterminated) loses. */
return FNM_NOMATCH;
@@ -205,31 +201,31 @@ fnmatch (const char *pattern, const char *string, int flags)
c = *p++;
if (!(flags & FNM_NOESCAPE) && c == '\\')
{
- if (*p == '\0')
- return FNM_NOMATCH;
- /* XXX 1003.2d11 is unclear if this is right. */
- ++p;
+ if (*p == '\0')
+ return FNM_NOMATCH;
+ /* XXX 1003.2d11 is unclear if this is right. */
+ ++p;
+ }
}
- }
- if (not)
- return FNM_NOMATCH;
+ if (not)
+ return FNM_NOMATCH;
}
break;
default:
if (c != FOLD (*n))
- return FNM_NOMATCH;
+ return FNM_NOMATCH;
}
- ++n;
- }
+ ++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 b08631b9317..6d6abc88999 100644
--- a/source/blender/blenlib/intern/freetypefont.c
+++ b/source/blender/blenlib/intern/freetypefont.c
@@ -36,10 +36,11 @@
#include <ft2build.h>
#include FT_FREETYPE_H
-#include FT_GLYPH_H
-#include FT_BBOX_H
-#include FT_SIZES_H
-#include <freetype/ttnameid.h>
+/* not needed yet */
+// #include FT_GLYPH_H
+// #include FT_BBOX_H
+// #include FT_SIZES_H
+// #include <freetype/ttnameid.h>
#include "MEM_guardedalloc.h"
@@ -49,7 +50,6 @@
//XXX #include "BIF_toolbox.h"
-#include "BKE_global.h"
#include "BKE_font.h"
#include "BKE_utildefines.h"
@@ -150,7 +150,7 @@ static void freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData *vf
nu->pntsu = onpoints[j];
nu->resolu= 8;
nu->flag= CU_2D;
- nu->flagu= CU_CYCLIC;
+ nu->flagu= CU_NURB_CYCLIC;
nu->bezt = bezt;
//individual curve loop, start-end
@@ -429,7 +429,7 @@ static int check_freetypefont(PackedFile * pf)
&face );
if(err) {
success = 0;
- //XXX error("This is not a valid font");
+ //XXX error("This is not a valid font");
}
else {
/*
@@ -522,14 +522,14 @@ int BLI_vfontchar_from_freetypefont(VFont *vfont, unsigned long character)
typedef struct FT_Outline_
{
- short n_contours; /* number of contours in glyph */
- short n_points; /* number of points in the glyph */
+ short n_contours; /* number of contours in glyph */
+ short n_points; /* number of points in the glyph */
- FT_Vector* points; /* the outline's points */
- char* tags; /* the points flags */
- short* contours; /* the contour end points */
+ FT_Vector* points; /* the outline's points */
+ char* tags; /* the points flags */
+ short* contours; /* the contour end points */
- int flags; /* outline masks */
+ int flags; /* outline masks */
} FT_Outline;
@@ -569,44 +569,44 @@ The following rules are applied to decompose the contour's points into segments
Note that it is possible to mix conic and cubic arcs in a single contour, even though no current
font driver produces such outlines.
- * # on
- * off
- __---__
+ * # on
+ * off
+ __---__
#-__ _-- -_
- --__ _- -
- --__ # \
- --__ #
- -#
- Two "on" points
+ --__ _- -
+ --__ # \
+ --__ #
+ -#
+ Two "on" points
Two "on" points and one "conic" point
- between them
+ between them
- *
+ *
# __ Two "on" points with two "conic"
\ - - points between them. The point
- \ / \ marked '0' is the middle of the
- - 0 \ "off" points, and is a 'virtual'
- -_ _- # "on" point where the curve passes.
- -- It does not appear in the point
- list.
- *
+ \ / \ marked '0' is the middle of the
+ - 0 \ "off" points, and is a 'virtual'
+ -_ _- # "on" point where the curve passes.
+ -- It does not appear in the point
+ list.
+ *
- * # on
- * * off
- __---__
- _-- -_
- _- -
+ * # on
+ * * off
+ __---__
+ _-- -_
+ _- -
# \
- #
+ #
- Two "on" points
+ Two "on" points
and two "cubic" point
- between them
+ between them
Each glyph's original outline points are located on a grid of indivisible units. The points are stored
diff --git a/source/blender/blenlib/intern/graph.c b/source/blender/blenlib/intern/graph.c
index dd708b27019..b1ea058eda1 100644
--- a/source/blender/blenlib/intern/graph.c
+++ b/source/blender/blenlib/intern/graph.c
@@ -1,5 +1,5 @@
/**
- * $Id:
+ * $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
@@ -529,7 +529,7 @@ void BLI_mirrorAlongAxis(float v[3], float center[3], float axis[3])
sub_v3_v3v3(dv, v, center);
project_v3_v3v3(pv, dv, axis);
mul_v3_fl(pv, -2);
- add_v3_v3v3(v, v, pv);
+ add_v3_v3(v, pv);
}
static void testRadialSymmetry(BGraph *graph, BNode* root_node, RadialArc* ring, int total, float axis[3], float limit, int group)
@@ -801,7 +801,7 @@ static void testAxialSymmetry(BGraph *graph, BNode* root_node, BNode* node1, BNo
sub_v3_v3v3(p, root_node->p, node2->p);
cross_v3_v3v3(vec, p, axis);
- add_v3_v3v3(vec, vec, nor);
+ add_v3_v3(vec, nor);
cross_v3_v3v3(nor, vec, axis);
@@ -905,7 +905,7 @@ static void markdownSecondarySymmetry(BGraph *graph, BNode *node, int depth, int
/* If arc is on the axis */
else if (connectedArc->symmetry_level == level)
{
- add_v3_v3v3(axis, axis, connectedArc->head->p);
+ add_v3_v3(axis, connectedArc->head->p);
sub_v3_v3v3(axis, axis, connectedArc->tail->p);
}
}
diff --git a/source/blender/blenlib/intern/gsqueue.c b/source/blender/blenlib/intern/gsqueue.c
index fbc1708c133..a8b40e187d8 100644
--- a/source/blender/blenlib/intern/gsqueue.c
+++ b/source/blender/blenlib/intern/gsqueue.c
@@ -31,10 +31,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_gsqueue.h"
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
typedef struct _GSQueueElem GSQueueElem;
struct _GSQueueElem {
GSQueueElem *next;
diff --git a/source/blender/blenlib/intern/jitter.c b/source/blender/blenlib/intern/jitter.c
index 12b7482897a..dfc554394d6 100644
--- a/source/blender/blenlib/intern/jitter.c
+++ b/source/blender/blenlib/intern/jitter.c
@@ -30,13 +30,10 @@
*/
#include <math.h>
-#include <stdlib.h>
#include <string.h>
#include "MEM_guardedalloc.h"
-#include "BLI_math.h"
#include "BLI_rand.h"
-#include "BLI_jitter.h"
void BLI_jitterate1(float *jit1, float *jit2, int num, float rad1)
diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c
index 5d046dce023..0a6831558d1 100644
--- a/source/blender/blenlib/intern/listbase.c
+++ b/source/blender/blenlib/intern/listbase.c
@@ -108,6 +108,17 @@ void BLI_remlink(ListBase *listbase, void *vlink)
if (listbase->first == link) listbase->first = link->next;
}
+int BLI_remlink_safe(ListBase *listbase, void *vlink)
+{
+ if(BLI_findindex(listbase, vlink) != -1) {
+ BLI_remlink(listbase, vlink);
+ return 1;
+ }
+ else {
+ return 0;
+ }
+}
+
void BLI_freelinkN(ListBase *listbase, void *vlink)
{
diff --git a/source/blender/blenlib/intern/math_base.c b/source/blender/blenlib/intern/math_base.c
index a0d878f3a03..686b35a878e 100644
--- a/source/blender/blenlib/intern/math_base.c
+++ b/source/blender/blenlib/intern/math_base.c
@@ -25,10 +25,6 @@
* ***** END GPL LICENSE BLOCK *****
* */
-#include <float.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
#include "BLI_math.h"
@@ -49,12 +45,12 @@ double copysign(double x, double y)
/* from python 3.1 pymath.c */
double round(double x)
{
- double absx, y;
- absx = fabs(x);
- y = floor(absx);
- if (absx - y >= 0.5)
- y += 1.0;
- return copysign(y, x);
+ double absx, y;
+ absx = fabs(x);
+ y = floor(absx);
+ if (absx - y >= 0.5)
+ y += 1.0;
+ return copysign(y, x);
}
#endif
diff --git a/source/blender/blenlib/intern/math_base_inline.c b/source/blender/blenlib/intern/math_base_inline.c
index fa0ca097ef1..b364ff73e4f 100644
--- a/source/blender/blenlib/intern/math_base_inline.c
+++ b/source/blender/blenlib/intern/math_base_inline.c
@@ -26,7 +26,6 @@
* */
#include <float.h>
-#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
diff --git a/source/blender/blenlib/intern/math_color.c b/source/blender/blenlib/intern/math_color.c
index fc6e722afeb..6637d74dbb1 100644
--- a/source/blender/blenlib/intern/math_color.c
+++ b/source/blender/blenlib/intern/math_color.c
@@ -25,10 +25,6 @@
* ***** END GPL LICENSE BLOCK *****
* */
-#include <float.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
#include "BLI_math.h"
@@ -113,7 +109,9 @@ void yuv_to_rgb(float y, float u, float v, float *lr, float *lg, float *lb)
*lb=b;
}
-void rgb_to_ycc(float r, float g, float b, float *ly, float *lcb, float *lcr)
+/* The RGB inputs are supposed gamma corrected and in the range 0 - 1.0f */
+/* 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, cr, cb;
@@ -122,24 +120,53 @@ void rgb_to_ycc(float r, float g, float b, float *ly, float *lcb, float *lcr)
sg=255.0f*g;
sb=255.0f*b;
-
- 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;
+ 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;
+ }
*ly=y;
*lcb=cb;
*lcr=cr;
}
-void ycc_to_rgb(float y, float cb, float cr, float *lr, float *lg, float *lb)
+
+/* YCC input have a range of 16-235 and 16-240 exepect with JFIF_0_255 where the range is 0-255 */
+/* RGB outputs are in the range 0 - 1.0f */
+void ycc_to_rgb(float y, float cb, float cr, float *lr, float *lg, float *lb, int colorspace)
{
float r,g,b;
- 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);
-
+ 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;
+ }
*lr=r/255.0f;
*lg=g/255.0f;
*lb=b/255.0f;
@@ -369,21 +396,21 @@ int constrain_rgb(float *r, float *g, float *b)
{
float w;
- /* Amount of white needed is w = - min(0, *r, *g, *b) */
+ /* Amount of white needed is w = - min(0, *r, *g, *b) */
- w = (0 < *r) ? 0 : *r;
- w = (w < *g) ? w : *g;
- w = (w < *b) ? w : *b;
- w = -w;
+ w = (0 < *r) ? 0 : *r;
+ w = (w < *g) ? w : *g;
+ w = (w < *b) ? w : *b;
+ w = -w;
- /* Add just enough white to make r, g, b all positive. */
+ /* Add just enough white to make r, g, b all positive. */
- if (w > 0) {
- *r += w; *g += w; *b += w;
- return 1; /* Color modified to fit RGB gamut */
- }
+ if (w > 0) {
+ *r += w; *g += w; *b += w;
+ return 1; /* Color modified to fit RGB gamut */
+ }
- return 0; /* Color within RGB gamut */
+ return 0; /* Color within RGB gamut */
}
float rgb_to_grayscale(float rgb[3])
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index 7e12cec5023..e8fb922ce4d 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -25,14 +25,13 @@
* ***** END GPL LICENSE BLOCK *****
* */
-#include <float.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
+
+#include "MEM_guardedalloc.h"
#include "BLI_math.h"
#include "BLI_memarena.h"
-#include "MEM_guardedalloc.h"
+
+#include "BKE_utildefines.h"
/********************************** Polygons *********************************/
@@ -63,6 +62,7 @@ float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const floa
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);
}
@@ -125,10 +125,6 @@ float area_tri_v3(const float v1[3], const float v2[3], const float v3[3]) /* T
return (len/2.0f);
}
-#define MAX2(x,y) ((x)>(y) ? (x) : (y))
-#define MAX3(x,y,z) MAX2(MAX2((x),(y)) , (z))
-
-
float area_poly_v3(int nr, float verts[][3], float *normal)
{
float x, y, z, area, max;
@@ -406,16 +402,17 @@ int isect_line_tri_v3(float p1[3], float p2[3], float v0[3], float v1[3], float
sub_v3_v3v3(s, p1, v0);
- cross_v3_v3v3(q, s, e1);
- *lambda = f * dot_v3v3(e2, q);
- if ((*lambda < 0.0)||(*lambda > 1.0)) return 0;
-
u = f * dot_v3v3(s, p);
if ((u < 0.0)||(u > 1.0)) return 0;
- v = f * dot_v3v3(d, q);
+ cross_v3_v3v3(q, s, e1);
+
+ v = f * dot_v3v3(d, q);
if ((v < 0.0)||((u + v) > 1.0)) return 0;
+ *lambda = f * dot_v3v3(e2, q);
+ if ((*lambda < 0.0)||(*lambda > 1.0)) return 0;
+
if(uv) {
uv[0]= u;
uv[1]= v;
@@ -445,17 +442,18 @@ int isect_ray_tri_v3(float p1[3], float d[3], float v0[3], float v1[3], float v2
sub_v3_v3v3(s, p1, v0);
- cross_v3_v3v3(q, s, e1);
- *lambda = f * dot_v3v3(e2, q);
- if ((*lambda < 0.0)) return 0;
-
u = f * dot_v3v3(s, p);
if ((u < 0.0)||(u > 1.0)) return 0;
+ cross_v3_v3v3(q, s, e1);
+
v = f * dot_v3v3(d, q);
if ((v < 0.0)||((u + v) > 1.0)) return 0;
- if(uv) {
+ *lambda = f * dot_v3v3(e2, q);
+ if ((*lambda < 0.0)) return 0;
+
+ if(uv) {
uv[0]= u;
uv[1]= v;
}
@@ -465,36 +463,36 @@ int isect_ray_tri_v3(float p1[3], float d[3], float v0[3], float v1[3], float v2
int isect_ray_tri_epsilon_v3(float p1[3], float d[3], float v0[3], float v1[3], float v2[3], float *lambda, float *uv, 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, d, e2);
- a = dot_v3v3(e1, p);
- if (a == 0.0f) return 0;
- f = 1.0f/a;
-
- sub_v3_v3v3(s, p1, v0);
-
- cross_v3_v3v3(q, s, e1);
+ float p[3], s[3], e1[3], e2[3], q[3];
+ float a, f, u, v;
- u = f * dot_v3v3(s, p);
- if ((u < -epsilon)||(u > 1.0f+epsilon)) return 0;
-
- v = f * dot_v3v3(d, q);
- if ((v < -epsilon)||((u + v) > 1.0f+epsilon)) return 0;
+ sub_v3_v3v3(e1, v1, v0);
+ sub_v3_v3v3(e2, v2, v0);
- *lambda = f * dot_v3v3(e2, q);
- if ((*lambda < 0.0f)) return 0;
+ cross_v3_v3v3(p, d, e2);
+ a = dot_v3v3(e1, p);
+ if (a == 0.0f) return 0;
+ f = 1.0f/a;
- if(uv) {
- uv[0]= u;
- uv[1]= v;
- }
-
- return 1;
+ sub_v3_v3v3(s, p1, v0);
+
+ u = f * dot_v3v3(s, p);
+ if ((u < -epsilon)||(u > 1.0f+epsilon)) return 0;
+
+ cross_v3_v3v3(q, s, e1);
+
+ v = f * dot_v3v3(d, q);
+ if ((v < -epsilon)||((u + v) > 1.0f+epsilon)) return 0;
+
+ *lambda = f * dot_v3v3(e2, q);
+ if ((*lambda < 0.0f)) return 0;
+
+ if(uv) {
+ uv[0]= u;
+ uv[1]= v;
+ }
+
+ return 1;
}
int isect_ray_tri_threshold_v3(float p1[3], float d[3], float v0[3], float v1[3], float v2[3], float *lambda, float *uv, float threshold)
@@ -724,7 +722,7 @@ int isect_sweeping_sphere_tri_v3(float p1[3], float p2[3], float radius, float v
*lambda = newLambda;
copy_v3_v3(ipoint,e1);
mul_v3_fl(ipoint,e);
- add_v3_v3v3(ipoint,ipoint,v0);
+ add_v3_v3(ipoint, v0);
found_by_sweep=1;
}
}
@@ -748,7 +746,7 @@ int isect_sweeping_sphere_tri_v3(float p1[3], float p2[3], float radius, float v
*lambda = newLambda;
copy_v3_v3(ipoint,e2);
mul_v3_fl(ipoint,e);
- add_v3_v3v3(ipoint,ipoint,v0);
+ add_v3_v3(ipoint, v0);
found_by_sweep=1;
}
}
@@ -777,7 +775,7 @@ int isect_sweeping_sphere_tri_v3(float p1[3], float p2[3], float radius, float v
*lambda = newLambda;
copy_v3_v3(ipoint,e3);
mul_v3_fl(ipoint,e);
- add_v3_v3v3(ipoint,ipoint,v1);
+ add_v3_v3(ipoint, v1);
found_by_sweep=1;
}
}
@@ -961,7 +959,7 @@ int isect_line_line_strict_v3(float v1[3], float v2[3], float v3[3], float v4[3]
int isect_aabb_aabb_v3(float min1[3], float max1[3], float min2[3], 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]);
+ min2[0]<max1[0] && min2[1]<max1[1] && min2[2]<max1[2]);
}
/* find closest point to p on line through l1,l2 and return lambda,
@@ -1400,14 +1398,14 @@ void barycentric_weights_v2(const float v1[2], const float v2[2], const float v3
wtot = w[0]+w[1]+w[2];
if (wtot != 0.0f) {
- wtot_inv = 1.0f/wtot;
+ wtot_inv = 1.0f/wtot;
- w[0] = w[0]*wtot_inv;
- w[1] = w[1]*wtot_inv;
- w[2] = w[2]*wtot_inv;
+ w[0] = w[0]*wtot_inv;
+ w[1] = w[1]*wtot_inv;
+ w[2] = w[2]*wtot_inv;
}
else /* dummy values for zero area face */
- w[0] = w[1] = w[2] = 1.0f/3.0f;
+ w[0] = w[1] = w[2] = 1.0f/3.0f;
}
/* given 2 triangles in 3D space, and a point in relation to the first triangle.
@@ -1612,21 +1610,21 @@ void interp_cubic_v3(float *x, float *v,float *x1, float *v1, float *x2, float *
void orthographic_m4(float matrix[][4],float left, float right, float bottom, float top, float nearClip, float farClip)
{
- float Xdelta, Ydelta, Zdelta;
+ float Xdelta, Ydelta, Zdelta;
- Xdelta = right - left;
- Ydelta = top - bottom;
- Zdelta = farClip - nearClip;
- if (Xdelta == 0.0 || Ydelta == 0.0 || Zdelta == 0.0) {
+ Xdelta = right - left;
+ Ydelta = top - bottom;
+ Zdelta = farClip - nearClip;
+ if (Xdelta == 0.0 || Ydelta == 0.0 || Zdelta == 0.0) {
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;
+ }
+ 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 perspective_m4(float mat[][4],float left, float right, float bottom, float top, float nearClip, float farClip)
@@ -1648,22 +1646,22 @@ void perspective_m4(float mat[][4],float left, float right, float bottom, float
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.0;
+ mat[1][0] = mat[1][2] = mat[1][3] =
+ mat[3][0] = mat[3][1] = mat[3][3] = 0.0;
}
static void i_multmatrix(float icand[][4], float Vm[][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];
+ 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);
}
@@ -1673,10 +1671,10 @@ void polarview_m4(float Vm[][4],float dist, float azimuth, float incidence, floa
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],float vx, float vy, float vz, float px, float py, float pz, float twist)
@@ -1687,7 +1685,7 @@ void lookat_m4(float mat[][4],float vx, float vy, float vz, float px, float py,
unit_m4(mat);
unit_m4(mat1);
- rotate_m4(mat,'z',-twist);
+ rotate_m4(mat, 'Z', -twist);
dx = px - vx;
dy = py - vy;
@@ -1710,8 +1708,8 @@ void lookat_m4(float mat[][4],float vx, float vy, float vz, float px, float py,
i_multmatrix(mat1, mat);
- mat1[1][1] = mat1[2][2] = 1.0f; /* be careful here to reinit */
- mat1[1][2] = mat1[2][1] = 0.0; /* 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.0; /* those modified by the last */
/* paragraph */
if (hyp != 0.0f) { /* rotate Y */
@@ -1767,6 +1765,27 @@ int box_clip_bounds_m4(float boundbox[2][3], float bounds[4], float winmat[4][4]
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;
+
+ 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];
+
+ mul_m4_v3(mat, vec);
+ DO_MINMAX(vec, mn, mx);
+ }
+
+ copy_v3_v3(min, mn);
+ copy_v3_v3(max, mx);
+}
+
/********************************** Mapping **********************************/
void map_to_tube(float *u, float *v,float x, float y, float z)
@@ -1798,9 +1817,7 @@ void map_to_sphere(float *u, float *v,float x, float y, float z)
}
}
-/********************************************************/
-
-/* Tangents */
+/********************************* Tangents **********************************/
/* For normal map tangents we need to detect uv boundaries, and only average
* tangents in case the uvs are connected. Alternative would be to store 1
@@ -1818,7 +1835,7 @@ void sum_or_add_vertex_tangent(void *arena, VertexTangent **vtang, float *tang,
/* find a tangent with connected uvs */
for(vt= *vtang; vt; vt=vt->next) {
if(fabs(uv[0]-vt->uv[0]) < STD_UV_CONNECT_LIMIT && fabs(uv[1]-vt->uv[1]) < STD_UV_CONNECT_LIMIT) {
- add_v3_v3v3(vt->tang, vt->tang, tang);
+ add_v3_v3(vt->tang, tang);
return;
}
}
@@ -1852,10 +1869,12 @@ void tangent_from_uv(float *uv1, float *uv2, float *uv3, float *co1, float *co2,
float s2= uv3[0] - uv1[0];
float t1= uv2[1] - uv1[1];
float t2= uv3[1] - uv1[1];
+ float det= (s1 * t2 - s2 * t1);
+
+ if(det != 0.0f) { /* otherwise 'tang' becomes nan */
+ float tangv[3], ct[3], e1[3], e2[3];
- if(s1 && s2 && t1 && t2) { /* otherwise 'tang' becomes nan */
- float tangv[3], ct[3], e1[3], e2[3], det;
- det= 1.0f / (s1 * t2 - s2 * t1);
+ det= 1.0f/det;
/* normals in render are inversed... */
sub_v3_v3v3(e1, co1, co2);
@@ -1877,11 +1896,11 @@ void tangent_from_uv(float *uv1, float *uv2, float *uv3, float *co1, float *co2,
}
}
-/********************************************************/
+/****************************** Vector Clouds ********************************/
/* vector clouds */
/* void vcloud_estimate_transform(int list_size, float (*pos)[3], float *weight,float (*rpos)[3], float *rweight,
- float lloc[3],float rloc[3],float lrot[3][3],float lscale[3][3])
+ float lloc[3],float rloc[3],float lrot[3][3],float lscale[3][3])
input
(
@@ -1905,13 +1924,13 @@ pointers may be NULL if not needed
/* can't believe there is none in math utils */
float _det_m3(float m2[3][3])
{
- float det = 0.f;
- if (m2){
- det= m2[0][0]* (m2[1][1]*m2[2][2] - m2[1][2]*m2[2][1])
- -m2[1][0]* (m2[0][1]*m2[2][2] - m2[0][2]*m2[2][1])
- +m2[2][0]* (m2[0][1]*m2[1][2] - m2[0][2]*m2[1][1]);
- }
- return det;
+ float det = 0.f;
+ if (m2){
+ det= m2[0][0]* (m2[1][1]*m2[2][2] - m2[1][2]*m2[2][1])
+ -m2[1][0]* (m2[0][1]*m2[2][2] - m2[0][2]*m2[2][1])
+ +m2[2][0]* (m2[0][1]*m2[1][2] - m2[0][2]*m2[1][1]);
+ }
+ return det;
}
@@ -1936,19 +1955,19 @@ void vcloud_estimate_transform(int list_size, float (*pos)[3], float *weight,flo
float v[3];
copy_v3_v3(v,pos[a]);
mul_v3_fl(v,weight[a]);
- add_v3_v3v3(accu_com,accu_com,v);
+ add_v3_v3(accu_com, v);
accu_weight +=weight[a];
}
- else add_v3_v3v3(accu_com,accu_com,pos[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_v3v3(accu_rcom,accu_rcom,v);
+ add_v3_v3(accu_rcom, v);
accu_rweight +=rweight[a];
}
- else add_v3_v3v3(accu_rcom,accu_rcom,rpos[a]);
+ else add_v3_v3(accu_rcom, rpos[a]);
}
if (!weight || !rweight){
@@ -2036,3 +2055,422 @@ void vcloud_estimate_transform(int list_size, float (*pos)[3], float *weight,flo
}
}
+/******************************* Form Factor *********************************/
+
+static void vec_add_dir(float r[3], float v1[3], float v2[3], 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]);
+}
+
+static int ff_visible_quad(float p[3], float n[3], float v0[3], float v1[3], float v2[3], float q0[3], float q1[3], float q2[3], float q3[3])
+{
+ static const float epsilon = 1e-6f;
+ float c, sd[3];
+
+ 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) {
+ if(sd[1] > 0) {
+ if(sd[2] > 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) {
+ // ++-
+ 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) {
+ if(sd[2] > 0) {
+ // +-+
+ 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) {
+ // +--
+ 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) {
+ // +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) {
+ // +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) {
+ if(sd[1] > 0) {
+ if(sd[2] > 0) {
+ // -++
+ 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) {
+ // -+-
+ 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) {
+ if(sd[2] > 0) {
+ // --+
+ 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) {
+ // ---
+ return 0;
+ }
+ else {
+ // --0
+ return 0;
+ }
+ }
+ else {
+ if(sd[2] > 0) {
+ // -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) {
+ // -0-
+ return 0;
+ }
+ else {
+ // -00
+ return 0;
+ }
+ }
+ }
+ else {
+ if(sd[1] > 0) {
+ if(sd[2] > 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[2] < 0) {
+ // 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) {
+ if(sd[2] > 0) {
+ // 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) {
+ // 0--
+ return 0;
+ }
+ else {
+ // 0-0
+ return 0;
+ }
+ }
+ else {
+ if(sd[2] > 0) {
+ // 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) {
+ // 00-
+ return 0;
+ }
+ else {
+ // 000
+ return 0;
+ }
+ }
+ }
+
+ return 1;
+}
+
+/* altivec optimization, this works, but is unused */
+
+#if 0
+#include <Accelerate/Accelerate.h>
+
+typedef union {
+ vFloat v;
+ float f[4];
+} vFloatResult;
+
+static vFloat vec_splat_float(float 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;
+
+ /* 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;
+
+ /* 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;
+
+ /* 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);
+
+ /* 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);
+
+ return result;
+}
+
+#endif
+
+/* SSE optimization, acos code doesn't work */
+
+#if 0
+
+#include <xmmintrin.h>
+
+static __m128 sse_approx_acos(__m128 x)
+{
+ /* needs a better approximation than taylor expansion of acos, since that
+ * gives big erros 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);
+}
+
+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;
+
+ /* 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]);
+
+ /* 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));
+
+ 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;
+
+ /* 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;
+
+ /* sum together */
+ result= (fresult[0] + fresult[1] + fresult[2] + fresult[3])*(0.5f/(float)M_PI);
+ result= MAX2(result, 0.0f);
+
+ return result;
+}
+
+#endif
+
+static void ff_normalize(float n[3])
+{
+ float d;
+
+ d= dot_v3v3(n, n);
+
+ if(d > 1.0e-35F) {
+ d= 1.0f/sqrtf(d);
+
+ n[0] *= d;
+ n[1] *= d;
+ n[2] *= d;
+ }
+}
+
+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;
+
+ 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);
+
+ 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));
+
+ 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);
+
+ 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])
+{
+ /* 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(ff_visible_quad(p, n, v1, v2, v3, q0, q1, q2, q3))
+ contrib += ff_quad_form_factor(p, n, q0, q1, q2, q3);
+
+ if(v4 && ff_visible_quad(p, n, v1, v3, v4, q0, q1, q2, q3))
+ contrib += ff_quad_form_factor(p, n, q0, q1, q2, q3);
+
+ return contrib;
+}
+
diff --git a/source/blender/blenlib/intern/math_geom_inline.c b/source/blender/blenlib/intern/math_geom_inline.c
new file mode 100644
index 00000000000..697ac8dc782
--- /dev/null
+++ b/source/blender/blenlib/intern/math_geom_inline.c
@@ -0,0 +1,138 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: some of this file.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ * */
+
+#include "BLI_math.h"
+
+#ifndef BLI_MATH_GEOM_INLINE
+#define BLI_MATH_GEOM_INLINE
+
+/****************************** Spherical Harmonics **************************/
+
+MINLINE void zero_sh(float r[9])
+{
+ memset(r, 0, sizeof(float)*9);
+}
+
+MINLINE void copy_sh_sh(float r[9], float a[9])
+{
+ memcpy(r, a, sizeof(float)*9);
+}
+
+MINLINE void mul_sh_fl(float r[9], float f)
+{
+ int i;
+
+ for(i=0; i<9; i++)
+ r[i] *= f;
+}
+
+MINLINE void add_sh_shsh(float r[9], float a[9], float b[9])
+{
+ int i;
+
+ for(i=0; i<9; i++)
+ r[i]= a[i] + b[i];
+}
+
+MINLINE float dot_shsh(float a[9], float b[9])
+{
+ float r= 0.0f;
+ int i;
+
+ for(i=0; i<9; i++)
+ r += a[i]*b[i];
+
+ return r;
+}
+
+MINLINE float diffuse_shv3(float sh[9], 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;
+}
+
+MINLINE void vec_fac_to_sh(float r[9], float v[3], float f)
+{
+ /* 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];
+
+ sh[0]= 0.282095f;
+
+ 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);
+
+ mul_sh_fl(sh, f);
+ copy_sh_sh(r, sh);
+}
+
+MINLINE float eval_shv3(float sh[9], float v[3])
+{
+ float tmp[9];
+
+ vec_fac_to_sh(tmp, v, 1.0f);
+ return dot_shsh(tmp, sh);
+}
+
+MINLINE void madd_sh_shfl(float r[9], float sh[3], float f)
+{
+ float tmp[9];
+
+ copy_sh_sh(tmp, sh);
+ mul_sh_fl(tmp, f);
+ add_sh_shsh(r, r, tmp);
+}
+
+#endif /* BLI_MATH_GEOM_INLINE */
+
diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c
index c970f2132c3..6e8f4622488 100644
--- a/source/blender/blenlib/intern/math_matrix.c
+++ b/source/blender/blenlib/intern/math_matrix.c
@@ -25,10 +25,6 @@
* ***** END GPL LICENSE BLOCK *****
*/
-#include <float.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
#include "BLI_math.h"
@@ -129,10 +125,15 @@ void swap_m4m4(float m1[][4], float m2[][4])
/******************************** Arithmetic *********************************/
-void mul_m4_m4m4(float m1[][4], float m2[][4], float m3[][4])
+void mul_m4_m4m4(float m1[][4], float m2_[][4], float m3_[][4])
{
- /* matrix product: m1[j][k] = m2[j][i].m3[i][k] */
+ float m2[4][4], m3[4][4];
+ /* copy so it works when m1 is the same pointer as m2 or m3 */
+ copy_m4_m4(m2, m2_);
+ copy_m4_m4(m3, m3_);
+
+ /* matrix product: m1[j][k] = m2[j][i].m3[i][k] */
m1[0][0] = m2[0][0]*m3[0][0] + m2[0][1]*m3[1][0] + m2[0][2]*m3[2][0] + m2[0][3]*m3[3][0];
m1[0][1] = m2[0][0]*m3[0][1] + m2[0][1]*m3[1][1] + m2[0][2]*m3[2][1] + m2[0][3]*m3[3][1];
m1[0][2] = m2[0][0]*m3[0][2] + m2[0][1]*m3[1][2] + m2[0][2]*m3[2][2] + m2[0][3]*m3[3][2];
@@ -155,20 +156,26 @@ void mul_m4_m4m4(float m1[][4], float m2[][4], float m3[][4])
}
-void mul_m3_m3m3(float m1[][3], float m3[][3], float m2[][3])
+void mul_m3_m3m3(float m1[][3], float m3_[][3], float m2_[][3])
{
- /* m1[i][j] = m2[i][k]*m3[k][j], args are flipped! */
- 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];
+ float m2[3][3], m3[3][3];
+
+ /* copy so it works when m1 is the same pointer as m2 or m3 */
+ copy_m3_m3(m2, m2_);
+ copy_m3_m3(m3, m3_);
+
+ /* m1[i][j] = m2[i][k]*m3[k][j], args are flipped! */
+ 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_m4m3(float (*m1)[4], float (*m3)[4], float (*m2)[3])
@@ -187,18 +194,18 @@ void mul_m4_m4m3(float (*m1)[4], float (*m3)[4], float (*m2)[3])
/* m1 = m2 * m3, ignore the elements on the 4th row/column of m3*/
void mul_m3_m3m4(float m1[][3], float m2[][3], float m3[][4])
{
- /* 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], float (*m3)[3], float (*m2)[4])
@@ -325,17 +332,23 @@ void mul_project_m4_v4(float mat[][4], float *vec)
vec[2] /= w;
}
-void mul_m4_v4(float mat[][4], float *vec)
+void mul_v4_m4v4(float r[4], float mat[4][4], float v[4])
{
- float x,y,z;
+ float x, y, z;
- x=vec[0];
- y=vec[1];
- z= vec[2];
- vec[0]=x*mat[0][0] + y*mat[1][0] + z*mat[2][0] + mat[3][0]*vec[3];
- vec[1]=x*mat[0][1] + y*mat[1][1] + z*mat[2][1] + mat[3][1]*vec[3];
- vec[2]=x*mat[0][2] + y*mat[1][2] + z*mat[2][2] + mat[3][2]*vec[3];
- vec[3]=x*mat[0][3] + y*mat[1][3] + z*mat[2][3] + mat[3][3]*vec[3];
+ x= v[0];
+ y= v[1];
+ 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];
+}
+
+void mul_m4_v4(float mat[4][4], float r[4])
+{
+ mul_v4_m4v4(r, mat, r);
}
void mul_v3_m3v3(float r[3], float M[3][3], float a[3])
@@ -441,8 +454,8 @@ int invert_m3_m3(float m1[3][3], float m2[3][3])
/* then determinant old matrix! */
det= m2[0][0]* (m2[1][1]*m2[2][2] - m2[1][2]*m2[2][1])
- -m2[1][0]* (m2[0][1]*m2[2][2] - m2[0][2]*m2[2][1])
- +m2[2][0]* (m2[0][1]*m2[1][2] - m2[0][2]*m2[1][1]);
+ -m2[1][0]* (m2[0][1]*m2[2][2] - m2[0][2]*m2[2][1])
+ +m2[2][0]* (m2[0][1]*m2[1][2] - m2[0][2]*m2[1][1]);
success= (det != 0);
@@ -827,8 +840,8 @@ float determinant_m3(float a1, float a2, float a3,
float ans;
ans = a1 * determinant_m2(b2, b3, c2, c3)
- - b1 * determinant_m2(a2, a3, c2, c3)
- + c1 * determinant_m2(a2, a3, b2, b3);
+ - b1 * determinant_m2(a2, a3, c2, c3)
+ + c1 * determinant_m2(a2, a3, b2, b3);
return ans;
}
@@ -859,9 +872,9 @@ float determinant_m4(float m[][4])
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);
+ - 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;
}
@@ -942,54 +955,47 @@ void scale_m4_fl(float m[][4], float scale)
void translate_m4(float mat[][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]);
}
-void rotate_m4(float mat[][4], char axis,float angle)
+void rotate_m4(float mat[][4], const char axis, const float angle)
{
int col;
- float temp[4];
- float cosine, sine;
-
- for(col=0; col<4 ; col++) /* init temp to zero matrix */
- temp[col] = 0;
-
- angle = (float)(angle*(3.1415926535/180.0));
- cosine = (float)cos(angle);
- sine = (float)sin(angle);
- switch(axis){
- case 'x':
- case 'X':
- for(col=0 ; col<4 ; col++)
- temp[col] = cosine*mat[1][col] + sine*mat[2][col];
- for(col=0 ; col<4 ; col++) {
- mat[2][col] = - sine*mat[1][col] + cosine*mat[2][col];
- mat[1][col] = temp[col];
+ float temp[4]= {0.0f, 0.0f, 0.0f, 0.0f};
+ float cosine, sine;
+
+ cosine = (float)cos(angle);
+ sine = (float)sin(angle);
+ switch(axis){
+ case 'X':
+ for(col=0 ; col<4 ; col++)
+ temp[col] = cosine*mat[1][col] + sine*mat[2][col];
+ for(col=0 ; col<4 ; col++) {
+ mat[2][col] = - sine*mat[1][col] + cosine*mat[2][col];
+ mat[1][col] = temp[col];
}
- break;
-
- case 'y':
- case 'Y':
- for(col=0 ; col<4 ; col++)
- temp[col] = cosine*mat[0][col] - sine*mat[2][col];
- for(col=0 ; col<4 ; col++) {
- mat[2][col] = sine*mat[0][col] + cosine*mat[2][col];
- mat[0][col] = temp[col];
- }
+ break;
+
+ case 'Y':
+ for(col=0 ; col<4 ; col++)
+ temp[col] = cosine*mat[0][col] - sine*mat[2][col];
+ for(col=0 ; col<4 ; col++) {
+ mat[2][col] = sine*mat[0][col] + cosine*mat[2][col];
+ mat[0][col] = temp[col];
+ }
break;
- case 'z':
- case 'Z':
- for(col=0 ; col<4 ; col++)
- temp[col] = cosine*mat[0][col] + sine*mat[1][col];
- for(col=0 ; col<4 ; col++) {
- mat[1][col] = - sine*mat[0][col] + cosine*mat[1][col];
- mat[0][col] = temp[col];
- }
+ case 'Z':
+ for(col=0 ; col<4 ; col++)
+ temp[col] = cosine*mat[0][col] + sine*mat[1][col];
+ for(col=0 ; col<4 ; col++) {
+ mat[1][col] = - sine*mat[0][col] + cosine*mat[1][col];
+ mat[0][col] = temp[col];
+ }
break;
- }
+ }
}
void blend_m3_m3m3(float out[][3], float dst[][3], float src[][3], float srcweight)
@@ -1143,3 +1149,458 @@ void print_m4(char *str, float m[][4])
printf("%f %f %f %f\n",m[0][3],m[1][3],m[2][3],m[3][3]);
printf("\n");
}
+
+/*********************************** SVD ************************************
+ * from TNT matrix library
+
+ * Compute the Single Value Decomposition of an arbitrary matrix A
+ * That is compute the 3 matrices U,W,V with U column orthogonal (m,n)
+ * ,W a diagonal matrix and V an orthogonal square matrix s.t.
+ * A = U.W.Vt. From this decomposition it is trivial to compute the
+ * (pseudo-inverse) of A as Ainv = V.Winv.tranpose(U).
+ */
+
+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 = minf(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 = minf(m-1,n);
+ int nrt = maxf(0,minf(n-2,m));
+
+ copy_m4_m4(A, A_);
+ zero_m4(U);
+ zero_v4(s);
+
+ for (k = 0; k < maxf(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 = minf(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;
+ k=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 = maxf(maxf(maxf(maxf(
+ 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], float A[4][4], float epsilon)
+{
+ /* compute moon-penrose pseudo inverse of matrix, singular values
+ below epsilon are ignored for stability (truncated SVD) */
+ float V[4][4], W[4], Wm[4][4], U[4][4];
+ int i;
+
+ transpose_m4(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];
+
+ transpose_m4(V);
+
+ mul_serie_m4(Ainv, U, Wm, V, 0, 0, 0, 0, 0);
+}
diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c
index a92f80e35c7..6b5bf7743ef 100644
--- a/source/blender/blenlib/intern/math_rotation.c
+++ b/source/blender/blenlib/intern/math_rotation.c
@@ -25,10 +25,6 @@
* ***** END GPL LICENSE BLOCK *****
* */
-#include <float.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
#include "BLI_math.h"
@@ -904,12 +900,12 @@ void quat_to_eul(float *eul,float *quat)
/* XYZ order */
void eul_to_quat(float *quat,float *eul)
{
- 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 = (float)cos(ti); cj = (float)cos(tj); ch = (float)cos(th);
- si = (float)sin(ti); sj = (float)sin(tj); sh = (float)sin(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 = (float)cos(ti); cj = (float)cos(tj); ch = (float)cos(th);
+ si = (float)sin(ti); sj = (float)sin(tj); sh = (float)sin(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;
@@ -923,8 +919,8 @@ void rotate_eul(float *beul, char axis, float ang)
float eul[3], mat1[3][3], mat2[3][3], totmat[3][3];
eul[0]= eul[1]= eul[2]= 0.0f;
- if(axis=='x') eul[0]= ang;
- else if(axis=='y') eul[1]= ang;
+ if(axis=='X') eul[0]= ang;
+ else if(axis=='Y') eul[1]= ang;
else eul[2]= ang;
eul_to_mat3(mat1,eul);
@@ -1029,7 +1025,7 @@ void mat3_to_compatible_eul(float *eul, float *oldrot,float mat[][3])
/* Euler Rotation Order Code:
* was adapted from
- ANSI C code from the article
+ ANSI C code from the article
"Euler Angle Conversion"
by Ken Shoemake, shoemake@graphics.cis.upenn.edu
in "Graphics Gems IV", Academic Press, 1994
@@ -1242,9 +1238,9 @@ void rotate_eulO(float beul[3], short order, char axis, float ang)
float eul[3], mat1[3][3], mat2[3][3], totmat[3][3];
eul[0]= eul[1]= eul[2]= 0.0f;
- if (axis=='x')
+ if (axis=='X')
eul[0]= ang;
- else if (axis=='y')
+ else if (axis=='Y')
eul[1]= ang;
else
eul[2]= ang;
@@ -1303,11 +1299,11 @@ void eulO_to_gimbal_axis(float gmat[][3], float *eul, short order)
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
- claim that you wrote the original software. If you use this software
- in a product, an acknowledgment in the product documentation would be
- appreciated but is not required.
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
- misrepresented as being the original software.
+ misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Author: Ladislav Kavan, kavanl@cs.tcd.ie
@@ -1507,3 +1503,13 @@ void copy_dq_dq(DualQuat *dq1, DualQuat *dq2)
memcpy(dq1, dq2, sizeof(DualQuat));
}
+/* lense/angle conversion (radians) */
+float lens_to_angle(float lens)
+{
+ return 2.0f * atan(16.0f/lens);
+}
+
+float angle_to_lens(float angle)
+{
+ return 16.0f / tan(angle * 0.5f);
+}
diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c
index 2452de0dc4c..9baf897c830 100644
--- a/source/blender/blenlib/intern/math_vector.c
+++ b/source/blender/blenlib/intern/math_vector.c
@@ -25,10 +25,6 @@
* ***** END GPL LICENSE BLOCK *****
* */
-#include <float.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
#include "BLI_math.h"
@@ -59,6 +55,16 @@ void interp_v3_v3v3(float target[3], const float a[3], const float b[3], const f
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)
+{
+ 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];
+}
+
/* 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])
@@ -77,6 +83,14 @@ void interp_v3_v3v3v3v3(float p[3], const float v1[3], const float v2[3], const
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])
+{
+ 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 mid_v3_v3v3(float *v, float *v1, float *v2)
{
v[0]= 0.5f*(v1[0] + v2[0]);
diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c
index 7fb6b8f6059..33d7f7cdd6d 100644
--- a/source/blender/blenlib/intern/math_vector_inline.c
+++ b/source/blender/blenlib/intern/math_vector_inline.c
@@ -66,7 +66,7 @@ MINLINE void copy_v3_v3(float r[3], const float a[3])
r[2]= a[2];
}
-MINLINE void copy_v4_v4(float r[4], float a[4])
+MINLINE void copy_v4_v4(float r[4], const float a[4])
{
r[0]= a[0];
r[1]= a[1];
@@ -97,45 +97,45 @@ MINLINE void swap_v4_v4(float a[4], float b[4])
/********************************* Arithmetic ********************************/
-MINLINE void add_v2_v2(float *r, float *a)
+MINLINE void add_v2_v2(float *r, const float *a)
{
r[0] += a[0];
r[1] += a[1];
}
-MINLINE void add_v2_v2v2(float *r, float *a, float *b)
+MINLINE void add_v2_v2v2(float *r, const float *a, const float *b)
{
r[0]= a[0] + b[0];
r[1]= a[1] + b[1];
}
-MINLINE void add_v3_v3(float *r, float *a)
+MINLINE void add_v3_v3(float *r, const float *a)
{
r[0] += a[0];
r[1] += a[1];
r[2] += a[2];
}
-MINLINE void add_v3_v3v3(float *r, float *a, float *b)
+MINLINE void add_v3_v3v3(float *r, const float *a, const float *b)
{
r[0]= a[0] + b[0];
r[1]= a[1] + b[1];
r[2]= a[2] + b[2];
}
-MINLINE void sub_v2_v2(float *r, float *a)
+MINLINE void sub_v2_v2(float *r, const float *a)
{
r[0] -= a[0];
r[1] -= a[1];
}
-MINLINE void sub_v2_v2v2(float *r, float *a, float *b)
+MINLINE void sub_v2_v2v2(float *r, const float *a, const float *b)
{
r[0]= a[0] - b[0];
r[1]= a[1] - b[1];
}
-MINLINE void sub_v3_v3(float *r, float *a)
+MINLINE void sub_v3_v3(float *r, const float *a)
{
r[0] -= a[0];
r[1] -= a[1];
@@ -181,48 +181,70 @@ MINLINE void mul_v2_v2(float r[2], const float a[2])
r[1] *= a[1];
}
-MINLINE void mul_v3_v3(float r[3], float a[3])
+MINLINE void mul_v3_v3(float r[3], const float a[3])
{
r[0] *= a[0];
r[1] *= a[1];
r[2] *= a[2];
}
-MINLINE void madd_v3_v3fl(float r[3], float a[3], float f)
+MINLINE void mul_v4_fl(float r[4], float f)
+{
+ r[0]*= f;
+ r[1]*= f;
+ r[2]*= f;
+ r[3]*= f;
+}
+
+MINLINE void madd_v2_v2fl(float r[2], const float a[2], float 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;
}
-MINLINE void madd_v3_v3v3(float r[3], float a[3], float b[3])
+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];
}
-MINLINE void madd_v2_v2v2fl(float r[2], const float a[2], const float b[2], const float f)
+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;
}
-MINLINE void madd_v3_v3v3fl(float r[3], float a[3], float b[3], float 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;
}
-MINLINE void madd_v3_v3v3v3(float r[3], float a[3], float b[3], float c[3])
+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];
}
-MINLINE void mul_v3_v3v3(float *v, float *v1, float *v2)
+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;
+}
+
+MINLINE void mul_v3_v3v3(float *v, const float *v1, const float *v2)
{
v[0] = v1[0] * v2[0];
v[1] = v1[1] * v2[1];
@@ -305,6 +327,14 @@ MINLINE float len_v3v3(const float a[3], const float b[3])
return len_v3(d);
}
+MINLINE float len_squared_v3v3(const float a[3], const float b[3])
+{
+ float d[3];
+
+ sub_v3_v3v3(d, b, a);
+ return dot_v3v3(d, d);
+}
+
MINLINE float normalize_v2_v2(float r[2], const float a[2])
{
float d= dot_v2v2(a, a);
@@ -371,14 +401,14 @@ MINLINE float normalize_v3(float n[3])
return normalize_v3_v3(n, n);
}
-MINLINE void normal_short_to_float_v3(float *out, short *in)
+MINLINE void normal_short_to_float_v3(float *out, const short *in)
{
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, float *in)
+MINLINE void normal_float_to_short_v3(short *out, const float *in)
{
out[0] = (short)(in[0]*32767.0f);
out[1] = (short)(in[1]*32767.0f);
@@ -414,7 +444,7 @@ MINLINE int compare_v3v3(float *v1, float *v2, float limit)
MINLINE int compare_len_v3v3(float *v1, float *v2, float limit)
{
- float x,y,z;
+ float x,y,z;
x=v1[0]-v2[0];
y=v1[1]-v2[1];
diff --git a/source/blender/blenlib/intern/noise.c b/source/blender/blenlib/intern/noise.c
index 343589d9a41..141e5438bc9 100644
--- a/source/blender/blenlib/intern/noise.c
+++ b/source/blender/blenlib/intern/noise.c
@@ -35,11 +35,6 @@
#endif
#include <math.h>
-#include "BLI_blenlib.h"
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
/* local */
static float noise3_perlin(float vec[3]);
@@ -204,8 +199,15 @@ float hashvectf[768]= {
/* IMPROVED PERLIN NOISE */
/**************************/
-#define lerp(t, a, b) ((a)+(t)*((b)-(a)))
-#define npfade(t) ((t)*(t)*(t)*((t)*((t)*6-15)+10))
+static float lerp(float t, float a, float b)
+{
+ return (a+t*(b-a));
+}
+
+static float npfade(float t)
+{
+ return (t*t*t*(t*(t*6.0f-15.0f)+10.0f));
+}
static float grad(int hash, float x, float y, float z)
{
@@ -908,11 +910,11 @@ float g[512+2][3]= {
#define DOT(a,b) (a[0] * b[0] + a[1] * b[1] + a[2] * b[2])
#define setup(i,b0,b1,r0,r1) \
- t = vec[i] + 10000.; \
- b0 = ((int)t) & 255; \
- b1 = (b0+1) & 255; \
- r0 = t - (int)t; \
- r1 = r0 - 1.;
+ t = vec[i] + 10000.; \
+ b0 = ((int)t) & 255; \
+ b1 = (b0+1) & 255; \
+ r0 = t - (int)t; \
+ r1 = r0 - 1.;
static float noise3_perlin(float vec[3])
@@ -1491,7 +1493,7 @@ float mg_fBm(float x, float y, float z, float H, float lacunarity, float octaves
* ``offset'' is the zero offset, which determines multifractality (NOT USED??)
*/
/* 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),
+ * 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)
{
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index fe43960b770..423bf452a4d 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -29,20 +29,14 @@
* various string, file, list operations.
*/
-#include <stdio.h>
-#include <fcntl.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
-#include <stdarg.h>
-#include <math.h> /* for log10 */
#include "MEM_guardedalloc.h"
-#include "DNA_listBase.h"
#include "DNA_userdef_types.h"
-#include "BLI_dynamiclist.h"
#include "BLI_fileops.h"
#include "BLI_path_util.h"
#include "BLI_string.h"
@@ -50,21 +44,13 @@
#include "BLI_storage_types.h"
#include "BKE_utildefines.h"
+#include "BKE_blender.h" // BLENDER_VERSION
+#include "GHOST_Path-api.h"
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifndef WIN32
-#include <unistd.h>
-#else
-#include <io.h>
-#endif
-
#ifdef WIN32
+#include <io.h>
#ifdef _WIN32_IE
#undef _WIN32_IE
@@ -75,29 +61,22 @@
#include "BLI_winstuff.h"
-#endif
-
-
-#ifndef WIN32
-#include <sys/time.h>
-#endif
-
-#ifdef __APPLE__
-#include <sys/param.h>
-#include <CoreFoundation/CoreFoundation.h>
-#endif
+#else /* non windows */
#ifdef __linux__
#include "binreloc.h"
#endif
+#endif /* WIN32 */
+
/* local */
static int add_win32_extension(char *name);
+static char *blender_version_decimal(void);
/* implementation */
-int BLI_stringdec(char *string, char *head, char *start, unsigned short *numlen)
+int BLI_stringdec(const char *string, char *head, char *tail, unsigned short *numlen)
{
unsigned short len, len2, lenlslash = 0, nums = 0, nume = 0;
short i, found = 0;
@@ -124,8 +103,8 @@ int BLI_stringdec(char *string, char *head, char *start, unsigned short *numlen)
if (found) break;
}
}
- if (found){
- if (start) strcpy(start,&string[nume+1]);
+ if (found) {
+ if (tail) strcpy(tail, &string[nume+1]);
if (head) {
strcpy(head,string);
head[nums]=0;
@@ -133,22 +112,22 @@ int BLI_stringdec(char *string, char *head, char *start, unsigned short *numlen)
if (numlen) *numlen = nume-nums+1;
return ((int)atoi(&(string[nums])));
}
- if (start) strcpy(start, string + len);
+ if (tail) strcpy(tail, string + len);
if (head) {
strncpy(head, string, len);
- head[len] = 0;
+ head[len] = '\0';
}
if (numlen) *numlen=0;
return 0;
}
-void BLI_stringenc(char *string, char *head, char *start, unsigned short numlen, int pic)
+void BLI_stringenc(char *string, const char *head, const char *tail, unsigned short numlen, int pic)
{
char fmtstr[16]="";
if(pic < 0) pic= 0;
sprintf(fmtstr, "%%s%%.%dd%%s", numlen);
- sprintf(string, fmtstr, head, pic, start);
+ sprintf(string, fmtstr, head, pic, tail);
}
@@ -270,7 +249,7 @@ void BLI_cleanup_file(const char *relabase, char *dir)
short a;
char *start, *eind;
if (relabase) {
- BLI_convertstringcode(dir, relabase);
+ BLI_path_abs(dir, relabase);
} else {
if (dir[0]=='/' && dir[1]=='/') {
if (dir[2]== '\0') {
@@ -369,10 +348,8 @@ void BLI_cleanup_file(const char *relabase, char *dir)
}
-void BLI_makestringcode(const char *relfile, char *file)
+void BLI_path_rel(char *file, const char *relfile)
{
- char * p;
- char * q;
char * lslash;
char temp[FILE_MAXDIR+FILE_MAXFILE];
char res[FILE_MAXDIR+FILE_MAXFILE];
@@ -420,11 +397,18 @@ void BLI_makestringcode(const char *relfile, char *file)
{
/* find the prefix of the filename that is equal for both filenames.
This is replaced by the two slashes at the beginning */
- p = temp;
- q = file;
- while (*p == *q) {
+ char *p= temp;
+ char *q= file;
+
+ while ((*p == *q)) {
++p; ++q;
+ /* dont 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
*/
@@ -542,7 +526,7 @@ static void ensure_digits(char *path, int digits)
}
}
-int BLI_convertstringframe(char *path, int frame, int digits)
+int BLI_path_frame(char *path, int frame, int digits)
{
int ch_sta, ch_end;
@@ -559,7 +543,7 @@ int BLI_convertstringframe(char *path, int frame, int digits)
return 0;
}
-int BLI_convertstringframe_range(char *path, int sta, int end, int digits)
+int BLI_path_frame_range(char *path, int sta, int end, int digits)
{
int ch_sta, ch_end;
@@ -576,7 +560,7 @@ int BLI_convertstringframe_range(char *path, int sta, int end, int digits)
return 0;
}
-int BLI_convertstringcode(char *path, const char *basepath)
+int BLI_path_abs(char *path, const char *basepath)
{
int wasrelative = (strncmp(path, "//", 2)==0);
char tmp[FILE_MAX];
@@ -638,7 +622,7 @@ int BLI_convertstringcode(char *path, const char *basepath)
char *lslash= BLI_last_slash(base);
if (lslash) {
int baselen= (int) (lslash-base) + 1;
- /* use path for for temp storage here, we copy back over it right away */
+ /* use path for temp storage here, we copy back over it right away */
BLI_strncpy(path, tmp+2, FILE_MAX);
memcpy(tmp, base, baselen);
@@ -677,7 +661,7 @@ int BLI_convertstringcode(char *path, const char *basepath)
* Should only be done with command line paths.
* this is NOT somthing blenders internal paths support like the // prefix
*/
-int BLI_convertstringcwd(char *path)
+int BLI_path_cwd(char *path)
{
int wasrelative = 1;
int filelen = strlen(path);
@@ -715,7 +699,7 @@ int BLI_convertstringcwd(char *path)
}
-/* copy di to fi, filename only */
+/* 'di's filename component is moved into 'fi', di is made a dir path */
void BLI_splitdirstring(char *di, char *fi)
{
char *lslash= BLI_last_slash(di);
@@ -762,76 +746,50 @@ char *BLI_gethome(void) {
ret = getenv("HOME");
if(ret) {
- sprintf(dir, "%s\\.blender", ret);
- if (BLI_exists(dir)) return dir;
+ sprintf(dir, "%s\\%s", ret, blender_version_decimal());
+ if (BLI_is_dir(dir)) return dir;
}
/* else, check install dir (path containing blender.exe) */
- BLI_getInstallationDir(dir);
-
- if (BLI_exists(dir))
+ if(BLI_getInstallationDir(dir))
{
- strcat(dir,"\\.blender");
- if (BLI_exists(dir)) return(dir);
+ sprintf(dir, "%s", dir, blender_version_decimal());
+ if (BLI_is_dir(dir)) return(dir);
}
- /* add user profile support for WIN 2K / NT */
+ /* add user profile support for WIN 2K / NT.
+ * This is %APPDATA%, which translates to either
+ * %USERPROFILE%\Application Data or since Vista
+ * to %USERPROFILE%\AppData\Roaming
+ */
hResult = SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, SHGFP_TYPE_CURRENT, appdatapath);
if (hResult == S_OK)
{
- if (BLI_exists(appdatapath)) { /* from fop, also below... */
+ if (BLI_is_dir(appdatapath)) { /* from fop, also below... */
sprintf(dir, "%s\\Blender Foundation\\Blender", appdatapath);
BLI_recurdir_fileops(dir);
- if (BLI_exists(dir)) {
- strcat(dir,"\\.blender");
- if(BLI_exists(dir)) return(dir);
+ if (BLI_is_dir(dir)) {
+ sprintf(dir,"%s\\%s", dir, blender_version_decimal());
+ if(BLI_is_dir(dir)) return(dir);
}
}
hResult = SHGetFolderPath(NULL, CSIDL_COMMON_APPDATA, NULL, SHGFP_TYPE_CURRENT, appdatapath);
if (hResult == S_OK)
{
- if (BLI_exists(appdatapath))
+ if (BLI_is_dir(appdatapath))
{ /* from fop, also below... */
sprintf(dir, "%s\\Blender Foundation\\Blender", appdatapath);
BLI_recurdir_fileops(dir);
- if (BLI_exists(dir)) {
- strcat(dir,"\\.blender");
- if(BLI_exists(dir)) return(dir);
+ if (BLI_is_dir(dir)) {
+ sprintf(dir,"%s\\%s", dir, blender_version_decimal());
+ if(BLI_is_dir(dir)) return(dir);
}
}
}
}
-#if 0
- ret = getenv("USERPROFILE");
- if (ret) {
- if (BLI_exists(ret)) { /* from fop, also below... */
- sprintf(dir, "%s\\Application Data\\Blender Foundation\\Blender", ret);
- BLI_recurdir_fileops(dir);
- if (BLI_exists(dir)) {
- strcat(dir,"\\.blender");
- if(BLI_exists(dir)) return(dir);
- }
- }
- }
-#endif
-
- /*
- Saving in the Windows dir is less than desirable.
- Use as a last resort ONLY! (aphex)
- */
-
- ret = getenv("WINDOWS");
- if (ret) {
- if(BLI_exists(ret)) return ret;
- }
-
- ret = getenv("WINDIR");
- if (ret) {
- if(BLI_exists(ret)) return ret;
- }
return "C:\\Temp"; /* sheesh! bad, bad, bad! (aphex) */
#endif
@@ -840,7 +798,7 @@ char *BLI_gethome(void) {
/* this function returns the path to a blender folder, if it exists
* utility functions for BLI_gethome_folder */
-/* #define PATH_DEBUG */ /* for testing paths that are checked */
+// #define PATH_DEBUG /* for testing paths that are checked */
static int test_data_path(char *targetpath, char *path_base, char *path_sep, char *folder_name)
{
@@ -851,7 +809,7 @@ static int test_data_path(char *targetpath, char *path_base, char *path_sep, cha
BLI_make_file_string("/", targetpath, tmppath, folder_name);
- if (BLI_exists(targetpath)) {
+ if (BLI_is_dir(targetpath)) {
#ifdef PATH_DEBUG
printf("\tpath found: %s\n", targetpath);
#endif
@@ -884,11 +842,12 @@ static int gethome_path_local(char *targetpath, char *folder_name)
i = s - bprogname + 1;
BLI_strncpy(bprogdir, bprogname, i);
- /* try release/folder_name (CWD relative) */
- if(test_data_path(targetpath, BLI_getwdN(cwd), "release", folder_name))
+ /* try release/folder_name (BIN relative) */
+ if(test_data_path(targetpath, bprogdir, "release", folder_name))
return 1;
- if(test_data_path(targetpath, bprogdir, "release", folder_name))
+ /* try release/folder_name (CWD relative) */
+ if(test_data_path(targetpath, BLI_getwdN(cwd), "release", folder_name))
return 1;
/* try ./.blender/folder_name */
@@ -950,6 +909,274 @@ char *BLI_gethome_folder(char *folder_name, int flag)
return NULL;
}
+
+/* NEW stuff, to be cleaned up when fully migrated */
+/* ************************************************************* */
+/* ************************************************************* */
+
+// #define PATH_DEBUG2
+
+static char *blender_version_decimal(void)
+{
+ static char version_str[5];
+ sprintf(version_str, "%d.%02d", BLENDER_VERSION/100, BLENDER_VERSION%100);
+ return version_str;
+}
+
+static int test_path(char *targetpath, char *path_base, char *path_sep, char *folder_name)
+{
+ char tmppath[FILE_MAX];
+
+ if(path_sep) BLI_join_dirfile(tmppath, path_base, path_sep);
+ else BLI_strncpy(tmppath, path_base, sizeof(tmppath));
+
+ BLI_make_file_string("/", targetpath, tmppath, folder_name);
+
+ if (BLI_is_dir(targetpath)) {
+#ifdef PATH_DEBUG2
+ printf("\tpath found: %s\n", targetpath);
+#endif
+ return 1;
+ }
+ else {
+#ifdef PATH_DEBUG2
+ printf("\tpath missing: %s\n", targetpath);
+#endif
+ //targetpath[0] = '\0';
+ return 0;
+ }
+}
+
+static int test_env_path(char *path, char *envvar)
+{
+ char *env = envvar?getenv(envvar):NULL;
+ if (!env) return 0;
+
+ if (BLI_is_dir(env)) {
+ BLI_strncpy(path, env, FILE_MAX);
+ return 1;
+ } else {
+ path[0] = '\0';
+ return 0;
+ }
+}
+
+static int get_path_local(char *targetpath, char *folder_name)
+{
+ extern char bprogname[]; /* argv[0] from creator.c */
+ char bprogdir[FILE_MAX];
+ char cwd[FILE_MAX];
+ char *s;
+ int i;
+
+#ifdef PATH_DEBUG2
+ printf("get_path_local...\n");
+#endif
+
+
+ /* use argv[0] (bprogname) to get the path to the executable */
+ s = BLI_last_slash(bprogname);
+ i = s - bprogname + 1;
+ BLI_strncpy(bprogdir, bprogname, i);
+
+ /* try EXECUTABLE_DIR/folder_name */
+ if(test_path(targetpath, bprogdir, "", folder_name))
+ return 1;
+
+ /* try CWD/release/folder_name */
+ if(test_path(targetpath, BLI_getwdN(cwd), "release", folder_name))
+ return 1;
+
+ /* try EXECUTABLE_DIR/release/folder_name */
+ if(test_path(targetpath, bprogdir, "release", folder_name))
+ return 1;
+
+ /* try EXECUTABLE_DIR/2.5/folder_name - new default directory for local blender installed files */
+ if(test_path(targetpath, bprogdir, blender_version_decimal(), folder_name))
+ return 1;
+
+ /* try ./.blender/folder_name -- DEPRECATED, need to update build systems */
+ if(test_path(targetpath, bprogdir, ".blender", folder_name))
+ return 1;
+
+ return 0;
+}
+
+static int get_path_user(char *targetpath, char *folder_name, char *envvar)
+{
+ char user_path[FILE_MAX];
+ const char *user_base_path;
+
+ user_path[0] = '\0';
+
+ if (test_env_path(targetpath, envvar))
+ return 1;
+
+ user_base_path = (const char *)GHOST_getUserDir();
+ if (user_base_path) {
+ BLI_snprintf(user_path, FILE_MAX, BLENDER_USER_FORMAT, user_base_path, blender_version_decimal());
+ }
+
+ if(!user_path[0])
+ return 0;
+
+#ifdef PATH_DEBUG2
+ printf("get_path_user: %s\n", user_path);
+#endif
+
+ /* try $HOME/folder_name */
+ return test_path(targetpath, user_path, NULL, folder_name);
+}
+
+static int get_path_system(char *targetpath, char *folder_name, char *envvar)
+{
+ char system_path[FILE_MAX];
+ const char *system_base_path;
+
+ system_path[0] = '\0';
+
+ if (test_env_path(targetpath, envvar))
+ return 1;
+
+ system_base_path = (const char *)GHOST_getSystemDir();
+ if (system_base_path) {
+ BLI_snprintf(system_path, FILE_MAX, BLENDER_SYSTEM_FORMAT, system_base_path, blender_version_decimal());
+ }
+
+ if(!system_path[0])
+ return 0;
+
+#ifdef PATH_DEBUG2
+ printf("get_path_system: %s\n", system_path);
+#endif
+
+ /* try $BLENDERPATH/folder_name */
+ return test_path(targetpath, system_path, NULL, folder_name);
+}
+
+/* get a folder out of the 'folder_id' presets for paths */
+/* returns the path if found, NULL string if not */
+char *BLI_get_folder(int folder_id, char *subfolder)
+{
+ static char path[FILE_MAX] = "";
+ char search_path[FILE_MAX];
+
+ switch (folder_id) {
+ case BLENDER_DATAFILES: /* general case */
+ BLI_join_dirfile(search_path, "datafiles", subfolder);
+ if (get_path_local(path, search_path)) break;
+ if (get_path_user(path, search_path, "BLENDER_USER_DATAFILES")) break;
+ if (get_path_system(path, search_path, "BLENDER_SYSTEM_DATAFILES")) break;
+ return NULL;
+
+ case BLENDER_USER_DATAFILES:
+ BLI_join_dirfile(search_path, "datafiles", subfolder);
+ if (get_path_local(path, search_path)) break;
+ if (get_path_user(path, search_path, "BLENDER_USER_DATAFILES")) break;
+ return NULL;
+
+ case BLENDER_SYSTEM_DATAFILES:
+ BLI_join_dirfile(search_path, "datafiles", subfolder);
+ if (get_path_system(path, search_path, "BLENDER_SYSTEM_DATAFILES")) break;
+ return NULL;
+
+ case BLENDER_CONFIG: /* general case */
+ BLI_join_dirfile(search_path, "config", subfolder);
+ if (get_path_local(path, search_path)) break;
+ if (get_path_user(path, search_path, "BLENDER_USER_CONFIG")) break;
+ if (get_path_system(path, search_path, "BLENDER_SYSTEM_CONFIG")) break;
+ return NULL;
+
+ case BLENDER_USER_CONFIG:
+ BLI_join_dirfile(search_path, "config", subfolder);
+ if (get_path_local(path, search_path)) break;
+ if (get_path_user(path, search_path, "BLENDER_USER_CONFIG")) break;
+ return NULL;
+
+ case BLENDER_SYSTEM_CONFIG:
+ BLI_join_dirfile(search_path, "config", subfolder);
+ if (get_path_system(path, search_path, "BLENDER_SYSTEM_CONFIG")) break;
+ return NULL;
+
+ case BLENDER_SCRIPTS: /* general case */
+ BLI_join_dirfile(search_path, "scripts", subfolder);
+ if (get_path_local(path, search_path)) break;
+ if (get_path_user(path, search_path, "BLENDER_USER_SCRIPTS")) break;
+ if (get_path_system(path, search_path, "BLENDER_SYSTEM_SCRIPTS")) break;
+ return NULL;
+
+ case BLENDER_USER_SCRIPTS:
+ BLI_join_dirfile(search_path, "scripts", subfolder);
+ if (get_path_local(path, search_path)) break;
+ if (get_path_user(path, search_path, "BLENDER_USER_SCRIPTS")) break;
+ return NULL;
+
+ case BLENDER_SYSTEM_SCRIPTS:
+ BLI_join_dirfile(search_path, "scripts", subfolder);
+ if (get_path_system(path, search_path, "BLENDER_SYSTEM_SCRIPTS")) break;
+ return NULL;
+
+ case BLENDER_PYTHON: /* general case */
+ BLI_join_dirfile(search_path, "python", subfolder);
+ if (get_path_local(path, search_path)) break;
+ if (get_path_system(path, search_path, "BLENDER_SYSTEM_PYTHON")) break;
+ return NULL;
+
+ case BLENDER_SYSTEM_PYTHON:
+ BLI_join_dirfile(search_path, "python", subfolder);
+ if (get_path_system(path, search_path, "BLENDER_SYSTEM_PYTHON")) break;
+ return NULL;
+ }
+
+ return path;
+}
+
+static char *BLI_get_user_folder_notest(int folder_id, char *subfolder)
+{
+ static char path[FILE_MAX] = "";
+ char search_path[FILE_MAX];
+
+ switch (folder_id) {
+ case BLENDER_USER_DATAFILES:
+ BLI_join_dirfile(search_path, "datafiles", subfolder);
+ get_path_user(path, search_path, "BLENDER_USER_DATAFILES");
+ break;
+ case BLENDER_USER_CONFIG:
+ BLI_join_dirfile(search_path, "config", subfolder);
+ get_path_user(path, search_path, "BLENDER_USER_CONFIG");
+ break;
+ }
+ if ('\0' == path[0]) {
+ return NULL;
+ }
+ return path;
+}
+
+char *BLI_get_folder_create(int folder_id, char *subfolder)
+{
+ char *path;
+
+ /* only for user folders */
+ if (!ELEM(folder_id, BLENDER_USER_DATAFILES, BLENDER_USER_CONFIG))
+ return NULL;
+
+ path = BLI_get_folder(folder_id, subfolder);
+
+ if (!path) {
+ path = BLI_get_user_folder_notest(folder_id, subfolder);
+ if (path) BLI_recurdir_fileops(path);
+ }
+
+ return path;
+}
+
+
+/* End new stuff */
+/* ************************************************************* */
+/* ************************************************************* */
+
+
+
#ifdef PATH_DEBUG
#undef PATH_DEBUG
#endif
@@ -1018,7 +1245,7 @@ void BLI_make_exist(char *dir) {
a = strlen(dir);
#ifdef WIN32
- while(BLI_exists(dir) == 0){
+ while(BLI_is_dir(dir) == 0){
a --;
while(dir[a] != '\\'){
a--;
@@ -1032,7 +1259,7 @@ void BLI_make_exist(char *dir) {
}
}
#else
- while(BLI_exist(dir) == 0){
+ while(BLI_is_dir(dir) == 0){
a --;
while(dir[a] != '/'){
a--;
@@ -1049,8 +1276,8 @@ void BLI_make_exist(char *dir) {
void BLI_make_existing_file(char *name)
{
- char di[FILE_MAXDIR], fi[FILE_MAXFILE];
-
+ char di[FILE_MAXDIR+FILE_MAXFILE], fi[FILE_MAXFILE];
+
strcpy(di, name);
BLI_splitdirstring(di, fi);
@@ -1154,25 +1381,38 @@ int BLI_testextensie(const char *str, const char *ext)
return (retval);
}
-/*
- * This is a simple version of BLI_split_dirfile that has the following advantages...
- *
- * Converts "/foo/bar.txt" to "/foo/" and "bar.txt"
+int BLI_replace_extension(char *path, int maxlen, const char *ext)
+{
+ int a;
+
+ for(a=strlen(path)-1; a>=0; a--)
+ if(path[a] == '.' || path[a] == '/' || path[a] == '\\')
+ break;
+
+ if(path[a] != '.')
+ a= strlen(path);
+
+ if(a + strlen(ext) >= maxlen)
+ return 0;
+
+ strcpy(path+a, ext);
+ return 1;
+}
+
+/* Converts "/foo/bar.txt" to "/foo/" and "bar.txt"
* - wont change 'string'
* - wont create any directories
* - dosnt use CWD, or deal with relative paths.
* - Only fill's in *dir and *file when they are non NULL
* */
-void BLI_split_dirfile_basic(const char *string, char *dir, char *file)
+void BLI_split_dirfile(const char *string, char *dir, char *file)
{
- int lslash=0, i = 0;
- for (i=0; string[i]!='\0'; i++) {
- if (string[i]=='\\' || string[i]=='/')
- lslash = i+1;
- }
+ char *lslash_str = BLI_last_slash(string);
+ int lslash= lslash_str ? (int)(lslash_str - string) + 1 : 0;
+
if (dir) {
if (lslash) {
- BLI_strncpy( dir, string, lslash+1); /* +1 to include the slash and the last char */
+ BLI_strncpy( dir, string, lslash + 1); /* +1 to include the slash and the last char */
} else {
dir[0] = '\0';
}
@@ -1183,128 +1423,6 @@ void BLI_split_dirfile_basic(const char *string, char *dir, char *file)
}
}
-
-/* Warning,
- * - May modify 'string' variable
- * - May create the directory if it dosnt exist
- * if this is not needed use BLI_split_dirfile_basic(...)
- */
-void BLI_split_dirfile(char *string, char *dir, char *file)
-{
- int a;
-#ifdef WIN32
- int sl;
- short is_relative = 0;
- char path[FILE_MAX];
-#endif
-
- dir[0]= 0;
- file[0]= 0;
-
-#ifdef WIN32
- BLI_strncpy(path, string, FILE_MAX);
- BLI_char_switch(path, '/', '\\'); /* make sure we have a valid path format */
- sl = strlen(path);
- if (sl) {
- int len;
- if (path[0] == '/' || path[0] == '\\') {
- BLI_strncpy(dir, path, FILE_MAXDIR);
- if (sl > 1 && path[0] == '\\' && path[1] == '\\') is_relative = 1;
- } else if (sl > 2 && path[1] == ':' && path[2] == '\\') {
- BLI_strncpy(dir, path, FILE_MAXDIR);
- } else {
- BLI_getwdN(dir);
- strcat(dir,"\\");
- strcat(dir,path);
- BLI_strncpy(path,dir,FILE_MAXDIR+FILE_MAXFILE);
- }
-
- // BLI_exist doesn't recognize a slashed dirname as a dir
- // check if a trailing slash exists, and remove it. Do not do this
- // when we are already at root. -jesterKing
- a = strlen(dir);
- if(a>=4 && dir[a-1]=='\\') dir[a-1] = 0;
-
- if (is_relative) {
- printf("WARNING: BLI_split_dirfile needs absolute dir\n");
- }
- else {
- BLI_make_exist(dir);
- }
-
- if (S_ISDIR(BLI_exist(dir))) {
-
- /* copy from end of string into file, to ensure filename itself isn't truncated
- if string is too long. (aphex) */
-
- len = FILE_MAXFILE - strlen(path);
-
- if (len < 0)
- BLI_strncpy(file,path + abs(len),FILE_MAXFILE);
- else
- BLI_strncpy(file,path,FILE_MAXFILE);
-
- if (strrchr(path,'\\')) {
- BLI_strncpy(file,strrchr(path,'\\')+1,FILE_MAXFILE);
- }
-
- if ( (a = strlen(dir)) ) {
- if (dir[a-1] != '\\') strcat(dir,"\\");
- }
- }
- else {
- a = strlen(dir) - 1;
- while(a>0 && dir[a] != '\\') a--;
- dir[a + 1] = 0;
- BLI_strncpy(file, path + strlen(dir),FILE_MAXFILE);
- }
-
- }
- else {
- /* defaulting to first valid drive hoping it's not empty CD and DVD drives */
- get_default_root(dir);
- file[0]=0;
- }
-#else
- if (strlen(string)) {
- if (string[0] == '/') {
- strcpy(dir, string);
- } else if (string[1] == ':' && string[2] == '\\') {
- string+=2;
- strcpy(dir, string);
- } else {
- BLI_getwdN(dir);
- strcat(dir,"/");
- strcat(dir,string);
- strcpy((char *)string,dir);
- }
-
- BLI_make_exist(dir);
-
- if (S_ISDIR(BLI_exist(dir))) {
- strcpy(file,string + strlen(dir));
-
- if (strrchr(file,'/')) strcpy(file,strrchr(file,'/')+1);
-
- if ( (a = strlen(dir)) ) {
- if (dir[a-1] != '/') strcat(dir,"/");
- }
- }
- else {
- a = strlen(dir) - 1;
- while(dir[a] != '/') a--;
- dir[a + 1] = 0;
- strcpy(file, string + strlen(dir));
- }
- }
- else {
- BLI_getwdN(dir);
- strcat(dir, "/");
- file[0] = 0;
- }
-#endif
-}
-
/* simple appending of filename to dir, does not check for valid path! */
void BLI_join_dirfile(char *string, const char *dir, const char *file)
{
@@ -1312,6 +1430,9 @@ void BLI_join_dirfile(char *string, const char *dir, const char *file)
if(string != dir) /* compare pointers */
BLI_strncpy(string, dir, FILE_MAX);
+
+ if (!file)
+ return;
sl_dir= BLI_add_slash(string);
@@ -1320,6 +1441,12 @@ void BLI_join_dirfile(char *string, const char *dir, const char *file)
}
}
+/* like pythons os.path.basename( ) */
+char *BLI_path_basename(char *path)
+{
+ char *filename= BLI_last_slash(path);
+ return filename ? filename + 1 : path;
+}
/*
Produce image export path.
@@ -1332,7 +1459,7 @@ void BLI_join_dirfile(char *string, const char *dir, const char *file)
Logic:
- if an image is "below" current .blend file directory, rebuild the
- same dir structure in dest_dir
+ same dir structure in dest_dir
For example //textures/foo/bar.png becomes
[dest_dir]/textures/foo/bar.png.
@@ -1363,7 +1490,7 @@ int BKE_rebase_path(char *abs, int abs_size, char *rel, int rel_size, const char
if (rel)
rel[0]= 0;
- BLI_split_dirfile_basic(base_dir, blend_dir, NULL);
+ BLI_split_dirfile(base_dir, blend_dir, NULL);
if (src_dir[0]=='\0')
return 0;
@@ -1371,10 +1498,10 @@ int BKE_rebase_path(char *abs, int abs_size, char *rel, int rel_size, const char
BLI_strncpy(path, src_dir, sizeof(path));
/* expand "//" in filename and get absolute path */
- BLI_convertstringcode(path, base_dir);
+ BLI_path_abs(path, base_dir);
/* get the directory part */
- BLI_split_dirfile_basic(path, dir, base);
+ BLI_split_dirfile(path, dir, base);
len= strlen(blend_dir);
@@ -1479,7 +1606,7 @@ void BLI_where_am_i(char *fullname, const char *name)
/* linux uses binreloc since argv[0] is not relyable, call br_init( NULL ) first */
path = br_find_exe( NULL );
if (path) {
- strcpy(fullname, path);
+ BLI_strncpy(fullname, path, FILE_MAXDIR+FILE_MAXFILE);
free(path);
return;
}
@@ -1555,7 +1682,7 @@ void BLI_where_is_temp(char *fullname, int usertemp)
{
fullname[0] = '\0';
- if (usertemp && BLI_exists(U.tempdir)) {
+ if (usertemp && BLI_is_dir(U.tempdir)) {
strcpy(fullname, U.tempdir);
}
@@ -1563,7 +1690,7 @@ void BLI_where_is_temp(char *fullname, int usertemp)
#ifdef WIN32
if (fullname[0] == '\0') {
char *tmp = getenv("TEMP"); /* Windows */
- if (tmp && BLI_exists(tmp)) {
+ if (tmp && BLI_is_dir(tmp)) {
strcpy(fullname, tmp);
}
}
@@ -1571,14 +1698,14 @@ void BLI_where_is_temp(char *fullname, int usertemp)
/* Other OS's - Try TMP and TMPDIR */
if (fullname[0] == '\0') {
char *tmp = getenv("TMP");
- if (tmp && BLI_exists(tmp)) {
+ if (tmp && BLI_is_dir(tmp)) {
strcpy(fullname, tmp);
}
}
if (fullname[0] == '\0') {
char *tmp = getenv("TMPDIR");
- if (tmp && BLI_exists(tmp)) {
+ if (tmp && BLI_is_dir(tmp)) {
strcpy(fullname, tmp);
}
}
@@ -1613,29 +1740,7 @@ char *get_install_dir(void) {
}
}
-/*
- * returns absolute path to the app bundle
- * only useful on OS X
- */
-#ifdef __APPLE__
-char* BLI_getbundle(void) {
- CFURLRef bundleURL;
- CFStringRef pathStr;
- static char path[MAXPATHLEN];
- CFBundleRef mainBundle = CFBundleGetMainBundle();
-
- bundleURL = CFBundleCopyBundleURL(mainBundle);
- pathStr = CFURLCopyFileSystemPath(bundleURL, kCFURLPOSIXPathStyle);
- CFStringGetCString(pathStr, path, MAXPATHLEN, kCFStringEncodingASCII);
- CFRelease(pathStr);
- CFRelease(bundleURL);
- return path;
-}
-#endif
-
#ifdef WITH_ICONV
-#include "iconv.h"
-#include "localcharset.h"
void BLI_string_to_utf8(char *original, char *utf_8, const char *code)
{
diff --git a/source/blender/blenlib/intern/pbvh.c b/source/blender/blenlib/intern/pbvh.c
index 9e1dd096528..4c5177a403e 100644
--- a/source/blender/blenlib/intern/pbvh.c
+++ b/source/blender/blenlib/intern/pbvh.c
@@ -20,11 +20,7 @@
* ***** END GPL LICENSE BLOCK *****
*/
-#include <float.h>
-#include <stdlib.h>
-#include <string.h>
-#include "MEM_guardedalloc.h"
#include "DNA_meshdata_types.h"
@@ -33,10 +29,10 @@
#include "BLI_pbvh.h"
#include "BKE_DerivedMesh.h"
-#include "BKE_mesh.h"
-#include "BKE_utildefines.h"
+#include "BKE_mesh.h" /* for mesh_calc_normals */
+#include "BKE_global.h" /* for mesh_calc_normals */
-#include "gpu_buffers.h"
+#include "GPU_buffers.h"
#define LEAF_LIMIT 10000
@@ -96,6 +92,11 @@ struct PBVHNode {
unsigned int uniq_verts, face_verts;
char flag;
+
+ float tmin; // used for raycasting, is how close bb is to the ray point
+
+ int proxy_count;
+ PBVHProxyNode* proxies;
};
struct PBVH {
@@ -126,6 +127,9 @@ struct PBVH {
#ifdef PERFCNTRS
int perf_modified;
#endif
+
+ /* flag are verts/faces deformed */
+ int deformed;
};
#define STACK_FIXED_DEPTH 100
@@ -228,10 +232,21 @@ static void update_node_vb(PBVH *bvh, PBVHNode *node)
node->vb= vb;
}
+//void BLI_pbvh_node_BB_reset(PBVHNode* node)
+//{
+// BB_reset(&node->vb);
+//}
+//
+//void BLI_pbvh_node_BB_expand(PBVHNode* node, float co[3])
+//{
+// BB_expand(&node->vb, co);
+//}
+
+
/* Adapted from BLI_kdopbvh.c */
/* Returns the index of the first element on the right of the partition */
static int partition_indices(int *prim_indices, int lo, int hi, int axis,
- float mid, BBC *prim_bbc)
+ float mid, BBC *prim_bbc)
{
int i=lo, j=hi;
for(;;) {
@@ -247,7 +262,7 @@ static int partition_indices(int *prim_indices, int lo, int hi, int axis,
}
void check_partitioning(int *prim_indices, int lo, int hi, int axis,
- float mid, BBC *prim_bbc, int index_of_2nd_partition)
+ float mid, BBC *prim_bbc, int index_of_2nd_partition)
{
int i;
for(i = lo; i <= hi; ++i) {
@@ -279,8 +294,8 @@ static void grow_nodes(PBVH *bvh, int totnode)
/* Add a vertex to the map, with a positive value for unique vertices and
a negative value for additional vertices */
static int map_insert_vert(PBVH *bvh, GHash *map,
- unsigned int *face_verts,
- unsigned int *uniq_verts, int vertex)
+ unsigned int *face_verts,
+ unsigned int *uniq_verts, int vertex)
{
void *value, *key = SET_INT_IN_POINTER(vertex);
@@ -309,7 +324,7 @@ static void build_mesh_leaf_node(PBVH *bvh, PBVHNode *node)
GHash *map;
int i, j, totface;
- map = BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp);
+ map = BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, "build_mesh_leaf_node gh");
node->uniq_verts = node->face_verts = 0;
totface= node->totprim;
@@ -334,8 +349,8 @@ static void build_mesh_leaf_node(PBVH *bvh, PBVHNode *node)
/* Build the vertex list, unique verts first */
for(iter = BLI_ghashIterator_new(map), i = 0;
- !BLI_ghashIterator_isDone(iter);
- BLI_ghashIterator_step(iter), ++i) {
+ !BLI_ghashIterator_isDone(iter);
+ BLI_ghashIterator_step(iter), ++i) {
void *value = BLI_ghashIterator_getValue(iter);
int ndx = GET_INT_FROM_POINTER(value);
@@ -352,21 +367,28 @@ static void build_mesh_leaf_node(PBVH *bvh, PBVHNode *node)
if(node->face_vert_indices[i] < 0)
node->face_vert_indices[i]= -node->face_vert_indices[i] + node->uniq_verts - 1;
- node->draw_buffers =
- GPU_build_mesh_buffers(map, bvh->verts, bvh->faces,
- node->prim_indices,
- node->totprim, node->vert_indices,
- node->uniq_verts,
- node->uniq_verts + node->face_verts);
+ if(!G.background) {
+ node->draw_buffers =
+ GPU_build_mesh_buffers(map, bvh->verts, bvh->faces,
+ node->prim_indices,
+ node->totprim, node->vert_indices,
+ node->uniq_verts,
+ node->uniq_verts + node->face_verts);
+ }
+
+ node->flag |= PBVH_UpdateDrawBuffers;
BLI_ghash_free(map, NULL, NULL);
}
static void build_grids_leaf_node(PBVH *bvh, PBVHNode *node)
{
- node->draw_buffers =
- GPU_build_grid_buffers(bvh->grids, node->prim_indices,
+ if(!G.background) {
+ node->draw_buffers =
+ GPU_build_grid_buffers(bvh->grids, node->prim_indices,
node->totprim, bvh->gridsize);
+ }
+ node->flag |= PBVH_UpdateDrawBuffers;
}
/* Recursively build a node in the tree
@@ -381,7 +403,7 @@ static void build_grids_leaf_node(PBVH *bvh, PBVHNode *node)
*/
void build_sub(PBVH *bvh, int node_index, BB *cb, BBC *prim_bbc,
- int offset, int count)
+ int offset, int count)
{
int i, axis, end;
BB cb_backing;
@@ -578,6 +600,15 @@ void BLI_pbvh_free(PBVH *bvh)
}
}
+ if (bvh->deformed) {
+ if (bvh->verts) {
+ /* if pbvh was deformed, new memory was allocated for verts/faces -- free it */
+
+ MEM_freeN(bvh->verts);
+ MEM_freeN(bvh->faces);
+ }
+ }
+
MEM_freeN(bvh->nodes);
MEM_freeN(bvh->prim_indices);
MEM_freeN(bvh);
@@ -626,13 +657,12 @@ static PBVHNode *pbvh_iter_next(PBVHIter *iter)
{
PBVHNode *node;
int revisiting;
- void *search_data;
/* purpose here is to traverse tree, visiting child nodes before their
parents, this order is necessary for e.g. computing bounding boxes */
while(iter->stacksize) {
- /* pop node */
+ /* pop node */
iter->stacksize--;
node= iter->stack[iter->stacksize].node;
@@ -647,10 +677,7 @@ static PBVHNode *pbvh_iter_next(PBVHIter *iter)
if(revisiting)
return node;
- /* check search callback */
- search_data= iter->search_data;
-
- if(iter->scb && !iter->scb(node, search_data))
+ if(iter->scb && !iter->scb(node, iter->search_data))
continue; /* don't traverse, outside of search zone */
if(node->flag & PBVH_Leaf) {
@@ -670,6 +697,34 @@ static PBVHNode *pbvh_iter_next(PBVHIter *iter)
return NULL;
}
+static PBVHNode *pbvh_iter_next_occluded(PBVHIter *iter)
+{
+ PBVHNode *node;
+
+ while(iter->stacksize) {
+ /* pop node */
+ iter->stacksize--;
+ node= iter->stack[iter->stacksize].node;
+
+ /* on a mesh with no faces this can happen
+ * can remove this check if we know meshes have at least 1 face */
+ if(node==NULL) return NULL;
+
+ if(iter->scb && !iter->scb(node, iter->search_data)) continue; /* don't traverse, outside of search zone */
+
+ if(node->flag & PBVH_Leaf) {
+ /* immediately hit leaf node */
+ return node;
+ }
+ else {
+ pbvh_stack_push(iter, iter->bvh->nodes+node->children_offset+1, 0);
+ pbvh_stack_push(iter, iter->bvh->nodes+node->children_offset, 0);
+ }
+ }
+
+ return NULL;
+}
+
void BLI_pbvh_search_gather(PBVH *bvh,
BLI_pbvh_SearchCallback scb, void *search_data,
PBVHNode ***r_array, int *r_tot)
@@ -721,12 +776,105 @@ void BLI_pbvh_search_callback(PBVH *bvh,
pbvh_iter_begin(&iter, bvh, scb, search_data);
while((node=pbvh_iter_next(&iter)))
- if(node->flag & PBVH_Leaf)
+ if (node->flag & PBVH_Leaf)
hcb(node, hit_data);
pbvh_iter_end(&iter);
}
+typedef struct node_tree {
+ PBVHNode* data;
+
+ struct node_tree* left;
+ struct node_tree* right;
+} node_tree;
+
+static void node_tree_insert(node_tree* tree, node_tree* new_node)
+{
+ if (new_node->data->tmin < tree->data->tmin) {
+ if (tree->left) {
+ node_tree_insert(tree->left, new_node);
+ }
+ else {
+ tree->left = new_node;
+ }
+ }
+ else {
+ if (tree->right) {
+ node_tree_insert(tree->right, new_node);
+ }
+ else {
+ tree->right = new_node;
+ }
+ }
+}
+
+static void traverse_tree(node_tree* tree, BLI_pbvh_HitOccludedCallback hcb, void* hit_data, float* tmin)
+{
+ if (tree->left) traverse_tree(tree->left, hcb, hit_data, tmin);
+
+ hcb(tree->data, hit_data, tmin);
+
+ if (tree->right) traverse_tree(tree->right, hcb, hit_data, tmin);
+}
+
+static void free_tree(node_tree* tree)
+{
+ if (tree->left) {
+ free_tree(tree->left);
+ tree->left = 0;
+ }
+
+ if (tree->right) {
+ free_tree(tree->right);
+ tree->right = 0;
+ }
+
+ free(tree);
+}
+
+float BLI_pbvh_node_get_tmin(PBVHNode* node)
+{
+ return node->tmin;
+}
+
+void BLI_pbvh_search_callback_occluded(PBVH *bvh,
+ BLI_pbvh_SearchCallback scb, void *search_data,
+ BLI_pbvh_HitOccludedCallback hcb, void *hit_data)
+{
+ PBVHIter iter;
+ PBVHNode *node;
+ node_tree *tree = 0;
+
+ pbvh_iter_begin(&iter, bvh, scb, search_data);
+
+ while((node=pbvh_iter_next_occluded(&iter))) {
+ if(node->flag & PBVH_Leaf) {
+ node_tree* new_node = malloc(sizeof(node_tree));
+
+ new_node->data = node;
+
+ new_node->left = NULL;
+ new_node->right = NULL;
+
+ if (tree) {
+ node_tree_insert(tree, new_node);
+ }
+ else {
+ tree = new_node;
+ }
+ }
+ }
+
+ pbvh_iter_end(&iter);
+
+ if (tree) {
+ float tmin = FLT_MAX;
+ traverse_tree(tree, hcb, hit_data, &tmin);
+ free_tree(tree);
+ }
+}
+
static int update_search_cb(PBVHNode *node, void *data_v)
{
int flag= GET_INT_FROM_POINTER(data_v);
@@ -752,11 +900,11 @@ static void pbvh_update_normals(PBVH *bvh, PBVHNode **nodes,
/* subtle assumptions:
- We know that for all edited vertices, the nodes with faces
- adjacent to these vertices have been marked with PBVH_UpdateNormals.
+ adjacent to these vertices have been marked with PBVH_UpdateNormals.
This is true because if the vertex is inside the brush radius, the
bounding box of it's adjacent faces will be as well.
- However this is only true for the vertices that have actually been
- edited, not for all vertices in the nodes marked for update, so we
+ edited, not for all vertices in the nodes marked for update, so we
can only update vertices marked with ME_VERT_PBVH_UPDATE.
*/
@@ -861,7 +1009,7 @@ static void pbvh_update_BB_redraw(PBVH *bvh, PBVHNode **nodes,
}
}
-static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode)
+static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode, int smooth)
{
PBVHNode *node;
int n;
@@ -876,7 +1024,8 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode)
bvh->grids,
node->prim_indices,
node->totprim,
- bvh->gridsize);
+ bvh->gridsize,
+ smooth);
}
else {
GPU_update_mesh_buffers(node->draw_buffers,
@@ -936,9 +1085,6 @@ void BLI_pbvh_update(PBVH *bvh, int flag, float (*face_nors)[3])
if(flag & (PBVH_UpdateBB|PBVH_UpdateOriginalBB|PBVH_UpdateRedraw))
pbvh_update_BB_redraw(bvh, nodes, totnode, flag);
- if(flag & PBVH_UpdateDrawBuffers)
- pbvh_update_draw_buffers(bvh, nodes, totnode);
-
if(flag & (PBVH_UpdateBB|PBVH_UpdateOriginalBB))
pbvh_flush_bb(bvh, bvh->nodes, flag);
@@ -972,9 +1118,10 @@ void BLI_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***gridfaces, int *tot
GHashIterator *hiter;
GHash *map;
void *face, **faces;
- int i, tot;
+ unsigned i;
+ int tot;
- map = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
+ map = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "pbvh_get_grid_updates gh");
pbvh_iter_begin(&iter, bvh, NULL, NULL);
@@ -1004,8 +1151,8 @@ void BLI_pbvh_get_grid_updates(PBVH *bvh, int clear, void ***gridfaces, int *tot
faces= MEM_callocN(sizeof(void*)*tot, "PBVH Grid Faces");
for(hiter = BLI_ghashIterator_new(map), i = 0;
- !BLI_ghashIterator_isDone(hiter);
- BLI_ghashIterator_step(hiter), ++i)
+ !BLI_ghashIterator_isDone(hiter);
+ BLI_ghashIterator_step(hiter), ++i)
faces[i]= BLI_ghashIterator_getKey(hiter);
BLI_ghashIterator_free(hiter);
@@ -1073,6 +1220,18 @@ void BLI_pbvh_node_get_original_BB(PBVHNode *node, float bb_min[3], float bb_max
copy_v3_v3(bb_max, node->orig_vb.bmax);
}
+void BLI_pbvh_node_get_proxies(PBVHNode* node, PBVHProxyNode** proxies, int* proxy_count)
+{
+ if (node->proxy_count > 0) {
+ if (proxies) *proxies = node->proxies;
+ if (proxy_count) *proxy_count = node->proxy_count;
+ }
+ else {
+ if (proxies) *proxies = 0;
+ if (proxy_count) *proxy_count = 0;
+ }
+}
+
/********************************* Raycast ***********************************/
typedef struct {
@@ -1087,16 +1246,13 @@ typedef struct {
static int ray_aabb_intersect(PBVHNode *node, void *data_v)
{
RaycastData *ray = data_v;
- float bb_min[3], bb_max[3], bbox[2][3];
+ float bbox[2][3];
float tmin, tmax, tymin, tymax, tzmin, tzmax;
if(ray->original)
- BLI_pbvh_node_get_original_BB(node, bb_min, bb_max);
+ BLI_pbvh_node_get_original_BB(node, bbox[0], bbox[1]);
else
- BLI_pbvh_node_get_BB(node, bb_min, bb_max);
-
- copy_v3_v3(bbox[0], bb_min);
- copy_v3_v3(bbox[1], bb_max);
+ BLI_pbvh_node_get_BB(node, bbox[0], bbox[1]);
tmin = (bbox[ray->sign[0]][0] - ray->start[0]) * ray->inv_dir[0];
tmax = (bbox[1-ray->sign[0]][0] - ray->start[0]) * ray->inv_dir[0];
@@ -1106,8 +1262,10 @@ static int ray_aabb_intersect(PBVHNode *node, void *data_v)
if((tmin > tymax) || (tymin > tmax))
return 0;
+
if(tymin > tmin)
tmin = tymin;
+
if(tymax < tmax)
tmax = tymax;
@@ -1116,21 +1274,21 @@ static int ray_aabb_intersect(PBVHNode *node, void *data_v)
if((tmin > tzmax) || (tzmin > tmax))
return 0;
-
- return 1;
- /* XXX: Not sure about this?
- if(tzmin > tmin)
- tmin = tzmin;
- if(tzmax < tmax)
- tmax = tzmax;
- return ((tmin < t1) && (tmax > t0));
- */
+ if(tzmin > tmin)
+ tmin = tzmin;
+
+ // XXX jwilkins: tmax does not need to be updated since we don't use it
+ // keeping this here for future reference
+ //if(tzmax < tmax) tmax = tzmax;
+ node->tmin = tmin;
+
+ return 1;
}
-void BLI_pbvh_raycast(PBVH *bvh, BLI_pbvh_HitCallback cb, void *data,
- float ray_start[3], float ray_normal[3], int original)
+void BLI_pbvh_raycast(PBVH *bvh, BLI_pbvh_HitOccludedCallback cb, void *data,
+ float ray_start[3], float ray_normal[3], int original)
{
RaycastData rcd;
@@ -1143,37 +1301,24 @@ void BLI_pbvh_raycast(PBVH *bvh, BLI_pbvh_HitCallback cb, void *data,
rcd.sign[2] = rcd.inv_dir[2] < 0;
rcd.original = original;
- BLI_pbvh_search_callback(bvh, ray_aabb_intersect, &rcd, cb, data);
+ BLI_pbvh_search_callback_occluded(bvh, ray_aabb_intersect, &rcd, cb, data);
}
-/* XXX: Code largely copied from bvhutils.c, could be unified */
-/* Returns 1 if a better intersection has been found */
static int ray_face_intersection(float ray_start[3], float ray_normal[3],
float *t0, float *t1, float *t2, float *t3,
float *fdist)
{
- int hit = 0;
-
- do
- {
- float dist = FLT_MAX;
-
- if(!isect_ray_tri_epsilon_v3(ray_start, ray_normal, t0, t1, t2,
- &dist, NULL, 0.1f))
- dist = FLT_MAX;
-
- if(dist >= 0 && dist < *fdist) {
- hit = 1;
- *fdist = dist;
- }
-
- t1 = t2;
- t2 = t3;
- t3 = NULL;
-
- } while(t2);
-
- return hit;
+ float dist;
+
+ if ((isect_ray_tri_epsilon_v3(ray_start, ray_normal, t0, t1, t2, &dist, NULL, 0.1f) && dist < *fdist) ||
+ (t3 && isect_ray_tri_epsilon_v3(ray_start, ray_normal, t0, t2, t3, &dist, NULL, 0.1f) && dist < *fdist))
+ {
+ *fdist = dist;
+ return 1;
+ }
+ else {
+ return 0;
+ }
}
int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3],
@@ -1218,6 +1363,8 @@ int BLI_pbvh_node_raycast(PBVH *bvh, PBVHNode *node, float (*origco)[3],
for(i = 0; i < totgrid; ++i) {
DMGridData *grid= bvh->grids[node->prim_indices[i]];
+ if (!grid)
+ continue;
for(y = 0; y < gridsize-1; ++y) {
for(x = 0; x < gridsize-1; ++x) {
@@ -1304,9 +1451,18 @@ int BLI_pbvh_node_planes_contain_AABB(PBVHNode *node, void *data)
return 1;
}
-void BLI_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3])
+void BLI_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3], int smooth)
{
- BLI_pbvh_update(bvh, PBVH_UpdateNormals|PBVH_UpdateDrawBuffers, face_nors);
+ PBVHNode **nodes;
+ int totnode;
+
+ BLI_pbvh_search_gather(bvh, update_search_cb, SET_INT_IN_POINTER(PBVH_UpdateNormals|PBVH_UpdateDrawBuffers),
+ &nodes, &totnode);
+
+ pbvh_update_normals(bvh, nodes, totnode, face_nors);
+ pbvh_update_draw_buffers(bvh, nodes, totnode, smooth);
+
+ if(nodes) MEM_freeN(nodes);
if(planes) {
BLI_pbvh_search_callback(bvh, BLI_pbvh_node_planes_contain_AABB,
@@ -1317,3 +1473,145 @@ void BLI_pbvh_draw(PBVH *bvh, float (*planes)[4], float (*face_nors)[3])
}
}
+void BLI_pbvh_grids_update(PBVH *bvh, DMGridData **grids, DMGridAdjacency *gridadj, void **gridfaces)
+{
+ bvh->grids= grids;
+ bvh->gridadj= gridadj;
+ bvh->gridfaces= gridfaces;
+}
+
+float (*BLI_pbvh_get_vertCos(PBVH *pbvh))[3]
+{
+ int a;
+ float (*vertCos)[3]= NULL;
+
+ if (pbvh->verts) {
+ float *co;
+ MVert *mvert= pbvh->verts;
+
+ vertCos= MEM_callocN(3*pbvh->totvert*sizeof(float), "BLI_pbvh_get_vertCoords");
+ co= (float*)vertCos;
+
+ for (a= 0; a<pbvh->totvert; a++, mvert++, co+= 3) {
+ copy_v3_v3(co, mvert->co);
+ }
+ }
+
+ return vertCos;
+}
+
+void BLI_pbvh_apply_vertCos(PBVH *pbvh, float (*vertCos)[3])
+{
+ int a;
+
+ if (!pbvh->deformed) {
+ if (pbvh->verts) {
+ /* if pbvh is not already deformed, verts/faces points to the */
+ /* original data and applying new coords to this arrays would lead to */
+ /* unneeded deformation -- duplicate verts/faces to avoid this */
+
+ pbvh->verts= MEM_dupallocN(pbvh->verts);
+ pbvh->faces= MEM_dupallocN(pbvh->faces);
+
+ pbvh->deformed= 1;
+ }
+ }
+
+ if (pbvh->verts) {
+ /* copy new verts coords */
+ for (a= 0; a < pbvh->totvert; ++a) {
+ copy_v3_v3(pbvh->verts[a].co, vertCos[a]);
+ }
+
+ /* coordinates are new -- normals should also be updated */
+ mesh_calc_normals(pbvh->verts, pbvh->totvert, pbvh->faces, pbvh->totprim, NULL);
+ }
+}
+
+int BLI_pbvh_isDeformed(PBVH *pbvh)
+{
+ return pbvh->deformed;
+}
+/* Proxies */
+
+PBVHProxyNode* BLI_pbvh_node_add_proxy(PBVH* bvh, PBVHNode* node)
+{
+ int index, totverts;
+
+ #pragma omp critical
+ {
+
+ index = node->proxy_count;
+
+ node->proxy_count++;
+
+ if (node->proxies)
+ node->proxies= MEM_reallocN(node->proxies, node->proxy_count*sizeof(PBVHProxyNode));
+ else
+ node->proxies= MEM_mallocN(sizeof(PBVHProxyNode), "PBVHNodeProxy");
+
+ if (bvh->grids)
+ totverts = node->totprim*bvh->gridsize*bvh->gridsize;
+ else
+ totverts = node->uniq_verts;
+
+ node->proxies[index].co= MEM_callocN(sizeof(float[3])*totverts, "PBVHNodeProxy.co");
+ }
+
+ return node->proxies + index;
+}
+
+void BLI_pbvh_node_free_proxies(PBVHNode* node)
+{
+ #pragma omp critical
+ {
+ int p;
+
+ for (p= 0; p < node->proxy_count; p++) {
+ MEM_freeN(node->proxies[p].co);
+ node->proxies[p].co= 0;
+ }
+
+ MEM_freeN(node->proxies);
+ node->proxies = 0;
+
+ node->proxy_count= 0;
+ }
+}
+
+void BLI_pbvh_gather_proxies(PBVH* pbvh, PBVHNode*** r_array, int* r_tot)
+{
+ PBVHNode **array= NULL, **newarray, *node;
+ int tot= 0, space= 0;
+ int n;
+
+ for (n= 0; n < pbvh->totnode; n++) {
+ node = pbvh->nodes + n;
+
+ if(node->proxy_count > 0) {
+ if(tot == space) {
+ /* resize array if needed */
+ space= (tot == 0)? 32: space*2;
+ newarray= MEM_callocN(sizeof(PBVHNode)*space, "BLI_pbvh_gather_proxies");
+
+ if (array) {
+ memcpy(newarray, array, sizeof(PBVHNode)*tot);
+ MEM_freeN(array);
+ }
+
+ array= newarray;
+ }
+
+ array[tot]= node;
+ tot++;
+ }
+ }
+
+ if(tot == 0 && array) {
+ MEM_freeN(array);
+ array= NULL;
+ }
+
+ *r_array= array;
+ *r_tot= tot;
+}
diff --git a/source/blender/blenlib/intern/rand.c b/source/blender/blenlib/intern/rand.c
index 4e469ad3834..7c14cfd3426 100644
--- a/source/blender/blenlib/intern/rand.c
+++ b/source/blender/blenlib/intern/rand.c
@@ -37,10 +37,6 @@
#include "BLI_threads.h"
#include "BLI_rand.h"
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
#if defined(WIN32) && !defined(FREE_WINDOWS)
typedef unsigned __int64 r_uint64;
diff --git a/source/blender/blenlib/intern/rct.c b/source/blender/blenlib/intern/rct.c
index 959d8be466f..5466acdba9f 100644
--- a/source/blender/blenlib/intern/rct.c
+++ b/source/blender/blenlib/intern/rct.c
@@ -36,11 +36,6 @@
*/
#include "DNA_vec_types.h"
-#include "BLI_blenlib.h"
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
int BLI_rcti_is_empty(rcti * rect)
{
@@ -147,6 +142,27 @@ void BLI_translate_rctf(rctf *rect, float x, float y)
rect->ymax += y;
}
+/* change width & height around the central location */
+void BLI_resize_rcti(rcti *rect, int x, int y)
+{
+ rect->xmin= rect->xmax= (rect->xmax + rect->xmin) / 2;
+ rect->ymin= rect->ymax= (rect->ymax + rect->ymin) / 2;
+ rect->xmin -= x / 2;
+ rect->ymin -= y / 2;
+ rect->xmax= rect->xmin + x;
+ rect->ymax= rect->ymin + y;
+}
+
+void BLI_resize_rctf(rctf *rect, float x, float y)
+{
+ rect->xmin= rect->xmax= (rect->xmax + rect->xmin) * 0.5f;
+ rect->ymin= rect->ymax= (rect->ymax + rect->ymin) * 0.5f;
+ rect->xmin -= x * 0.5f;
+ rect->ymin -= y * 0.5f;
+ rect->xmax= rect->xmin + x;
+ rect->ymax= rect->ymin + y;
+}
+
int BLI_isect_rctf(rctf *src1, rctf *src2, rctf *dest)
{
float xmin, xmax;
diff --git a/source/blender/blenlib/intern/scanfill.c b/source/blender/blenlib/intern/scanfill.c
index e430f78a100..d1150748dff 100644
--- a/source/blender/blenlib/intern/scanfill.c
+++ b/source/blender/blenlib/intern/scanfill.c
@@ -35,21 +35,13 @@
#include "MEM_guardedalloc.h"
-#include "DNA_listBase.h"
-#include "DNA_mesh_types.h"
#include "BLI_editVert.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
-#include "BLI_scanfill.h"
-#include "BLI_callbacks.h"
#include "BKE_utildefines.h"
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
/* callbacks for errors and interrupts and some goo */
static void (*BLI_localErrorCallBack)(char*) = NULL;
static int (*BLI_localInterruptCallBack)(void) = NULL;
@@ -187,7 +179,7 @@ static void *new_mem_element(int size)
if(cur) {
if(size+offs < blocksize) {
adr= (void *) (cur->data+offs);
- offs+= size;
+ offs+= size;
return adr;
}
}
@@ -306,7 +298,7 @@ static short testedgeside(float *v1, float *v2, float *v3)
float inp;
inp= (v2[cox]-v1[cox])*(v1[coy]-v3[coy])
- +(v1[coy]-v2[coy])*(v1[cox]-v3[cox]);
+ +(v1[coy]-v2[coy])*(v1[cox]-v3[cox]);
if(inp<0.0) return 0;
else if(inp==0) {
@@ -383,7 +375,7 @@ static ScFillVert *addedgetoscanlist(EditEdge *eed, int len)
/* find location in list */
scsearch.v1= eed->v1;
sc= (ScFillVert *)bsearch(&scsearch,scdata,len,
- sizeof(ScFillVert), vergscdata);
+ sizeof(ScFillVert), vergscdata);
if(sc==0) printf("Error in search edge: %p\n",eed);
else if(addedgetoscanvert(sc,eed)==0) return sc;
diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c
index f21e5ef5575..3315e9645d4 100644
--- a/source/blender/blenlib/intern/storage.c
+++ b/source/blender/blenlib/intern/storage.c
@@ -76,7 +76,6 @@
#endif
#ifdef WIN32
-#include <sys/types.h>
#include <io.h>
#include <direct.h>
#include "BLI_winstuff.h"
@@ -90,8 +89,6 @@
#include "BLI_listbase.h"
#include "BLI_linklist.h"
-#include "BLI_path_util.h"
-#include "BLI_storage.h"
#include "BLI_storage_types.h"
#include "BLI_string.h"
#include "BKE_utildefines.h"
@@ -204,14 +201,6 @@ double BLI_diskfree(char *dir)
#endif
}
-static int hide_dot= 0;
-
-void BLI_hide_dot_files(int set)
-{
- if(set) hide_dot= 1;
- else hide_dot= 0;
-}
-
void BLI_builddir(char *dirname, char *relname)
{
struct dirent *fname;
@@ -237,17 +226,12 @@ void BLI_builddir(char *dirname, char *relname)
while ((fname = (struct dirent*) readdir(dir)) != NULL) {
len= strlen(fname->d_name);
- if(hide_dot && fname->d_name[0]=='.' && fname->d_name[1]!='.' && fname->d_name[1]!=0); /* ignore .file */
- else if(hide_dot && len && fname->d_name[len-1]=='~'); /* ignore file~ */
- else if (((fname->d_name[0] == '.') && (fname->d_name[1] == 0) )); /* ignore . */
- else {
- dlink = (struct dirlink *)malloc(sizeof(struct dirlink));
- if (dlink){
- strcpy(buf+rellen,fname->d_name);
- dlink->name = BLI_strdup(buf);
- BLI_addhead(dirbase,dlink);
- newnum++;
- }
+ dlink = (struct dirlink *)malloc(sizeof(struct dirlink));
+ if (dlink){
+ strcpy(buf+rellen,fname->d_name);
+ dlink->name = BLI_strdup(buf);
+ BLI_addhead(dirbase,dlink);
+ newnum++;
}
}
@@ -308,10 +292,8 @@ void BLI_adddirstrings()
struct direntry * file;
struct tm *tm;
time_t zero= 0;
-
- file = &files[0];
- for(num=0;num<actnum;num++){
+ for(num=0, file= files; num<actnum; num++, file++){
#ifdef WIN32
mode = 0;
strcpy(file->mode1, types[0]);
@@ -340,43 +322,43 @@ void BLI_adddirstrings()
#endif
#ifdef WIN32
- strcpy(files[num].owner,"user");
+ strcpy(file->owner,"user");
#else
{
struct passwd *pwuser;
- pwuser = getpwuid(files[num].s.st_uid);
+ pwuser = getpwuid(file->s.st_uid);
if ( pwuser ) {
- strcpy(files[num].owner, pwuser->pw_name);
+ BLI_strncpy(file->owner, pwuser->pw_name, sizeof(file->owner));
} else {
- sprintf(files[num].owner, "%d", files[num].s.st_uid);
- }
+ snprintf(file->owner, sizeof(file->owner), "%d", file->s.st_uid);
+ }
}
#endif
- tm= localtime(&files[num].s.st_mtime);
+ tm= localtime(&file->s.st_mtime);
// prevent impossible dates in windows
if(tm==NULL) tm= localtime(&zero);
- strftime(files[num].time, 8, "%H:%M", tm);
- strftime(files[num].date, 16, "%d-%b-%y", tm);
+ strftime(file->time, 8, "%H:%M", tm);
+ strftime(file->date, 16, "%d-%b-%y", tm);
/*
* 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.
*/
- st_size= files[num].s.st_size;
+ st_size= file->s.st_size;
if (st_size > 1024*1024*1024) {
- sprintf(files[num].size, "%.2f GB", ((double)st_size)/(1024*1024*1024));
+ sprintf(file->size, "%.2f GB", ((double)st_size)/(1024*1024*1024));
}
else if (st_size > 1024*1024) {
- sprintf(files[num].size, "%.1f MB", ((double)st_size)/(1024*1024));
+ sprintf(file->size, "%.1f MB", ((double)st_size)/(1024*1024));
}
else if (st_size > 1024) {
- sprintf(files[num].size, "%d KB", (int)(st_size/1024));
+ sprintf(file->size, "%d KB", (int)(st_size/1024));
}
else {
- sprintf(files[num].size, "%d B", (int)st_size);
+ sprintf(file->size, "%d B", (int)st_size);
}
strftime(datum, 32, "%d-%b-%y %H:%M", tm);
@@ -392,15 +374,13 @@ void BLI_adddirstrings()
sprintf(size, "%10d", (int) st_size);
}
- sprintf(buf,"%s %s %s %7s %s %s %10s %s", file->mode1, file->mode2, file->mode3, files[num].owner, files[num].date, files[num].time, size,
- files[num].relname);
+ sprintf(buf,"%s %s %s %7s %s %s %10s %s", file->mode1, file->mode2, file->mode3, file->owner, file->date, file->time, size,
+ file->relname);
- files[num].string=MEM_mallocN(strlen(buf)+1, "filestring");
- if (files[num].string){
- strcpy(files[num].string,buf);
+ file->string=MEM_mallocN(strlen(buf)+1, "filestring");
+ if (file->string){
+ strcpy(file->string,buf);
}
-
- file++;
}
}
@@ -452,18 +432,20 @@ int BLI_filepathsize(const char *path)
int BLI_exist(char *name)
{
- struct stat st;
#ifdef WIN32
+ struct _stat64i32 st;
/* in Windows stat doesn't recognize dir ending on a slash
To not break code where the ending slash is expected we
don't mess with the argument name directly here - elubie */
char tmp[FILE_MAXDIR+FILE_MAXFILE];
- int len;
+ int len, res;
BLI_strncpy(tmp, name, FILE_MAXDIR+FILE_MAXFILE);
len = strlen(tmp);
if (len > 3 && ( tmp[len-1]=='\\' || tmp[len-1]=='/') ) tmp[len-1] = '\0';
- if (stat(tmp,&st)) return(0);
+ res = _stat(tmp, &st);
+ if (res == -1) return(0);
#else
+ struct stat st;
if (stat(name,&st)) return(0);
#endif
return(st.st_mode);
@@ -519,3 +501,14 @@ void BLI_free_file_lines(LinkNode *lines)
{
BLI_linklist_free(lines, (void(*)(void*)) MEM_freeN);
}
+
+int BLI_file_older(const char *file1, const char *file2)
+{
+ struct stat st1, st2;
+
+ if(stat(file1, &st1)) return 0;
+ if(stat(file2, &st2)) return 0;
+
+ return (st1.st_mtime < st2.st_mtime);
+}
+
diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c
index dd1d0a3bd4f..c344d8c0711 100644
--- a/source/blender/blenlib/intern/string.c
+++ b/source/blender/blenlib/intern/string.c
@@ -32,7 +32,6 @@
*
*/
-#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
@@ -221,10 +220,10 @@ int BLI_strcaseeq(const char *a, const char *b)
/* strcasestr not available in MSVC */
char *BLI_strcasestr(const char *s, const char *find)
{
- register char c, sc;
- register size_t len;
+ register char c, sc;
+ register size_t len;
- if ((c = *find++) != 0) {
+ if ((c = *find++) != 0) {
c= tolower(c);
len = strlen(find);
do {
@@ -235,8 +234,8 @@ char *BLI_strcasestr(const char *s, const char *find)
} while (sc != c);
} while (BLI_strncasecmp(s, find, len) != 0);
s--;
- }
- return ((char *) s);
+ }
+ return ((char *) s);
}
diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c
index 371fae3dda2..726ed817f8b 100644
--- a/source/blender/blenlib/intern/threads.c
+++ b/source/blender/blenlib/intern/threads.c
@@ -28,15 +28,11 @@
* ***** END GPL LICENSE BLOCK *****
*/
-#include <math.h>
-#include <stdlib.h>
-#include <string.h>
-#include <pthread.h>
#include <errno.h>
+#include <string.h>
#include "MEM_guardedalloc.h"
-#include "DNA_listBase.h"
#include "BLI_blenlib.h"
#include "BLI_gsqueue.h"
@@ -56,6 +52,12 @@
#include <sys/time.h>
#endif
+#if defined(__APPLE__) && (PARALLEL == 1) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 2)
+/* ************** libgomp (Apple gcc 4.2.1) TLS bug workaround *************** */
+extern pthread_key_t gomp_tls_key;
+static void *thread_tls_data;
+#endif
+
/* ********** basic thread control API ************
Many thread cases have an X amount of jobs, and only an Y amount of
@@ -103,7 +105,11 @@ A sample loop can look like this (pseudo c);
static pthread_mutex_t _malloc_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t _image_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t _preview_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t _viewer_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t _custom1_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t _rcache_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t _opengl_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_t mainid;
static int thread_levels= 0; /* threads can be invoked inside threads */
/* just a max for security reasons */
@@ -127,6 +133,11 @@ static void BLI_unlock_malloc_thread(void)
pthread_mutex_unlock(&_malloc_lock);
}
+void BLI_threadapi_init(void)
+{
+ mainid = pthread_self();
+}
+
/* tot = 0 only initializes malloc mutex in a safe way (see sequence.c)
problem otherwise: scene render will kill of the mutex!
*/
@@ -134,7 +145,7 @@ static void BLI_unlock_malloc_thread(void)
void BLI_init_threads(ListBase *threadbase, void *(*do_thread)(void *), int tot)
{
int a;
-
+
if(threadbase != NULL && tot > 0) {
threadbase->first= threadbase->last= NULL;
@@ -147,12 +158,20 @@ void BLI_init_threads(ListBase *threadbase, void *(*do_thread)(void *), int tot)
tslot->do_thread= do_thread;
tslot->avail= 1;
}
-
- if(thread_levels == 0)
- MEM_set_lock_callback(BLI_lock_malloc_thread, BLI_unlock_malloc_thread);
-
- thread_levels++;
}
+
+ if(thread_levels == 0) {
+ MEM_set_lock_callback(BLI_lock_malloc_thread, BLI_unlock_malloc_thread);
+
+#if defined(__APPLE__) && (PARALLEL == 1) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 2)
+ /* 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
+ }
+
+ thread_levels++;
}
/* amount of available threads */
@@ -181,6 +200,22 @@ int BLI_available_thread_index(ListBase *threadbase)
return 0;
}
+static void *tslot_thread_start(void *tslot_p)
+{
+ ThreadSlot *tslot= (ThreadSlot*)tslot_p;
+
+#if defined(__APPLE__) && (PARALLEL == 1) && (__GNUC__ == 4) && (__GNUC_MINOR__ == 2)
+ /* 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);
+}
+
+int BLI_thread_is_main(void) {
+ return pthread_equal(pthread_self(), mainid);
+}
void BLI_insert_thread(ListBase *threadbase, void *callerdata)
{
@@ -190,7 +225,7 @@ void BLI_insert_thread(ListBase *threadbase, void *callerdata)
if(tslot->avail) {
tslot->avail= 0;
tslot->callerdata= callerdata;
- pthread_create(&tslot->pthread, NULL, tslot->do_thread, tslot->callerdata);
+ pthread_create(&tslot->pthread, NULL, tslot_thread_start, tslot);
return;
}
}
@@ -203,8 +238,8 @@ void BLI_remove_thread(ListBase *threadbase, void *callerdata)
for(tslot= threadbase->first; tslot; tslot= tslot->next) {
if(tslot->callerdata==callerdata) {
- tslot->callerdata= NULL;
pthread_join(tslot->pthread, NULL);
+ tslot->callerdata= NULL;
tslot->avail= 1;
}
}
@@ -217,8 +252,8 @@ void BLI_remove_thread_index(ListBase *threadbase, int index)
for(tslot = threadbase->first; tslot; tslot = tslot->next, counter++) {
if (counter == index && tslot->avail == 0) {
- tslot->callerdata = NULL;
pthread_join(tslot->pthread, NULL);
+ tslot->callerdata = NULL;
tslot->avail = 1;
break;
}
@@ -231,8 +266,8 @@ void BLI_remove_threads(ListBase *threadbase)
for(tslot = threadbase->first; tslot; tslot = tslot->next) {
if (tslot->avail == 0) {
- tslot->callerdata = NULL;
pthread_join(tslot->pthread, NULL);
+ tslot->callerdata = NULL;
tslot->avail = 1;
}
}
@@ -252,11 +287,11 @@ void BLI_end_threads(ListBase *threadbase)
}
}
BLI_freelistN(threadbase);
-
- thread_levels--;
- if(thread_levels==0)
- MEM_set_lock_callback(NULL, NULL);
}
+
+ thread_levels--;
+ if(thread_levels==0)
+ MEM_set_lock_callback(NULL, NULL);
}
/* System Information */
@@ -301,8 +336,14 @@ void BLI_lock_thread(int type)
pthread_mutex_lock(&_image_lock);
else if (type==LOCK_PREVIEW)
pthread_mutex_lock(&_preview_lock);
+ else if (type==LOCK_VIEWER)
+ pthread_mutex_lock(&_viewer_lock);
else if (type==LOCK_CUSTOM1)
pthread_mutex_lock(&_custom1_lock);
+ else if (type==LOCK_RCACHE)
+ pthread_mutex_lock(&_rcache_lock);
+ else if (type==LOCK_OPENGL)
+ pthread_mutex_lock(&_opengl_lock);
}
void BLI_unlock_thread(int type)
@@ -311,8 +352,14 @@ void BLI_unlock_thread(int type)
pthread_mutex_unlock(&_image_lock);
else if (type==LOCK_PREVIEW)
pthread_mutex_unlock(&_preview_lock);
+ else if (type==LOCK_VIEWER)
+ pthread_mutex_unlock(&_viewer_lock);
else if(type==LOCK_CUSTOM1)
pthread_mutex_unlock(&_custom1_lock);
+ else if(type==LOCK_RCACHE)
+ pthread_mutex_unlock(&_rcache_lock);
+ else if(type==LOCK_OPENGL)
+ pthread_mutex_unlock(&_opengl_lock);
}
/* Mutex Locks */
diff --git a/source/blender/blenlib/intern/time.c b/source/blender/blenlib/intern/time.c
index b0a284c4074..0992e08b28f 100644
--- a/source/blender/blenlib/intern/time.c
+++ b/source/blender/blenlib/intern/time.c
@@ -26,14 +26,9 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
-#include "PIL_time.h"
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
#ifdef WIN32
-
+#include "PIL_time.h"
#include <windows.h>
double PIL_check_seconds_timer(void)
diff --git a/source/blender/blenlib/intern/uvproject.c b/source/blender/blenlib/intern/uvproject.c
new file mode 100644
index 00000000000..cc115d52928
--- /dev/null
+++ b/source/blender/blenlib/intern/uvproject.c
@@ -0,0 +1,191 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <math.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "DNA_camera_types.h"
+#include "DNA_object_types.h"
+
+#include "BLI_math.h"
+
+typedef struct UvCameraInfo {
+ float camangle;
+ float camsize;
+ float xasp, yasp;
+ float shiftx, shifty;
+ float rotmat[4][4];
+ float caminv[4][4];
+ short do_persp, do_pano, do_rotmat;
+} UvCameraInfo;
+
+void project_from_camera(float target[2], float source[3], UvCameraInfo *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]) / (M_PI * 2.0); /* angle around the camera */
+ if (uci->do_persp==0) {
+ target[0]= angle; /* no correct method here, just map to 0-1 */
+ target[1]= pv4[1] / uci->camsize;
+ }
+ else {
+ float vec2d[2]= {pv4[0], pv4[2]}; /* 2D position from the camera */
+ target[0]= angle * (M_PI / uci->camangle);
+ target[1]= pv4[1] / (len_v2(vec2d) * uci->camsize);
+ }
+ }
+ else {
+ if (pv4[2]==0.0f) pv4[2]= 0.00001f; /* don't allow div by 0 */
+
+ if (uci->do_persp==0) {
+ 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 project_from_view(float target[2], float source[3], float persmat[4][4], float rotmat[4][4], float winx, float winy)
+{
+ float pv[3], pv4[4], x= 0.0, y= 0.0;
+
+ mul_v3_m4v3(pv, rotmat, source);
+
+ copy_v3_v3(pv4, source);
+ pv4[3]= 1.0;
+
+ /* rotmat is the object matrix in this case */
+ mul_m4_v4(rotmat, pv4);
+
+ /* almost project_short */
+ mul_m4_v4(persmat, pv4);
+ if(fabs(pv4[3]) > 0.00001) { /* avoid division by zero */
+ target[0] = winx/2.0 + (winx/2.0) * pv4[0] / pv4[3];
+ target[1] = winy/2.0 + (winy/2.0) * pv4[1] / pv4[3];
+ }
+ else {
+ /* scaling is lost but give a valid result */
+ target[0] = winx/2.0 + (winx/2.0) * pv4[0];
+ target[1] = winy/2.0 + (winy/2.0) * pv4[1];
+ }
+
+ /* v3d->persmat seems to do this funky scaling */
+ if(winx > winy) {
+ y= (winx - winy)/2.0;
+ winy = winx;
+ }
+ else {
+ x= (winy - winx)/2.0;
+ 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 */
+UvCameraInfo *project_camera_info(Object *ob, float (*rotmat)[4], float winx, float winy)
+{
+ UvCameraInfo uci;
+ Camera *camera= ob->data;
+
+ uci.do_pano = (camera->flag & CAM_PANORAMA);
+ uci.do_persp = (camera->type==CAM_PERSP);
+
+ uci.camangle= lens_to_angle(camera->lens) / 2.0f;
+ uci.camsize= uci.do_persp ? tanf(uci.camangle) : camera->ortho_scale;
+
+ if (invert_m4_m4(uci.caminv, ob->obmat)) {
+ UvCameraInfo *uci_pt;
+
+ /* normal projection */
+ if(rotmat) {
+ copy_m4_m4(uci.rotmat, rotmat);
+ uci.do_rotmat= 1;
+ }
+ else {
+ uci.do_rotmat= 0;
+ }
+
+ /* 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.shifty = 0.5f - camera->shifty;
+
+ uci_pt= MEM_mallocN(sizeof(UvCameraInfo), "UvCameraInfo");
+ *uci_pt= uci;
+ return uci_pt;
+ }
+
+ return NULL;
+}
+
+void project_from_view_ortho(float target[2], float source[3], float rotmat[4][4])
+{
+ float pv[3];
+
+ mul_v3_m4v3(pv, rotmat, source);
+
+ /* ortho projection */
+ target[0] = -pv[0];
+ target[1] = pv[2];
+}
+
+
+void project_camera_info_scale(UvCameraInfo *uci, float scale_x, float scale_y)
+{
+ uci->xasp *= scale_x;
+ uci->yasp *= scale_y;
+}
diff --git a/source/blender/blenlib/intern/voxel.c b/source/blender/blenlib/intern/voxel.c
index 78267528e21..2b04a49e848 100644
--- a/source/blender/blenlib/intern/voxel.c
+++ b/source/blender/blenlib/intern/voxel.c
@@ -25,18 +25,12 @@
*
* ***** END GPL LICENSE BLOCK *****
*/
-#include <math.h>
#include "BLI_voxel.h"
#include "BKE_utildefines.h"
-
-#if defined( _MSC_VER ) && !defined( __cplusplus )
-# define inline __inline
-#endif // defined( _MSC_VER ) && !defined( __cplusplus )
-
-static inline float D(float *data, int *res, int x, int y, int z)
+BM_INLINE float D(float *data, int *res, int x, int y, int z)
{
CLAMP(x, 0, res[0]-1);
CLAMP(y, 0, res[1]-1);
@@ -58,7 +52,7 @@ float voxel_sample_nearest(float *data, int *res, float *co)
}
// returns highest integer <= x as integer (slightly faster than floor())
-inline int FLOORI(float x)
+BM_INLINE int FLOORI(float x)
{
const int r = (int)x;
return ((x >= 0.f) || (float)r == x) ? r : (r - 1);
@@ -66,7 +60,7 @@ inline int FLOORI(float x)
// clamp function, cannot use the CLAMPIS macro, it sometimes returns unwanted results apparently related to gcc optimization flag -fstrict-overflow which is enabled at -O2
// this causes the test (x + 2) < 0 with int x == 2147483647 to return false (x being an integer, x + 2 should wrap around to -2147483647 so the test < 0 should return true, which it doesn't)
-inline int _clamp(int a, int b, int c)
+BM_INLINE int _clamp(int a, int b, int c)
{
return (a < b) ? b : ((a > c) ? c : a);
}
@@ -94,9 +88,9 @@ float voxel_sample_trilinear(float *data, int *res, float *co)
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]] ) );
+ + 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;
@@ -120,14 +114,14 @@ float voxel_sample_triquadratic(float *data, int *res, float *co)
const float w[3] = {dz*(0.5f*dz - 1.f) + 0.5f, dz*(1.f - 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]] ) );
+ + 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;
@@ -177,21 +171,21 @@ float voxel_sample_tricubic(float *data, int *res, float *co, int bspline)
}
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]] ) );
+ + 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 194a164216a..f2261546f5c 100644
--- a/source/blender/blenlib/intern/winstuff.c
+++ b/source/blender/blenlib/intern/winstuff.c
@@ -28,10 +28,6 @@
* Windows-posix compatibility layer, windows-specific functions.
*/
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
#ifdef WIN32
#include <stdlib.h>
@@ -225,21 +221,21 @@ int check_file_chars(char *filename)
#include <string.h>
char* dirname(char *path)
{
- char *p;
- if( path == NULL || *path == '\0' )
- return ".";
- p = path + strlen(path) - 1;
- while( *p == '/' ) {
- if( p == path )
- return path;
- *p-- = '\0';
- }
- while( p >= path && *p != '/' )
- p--;
- return
- p < path ? "." :
- p == path ? "/" :
- (*p = '\0', path);
+ char *p;
+ if( path == NULL || *path == '\0' )
+ return ".";
+ p = path + strlen(path) - 1;
+ while( *p == '/' ) {
+ if( p == path )
+ return path;
+ *p-- = '\0';
+ }
+ while( p >= path && *p != '/' )
+ p--;
+ return
+ p < path ? "." :
+ p == path ? "/" :
+ (*p = '\0', path);
}
/* End of copied part */