diff options
author | Lukas Steiblys <imbusy@imbusy.org> | 2009-10-02 02:29:15 +0400 |
---|---|---|
committer | Lukas Steiblys <imbusy@imbusy.org> | 2009-10-02 02:29:15 +0400 |
commit | 0677398a649b6b8c293df3ce3c6668f0a3be3bc8 (patch) | |
tree | 9d510a5bd23559bf4fae670ed04d7e5d6c12578c /source/blender/blenlib | |
parent | 59248e9f62006ba05e3098e4d213f3dcb23fe711 (diff) | |
parent | bc942eceacb638735dc4f4f68252c4c207147a70 (diff) |
merge from 23153 to 23595soc-2009-imbusy
Diffstat (limited to 'source/blender/blenlib')
-rw-r--r-- | source/blender/blenlib/BLI_arithb.h | 14 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_bfile.h | 138 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_ghash.h | 8 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_listbase.h | 4 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_threads.h | 53 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_util.h | 9 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_winstuff.h | 21 | ||||
-rw-r--r-- | source/blender/blenlib/intern/BLI_bfile.c | 236 | ||||
-rw-r--r-- | source/blender/blenlib/intern/BLI_kdopbvh.c | 4 | ||||
-rw-r--r-- | source/blender/blenlib/intern/BLI_kdtree.c | 2 | ||||
-rw-r--r-- | source/blender/blenlib/intern/arithb.c | 60 | ||||
-rw-r--r-- | source/blender/blenlib/intern/dynlib.c | 200 | ||||
-rw-r--r-- | source/blender/blenlib/intern/freetypefont.c | 4 | ||||
-rw-r--r-- | source/blender/blenlib/intern/graph.c | 6 | ||||
-rw-r--r-- | source/blender/blenlib/intern/listbase.c | 14 | ||||
-rw-r--r-- | source/blender/blenlib/intern/noise.c | 12 | ||||
-rw-r--r-- | source/blender/blenlib/intern/threads.c | 96 | ||||
-rw-r--r-- | source/blender/blenlib/intern/util.c | 167 |
18 files changed, 707 insertions, 341 deletions
diff --git a/source/blender/blenlib/BLI_arithb.h b/source/blender/blenlib/BLI_arithb.h index c2d707f60f0..1d275e70a17 100644 --- a/source/blender/blenlib/BLI_arithb.h +++ b/source/blender/blenlib/BLI_arithb.h @@ -178,7 +178,7 @@ float power_of_2(float val); */ /* Defines for rotation orders - * WARNING: must match the ePchan_RotMode in DNA_action_types.h + * WARNING: must match the eRotationModes in DNA_action_types.h * order matters - types are saved to file! */ typedef enum eEulerRotationOrders { @@ -364,7 +364,8 @@ void printvec4f(char *str, float v[4]); void VecAddf(float *v, float *v1, float *v2); void VecSubf(float *v, float *v1, float *v2); void VecMulVecf(float *v, float *v1, float *v2); -void VecLerpf(float *target, float *a, float *b, float t); +void VecLerpf(float *target, const float *a, const float *b, const float t); +void VecLerp3f(float p[3], const float v1[3], const float v2[3], const float v3[3], const float w[3]); void VecMidf(float *v, float *v1, float *v2); void VecOrthoBasisf(float *v, float *v1, float *v2); @@ -375,7 +376,8 @@ void Vec2Mulf(float *v1, float f); void Vec2Addf(float *v, float *v1, float *v2); void Vec2Subf(float *v, float *v1, float *v2); void Vec2Copyf(float *v1, float *v2); -void Vec2Lerpf(float *target, float *a, float *b, float t); +void Vec2Lerpf(float *target, const float *a, const float *b, const float t); +void Vec2Lerp3f(float p[2], const float v1[2], const float v2[2], const float v3[2], const float w[3]); void AxisAngleToQuat(float q[4], float axis[3], float angle); void QuatToAxisAngle(float q[4], float axis[3], float *angle); @@ -401,7 +403,7 @@ float VecAngle2(float *v1, float *v2); float VecAngle3(float *v1, float *v2, float *v3); float NormalizedVecAngle2(float *v1, float *v2); -float VecAngle3_2D(float *v1, float *v2, float *v3); +float Vec2Angle3(float *v1, float *v2, float *v3); float NormalizedVecAngle2_2D(float *v1, float *v2); void NormalShortToFloat(float *out, short *in); @@ -454,6 +456,8 @@ void i_window( #define BLI_CS_REC709 1 #define BLI_CS_CIE 2 +#define RAD2DEG(_rad) ((_rad)*(180.0/M_PI)) + void hsv_to_rgb(float h, float s, float v, float *r, float *g, float *b); void hex_to_rgb(char *hexcol, float *r, float *g, float *b); void rgb_to_yuv(float r, float g, float b, float *ly, float *lu, float *lv); @@ -525,6 +529,8 @@ int point_in_tri_prism(float p[3], float v1[3], float v2[3], float v3[3]); float lambda_cp_line_ex(float p[3], float l1[3], float l2[3], float cp[3]); +float AngleToLength(const float angle); + typedef struct DualQuat { float quat[4]; float trans[4]; diff --git a/source/blender/blenlib/BLI_bfile.h b/source/blender/blenlib/BLI_bfile.h new file mode 100644 index 00000000000..92543558a19 --- /dev/null +++ b/source/blender/blenlib/BLI_bfile.h @@ -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) 2009 by Stichting Blender Foundation. + * All rights reserved. + * + * ***** END GPL LICENSE BLOCK ***** + * BFILE* based abstraction of file access. + */ + +#ifndef BLI_BFILE_H +#define BLI_BFILE_H + +/* For fopen's FILE */ +#include <stdio.h> + +/** + Defines for the bflags param. + */ +/* Special handling: */ +/* For "symmetry" of flags */ +#define BFILE_NORMAL (0) +/* No supervision, just translate // if needed, RISKY */ +#define BFILE_RAW (1<<0) +/* Path is relative to config dirs */ +#define BFILE_CONFIG (1<<1) +/* Path is for current session temp file */ +#define BFILE_TEMP (1<<2) + +/* Config handling, special cases: */ +#define BFILE_USERONLY (1<<3) +#define BFILE_SYSONLY (1<<4) + +/* Compression to apply on close: */ +#define BFILE_GZIP (1<<5) + +/** + File descriptor for Blender abstracted file access. + */ +typedef struct { + FILE *stream; + int fd; + + /* Anything below should not be touched directly */ + int uflags; /* Special options requested by upper level, copy of bflags */ + char *fpath; /* Final/requested path name */ + char *tpath; /* Temp path name if applicable */ + int type; /* Own flags, common classification of open and fopen */ + int error; /* An op caused an error, unsafe to replace older files */ +} BFILE; + +/** + Open a BFILE* with fopen()-like syntax. + */ +BFILE *BLI_bfile_fopen(const char *path, const char *mode, int bflags); + +/** + Open a BFILE* with open()-like syntax. + */ +BFILE *BLI_bfile_open(const char *pathname, int flags, int bflags); + +/** + Get the FILE* associated with the BFILE*. + */ +FILE *BLI_bfile_file_from_bfile(BFILE *bfile); + +/** + Get the fd associated with the BFILE*. + */ +int BLI_bfile_fd_from_bfile(BFILE *bfile); + +/** + write()-like using BFILE*. + */ +ssize_t BLI_bfile_write(BFILE *f, const void *buf, size_t count); + +/** + read()-like using BFILE*. + */ +ssize_t BLI_bfile_read(BFILE *f, void *buf, size_t count); + +/** + fwrite()-like using BFILE*. + */ +size_t BLI_bfile_fwrite(const void *ptr, size_t size, size_t nmemb, BFILE *f); + +/** + fread()-like using BFILE*. + */ +size_t BLI_bfile_fread(void *ptr, size_t size, size_t nmemb, BFILE *f); + +/** + Close a BFILE, to match close() and fclose(). + */ +void BLI_bfile_close(BFILE *bfile); + +/** + Clear error status. + Call it only if the error has been really handled. + */ +void BLI_bfile_clear_error(BFILE *bfile); + +/** + Set the error status. + Call it to mark writing by a 3rd party failed (libjpeg reported error, ie). + */ +void BLI_bfile_set_error(BFILE *bfile, int error); + +/* +TODO +Maybe also provide more OS/libc things like: +fflush +fprintf and related +fscanf +fgetc/fputc and related +fseek and related + +Probably good to do: +readdir (compacted list showing all files for a "directory" (user versions on top of system's)) +*/ + +#endif /* ifndef BLI_BFILE_H */ diff --git a/source/blender/blenlib/BLI_ghash.h b/source/blender/blenlib/BLI_ghash.h index c77e82f0a2b..c9a8b1b841f 100644 --- a/source/blender/blenlib/BLI_ghash.h +++ b/source/blender/blenlib/BLI_ghash.h @@ -32,6 +32,10 @@ #ifndef BLI_GHASH_H #define BLI_GHASH_H +#ifdef __cplusplus +extern "C" { +#endif + struct GHash; typedef struct GHash GHash; @@ -125,5 +129,9 @@ int BLI_ghashutil_strcmp (void *a, void *b); unsigned int BLI_ghashutil_inthash (void *ptr); int BLI_ghashutil_intcmp(void *a, void *b); +#ifdef __cplusplus +} +#endif + #endif diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h index d0b106b59c3..21b4c83bd88 100644 --- a/source/blender/blenlib/BLI_listbase.h +++ b/source/blender/blenlib/BLI_listbase.h @@ -34,6 +34,7 @@ //#include "DNA_listbase.h" struct ListBase; +struct LinkData; #ifdef __cplusplus extern "C" { @@ -56,6 +57,9 @@ int BLI_countlist(struct ListBase *listbase); void BLI_freelinkN(struct ListBase *listbase, void *vlink); void BLI_duplicatelist(struct ListBase *list1, struct ListBase *list2); /* copy from 2 to 1 */ +/* create a generic list node containing link to provided data */ +struct LinkData *BLI_genericNodeN(void *data); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenlib/BLI_threads.h b/source/blender/blenlib/BLI_threads.h index 8babb5fe780..ace9ddd729f 100644 --- a/source/blender/blenlib/BLI_threads.h +++ b/source/blender/blenlib/BLI_threads.h @@ -31,14 +31,15 @@ #ifndef BLI_THREADS_H #define BLI_THREADS_H -/* one custom lock available now. can be extended */ -#define LOCK_IMAGE 0 -#define LOCK_CUSTOM1 1 +#include <pthread.h> /* for tables, button in UI, etc */ #define BLENDER_MAX_THREADS 8 struct ListBase; + +/* Threading API */ + void BLI_init_threads (struct ListBase *threadbase, void *(*do_thread)(void *), int tot); int BLI_available_threads(struct ListBase *threadbase); int BLI_available_thread_index(struct ListBase *threadbase); @@ -48,18 +49,46 @@ void BLI_remove_thread_index(struct ListBase *threadbase, int index); void BLI_remove_threads(struct ListBase *threadbase); void BLI_end_threads (struct ListBase *threadbase); -void BLI_lock_thread (int type); -void BLI_unlock_thread (int type); +/* System Information */ + +int BLI_system_thread_count(void); /* gets the number of threads the system can make use of */ + +/* Global Mutex Locks + * + * One custom lock available now. can be extended. */ + +#define LOCK_IMAGE 0 +#define LOCK_PREVIEW 1 +#define LOCK_CUSTOM1 2 + +void BLI_lock_thread(int type); +void BLI_unlock_thread(int type); + +/* Mutex Lock */ + +typedef pthread_mutex_t ThreadMutex; + +void BLI_mutex_init(ThreadMutex *mutex); +void BLI_mutex_lock(ThreadMutex *mutex); +void BLI_mutex_unlock(ThreadMutex *mutex); +void BLI_mutex_end(ThreadMutex *mutex); -int BLI_system_thread_count( void ); /* gets the number of threads the system can make use of */ +/* Read/Write Mutex Lock */ - /* exported by preview render, it has to ensure render buffers are not freed while draw */ -void BLI_lock_malloc_thread(void); -void BLI_unlock_malloc_thread(void); +#define THREAD_LOCK_READ 1 +#define THREAD_LOCK_WRITE 2 -/* ThreadedWorker is a simple tool for dispatching work to a limited number of threads in a transparent - * fashion from the caller's perspective - * */ +typedef pthread_rwlock_t ThreadRWMutex; + +void BLI_rw_mutex_init(ThreadRWMutex *mutex); +void BLI_rw_mutex_lock(ThreadRWMutex *mutex, int mode); +void BLI_rw_mutex_unlock(ThreadRWMutex *mutex); +void BLI_rw_mutex_end(ThreadRWMutex *mutex); + +/* ThreadedWorker + * + * A simple tool for dispatching work to a limited number of threads + * in a transparent fashion from the caller's perspective. */ struct ThreadedWorker; diff --git a/source/blender/blenlib/BLI_util.h b/source/blender/blenlib/BLI_util.h index f9a84e071e7..1ce7a8cdb77 100644 --- a/source/blender/blenlib/BLI_util.h +++ b/source/blender/blenlib/BLI_util.h @@ -42,7 +42,14 @@ struct ListBase; struct direntry; char *BLI_gethome(void); -char *BLI_gethome_folder(char *folder_name); +char *BLI_gethome_folder(char *folder_name, int flag); + +/* BLI_gethome_folder flag */ +#define BLI_GETHOME_LOCAL 1<<1 /* relative location for portable binaries */ +#define BLI_GETHOME_SYSTEM 1<<2 /* system location, or set from the BLENDERPATH env variable (UNIX only) */ +#define BLI_GETHOME_USER 1<<3 /* home folder ~/.blender */ +#define BLI_GETHOME_ALL (BLI_GETHOME_SYSTEM|BLI_GETHOME_LOCAL|BLI_GETHOME_USER) + void BLI_setenv(const char *env, const char *val); void BLI_make_file_string(const char *relabase, char *string, const char *dir, const char *file); diff --git a/source/blender/blenlib/BLI_winstuff.h b/source/blender/blenlib/BLI_winstuff.h index b46ebebacd5..757b3605203 100644 --- a/source/blender/blenlib/BLI_winstuff.h +++ b/source/blender/blenlib/BLI_winstuff.h @@ -28,7 +28,13 @@ * * ***** END GPL LICENSE BLOCK ***** */ + +#ifndef __WINSTUFF_H__ +#define __WINSTUFF_H__ + +#ifndef FREE_WINDOWS #pragma warning(once: 4761 4305 4244 4018) +#endif #define WIN32_LEAN_AND_MEAN @@ -56,10 +62,7 @@ #undef small -#ifndef __WINSTUFF_H__ -#define __WINSTUFF_H__ - - // These definitions are also in arithb for simplicity +// These definitions are also in arithb for simplicity #ifdef __cplusplus extern "C" { @@ -91,6 +94,16 @@ extern "C" { typedef unsigned int mode_t; #endif +/* mingw using _SSIZE_T_ to declare ssize_t type */ +#ifndef _SSIZE_T_ +#define _SSIZE_T_ +/* python uses HAVE_SSIZE_T */ +#ifndef HAVE_SSIZE_T +#define HAVE_SSIZE_T 1 +typedef long ssize_t; +#endif +#endif + struct dirent { int d_ino; int d_off; diff --git a/source/blender/blenlib/intern/BLI_bfile.c b/source/blender/blenlib/intern/BLI_bfile.c new file mode 100644 index 00000000000..a7ce1df5712 --- /dev/null +++ b/source/blender/blenlib/intern/BLI_bfile.c @@ -0,0 +1,236 @@ +/* + * $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) 2009 by Stichting Blender Foundation. + * All rights reserved. + * + * ***** END GPL LICENSE BLOCK ***** + * BFILE* based abstraction for file access. + */ + +#include <string.h> + +#ifndef WIN32 + #include <unistd.h> +#else + #include <io.h> + #include "BLI_winstuff.h" +#endif + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> + +#include "MEM_guardedalloc.h" + +#include "BLI_bfile.h" + +// This would provide config paths and their oldest viable version +// so if there is an uncompatible change, user's old versions are not loaded +//#include "bfile_tables.h" + +/* Internal bfile type flags */ +#define BTF_OPEN (0) +#define BTF_FOPEN (1<<0) +#define BTF_READ (1<<1) +#define BTF_WRITE (1<<2) +#define BTF_AT_END (1<<3) +#define BTF_DISCARD (1<<4) + + +void fill_paths(BFILE *bfile, const char *path) { + char* source_path = NULL; + int bflags = bfile->uflags; + + if(bflags & BFILE_NORMAL || bflags & BFILE_RAW) { +// bfile->fpath is path with // replaced + } + if(bflags & BFILE_TEMP) { +// bfile->fpath is tempdir+path + } + if(bflags & BFILE_CONFIG) { +// 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->type & BTF_WRITE && !(bflags & BFILE_RAW)) { + /* Generate temp path */ + // bfile->tpath is fpath+randstring + if(!(bfile->type & BTF_DISCARD)) { + /* Copy data to tpath */ + if(source_path) { + // copy it from older version or sys version + } + } + } else { + bfile->tpath = bfile->fpath; + } +} + +BFILE *BLI_bfile_fopen(const char *path, const char *mode, int bflags) { + BFILE *bfile; + + bfile = MEM_mallocN(sizeof(BFILE), "bfile-fopen"); + bfile->type = BTF_FOPEN; + bfile->uflags = bflags; + + /* From fopen() doc, we can guess some logic: + r BTF_READ + r+ BTF_READ | BTF_WRITE + w BTF_DISCARD | BTF_WRITE + w+ BTF_DISCARD | BTF_WRITE | BTF_READ + a BTF_AT_END | BTF_WRITE + a+ BTF_AT_END | BTF_WRITE | BTF_READ + */ + if(strchr(mode, 'r')) + bfile->type |= BTF_READ; + if(strchr(mode, 'w')) + bfile->type |= (BTF_DISCARD | BTF_WRITE); + if(strchr(mode, 'a')) + bfile->type |= (BTF_AT_END | BTF_WRITE); + if(strchr(mode, '+')) + bfile->type |= (BTF_READ | BTF_WRITE); + + fill_paths(bfile, path); + + bfile->stream = fopen(bfile->tpath, mode); + // detect failed fopen + bfile->fd = fileno(bfile->stream); + return bfile; +} + + +BFILE *BLI_bfile_open(const char *pathname, int flags, int bflags) { + BFILE *bfile; + + bfile = MEM_mallocN(sizeof(BFILE), "bfile-open"); + bfile->type = BTF_OPEN; + bfile->uflags = bflags; + + /* Easy mapping for open() */ + if(flags & O_RDONLY) + bfile->type |= BTF_READ; + if(flags & O_WRONLY) + bfile->type |= BTF_WRITE; + if(flags & O_RDWR) + bfile->type |= (BTF_READ | BTF_WRITE); + if(flags & O_APPEND) + bfile->type |= BTF_AT_END; + if(flags & O_TRUNC) + bfile->type |= BTF_DISCARD; + + fill_paths(bfile, pathname); + + bfile->fd = open(bfile->tpath, flags); + // detect failed open +// bfile->stream = fdopen(bfile->fd, XXX); /* MSWindows _fdopen? */ + return bfile; +} + + +FILE *BLI_bfile_file_from_bfile(BFILE *bfile) { + return bfile->stream; +} + + +int BLI_bfile_fd_from_bfile(BFILE *bfile) { + return bfile->fd; +} + + +ssize_t BLI_bfile_write(BFILE *f, const void *buf, size_t count) { + ssize_t ret; + + ret = write((f->fd), buf, count); + if (ret == -1) { + f->error = 1; + } + + return ret; +} + + +ssize_t BLI_bfile_read(BFILE *f, void *buf, size_t count) { + ssize_t ret; + + ret = read((f->fd), buf, count); + if (ret == -1) { + f->error = 1; + } + + return ret; +} + + +size_t BLI_bfile_fwrite(const void *ptr, size_t size, size_t nmemb, BFILE *f) { + size_t ret; + + ret = fwrite(ptr, size, nmemb, f->stream); + if (ret < 0) { + f->error = 1; + } + + return ret; +} + + +size_t BLI_bfile_fread(void *ptr, size_t size, size_t nmemb, BFILE *f) { + size_t ret; + + ret = fread(ptr, size, nmemb, f->stream); + if ((ret < 0) && ferror(f->stream)) { + f->error = 1; + } + + return ret; +} + + +void BLI_bfile_close(BFILE *bfile) { + if((bfile->type | BTF_WRITE) && + !(bfile->uflags | BFILE_RAW)) { + /* Make sure data is on disk */ + /* Move to final name if no errors */ + } + + /* Normal close */ + + /* Cleanup */ + if(bfile->fpath) { + MEM_freeN(bfile->fpath); + } + if(bfile->tpath) { + MEM_freeN(bfile->tpath); + } +} + + +void BLI_bfile_clear_error(BFILE *bfile) { + bfile->error = 0; +} + + +void BLI_bfile_set_error(BFILE *bfile, int error) { + /* No cheating, use clear_error() for 0 */ + if (error) { + bfile->error = error; + } +} diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index 61d9cce1a58..48bbfc12370 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -329,7 +329,7 @@ static void sort(BVHNode **a0, int begin, int end, int axis) bvh_insertionsort(a, begin, end, axis); } } -void sort_along_axis(BVHTree *tree, int start, int end, int axis) +static void sort_along_axis(BVHTree *tree, int start, int end, int axis) { sort(tree->nodes, start, end, axis); } @@ -337,7 +337,7 @@ void sort_along_axis(BVHTree *tree, int start, int end, int axis) //after a call to this function you can expect one of: // every node to left of a[n] are smaller or equal to it // every node to the right of a[n] are greater or equal to it -int partition_nth_element(BVHNode **a, int _begin, int _end, int n, int axis){ +static int partition_nth_element(BVHNode **a, int _begin, int _end, int n, int axis){ int begin = _begin, end = _end, cut; while(end-begin > 3) { diff --git a/source/blender/blenlib/intern/BLI_kdtree.c b/source/blender/blenlib/intern/BLI_kdtree.c index 1f3a861ba6a..ccf79ed42dc 100644 --- a/source/blender/blenlib/intern/BLI_kdtree.c +++ b/source/blender/blenlib/intern/BLI_kdtree.c @@ -337,7 +337,7 @@ int BLI_kdtree_find_n_nearest(KDTree *tree, int n, float *co, float *nor, KDTree return found; } -int range_compare(const void * a, const void * b) +static int range_compare(const void * a, const void * b) { const KDTreeNearest *kda = a; const KDTreeNearest *kdb = b; diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c index 9e769e19674..26bbbf040f3 100644 --- a/source/blender/blenlib/intern/arithb.c +++ b/source/blender/blenlib/intern/arithb.c @@ -2187,23 +2187,40 @@ void VecMulVecf(float *v, float *v1, float *v2) v[2] = v1[2] * v2[2]; } -void VecLerpf(float *target, float *a, float *b, float t) +void VecLerpf(float *target, const float *a, const float *b, const float t) { - float s = 1.0f-t; + const float s = 1.0f-t; target[0]= s*a[0] + t*b[0]; target[1]= s*a[1] + t*b[1]; target[2]= s*a[2] + t*b[2]; } -void Vec2Lerpf(float *target, float *a, float *b, float t) +void Vec2Lerpf(float *target, const float *a, const float *b, const float t) { - float s = 1.0f-t; + const float s = 1.0f-t; target[0]= s*a[0] + t*b[0]; target[1]= s*a[1] + t*b[1]; } +/* weight 3 vectors, (VecWeightf in 2.4x) + * 'w' must be unit length but is not a vector, just 3 weights */ +void VecLerp3f(float p[3], const float v1[3], const float v2[3], const float v3[3], const float w[3]) +{ + p[0] = v1[0]*w[0] + v2[0]*w[1] + v3[0]*w[2]; + p[1] = v1[1]*w[0] + v2[1]*w[1] + v3[1]*w[2]; + p[2] = v1[2]*w[0] + v2[2]*w[1] + v3[2]*w[2]; +} + +/* weight 3 2D vectors, (Vec2Weightf in 2.4x) + * 'w' must be unit length but is not a vector, just 3 weights */ +void Vec2Lerp3f(float p[2], const float v1[2], const float v2[2], const float v3[2], const float w[3]) +{ + p[0] = v1[0]*w[0] + v2[0]*w[1] + v3[0]*w[2]; + p[1] = v1[1]*w[0] + v2[1]*w[1] + v3[1]*w[2]; +} + void VecMidf(float *v, float *v1, float *v2) { v[0]= 0.5f*(v1[0]+ v2[0]); @@ -3548,10 +3565,10 @@ float VecAngle3(float *v1, float *v2, float *v3) Normalize(vec1); Normalize(vec2); - return NormalizedVecAngle2(vec1, vec2) * (float)(180.0/M_PI); + return NormalizedVecAngle2(vec1, vec2); } -float VecAngle3_2D(float *v1, float *v2, float *v3) +float Vec2Angle3(float *v1, float *v2, float *v3) { float vec1[2], vec2[2]; @@ -3564,7 +3581,7 @@ float VecAngle3_2D(float *v1, float *v2, float *v3) Normalize2(vec1); Normalize2(vec2); - return NormalizedVecAngle2_2D(vec1, vec2) * (float)(180.0/M_PI); + return NormalizedVecAngle2_2D(vec1, vec2); } /* Return the shortest angle in degrees between the 2 vectors */ @@ -3577,7 +3594,7 @@ float VecAngle2(float *v1, float *v2) Normalize(vec1); Normalize(vec2); - return NormalizedVecAngle2(vec1, vec2)* (float)(180.0/M_PI); + return NormalizedVecAngle2(vec1, vec2); } float NormalizedVecAngle2(float *v1, float *v2) @@ -4093,19 +4110,19 @@ void spheremap(float x, float y, float z, float *u, float *v) /* proposed api by ton and zr, not used yet */ #if 0 /* ***************** m1 = m2 ***************** */ -void cpy_m3_m3(float m1[][3], float m2[][3]) +static void cpy_m3_m3(float m1[][3], float m2[][3]) { memcpy(m1[0], m2[0], 9*sizeof(float)); } /* ***************** m1 = m2 ***************** */ -void cpy_m4_m4(float m1[][4], float m2[][4]) +static void cpy_m4_m4(float m1[][4], float m2[][4]) { memcpy(m1[0], m2[0], 16*sizeof(float)); } /* ***************** identity matrix ***************** */ -void ident_m4(float m[][4]) +static void ident_m4(float m[][4]) { m[0][0]= m[1][1]= m[2][2]= m[3][3]= 1.0; @@ -4116,7 +4133,7 @@ void ident_m4(float m[][4]) } /* ***************** m1 = m2 (pre) * m3 (post) ***************** */ -void mul_m3_m3m3(float m1[][3], float m2[][3], float m3[][3]) +static void mul_m3_m3m3(float m1[][3], float m2[][3], float m3[][3]) { float m[3][3]; @@ -4136,7 +4153,7 @@ void mul_m3_m3m3(float m1[][3], float m2[][3], float m3[][3]) } /* ***************** m1 = m2 (pre) * m3 (post) ***************** */ -void mul_m4_m4m4(float m1[][4], float m2[][4], float m3[][4]) +static void mul_m4_m4m4(float m1[][4], float m2[][4], float m3[][4]) { float m[4][4]; @@ -4164,7 +4181,7 @@ void mul_m4_m4m4(float m1[][4], float m2[][4], float m3[][4]) } /* ***************** m1 = inverse(m2) ***************** */ -void inv_m3_m3(float m1[][3], float m2[][3]) +static void inv_m3_m3(float m1[][3], float m2[][3]) { short a,b; float det; @@ -4187,7 +4204,7 @@ void inv_m3_m3(float m1[][3], float m2[][3]) } /* ***************** m1 = inverse(m2) ***************** */ -int inv_m4_m4(float inverse[][4], float mat[][4]) +static int inv_m4_m4(float inverse[][4], float mat[][4]) { int i, j, k; double temp; @@ -4240,7 +4257,7 @@ int inv_m4_m4(float inverse[][4], float mat[][4]) } /* ***************** v1 = v2 * mat ***************** */ -void mul_v3_v3m4(float *v1, float *v2, float mat[][4]) +static void mul_v3_v3m4(float *v1, float *v2, float mat[][4]) { float x, y; @@ -4715,7 +4732,7 @@ int LineIntersectLine(float v1[3], float v2[3], float v3[3], float v4[3], float VecSubf(c, v3t, v1); VecSubf(a, v2, v1); - VecSubf(b, v4t, v3); + VecSubf(b, v4t, v3t); Crossf(ab, a, b); Crossf(cb, c, b); @@ -4823,6 +4840,15 @@ static float lambda_cp_line(float p[3], float l1[3], float l2[3]) } #endif +/* useful to calculate an even width shell, by taking the angle between 2 planes. + * The return value is a scale on the offset. + * no angle between planes is 1.0, as the angle between the 2 planes approches 180d + * the distance gets very high, 180d would be inf, but this case isn't valid */ +float AngleToLength(const float angle) +{ + return (angle < SMALL_NUMBER) ? 1.0f : fabsf(1.0f / cosf(angle * (M_PI/180.0f))); +} + /* Similar to LineIntersectsTriangleUV, except it operates on a quad and in 2d, assumes point is in quad */ void PointInQuad2DUV(float v0[2], float v1[2], float v2[2], float v3[2], float pt[2], float *uv) { diff --git a/source/blender/blenlib/intern/dynlib.c b/source/blender/blenlib/intern/dynlib.c index 858aa6e60bf..4820f5529c1 100644 --- a/source/blender/blenlib/intern/dynlib.c +++ b/source/blender/blenlib/intern/dynlib.c @@ -23,8 +23,6 @@ * The Original Code is: all of this file, with exception of below: * * Contributor(s): Peter O'Gorman - * The functions osxdlopen() and osxerror() - * are Copyright (c) 2002 Peter O'Gorman <ogorman@users.sourceforge.net> * * ***** END GPL LICENSE BLOCK ***** */ @@ -102,202 +100,6 @@ void PIL_dynlib_close(PILdynlib *lib) { free(lib); } -#else -#ifdef __APPLE__ /* MacOS X */ - -#include <mach-o/dyld.h> -#include <dlfcn.h> -#include <stdarg.h> - -#define ERR_STR_LEN 256 - -struct PILdynlib { - void *handle; -}; - -static char *osxerror(int setget, const char *str, ...) -{ - static char errstr[ERR_STR_LEN]; - static int err_filled = 0; - char *retval; - NSLinkEditErrors ler; - int lerno; - const char *dylderrstr; - const char *file; - va_list arg; - if (setget <= 0) - { - va_start(arg, str); - strncpy(errstr, "dlsimple: ", ERR_STR_LEN); - vsnprintf(errstr + 10, ERR_STR_LEN - 10, str, arg); - va_end(arg); - /* We prefer to use the dyld error string if setget is 0 */ - if (setget == 0) { - NSLinkEditError(&ler, &lerno, &file, &dylderrstr); -// printf("dyld: %s\n",dylderrstr); - if (dylderrstr && strlen(dylderrstr)) - strncpy(errstr,dylderrstr,ERR_STR_LEN); - } - err_filled = 1; - retval = NULL; - } - else - { - if (!err_filled) - retval = NULL; - else - retval = errstr; - err_filled = 0; - } - return retval; -} - -static void *osxdlopen(const char *path, int mode) -{ - void *module = 0; - NSObjectFileImage ofi = 0; - NSObjectFileImageReturnCode ofirc; - static int (*make_private_module_public) (NSModule module) = 0; - unsigned int flags = NSLINKMODULE_OPTION_RETURN_ON_ERROR | NSLINKMODULE_OPTION_PRIVATE; - - /* If we got no path, the app wants the global namespace, use -1 as the marker - in this case */ - if (!path) - return (void *)-1; - - /* Create the object file image, works for things linked with the -bundle arg to ld */ - ofirc = NSCreateObjectFileImageFromFile(path, &ofi); - switch (ofirc) - { - case NSObjectFileImageSuccess: - /* It was okay, so use NSLinkModule to link in the image */ - if (!(mode & RTLD_LAZY)) flags += NSLINKMODULE_OPTION_BINDNOW; - module = NSLinkModule(ofi, path,flags); - /* Don't forget to destroy the object file image, unless you like leaks */ - NSDestroyObjectFileImage(ofi); - /* If the mode was global, then change the module, this avoids - multiply defined symbol errors to first load private then make - global. Silly, isn't it. */ - if ((mode & RTLD_GLOBAL)) - { - if (!make_private_module_public) - { - _dyld_func_lookup("__dyld_NSMakePrivateModulePublic", - (unsigned long *)&make_private_module_public); - } - make_private_module_public(module); - } - break; - case NSObjectFileImageInappropriateFile: - /* It may have been a dynamic library rather than a bundle, try to load it */ - module = (void *)NSAddImage(path, NSADDIMAGE_OPTION_RETURN_ON_ERROR); - break; - case NSObjectFileImageFailure: - osxerror(0,"Object file setup failure : \"%s\"", path); - return 0; - case NSObjectFileImageArch: - osxerror(0,"No object for this architecture : \"%s\"", path); - return 0; - case NSObjectFileImageFormat: - osxerror(0,"Bad object file format : \"%s\"", path); - return 0; - case NSObjectFileImageAccess: - osxerror(0,"Can't read object file : \"%s\"", path); - return 0; - } - if (!module) - osxerror(0, "Can not open \"%s\"", path); - return module; -} - -PILdynlib *PIL_dynlib_open(char *name) { - void *handle= osxdlopen(name, RTLD_LAZY); - - if (handle) { - PILdynlib *lib= malloc(sizeof(*lib)); - lib->handle= handle; - - return lib; - } else { - return NULL; - } -} - -void *PIL_dynlib_find_symbol(PILdynlib* lib, char *symname) -{ - int sym_len = strlen(symname); - void *value = NULL; - char *malloc_sym = NULL; - NSSymbol *nssym = 0; - malloc_sym = malloc(sym_len + 2); - if (malloc_sym) - { - sprintf(malloc_sym, "_%s", symname); - /* If the lib->handle is -1, if is the app global context */ - if (lib->handle == (void *)-1) - { - /* Global context, use NSLookupAndBindSymbol */ - if (NSIsSymbolNameDefined(malloc_sym)) - { - nssym = NSLookupAndBindSymbol(malloc_sym); - } - } - /* Now see if the lib->handle is a struch mach_header* or not, use NSLookupSymbol in image - for libraries, and NSLookupSymbolInModule for bundles */ - else - { - /* Check for both possible magic numbers depending on x86/ppc byte order */ - if ((((struct mach_header *)lib->handle)->magic == MH_MAGIC) || - (((struct mach_header *)lib->handle)->magic == MH_CIGAM)) - { - if (NSIsSymbolNameDefinedInImage((struct mach_header *)lib->handle, malloc_sym)) - { - nssym = NSLookupSymbolInImage((struct mach_header *)lib->handle, - malloc_sym, - NSLOOKUPSYMBOLINIMAGE_OPTION_BIND - | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR); - } - - } - else - { - nssym = NSLookupSymbolInModule(lib->handle, malloc_sym); - } - } - if (!nssym) - { - osxerror(0, "symname \"%s\" Not found", symname); - } - value = NSAddressOfSymbol(nssym); - free(malloc_sym); - } - else - { - osxerror(-1, "Unable to allocate memory"); - } - return value; -} - -char *PIL_dynlib_get_error_as_string(PILdynlib* lib) -{ - return osxerror(1, (char *)NULL); -} - -void PIL_dynlib_close(PILdynlib *lib) -{ - if ((((struct mach_header *)lib->handle)->magic == MH_MAGIC) || - (((struct mach_header *)lib->handle)->magic == MH_CIGAM)) - { - osxerror(-1, "Can't remove dynamic libraries on darwin"); - } - if (!NSUnLinkModule(lib->handle, 0)) - { - osxerror(0, "unable to unlink module %s", NSNameOfModule(lib->handle)); - } - - free(lib); -} - #else /* Unix */ #include <dlfcn.h> @@ -334,4 +136,4 @@ void PIL_dynlib_close(PILdynlib *lib) { } #endif -#endif + diff --git a/source/blender/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c index 985700efda1..cb5632df569 100644 --- a/source/blender/blenlib/intern/freetypefont.c +++ b/source/blender/blenlib/intern/freetypefont.c @@ -65,7 +65,7 @@ static FT_Library library; static FT_Error err; -void freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData *vfd) +static void freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData *vfd) { // Blender struct Nurb *nu; @@ -275,7 +275,7 @@ void freetypechar_to_vchar(FT_Face face, FT_ULong charcode, VFontData *vfd) } } -int objchr_to_ftvfontdata(VFont *vfont, FT_ULong charcode) +static int objchr_to_ftvfontdata(VFont *vfont, FT_ULong charcode) { // Freetype2 FT_Face face; diff --git a/source/blender/blenlib/intern/graph.c b/source/blender/blenlib/intern/graph.c index cc15c499290..49a3cad53f1 100644 --- a/source/blender/blenlib/intern/graph.c +++ b/source/blender/blenlib/intern/graph.c @@ -354,7 +354,7 @@ void BLI_ReflagSubgraph(BGraph *graph, int old_subgraph, int new_subgraph) /*************************************** CYCLE DETECTION ***********************************************/ -int detectCycle(BNode *node, BArc *src_arc) +static int detectCycle(BNode *node, BArc *src_arc) { int value = 0; @@ -520,7 +520,7 @@ void BLI_calcGraphLength(BGraph *graph) /********************************* SYMMETRY DETECTION **************************************************/ -void markdownSymmetryArc(BGraph *graph, BArc *arc, BNode *node, int level, float limit); +static void markdownSymmetryArc(BGraph *graph, BArc *arc, BNode *node, int level, float limit); void BLI_mirrorAlongAxis(float v[3], float center[3], float axis[3]) { @@ -935,7 +935,7 @@ static void markdownSecondarySymmetry(BGraph *graph, BNode *node, int depth, int } } -void markdownSymmetryArc(BGraph *graph, BArc *arc, BNode *node, int level, float limit) +static void markdownSymmetryArc(BGraph *graph, BArc *arc, BNode *node, int level, float limit) { int i; diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c index 3194593374f..b3a4722d6d9 100644 --- a/source/blender/blenlib/intern/listbase.c +++ b/source/blender/blenlib/intern/listbase.c @@ -359,3 +359,17 @@ void BLI_duplicatelist(ListBase *list1, ListBase *list2) /* copy from 2 to 1 */ } } +/* create a generic list node containing link to provided data */ +LinkData *BLI_genericNodeN (void *data) +{ + LinkData *ld; + + if (data == NULL) + return NULL; + + /* create new link, and make it hold the given data */ + ld= MEM_callocN(sizeof(LinkData), "BLI_genericNodeN()"); + ld->data= data; + + return ld; +} diff --git a/source/blender/blenlib/intern/noise.c b/source/blender/blenlib/intern/noise.c index 0bd30a69d05..66e9a65dba5 100644 --- a/source/blender/blenlib/intern/noise.c +++ b/source/blender/blenlib/intern/noise.c @@ -42,9 +42,9 @@ #endif /* local */ -float noise3_perlin(float vec[3]); -float turbulence_perlin(float *point, float lofreq, float hifreq); -float turbulencep(float noisesize, float x, float y, float z, int nr); +static float noise3_perlin(float vec[3]); +static float turbulence_perlin(float *point, float lofreq, float hifreq); +static float turbulencep(float noisesize, float x, float y, float z, int nr); #define HASHVEC(x,y,z) hashvectf+3*hash[ (hash[ (hash[(z) & 255]+(y)) & 255]+(x)) & 255] @@ -915,7 +915,7 @@ float g[512+2][3]= { r1 = r0 - 1.; -float noise3_perlin(float vec[3]) +static float noise3_perlin(float vec[3]) { int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11; float rx0, rx1, ry0, ry1, rz0, rz1, *q, sx, sy, sz, a, b, c, d, t, u, v; @@ -976,7 +976,7 @@ float noise3_perlin(float vec[3]) return 1.5 * lerp(sz, c, d); /* interpolate in z */ } -float turbulence_perlin(float *point, float lofreq, float hifreq) +static float turbulence_perlin(float *point, float lofreq, float hifreq) { float freq, t, p[3]; @@ -1029,7 +1029,7 @@ float BLI_hnoisep(float noisesize, float x, float y, float z) return noise3_perlin(vec); } -float turbulencep(float noisesize, float x, float y, float z, int nr) +static float turbulencep(float noisesize, float x, float y, float z, int nr) { float vec[3]; diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c index ed3e07b7f7e..b5c6a5a3b4e 100644 --- a/source/blender/blenlib/intern/threads.c +++ b/source/blender/blenlib/intern/threads.c @@ -98,6 +98,7 @@ 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 _custom1_lock = PTHREAD_MUTEX_INITIALIZER; static int thread_levels= 0; /* threads can be invoked inside threads */ @@ -112,12 +113,12 @@ typedef struct ThreadSlot { int avail; } ThreadSlot; -void BLI_lock_malloc_thread(void) +static void BLI_lock_malloc_thread(void) { pthread_mutex_lock(&_malloc_lock); } -void BLI_unlock_malloc_thread(void) +static void BLI_unlock_malloc_thread(void) { pthread_mutex_unlock(&_malloc_lock); } @@ -143,7 +144,9 @@ void BLI_init_threads(ListBase *threadbase, void *(*do_thread)(void *), int tot) tslot->avail= 1; } - MEM_set_lock_callback(BLI_lock_malloc_thread, BLI_unlock_malloc_thread); + if(thread_levels == 0) + MEM_set_lock_callback(BLI_lock_malloc_thread, BLI_unlock_malloc_thread); + thread_levels++; } } @@ -252,21 +255,7 @@ void BLI_end_threads(ListBase *threadbase) } } -void BLI_lock_thread(int type) -{ - if (type==LOCK_IMAGE) - pthread_mutex_lock(&_image_lock); - else if (type==LOCK_CUSTOM1) - pthread_mutex_lock(&_custom1_lock); -} - -void BLI_unlock_thread(int type) -{ - if (type==LOCK_IMAGE) - pthread_mutex_unlock(&_image_lock); - else if(type==LOCK_CUSTOM1) - pthread_mutex_unlock(&_custom1_lock); -} +/* System Information */ /* how many threads are native on this system? */ int BLI_system_thread_count( void ) @@ -300,6 +289,75 @@ int BLI_system_thread_count( void ) return t; } +/* Global Mutex Locks */ + +void BLI_lock_thread(int type) +{ + if (type==LOCK_IMAGE) + pthread_mutex_lock(&_image_lock); + else if (type==LOCK_PREVIEW) + pthread_mutex_lock(&_preview_lock); + else if (type==LOCK_CUSTOM1) + pthread_mutex_lock(&_custom1_lock); +} + +void BLI_unlock_thread(int type) +{ + if (type==LOCK_IMAGE) + pthread_mutex_unlock(&_image_lock); + else if (type==LOCK_PREVIEW) + pthread_mutex_unlock(&_preview_lock); + else if(type==LOCK_CUSTOM1) + pthread_mutex_unlock(&_custom1_lock); +} + +/* Mutex Locks */ + +void BLI_mutex_init(ThreadMutex *mutex) +{ + pthread_mutex_init(mutex, NULL); +} + +void BLI_mutex_lock(ThreadMutex *mutex) +{ + pthread_mutex_lock(mutex); +} + +void BLI_mutex_unlock(ThreadMutex *mutex) +{ + pthread_mutex_unlock(mutex); +} + +void BLI_mutex_end(ThreadMutex *mutex) +{ + pthread_mutex_destroy(mutex); +} + +/* Read/Write Mutex Lock */ + +void BLI_rw_mutex_init(ThreadRWMutex *mutex) +{ + pthread_rwlock_init(mutex, NULL); +} + +void BLI_rw_mutex_lock(ThreadRWMutex *mutex, int mode) +{ + if(mode == THREAD_LOCK_READ) + pthread_rwlock_rdlock(mutex); + else + pthread_rwlock_wrlock(mutex); +} + +void BLI_rw_mutex_unlock(ThreadRWMutex *mutex) +{ + pthread_rwlock_unlock(mutex); +} + +void BLI_rw_mutex_end(ThreadRWMutex *mutex) +{ + pthread_rwlock_destroy(mutex); +} + /* ************************************************ */ typedef struct ThreadedWorker { @@ -316,7 +374,7 @@ typedef struct WorkParam { int index; } WorkParam; -void *exec_work_fnct(void *v_param) +static void *exec_work_fnct(void *v_param) { WorkParam *p = (WorkParam*)v_param; void *value; diff --git a/source/blender/blenlib/intern/util.c b/source/blender/blenlib/intern/util.c index c7bb7a54457..f6fa4f1ebd2 100644 --- a/source/blender/blenlib/intern/util.c +++ b/source/blender/blenlib/intern/util.c @@ -856,98 +856,123 @@ char *BLI_gethome(void) { #endif } -/* this function returns the path to a blender folder, if it exists, - * trying in this order: - * - * path_to_executable/release/folder_name (in svn) - * ./release/folder_name (in svn) - * $HOME/.blender/folder_name - * path_to_executable/.blender/folder_name - * - * returns NULL if none is found. */ +/* this function returns the path to a blender folder, if it exists + * utility functions for BLI_gethome_folder */ -char *BLI_gethome_folder(char *folder_name) +/* #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) +{ + char tmppath[FILE_MAXDIR]; + + 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_exists(targetpath)) { +#ifdef PATH_DEBUG + printf("\tpath found: %s\n", targetpath); +#endif + return 1; + } + else { +#ifdef PATH_DEBUG + printf("\tpath missing: %s\n", targetpath); +#endif + targetpath[0] = '\0'; + return 0; + } +} + +static int gethome_path_local(char *targetpath, char *folder_name) { extern char bprogname[]; /* argv[0] from creator.c */ - static char homedir[FILE_MAXDIR] = ""; - static char fulldir[FILE_MAXDIR] = ""; - char tmpdir[FILE_MAXDIR]; char bprogdir[FILE_MAXDIR]; + char cwd[FILE_MAXDIR]; char *s; int i; - + +#ifdef PATH_DEBUG + printf("gethome_path_local...\n"); +#endif + + /* try release/folder_name (binary relative) */ /* 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 path_to_executable/release/folder_name (in svn) */ - if (folder_name) { - BLI_snprintf(tmpdir, sizeof(tmpdir), "release/%s", folder_name); - BLI_make_file_string("/", fulldir, bprogdir, tmpdir); - if (BLI_exists(fulldir)) return fulldir; - else fulldir[0] = '\0'; - } + /* try release/folder_name (CWD relative) */ + if(test_data_path(targetpath, BLI_getwdN(cwd), "release", folder_name)) + return 1; - /* try ./release/folder_name (in svn) */ - if(folder_name) { - BLI_snprintf(fulldir, sizeof(fulldir), "./release/%s", folder_name); - if (BLI_exists(fulldir)) return fulldir; - else fulldir[0] = '\0'; - } + if(test_data_path(targetpath, bprogdir, "release", folder_name)) + return 1; - /* BLI_gethome() can return NULL if env vars are not set */ - s = BLI_gethome(); + /* try ./.blender/folder_name */ + if(test_data_path(targetpath, bprogdir, ".blender", folder_name)) + return 1; + + return 0; +} - if(!s) { /* bail if no $HOME */ - printf("$HOME is NOT set\n"); - return NULL; - } +static int gethome_path_user(char *targetpath, char *folder_name) +{ + char *home_path= BLI_gethome(); - if(strstr(s, ".blender")) - BLI_strncpy(homedir, s, FILE_MAXDIR); - else - BLI_make_file_string("/", homedir, s, ".blender"); +#ifdef PATH_DEBUG + printf("gethome_path_user...\n"); +#endif + + /* try $HOME/folder_name */ + return test_data_path(targetpath, home_path, ".blender", folder_name); +} - /* if $HOME/.blender/folder_name exists, return it */ - if(BLI_exists(homedir)) { - if (folder_name) { - BLI_make_file_string("/", fulldir, homedir, folder_name); - if(BLI_exists(fulldir)) - return fulldir; - } - else - return homedir; - } - else - homedir[0] = '\0'; - - /* using tmpdir to preserve homedir (if) found above: - * the ideal is to have a home dir with folder_name dir inside - * it, but if that isn't available, it's possible to - * have a 'broken' home dir somewhere and a folder_name dir in the - * svn sources */ - BLI_make_file_string("/", tmpdir, bprogdir, ".blender"); - - if(BLI_exists(tmpdir)) { - if(folder_name) { - BLI_make_file_string("/", fulldir, tmpdir, folder_name); - if(BLI_exists(fulldir)) { - BLI_strncpy(homedir, tmpdir, FILE_MAXDIR); - return fulldir; - } - else { - homedir[0] = '\0'; - fulldir[0] = '\0'; - } - } - else return homedir; +static int gethome_path_system(char *targetpath, char *folder_name) +{ + extern char blender_path[]; /* unix prefix eg. /usr/share/blender/2.5 creator.c */ + + if(!blender_path[0]) + return 0; + +#ifdef PATH_DEBUG + printf("gethome_path_system...\n"); +#endif + + /* try $BLENDERPATH/folder_name */ + return test_data_path(targetpath, blender_path, NULL, folder_name); +} + +char *BLI_gethome_folder(char *folder_name, int flag) +{ + static char fulldir[FILE_MAXDIR] = ""; + + /* first check if this is a redistributable bundle */ + if(flag & BLI_GETHOME_LOCAL) { + if (gethome_path_local(fulldir, folder_name)) + return fulldir; } + /* then check if the OS has blender data files installed in a global location */ + if(flag & BLI_GETHOME_SYSTEM) { + if (gethome_path_system(fulldir, folder_name)) + return fulldir; + } + + /* now check the users home dir for data files */ + if(flag & BLI_GETHOME_USER) { + if (gethome_path_user(fulldir, folder_name)) + return fulldir; + } + return NULL; } +#ifdef PATH_DEBUG +#undef PATH_DEBUG +#endif + void BLI_setenv(const char *env, const char*val) { /* SGI or free windows */ |