diff options
Diffstat (limited to 'source/blender/blenlib')
48 files changed, 3030 insertions, 3774 deletions
diff --git a/source/blender/blenlib/BLI_arithb.h b/source/blender/blenlib/BLI_arithb.h index 796213ef793..0a0749d3382 100644 --- a/source/blender/blenlib/BLI_arithb.h +++ b/source/blender/blenlib/BLI_arithb.h @@ -38,6 +38,12 @@ extern "C" { #endif +#ifdef WIN32 +#define _USE_MATH_DEFINES +#endif + +#include <math.h> + #ifndef M_PI #define M_PI 3.14159265358979323846 #endif @@ -54,6 +60,68 @@ extern "C" { #define M_1_PI 0.318309886183790671538 #endif +#ifndef M_E +#define M_E 2.7182818284590452354 +#endif +#ifndef M_LOG2E +#define M_LOG2E 1.4426950408889634074 +#endif +#ifndef M_LOG10E +#define M_LOG10E 0.43429448190325182765 +#endif +#ifndef M_LN2 +#define M_LN2 0.69314718055994530942 +#endif +#ifndef M_LN10 +#define M_LN10 2.30258509299404568402 +#endif + +#ifndef sqrtf +#define sqrtf(a) ((float)sqrt(a)) +#endif +#ifndef powf +#define powf(a, b) ((float)pow(a, b)) +#endif +#ifndef cosf +#define cosf(a) ((float)cos(a)) +#endif +#ifndef sinf +#define sinf(a) ((float)sin(a)) +#endif +#ifndef acosf +#define acosf(a) ((float)acos(a)) +#endif +#ifndef asinf +#define asinf(a) ((float)asin(a)) +#endif +#ifndef atan2f +#define atan2f(a, b) ((float)atan2(a, b)) +#endif +#ifndef tanf +#define tanf(a) ((float)tan(a)) +#endif +#ifndef atanf +#define atanf(a) ((float)atan(a)) +#endif +#ifndef floorf +#define floorf(a) ((float)floor(a)) +#endif +#ifndef ceilf +#define ceilf(a) ((float)ceil(a)) +#endif +#ifndef fabsf +#define fabsf(a) ((float)fabs(a)) +#endif +#ifndef logf +#define logf(a) ((float)log(a)) +#endif +#ifndef expf +#define expf(a) ((float)exp(a)) +#endif +#ifndef fmodf +#define fmodf(a, b) ((float)fmod(a, b)) +#endif + #ifdef WIN32 #ifndef FREE_WINDOWS #define isnan(n) _isnan(n) @@ -89,6 +157,9 @@ double Sqrt3d(double d); float saacos(float fac); float saasin(float fac); float sasqrt(float fac); +float saacosf(float fac); +float saasinf(float fac); +float sasqrtf(float fac); int FloatCompare(float *v1, float *v2, float limit); int FloatCompare4(float *v1, float *v2, float limit); @@ -123,6 +194,7 @@ void Mat3ToCompatibleEul(float mat[][3], float *eul, float *oldrot); * @section Quaternion arithmetic routines */ +int QuatIsNul(float *q); void QuatToEul(float *quat, float *eul); void QuatOne(float *); void QuatMul(float *, float *, float *); @@ -339,7 +411,6 @@ void rgb_to_ycc(float r, float g, float b, float *ly, float *lcb, float *lcr); void rgb_to_hsv(float r, float g, float b, float *lh, float *ls, float *lv); void xyz_to_rgb(float x, float y, float z, float *r, float *g, float *b, int colorspace); int constrain_rgb(float *r, float *g, float *b); -void gamma_correct_rgb(float *r, float *g, float *b); unsigned int hsv_to_cpack(float h, float s, float v); unsigned int rgb_to_cpack(float r, float g, float b); void cpack_to_rgb(unsigned int col, float *r, float *g, float *b); @@ -402,6 +473,8 @@ int AabbIntersectAabb(float min1[3], float max1[3], float min2[3], float max2[3] void VecfCubicInterpol(float *x1, float *v1, float *x2, float *v2, float t, float *x, float *v); void PointInQuad2DUV(float v0[2], float v1[2], float v2[2], float v3[2], float pt[2], float *uv); void PointInFace2DUV(int isquad, float v0[2], float v1[2], float v2[2], float v3[2], float pt[2], float *uv); +int IsPointInTri2D(float v1[2], float v2[2], float v3[2], float pt[2]); +int IsPointInTri2DInts(int x1, int y1, int x2, int y2, int a, int b); 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]); diff --git a/source/blender/blenlib/BLI_blenlib.h b/source/blender/blenlib/BLI_blenlib.h index 13d5b5fe829..cb5f68ed1e0 100644 --- a/source/blender/blenlib/BLI_blenlib.h +++ b/source/blender/blenlib/BLI_blenlib.h @@ -62,354 +62,33 @@ #ifndef BLI_BLENLIB_H #define BLI_BLENLIB_H -/* braindamage for the masses... needed - because fillfacebase and fillvertbase are used outside */ -#include "DNA_listBase.h" +struct ListBase; #include <stdlib.h> -extern ListBase fillfacebase; -extern ListBase fillvertbase; -/** - * @attention Defined in scanfill.c - */ -extern ListBase filledgebase; extern char btempdir[]; /* creator.c temp dir used instead of U.tempdir, set with BLI_where_is_temp( btempdir, 1 ); */ -struct chardesc; -struct direntry; -struct rctf; -struct rcti; -struct EditVert; -struct PackedFile; -struct LinkNode; -struct DynamicList; - #ifdef __cplusplus extern "C" { #endif -/* BLI_util.h */ -char *BLI_gethome(void); -void BLI_make_file_string(const char *relabase, char *string, const char *dir, const char *file); -void BLI_make_exist(char *dir); -void BLI_make_existing_file(char *name); -void BLI_split_dirfile(char *string, char *dir, char *file); -void BLI_split_dirfile_basic(const char *string, char *dir, char *file); -void BLI_join_dirfile(char *string, const char *dir, const char *file); -int BLI_testextensie(const char *str, const char *ext); -void addlisttolist(ListBase *list1, ListBase *list2); -void BLI_insertlink(struct ListBase *listbase, void *vprevlink, void *vnewlink); -void *BLI_findlink(struct ListBase *listbase, int number); -int BLI_findindex(struct ListBase *listbase, void *vlink); -void BLI_freelistN(struct ListBase *listbase); -void BLI_addtail(struct ListBase *listbase, void *vlink); -void BLI_remlink(struct ListBase *listbase, void *vlink); -void BLI_uniquename(struct ListBase *list, void *vlink, char defname[], short name_offs, short len); -void BLI_newname(char * name, int add); -int BLI_stringdec(char *string, char *kop, char *start, unsigned short *numlen); -void BLI_stringenc(char *string, char *kop, char *start, unsigned short numlen, int pic); -void BLI_addhead(struct ListBase *listbase, void *vlink); -void BLI_insertlinkbefore(struct ListBase *listbase, void *vnextlink, void *vnewlink); -void BLI_insertlinkafter(struct ListBase *listbase, void *vprevlink, void *vnewlink); -void BLI_sortlist(struct ListBase *listbase, int (*cmp)(void *, void *)); -void BLI_freelist(struct ListBase *listbase); -int BLI_countlist(struct ListBase *listbase); -void BLI_freelinkN(ListBase *listbase, void *vlink); -void BLI_splitdirstring(char *di,char *fi); - -struct DynamicList *BLI_dlist_from_listbase(struct ListBase *lb); -struct ListBase *BLI_listbase_from_dlist(struct DynamicList *dlist, struct ListBase *lb); -void * BLI_dlist_find_link(struct DynamicList *dlist, unsigned int index); -unsigned int BLI_count_items(struct DynamicList *dlist); -void BLI_dlist_free_item(struct DynamicList *dlist, unsigned int index); -void BLI_dlist_rem_item(struct DynamicList *dlist, unsigned int index); -void * BLI_dlist_add_item_index(struct DynamicList *dlist, void *item, unsigned int index); -void BLI_dlist_destroy(struct DynamicList *dlist); -void BLI_dlist_init(struct DynamicList *dlist); -void BLI_dlist_reinit(struct DynamicList *dlist); - - /** - * dir can be any input, like from buttons, and this function - * converts it to a regular full path. - * Also removes garbage from directory paths, like /../ or double slashes etc - */ -void BLI_cleanup_file(const char *relabase, char *dir); -void BLI_cleanup_dir(const char *relabase, char *dir); /* same as above but adds a trailing slash */ - -/* go back one directory */ -int BLI_parent_dir(char *path); - - /** - * Blender's path code replacement function. - * Bases @a path strings leading with "//" by the - * directory @a basepath, and replaces instances of - * '#' with the @a framenum. Results are written - * back into @a path. - * - * @a path The path to convert - * @a basepath The directory to base relative paths with. - * @a framenum The framenumber to replace the frame code with. - * @retval Returns true if the path was relative (started with "//"). - */ -int BLI_convertstringcode(char *path, const char *basepath); -int BLI_convertstringframe(char *path, int frame); -int BLI_convertstringcwd(char *path); - -void BLI_makestringcode(const char *relfile, char *file); - - /** - * Change every @a from in @a string into @a to. The - * result will be in @a string - * - * @a string The string to work on - * @a from The character to replace - * @a to The character to replace with - */ -void BLI_char_switch(char *string, char from, char to); - - /** - * Makes sure @a path has platform-specific slashes. - * - * @a path The path to 'clean' - */ -void BLI_clean(char *path); - /** - * Duplicates the cstring @a str into a newly mallocN'd - * string and returns it. - * - * @param str The string to be duplicated - * @retval Returns the duplicated string - */ -char *BLI_strdup(const char *str); - - /** - * Duplicates the first @a len bytes of cstring @a str - * into a newly mallocN'd string and returns it. @a str - * is assumed to be at least len bytes long. - * - * @param str The string to be duplicated - * @param len The number of bytes to duplicate - * @retval Returns the duplicated string - */ -char *BLI_strdupn(const char *str, int len); - - /** - * Like strncpy but ensures dst is always - * '\0' terminated. - * - * @param dst Destination for copy - * @param src Source string to copy - * @param maxncpy Maximum number of characters to copy (generally - * the size of dst) - * @retval Returns dst - */ -char *BLI_strncpy(char *dst, const char *src, int maxncpy); - - /* - * Replacement for snprintf - */ -int BLI_snprintf(char *buffer, size_t count, const char *format, ...); - - /** - * Compare two strings - * - * @retval True if the strings are equal, false otherwise. - */ -int BLI_streq(char *a, char *b); - - /** - * Compare two strings without regard to case. - * - * @retval True if the strings are equal, false otherwise. - */ -int BLI_strcaseeq(char *a, char *b); - -/* in util.c */ -#ifdef WITH_ICONV -void BLI_string_to_utf8(char *original, char *utf_8, const char *code); -#endif - - /** - * Read a file as ASCII lines. An empty list is - * returned if the file cannot be opened or read. - * - * @attention The returned list should be free'd with - * BLI_free_file_lines. - * - * @param name The name of the file to read. - * @retval A list of strings representing the file lines. - */ -struct LinkNode *BLI_read_file_as_lines(char *name); +#include "BLI_listbase.h" - /** - * Free the list returned by BLI_read_file_as_lines. - */ -void BLI_free_file_lines(struct LinkNode *lines); +#include "BLI_dynamiclist.h" - /** - * Checks if name is a fully qualified filename to an executable. - * If not it searches $PATH for the file. On Windows it also - * adds the correct extension (.com .exe etc) from - * $PATHEXT if necessary. Also on Windows it translates - * the name to its 8.3 version to prevent problems with - * spaces and stuff. Final result is returned in fullname. - * - * @param fullname The full path and full name of the executable - * @param name The name of the executable (usually argv[0]) to be checked - */ -void BLI_where_am_i(char *fullname, const char *name); +#include "BLI_string.h" -char *get_install_dir(void); - /** - * Gets the temp directory when blender first runs. - * If the default path is not found, use try $TEMP - * - * Also make sure the temp dir has a trailing slash - * - * @param fullname The full path to the temp directory - */ -void BLI_where_is_temp(char *fullname, int usertemp); +#include "BLI_util.h" +#include "BLI_storage.h" - /** - * determines the full path to the application bundle on OS X - * - * @return path to application bundle - */ -#ifdef __APPLE__ -char* BLI_getbundle(void); -#endif - -#ifdef WIN32 -int BLI_getInstallationDir(char *str); -#endif - -/* BLI_storage.h */ -int BLI_filesize(int file); -int BLI_filepathsize(const char *path); -double BLI_diskfree(char *dir); -char *BLI_getwdN(char *dir); -void BLI_hide_dot_files(int set); -unsigned int BLI_getdir(char *dirname, struct direntry **filelist); +#include "BLI_fileops.h" -/** - * @attention Do not confuse with BLI_exists - */ -int BLI_exist(char *name); +#include "BLI_rect.h" -/* BLI_fileops.h */ -void BLI_recurdir_fileops(char *dirname); -int BLI_link(char *file, char *to); -int BLI_is_writable(char *filename); +#include "BLI_scanfill.h" -/** - * @attention Do not confuse with BLI_exist - */ -int BLI_exists(char *file); -int BLI_copy_fileops(char *file, char *to); -int BLI_rename(char *from, char *to); -int BLI_gzip(char *from, char *to); -int BLI_delete(char *file, int dir, int recursive); -int BLI_move(char *file, char *to); -int BLI_touch(const char *file); -char *BLI_last_slash(const char *string); -void BLI_add_slash(char *string); -void BLI_del_slash(char *string); - -/* BLI_rct.c */ -/** - * Determine if a rect is empty. An empty - * rect is one with a zero (or negative) - * width or height. - * - * @return True if @a rect is empty. - */ -int BLI_rcti_is_empty(struct rcti *rect); -void BLI_init_rctf(struct rctf *rect, float xmin, float xmax, float ymin, float ymax); -void BLI_init_rcti(struct rcti *rect, int xmin, int xmax, int ymin, int ymax); -void BLI_translate_rctf(struct rctf *rect, float x, float y); -void BLI_translate_rcti(struct rcti *rect, int x, int y); -int BLI_in_rcti(struct rcti *rect, int x, int y); -int BLI_in_rctf(struct rctf *rect, float x, float y); -int BLI_isect_rctf(struct rctf *src1, struct rctf *src2, struct rctf *dest); -int BLI_isect_rcti(struct rcti *src1, struct rcti *src2, struct rcti *dest); -void BLI_union_rctf(struct rctf *rcta, struct rctf *rctb); - -/* scanfill.c: used in displist only... */ -struct EditVert *BLI_addfillvert(float *vec); -struct EditEdge *BLI_addfilledge(struct EditVert *v1, struct EditVert *v2); -int BLI_edgefill(int mode, int mat_nr); -void BLI_end_edgefill(void); - -/* noise.h: */ -float BLI_hnoise(float noisesize, float x, float y, float z); -float BLI_hnoisep(float noisesize, float x, float y, float z); -float BLI_turbulence(float noisesize, float x, float y, float z, int nr); -float BLI_turbulence1(float noisesize, float x, float y, float z, int nr); -/* newnoise: generic noise & turbulence functions to replace the above BLI_hnoise/p & BLI_turbulence/1. - * This is done so different noise basis functions can be used */ -float BLI_gNoise(float noisesize, float x, float y, float z, int hard, int noisebasis); -float BLI_gTurbulence(float noisesize, float x, float y, float z, int oct, int hard, int noisebasis); -/* newnoise: musgrave functions */ -float mg_fBm(float x, float y, float z, float H, float lacunarity, float octaves, int noisebasis); -float mg_MultiFractal(float x, float y, float z, float H, float lacunarity, float octaves, int noisebasis); -float mg_VLNoise(float x, float y, float z, float distortion, int nbas1, int nbas2); -float mg_HeteroTerrain(float x, float y, float z, float H, float lacunarity, float octaves, float offset, int noisebasis); -float mg_HybridMultiFractal(float x, float y, float z, float H, float lacunarity, float octaves, float offset, float gain, int noisebasis); -float mg_RidgedMultiFractal(float x, float y, float z, float H, float lacunarity, float octaves, float offset, float gain, int noisebasis); -/* newnoise: voronoi */ -void voronoi(float x, float y, float z, float* da, float* pa, float me, int dtype); -/* newnoise: cellNoise & cellNoiseV (for vector/point/color) */ -float cellNoise(float x, float y, float z); -void cellNoiseV(float x, float y, float z, float *ca); - -/* These callbacks are needed to make the lib finction properly */ - -/** - * Set a function taking a char* as argument to flag errors. If the - * callback is not set, the error is discarded. - * @param f The function to use as callback - * @attention used in creator.c - */ -void BLI_setErrorCallBack(void (*f)(char*)); - -/** - * Set a function to be able to interrupt the execution of processing - * in this module. If the function returns true, the execution will - * terminate gracefully. If the callback is not set, interruption is - * not possible. - * @param f The function to use as callback - * @attention used in creator.c - */ -void BLI_setInterruptCallBack(int (*f)(void)); - -char *BLI_strcasestr(const char *s, const char *find); -int BLI_strcasecmp(const char *s1, const char *s2); -int BLI_strncasecmp(const char *s1, const char *s2, int n); -void BLI_timestr(double _time, char *str); /* time var is global */ - -/** - * Trick to address 32 GB with an int (only for malloced pointers) - */ -int BLI_int_from_pointer(void *poin); -void *BLI_pointer_from_int(int val); - - -#define PRNTSUB(type,arg) printf(#arg ": %" #type " ", arg) - -#ifndef PRINT -#define PRINT(t,v) {PRNTSUB(t,v); printf("\n");} -#define PRINT2(t1,v1,t2,v2) {PRNTSUB(t1,v1); PRNTSUB(t2,v2); printf("\n");} -#define PRINT3(t1,v1,t2,v2,t3,v3) {PRNTSUB(t1,v1); PRNTSUB(t2,v2); PRNTSUB(t3,v3); printf("\n");} -#define PRINT4(t1,v1,t2,v2,t3,v3,t4,v4) {PRNTSUB(t1,v1); PRNTSUB(t2,v2); PRNTSUB(t3,v3); PRNTSUB(t4,v4); printf("\n");} -#endif - -/** - * @param array The array in question - * @retval The number of elements in the array. - */ -#define BLI_ARRAY_NELEMS(array) (sizeof((array))/sizeof((array)[0])) +#include "BLI_noise.h" /** * @param strct The structure of interest diff --git a/source/blender/blenlib/BLI_dlrbTree.h b/source/blender/blenlib/BLI_dlrbTree.h new file mode 100644 index 00000000000..a17cbbd1993 --- /dev/null +++ b/source/blender/blenlib/BLI_dlrbTree.h @@ -0,0 +1,101 @@ +/** + * $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 Blender Foundation, Joshua Leung + * All rights reserved. + * + * Contributor(s): Joshua Leung (original author) + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef BLI_DLRB_TREE_H +#define BLI_DLRB_TREE_H + +/* Double-Linked Red-Black Tree Implementation: + * + * This is simply a Red-Black Tree implementation whose nodes can later + * be arranged + retrieved as elements in a Double-Linked list (i.e. ListBase). + * The Red-Black Tree implementation is based on the methods defined by Wikipedia. + */ + +/* ********************************************** */ +/* Data Types and Type Defines */ + +/* Base Structs --------------------------------- */ + +/* Basic Layout for a Node */ +typedef struct DLRBT_Node { + /* ListBase capabilities */ + struct DLRBT_Node *next, *prev; + + /* Tree Associativity settings */ + struct DLRBT_Node *left, *right; + struct DLRBT_Node *parent; + + char tree_col; + /* ... for nice alignment, next item should usually be a char too... */ +} DLRBT_Node; + +/* Red/Black defines for tree_col */ +enum eDLRBT_Colors { + DLRBT_BLACK= 0, + DLRBT_RED, +}; + +/* -------- */ + +/* The Tree Data */ +typedef struct DLRBT_Tree { + /* ListBase capabilities */ + void *first, *last; /* these should be based on DLRBT_Node-s */ + + /* Root Node */ + void *root; /* this should be based on DLRBT_Node-s */ +} DLRBT_Tree; + +/* ********************************************** */ +/* Public API */ + +/* Create a new tree, and initialise as necessary */ +DLRBT_Tree *BLI_dlrbTree_new(void); + +/* Initialises some given trees */ +void BLI_dlrbTree_init(DLRBT_Tree *tree); + +/* Free some tree */ +void BLI_dlrbTree_free(DLRBT_Tree *tree); + +/* Make sure the tree's Double-Linked list representation is valid */ +void BLI_dlrbTree_linkedlist_sync(DLRBT_Tree *tree); + + + +/* Balance the tree after the given element has been added to it + * (using custom code, in the Binary Tree way). + */ +void BLI_dlrbTree_insert(DLRBT_Tree *tree, DLRBT_Node *node); + +/* Remove the given element from the tree and balance again */ +// FIXME: this is not implemented yet... +void BLI_dlrbTree_remove(DLRBT_Tree *tree, DLRBT_Node *node); + +/* ********************************************** */ + +#endif // BLI_DLRB_TREE_H diff --git a/source/blender/blenlib/BLI_dynamiclist.h b/source/blender/blenlib/BLI_dynamiclist.h index e8c93fbcf23..ee5ccf516b9 100644 --- a/source/blender/blenlib/BLI_dynamiclist.h +++ b/source/blender/blenlib/BLI_dynamiclist.h @@ -26,12 +26,10 @@ * ***** END GPL LICENSE BLOCK ***** */ -#ifndef B_DYNAMIC_LIST_H -#define B_DYNAMIC_LIST_H +#ifndef BLI_DYNAMIC_LIST_H +#define BLI_DYNAMIC_LIST_H -#define PAGE_SIZE 4 - -struct ListBase; +#include "DNA_listBase.h" /* * Access array using realloc @@ -52,4 +50,16 @@ typedef struct DynamicList { struct ListBase lb; /* two way linked dynamic list */ } DynamicList; +/* note: 'index' is a string.h function, do not use in includes */ +struct DynamicList *BLI_dlist_from_listbase(struct ListBase *); +struct ListBase *BLI_listbase_from_dlist(struct DynamicList *, struct ListBase *); +void * BLI_dlist_find_link(struct DynamicList *, unsigned int); +unsigned int BLI_count_items(struct DynamicList *); +void BLI_dlist_free_item(struct DynamicList *, unsigned int); +void BLI_dlist_rem_item(struct DynamicList *, unsigned int); +void * BLI_dlist_add_item_index(struct DynamicList *, void *, unsigned int); +void BLI_dlist_destroy(struct DynamicList *); +void BLI_dlist_init(struct DynamicList *); +void BLI_dlist_reinit(struct DynamicList *); + #endif diff --git a/source/blender/blenlib/BLI_dynstr.h b/source/blender/blenlib/BLI_dynstr.h index e5b94aecb4f..39bb4e9e113 100644 --- a/source/blender/blenlib/BLI_dynstr.h +++ b/source/blender/blenlib/BLI_dynstr.h @@ -38,6 +38,8 @@ #ifndef BLI_DYNSTR_H #define BLI_DYNSTR_H +#include <stdarg.h> + struct DynStr; /** The abstract DynStr type */ @@ -56,7 +58,16 @@ DynStr* BLI_dynstr_new (void); * @param ds The DynStr to append to. * @param cstr The c-string to append. */ -void BLI_dynstr_append (DynStr *ds, char *cstr); +void BLI_dynstr_append (DynStr *ds, const char *cstr); + + /** + * Append a c-string to a DynStr, but with formatting like printf. + * + * @param ds The DynStr to append to. + * @param format The printf format string to use. + */ +void BLI_dynstr_appendf (DynStr *ds, const char *format, ...); +void BLI_dynstr_vappendf (DynStr *ds, const char *format, va_list args); /** * Find the length of a DynStr. @@ -69,7 +80,7 @@ int BLI_dynstr_get_len (DynStr *ds); /** * Get a DynStr's contents as a c-string. * <i> The returned c-string should be free'd - * using BLI_freeN. </i> + * using MEM_freeN. </i> * * @param ds The DynStr of interest. * @return The contents of @a ds as a c-string. diff --git a/source/blender/blenlib/BLI_editVert.h b/source/blender/blenlib/BLI_editVert.h index 447f6a2a485..56a20d8462a 100644 --- a/source/blender/blenlib/BLI_editVert.h +++ b/source/blender/blenlib/BLI_editVert.h @@ -70,9 +70,6 @@ typedef struct EditVert short fast; /* only 0 or 1, for editmesh_fastmalloc, do not store temp data here! */ int hash; int keyindex; /* original index #, for restoring key information */ -/*#ifdef WITH_VERSE*/ - void *vvert; -/*#endif*/ void *data; /* custom vertex data */ } EditVert; @@ -128,13 +125,11 @@ typedef struct EditFace float fp; } tmp; float n[3], cent[3]; - unsigned char mat_nr, flag; + unsigned char flag; unsigned char f, f1, h; unsigned char fast; /* only 0 or 1, for editmesh_fastmalloc */ unsigned char fgonf; /* flag for fgon options */ -/*#ifdef WITH_VERSE*/ - void *vface; -/*#endif*/ + short mat_nr; void *data; /* custom face data */ } EditFace; @@ -172,6 +167,13 @@ typedef struct EditMesh * never access this directly, use EM_set_actFace and EM_get_actFace */ EditFace *act_face; + /* copy from scene */ + short selectmode; + /* copy from object actcol */ + short mat_nr; + /* stats */ + int totvert, totedge, totface, totvertsel, totedgesel, totfacesel; + struct DerivedMesh *derivedCage, *derivedFinal; /* the custom data layer mask that was last used to calculate * derivedCage and derivedFinal @@ -182,9 +184,6 @@ typedef struct EditMesh CustomData vdata, edata, fdata; -#ifdef WITH_VERSE - void *vnode; -#endif } EditMesh; #endif diff --git a/source/blender/blenlib/intern/BLI_fileops.h b/source/blender/blenlib/BLI_fileops.h index bc42030e475..d2dd40b21a5 100644 --- a/source/blender/blenlib/intern/BLI_fileops.h +++ b/source/blender/blenlib/BLI_fileops.h @@ -36,6 +36,25 @@ #ifndef BLI_FILEOPS_H #define BLI_FILEOPS_H + + +void BLI_recurdir_fileops(char *dirname); +int BLI_link(char *file, char *to); +int BLI_is_writable(char *filename); + +/** + * @attention Do not confuse with BLI_exist + */ +int BLI_exists(char *file); +int BLI_copy_fileops(char *file, char *to); +int BLI_rename(char *from, char *to); +int BLI_gzip(char *from, char *to); +int BLI_delete(char *file, int dir, int recursive); +int BLI_move(char *file, char *to); +int BLI_touch(const char *file); +char *BLI_last_slash(const char *string); +int BLI_add_slash(char *string); +void BLI_del_slash(char *string); char *first_slash(char *string); /* only for the sane unix world: direct calls to system functions :( */ diff --git a/source/blender/blenlib/BLI_graph.h b/source/blender/blenlib/BLI_graph.h index f4fccfcbb2c..1dd439468f7 100644 --- a/source/blender/blenlib/BLI_graph.h +++ b/source/blender/blenlib/BLI_graph.h @@ -88,6 +88,7 @@ typedef struct BArcIterator { StoppedFct stopped; float *p, *no; + float size; int length; int index; diff --git a/source/blender/blenlib/BLI_kdopbvh.h b/source/blender/blenlib/BLI_kdopbvh.h index 62aede31682..fe6bc576fbd 100644 --- a/source/blender/blenlib/BLI_kdopbvh.h +++ b/source/blender/blenlib/BLI_kdopbvh.h @@ -1,6 +1,6 @@ /** * - * $Id: BLI_kdopbvh.h 19805 2009-04-20 00:19:16Z genscher $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -74,7 +74,6 @@ typedef void (*BVHTree_RayCastCallback) (void *userdata, int index, const BVHTre /* callback to range search query */ typedef void (*BVHTree_RangeQuery) (void *userdata, int index, float squared_dist); - BVHTree *BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis); void BLI_bvhtree_free(BVHTree *tree); @@ -96,6 +95,8 @@ int BLI_bvhtree_find_nearest(BVHTree *tree, const float *co, BVHTreeNearest *nea int BLI_bvhtree_ray_cast(BVHTree *tree, const float *co, const float *dir, float radius, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata); +float BLI_bvhtree_bb_raycast(float *bv, float *light_start, float *light_end, float *pos); + /* range query */ int BLI_bvhtree_range_query(BVHTree *tree, const float *co, float radius, BVHTree_RangeQuery callback, void *userdata); diff --git a/source/blender/blenlib/BLI_kdtree.h b/source/blender/blenlib/BLI_kdtree.h index 2d1925e5a52..3b1947cf0c9 100644 --- a/source/blender/blenlib/BLI_kdtree.h +++ b/source/blender/blenlib/BLI_kdtree.h @@ -1,7 +1,7 @@ /** * A kd-tree for nearest neighbour search. * - * $Id: BLI_kdtree.h 19485 2009-03-31 22:34:34Z gsrb3d $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -52,9 +52,13 @@ void BLI_kdtree_balance(KDTree *tree); /* Find nearest returns index, and -1 if no node is found. * Find n nearest returns number of points found, with results in nearest. - * Normal is optional. */ + * Normal is optional, but if given will limit results to points in normal direction from co. */ int BLI_kdtree_find_nearest(KDTree *tree, float *co, float *nor, KDTreeNearest *nearest); int BLI_kdtree_find_n_nearest(KDTree *tree, int n, float *co, float *nor, KDTreeNearest *nearest); +/* Range search returns number of points found, with results in nearest */ +/* Normal is optional, but if given will limit results to points in normal direction from co. */ +/* Remember to free nearest after use! */ +int BLI_kdtree_range_search(KDTree *tree, float range, float *co, float *nor, KDTreeNearest **nearest); #endif diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h new file mode 100644 index 00000000000..d0b106b59c3 --- /dev/null +++ b/source/blender/blenlib/BLI_listbase.h @@ -0,0 +1,63 @@ +/* + * $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: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + * + * $Id$ +*/ + +#ifndef BLI_LISTBASE_H +#define BLI_LISTBASE_H + +//#include "DNA_listbase.h" +struct ListBase; + +#ifdef __cplusplus +extern "C" { +#endif + +void addlisttolist(struct ListBase *list1, struct ListBase *list2); +void BLI_insertlink(struct ListBase *listbase, void *vprevlink, void *vnewlink); +void *BLI_findlink(struct ListBase *listbase, int number); +int BLI_findindex(struct ListBase *listbase, void *vlink); +void BLI_freelistN(struct ListBase *listbase); +void BLI_addtail(struct ListBase *listbase, void *vlink); +void BLI_remlink(struct ListBase *listbase, void *vlink); + +void BLI_addhead(struct ListBase *listbase, void *vlink); +void BLI_insertlinkbefore(struct ListBase *listbase, void *vnextlink, void *vnewlink); +void BLI_insertlinkafter(struct ListBase *listbase, void *vprevlink, void *vnewlink); +void BLI_sortlist(struct ListBase *listbase, int (*cmp)(void *, void *)); +void BLI_freelist(struct ListBase *listbase); +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 */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/source/blender/blenlib/BLI_noise.h b/source/blender/blenlib/BLI_noise.h new file mode 100644 index 00000000000..0886eb3a8a5 --- /dev/null +++ b/source/blender/blenlib/BLI_noise.h @@ -0,0 +1,65 @@ +/* + * $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: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + * +*/ + +#ifndef BLI_NOISE_H +#define BLI_NOISE_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* noise.h: */ +float BLI_hnoise(float noisesize, float x, float y, float z); +float BLI_hnoisep(float noisesize, float x, float y, float z); +float BLI_turbulence(float noisesize, float x, float y, float z, int nr); +float BLI_turbulence1(float noisesize, float x, float y, float z, int nr); +/* newnoise: generic noise & turbulence functions to replace the above BLI_hnoise/p & BLI_turbulence/1. + * This is done so different noise basis functions can be used */ +float BLI_gNoise(float noisesize, float x, float y, float z, int hard, int noisebasis); +float BLI_gTurbulence(float noisesize, float x, float y, float z, int oct, int hard, int noisebasis); +/* newnoise: musgrave functions */ +float mg_fBm(float x, float y, float z, float H, float lacunarity, float octaves, int noisebasis); +float mg_MultiFractal(float x, float y, float z, float H, float lacunarity, float octaves, int noisebasis); +float mg_VLNoise(float x, float y, float z, float distortion, int nbas1, int nbas2); +float mg_HeteroTerrain(float x, float y, float z, float H, float lacunarity, float octaves, float offset, int noisebasis); +float mg_HybridMultiFractal(float x, float y, float z, float H, float lacunarity, float octaves, float offset, float gain, int noisebasis); +float mg_RidgedMultiFractal(float x, float y, float z, float H, float lacunarity, float octaves, float offset, float gain, int noisebasis); +/* newnoise: voronoi */ +void voronoi(float x, float y, float z, float* da, float* pa, float me, int dtype); +/* newnoise: cellNoise & cellNoiseV (for vector/point/color) */ +float cellNoise(float x, float y, float z); +void cellNoiseV(float x, float y, float z, float *ca); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/source/blender/blenlib/BLI_rect.h b/source/blender/blenlib/BLI_rect.h new file mode 100644 index 00000000000..c36a41af84b --- /dev/null +++ b/source/blender/blenlib/BLI_rect.h @@ -0,0 +1,66 @@ +/* + * $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: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + * +*/ + +#ifndef BLI_RECT_H +#define BLI_RECT_H + +struct rctf; +struct rcti; + +#ifdef __cplusplus +extern "C" { +#endif + +/* BLI_rct.c */ +/** + * Determine if a rect is empty. An empty + * rect is one with a zero (or negative) + * width or height. + * + * @return True if @a rect is empty. + */ +int BLI_rcti_is_empty(struct rcti *rect); +void BLI_init_rctf(struct rctf *rect, float xmin, float xmax, float ymin, float ymax); +void BLI_init_rcti(struct rcti *rect, int xmin, int xmax, int ymin, int ymax); +void BLI_translate_rctf(struct rctf *rect, float x, float y); +void BLI_translate_rcti(struct rcti *rect, int x, int y); +int BLI_in_rcti(struct rcti *rect, int x, int y); +int BLI_in_rctf(struct rctf *rect, float x, float y); +int BLI_isect_rctf(struct rctf *src1, struct rctf *src2, struct rctf *dest); +int BLI_isect_rcti(struct rcti *src1, struct rcti *src2, struct rcti *dest); +void BLI_union_rctf(struct rctf *rcta, struct rctf *rctb); +void BLI_union_rcti(struct rcti *rcti1, struct rcti *rcti2); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/source/blender/blenlib/BLI_scanfill.h b/source/blender/blenlib/BLI_scanfill.h new file mode 100644 index 00000000000..1541b01da62 --- /dev/null +++ b/source/blender/blenlib/BLI_scanfill.h @@ -0,0 +1,81 @@ +/** + * blenlib/BLI_scanfill.h mar 2001 Nzc + * + * Filling meshes. + * + * $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: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef BLI_SCANFILL_H +#define BLI_SCANFILL_H + +/** + * @attention Defined in scanfill.c + */ +extern struct ListBase fillvertbase; +extern struct ListBase filledgebase; +extern struct ListBase fillfacebase; + +struct EditVert; + +#ifdef __cplusplus +extern "C" { +#endif + +/* scanfill.c: used in displist only... */ +struct EditVert *BLI_addfillvert(float *vec); +struct EditEdge *BLI_addfilledge(struct EditVert *v1, struct EditVert *v2); +int BLI_edgefill(int mode, int mat_nr); +void BLI_end_edgefill(void); + +/* These callbacks are needed to make the lib finction properly */ + +/** + * Set a function taking a char* as argument to flag errors. If the + * callback is not set, the error is discarded. + * @param f The function to use as callback + * @attention used in creator.c + */ +void BLI_setErrorCallBack(void (*f)(char*)); + +/** + * Set a function to be able to interrupt the execution of processing + * in this module. If the function returns true, the execution will + * terminate gracefully. If the callback is not set, interruption is + * not possible. + * @param f The function to use as callback + * @attention used in creator.c + */ +void BLI_setInterruptCallBack(int (*f)(void)); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/source/blender/blenlib/intern/BLI_storage.h b/source/blender/blenlib/BLI_storage.h index 3e0dec367da..fa44bb36e15 100644 --- a/source/blender/blenlib/intern/BLI_storage.h +++ b/source/blender/blenlib/BLI_storage.h @@ -25,21 +25,53 @@ * * ***** END GPL LICENSE BLOCK ***** */ + #ifndef BLI_STORAGE_H #define BLI_STORAGE_H +/* NOTE: these have to be defined before including unistd.h! */ #ifndef __APPLE__ #ifndef WIN32 -#define _LARGEFILE_SOURCE 1 +#ifndef _LARGEFILE_SOURCE +#define _LARGEFILE_SOURCE +#define _LARGEFILE64_SOURCE #define _FILE_OFFSET_BITS 64 #endif #endif +#endif -#include "BLI_storage_types.h" +struct direntry; void BLI_adddirstrings(void); void BLI_builddir(char *dirname, char *relname); int BLI_compare(struct direntry *entry1, struct direntry *entry2); +int BLI_filesize(int file); +int BLI_filepathsize(const char *path); +double BLI_diskfree(char *dir); +char *BLI_getwdN(char *dir); +void BLI_hide_dot_files(int set); +unsigned int BLI_getdir(char *dirname, struct direntry **filelist); +/** + * @attention Do not confuse with BLI_exists + */ +int BLI_exist(char *name); +/** + * Read a file as ASCII lines. An empty list is + * returned if the file cannot be opened or read. + * + * @attention The returned list should be free'd with + * BLI_free_file_lines. + * + * @param name The name of the file to read. + * @retval A list of strings representing the file lines. + */ +struct LinkNode *BLI_read_file_as_lines(char *name); + + /** + * Free the list returned by BLI_read_file_as_lines. + */ +void BLI_free_file_lines(struct LinkNode *lines); + #endif /* BLI_STORAGE_H */ diff --git a/source/blender/blenlib/BLI_storage_types.h b/source/blender/blenlib/BLI_storage_types.h index fda20d73fad..36d96f6075c 100644 --- a/source/blender/blenlib/BLI_storage_types.h +++ b/source/blender/blenlib/BLI_storage_types.h @@ -55,7 +55,11 @@ struct direntry{ char *string; mode_t type; char *relname; +#if (defined(WIN32) || defined(WIN64)) && (_MSC_VER>=1500) + struct _stat64 s; +#else struct stat s; +#endif unsigned int flags; char size[16]; char mode1[4]; @@ -70,6 +74,14 @@ struct direntry{ struct ImBuf *image; }; +#define SELECT 1 +#define HIDDEN 1 +#define FIRST 1 +#define DESELECT 0 +#define NOT_YET 0 +#define VISIBLE 0 +#define LAST 0 + struct dirlink { struct dirlink *next,*prev; diff --git a/source/blender/blenlib/BLI_string.h b/source/blender/blenlib/BLI_string.h new file mode 100644 index 00000000000..bf93dc19cc5 --- /dev/null +++ b/source/blender/blenlib/BLI_string.h @@ -0,0 +1,107 @@ +/* + * $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: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + * + * $Id$ +*/ + +#ifndef BLI_STRING_H +#define BLI_STRING_H + +#ifdef __cplusplus +extern "C" { +#endif + + /** + * Duplicates the cstring @a str into a newly mallocN'd + * string and returns it. + * + * @param str The string to be duplicated + * @retval Returns the duplicated string + */ +char *BLI_strdup(const char *str); + + /** + * Duplicates the first @a len bytes of cstring @a str + * into a newly mallocN'd string and returns it. @a str + * is assumed to be at least len bytes long. + * + * @param str The string to be duplicated + * @param len The number of bytes to duplicate + * @retval Returns the duplicated string + */ +char *BLI_strdupn(const char *str, int len); + + /** + * Like strncpy but ensures dst is always + * '\0' terminated. + * + * @param dst Destination for copy + * @param src Source string to copy + * @param maxncpy Maximum number of characters to copy (generally + * the size of dst) + * @retval Returns dst + */ +char *BLI_strncpy(char *dst, const char *src, int maxncpy); + + /* + * Replacement for snprintf + */ +int BLI_snprintf(char *buffer, size_t count, const char *format, ...); + + /* + * Print formatted string into a newly mallocN'd string + * and return it. + */ +char *BLI_sprintfN(const char *format, ...); + + /** + * Compare two strings + * + * @retval True if the strings are equal, false otherwise. + */ +int BLI_streq(const char *a, const char *b); + + /** + * Compare two strings without regard to case. + * + * @retval True if the strings are equal, false otherwise. + */ +int BLI_strcaseeq(const char *a, const char *b); + +char *BLI_strcasestr(const char *s, const char *find); +int BLI_strcasecmp(const char *s1, const char *s2); +int BLI_strncasecmp(const char *s1, const char *s2, int n); +int BLI_natstrcmp(const char *s1, const char *s2); + +void BLI_timestr(double _time, char *str); /* time var is global */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/source/blender/blenlib/BLI_threads.h b/source/blender/blenlib/BLI_threads.h index 5a7e84c42fb..8babb5fe780 100644 --- a/source/blender/blenlib/BLI_threads.h +++ b/source/blender/blenlib/BLI_threads.h @@ -53,6 +53,10 @@ void BLI_unlock_thread (int type); int BLI_system_thread_count( void ); /* gets the number of threads the system can make use of */ + /* 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); + /* ThreadedWorker is a simple tool for dispatching work to a limited number of threads in a transparent * fashion from the caller's perspective * */ diff --git a/source/blender/blenlib/BLI_util.h b/source/blender/blenlib/BLI_util.h new file mode 100644 index 00000000000..f9a84e071e7 --- /dev/null +++ b/source/blender/blenlib/BLI_util.h @@ -0,0 +1,146 @@ +/** + * blenlib/BLI_storage_types.h + * + * Some types for dealing with directories + * + * $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: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ +#ifndef BLI_UTIL_H +#define BLI_UTIL_H + +/* XXX doesn't seem to be used, marded for removal +#define mallocstructN(x,y,name) (x*)MEM_mallocN((y)* sizeof(x),name) +#define callocstructN(x,y,name) (x*)MEM_callocN((y)* sizeof(x),name) +*/ + +struct ListBase; +struct direntry; + +char *BLI_gethome(void); +char *BLI_gethome_folder(char *folder_name); +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); +void BLI_make_exist(char *dir); +void BLI_make_existing_file(char *name); +void BLI_split_dirfile(char *string, char *dir, char *file); +void BLI_split_dirfile_basic(const char *string, char *dir, char *file); +void BLI_join_dirfile(char *string, const char *dir, const char *file); +void BLI_getlastdir(const char* dir, char *last, int maxlen); +int BLI_testextensie(const char *str, const char *ext); +void BLI_uniquename(struct ListBase *list, void *vlink, char defname[], char delim, short name_offs, short len); +void BLI_newname(char * name, int add); +int BLI_stringdec(char *string, char *kop, char *start, unsigned short *numlen); +void BLI_stringenc(char *string, char *kop, char *start, unsigned short numlen, int pic); +void BLI_splitdirstring(char *di,char *fi); + +/* make sure path separators conform to system one */ +void BLI_clean(char *path); + +/** + * dir can be any input, like from buttons, and this function + * converts it to a regular full path. + * Also removes garbage from directory paths, like /../ or double slashes etc + */ +void BLI_cleanup_file(const char *relabase, char *dir); +void BLI_cleanup_dir(const char *relabase, char *dir); /* same as above but adds a trailing slash */ + +/* go back one directory */ +int BLI_parent_dir(char *path); + +/* return whether directory is root and thus has no parent dir */ +int BLI_has_parent(char *path); + + /** + * Blender's path code replacement function. + * Bases @a path strings leading with "//" by the + * directory @a basepath, and replaces instances of + * '#' with the @a framenum. Results are written + * back into @a path. + * + * @a path The path to convert + * @a basepath The directory to base relative paths with. + * @a framenum The framenumber to replace the frame code with. + * @retval Returns true if the path was relative (started with "//"). + */ +int BLI_convertstringcode(char *path, const char *basepath); +int BLI_convertstringframe(char *path, int frame); +int BLI_convertstringcwd(char *path); + +void BLI_makestringcode(const char *relfile, char *file); + + /** + * Change every @a from in @a string into @a to. The + * result will be in @a string + * + * @a string The string to work on + * @a from The character to replace + * @a to The character to replace with + */ +void BLI_char_switch(char *string, char from, char to); + +/** + * Checks if name is a fully qualified filename to an executable. + * If not it searches $PATH for the file. On Windows it also + * adds the correct extension (.com .exe etc) from + * $PATHEXT if necessary. Also on Windows it translates + * the name to its 8.3 version to prevent problems with + * spaces and stuff. Final result is returned in fullname. + * + * @param fullname The full path and full name of the executable + * @param name The name of the executable (usually argv[0]) to be checked + */ +void BLI_where_am_i(char *fullname, const char *name); + +char *get_install_dir(void); + /** + * Gets the temp directory when blender first runs. + * If the default path is not found, use try $TEMP + * + * Also make sure the temp dir has a trailing slash + * + * @param fullname The full path to the temp directory + */ +void BLI_where_is_temp(char *fullname, int usertemp); + + + /** + * determines the full path to the application bundle on OS X + * + * @return path to application bundle + */ +#ifdef __APPLE__ +char* BLI_getbundle(void); +#endif + +#ifdef WITH_ICONV +void BLI_string_to_utf8(char *original, char *utf_8, const char *code); +#endif + +#endif + diff --git a/source/blender/blenlib/BLI_vfontdata.h b/source/blender/blenlib/BLI_vfontdata.h index 8838b1992e4..070d8d12c08 100644 --- a/source/blender/blenlib/BLI_vfontdata.h +++ b/source/blender/blenlib/BLI_vfontdata.h @@ -54,7 +54,7 @@ typedef struct VFontData { typedef struct VChar { struct VChar *next, *prev; ListBase nurbsbase; - unsigned long index; + intptr_t index; float resol; float width; float *points; @@ -67,19 +67,6 @@ struct TmpFont struct VFont *vfont; }; - -/** - * Construct a new VFontData structure from - * PostScript font data in a PackedFile. - * - * @param pf The font data. - * @retval A new VFontData structure, or NULL - * if unable to load. - */ - VFontData* -BLI_vfontdata_from_psfont( - struct PackedFile *pf); - /** * Construct a new VFontData structure from * Freetype font data in a PackedFile. diff --git a/source/blender/blenlib/BLI_winstuff.h b/source/blender/blenlib/BLI_winstuff.h index 3bb63506c95..3e1b73e51be 100644 --- a/source/blender/blenlib/BLI_winstuff.h +++ b/source/blender/blenlib/BLI_winstuff.h @@ -120,6 +120,10 @@ int closedir (DIR *dp); void get_default_root(char *root); int check_file_chars(char *filename); +#ifdef WIN32 +int BLI_getInstallationDir(char *str); +#endif + #ifdef __cplusplus } #endif diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index 4eb01a50f39..334c8e6906b 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -40,15 +40,6 @@ SET(INC ) ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux") -IF(WITH_VERSE) - ADD_DEFINITIONS(-DWITH_VERSE) - SET(INC ${INC} ${VERSE_INC}) -ENDIF(WITH_VERSE) - -IF(WITH_INTERNATIONAL) - ADD_DEFINITIONS(-DWITH_FREETYPE2) -ENDIF(WITH_INTERNATIONAL) - IF(WIN32) SET(INC ${INC} ${PTHREADS_INC}) ENDIF(WIN32) diff --git a/source/blender/blenlib/SConscript b/source/blender/blenlib/SConscript index 829b39f4a61..3d7d6b63e64 100644 --- a/source/blender/blenlib/SConscript +++ b/source/blender/blenlib/SConscript @@ -4,26 +4,16 @@ Import ('env') sources = env.Glob('intern/*.c') cflags='' -incs = '. ../makesdna ../blenkernel #/intern/guardedalloc ../include' +incs = '. ../makesdna ../blenkernel #/intern/guardedalloc ../editors/include' incs += ' ' + env['BF_FREETYPE_INC'] incs += ' ' + env['BF_ZLIB_INC'] defs = '' -if env['WITH_BF_SDL']: - incs += ' ' + env['BF_SDL_INC'] - -if env['WITH_BF_INTERNATIONAL']: - defs = 'WITH_FREETYPE2' - -if env['WITH_BF_VERSE']: - defs += ' WITH_VERSE' - incs += ' ' + env['BF_VERSE_INCLUDE'] - if env['OURPLATFORM'] == 'linux2': cflags='-pthread' incs += ' ../../../extern/binreloc/include' -if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross'): +if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): incs += ' ' + env['BF_PTHREADS_INC'] -env.BlenderLib ( 'bf_blenlib', sources, Split(incs), Split(defs), libtype=['core', 'intern', 'player'], priority = [85,150,195], compileflags =cflags ) +env.BlenderLib ( 'bf_blenlib', sources, Split(incs), Split(defs), libtype=['core'], priority = [180], compileflags =cflags ) diff --git a/source/blender/blenlib/intern/BLI_dynstr.c b/source/blender/blenlib/intern/BLI_dynstr.c index 43c80dd24f0..dd10d898a7f 100644 --- a/source/blender/blenlib/intern/BLI_dynstr.c +++ b/source/blender/blenlib/intern/BLI_dynstr.c @@ -28,6 +28,8 @@ * Dynamically sized string ADT */ +#include <stdarg.h> +#include <stdio.h> #include <stdlib.h> #include <string.h> @@ -35,8 +37,10 @@ #include "BLI_blenlib.h" #include "BLI_dynstr.h" -#ifdef HAVE_CONFIG_H -#include <config.h> +#ifdef _WIN32 +#ifndef vsnprintf +#define vsnprintf _vsnprintf +#endif #endif /***/ @@ -63,7 +67,7 @@ DynStr *BLI_dynstr_new(void) { return ds; } -void BLI_dynstr_append(DynStr *ds, char *cstr) { +void BLI_dynstr_append(DynStr *ds, const char *cstr) { DynStrElem *dse= malloc(sizeof(*dse)); int cstrlen= strlen(cstr); @@ -79,6 +83,105 @@ void BLI_dynstr_append(DynStr *ds, char *cstr) { ds->curlen+= cstrlen; } +void BLI_dynstr_vappendf(DynStr *ds, const char *format, va_list args) +{ + char *message, fixedmessage[256]; + int len= 256, maxlen= 65536, retval; + + while(1) { + if(len == sizeof(fixedmessage)) + message= fixedmessage; + else + message= MEM_callocN(sizeof(char)*(len+1), "BLI_dynstr_appendf"); + + retval= vsnprintf(message, len, format, args); + + if(retval == -1) { + /* -1 means not enough space, but on windows it may also mean + * there is a formatting error, so we impose a maximum length */ + if(message != fixedmessage) + MEM_freeN(message); + message= NULL; + + len *= 2; + if(len > maxlen) { + fprintf(stderr, "BLI_dynstr_append text too long or format error.\n"); + break; + } + } + else if(retval > len) { + /* in C99 the actual length required is returned */ + if(message != fixedmessage) + MEM_freeN(message); + message= NULL; + + len= retval; + } + else + break; + } + + if(message) { + BLI_dynstr_append(ds, message); + + if(message != fixedmessage) + MEM_freeN(message); + } +} + +void BLI_dynstr_appendf(DynStr *ds, const char *format, ...) +{ + va_list args; + char *message, fixedmessage[256]; + int len= 256, maxlen= 65536, retval; + + /* note that it's tempting to just call BLI_dynstr_vappendf here + * and avoid code duplication, that crashes on some system because + * va_start/va_end have to be called for each vsnprintf call */ + + while(1) { + if(len == sizeof(fixedmessage)) + message= fixedmessage; + else + message= MEM_callocN(sizeof(char)*(len+1), "BLI_dynstr_appendf"); + + va_start(args, format); + retval= vsnprintf(message, len, format, args); + va_end(args); + + if(retval == -1) { + /* -1 means not enough space, but on windows it may also mean + * there is a formatting error, so we impose a maximum length */ + if(message != fixedmessage) + MEM_freeN(message); + message= NULL; + + len *= 2; + if(len > maxlen) { + fprintf(stderr, "BLI_dynstr_append text too long or format error.\n"); + break; + } + } + else if(retval > len) { + /* in C99 the actual length required is returned */ + if(message != fixedmessage) + MEM_freeN(message); + message= NULL; + + len= retval; + } + else + break; + } + + if(message) { + BLI_dynstr_append(ds, message); + + if(message != fixedmessage) + MEM_freeN(message); + } +} + int BLI_dynstr_get_len(DynStr *ds) { return ds->curlen; } diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c index 1967b8a88e2..80cd507520c 100644 --- a/source/blender/blenlib/intern/BLI_ghash.c +++ b/source/blender/blenlib/intern/BLI_ghash.c @@ -253,7 +253,7 @@ int BLI_ghashIterator_isDone(GHashIterator *ghi) { /***/ unsigned int BLI_ghashutil_ptrhash(void *key) { - return (unsigned int) key; + return (unsigned int)(intptr_t)key; } int BLI_ghashutil_ptrcmp(void *a, void *b) { if (a==b) diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index df37ff457f6..014c3d52cda 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -72,10 +72,10 @@ struct BVHTree char start_axis, stop_axis; // KDOP_AXES array indices according to axis }; -typedef struct BVHOverlapData -{ - BVHTree *tree1, *tree2; - BVHTreeOverlap *overlap; +typedef struct BVHOverlapData +{ + BVHTree *tree1, *tree2; + BVHTreeOverlap *overlap; int i, max_overlap; /* i is number of overlaps */ int start_axis, stop_axis; } BVHOverlapData; @@ -109,7 +109,7 @@ typedef struct BVHRayCastData //////////////////////////////////////////////////////////////////////// // Bounding Volume Hierarchy Definition -// +// // Notes: From OBB until 26-DOP --> all bounding volumes possible, just choose type below // Notes: You have to choose the type at compile time ITM // Notes: You can choose the tree type --> binary, quad, octree, choose below @@ -188,10 +188,10 @@ int ADJUST_MEMORY(void *local_memblock, void **memblock, int new_size, int *max_ ////////////////////////////////////////////////////////////////////////////////////////////////////// -// Introsort +// Introsort // with permission deriven from the following Java code: // http://ralphunden.net/content/tutorials/a-guide-to-introsort/ -// and he derived it from the SUN STL +// and he derived it from the SUN STL ////////////////////////////////////////////////////////////////////////////////////////////////////// static int size_threshold = 16; /* @@ -362,7 +362,7 @@ static void create_kdop_hull(BVHTree *tree, BVHNode *node, float *co, int numpoi float newminmax; float *bv = node->bv; int i, k; - + // don't init boudings for the moving case if(!moving) { @@ -372,7 +372,7 @@ static void create_kdop_hull(BVHTree *tree, BVHNode *node, float *co, int numpoi bv[2*i + 1] = -FLT_MAX; } } - + for(k = 0; k < numpoints; k++) { // for all Axes. @@ -394,7 +394,7 @@ static void refit_kdop_hull(BVHTree *tree, BVHNode *node, int start, int end) int i, j; float *bv = node->bv; - + for (i = tree->start_axis; i < tree->stop_axis; i++) { bv[2*i] = FLT_MAX; @@ -406,10 +406,10 @@ static void refit_kdop_hull(BVHTree *tree, BVHNode *node, int start, int end) // for all Axes. for (i = tree->start_axis; i < tree->stop_axis; i++) { - newmin = tree->nodes[j]->bv[(2 * i)]; + newmin = tree->nodes[j]->bv[(2 * i)]; if ((newmin < bv[(2 * i)])) bv[(2 * i)] = newmin; - + newmax = tree->nodes[j]->bv[(2 * i) + 1]; if ((newmax > bv[(2 * i) + 1])) bv[(2 * i) + 1] = newmax; @@ -427,14 +427,14 @@ static char get_largest_axis(float *bv) middle_point[0] = (bv[1]) - (bv[0]); // x axis middle_point[1] = (bv[3]) - (bv[2]); // y axis middle_point[2] = (bv[5]) - (bv[4]); // z axis - if (middle_point[0] > middle_point[1]) + if (middle_point[0] > middle_point[1]) { if (middle_point[0] > middle_point[2]) return 1; // max x axis else return 5; // max z axis } - else + else { if (middle_point[1] > middle_point[2]) return 3; // max y axis @@ -448,24 +448,24 @@ static char get_largest_axis(float *bv) static void node_join(BVHTree *tree, BVHNode *node) { int i, j; - + for (i = tree->start_axis; i < tree->stop_axis; i++) { node->bv[2*i] = FLT_MAX; node->bv[2*i + 1] = -FLT_MAX; } - + for (i = 0; i < tree->tree_type; i++) { - if (node->children[i]) + if (node->children[i]) { for (j = tree->start_axis; j < tree->stop_axis; j++) { - // update minimum - if (node->children[i]->bv[(2 * j)] < node->bv[(2 * j)]) + // update minimum + if (node->children[i]->bv[(2 * j)] < node->bv[(2 * j)]) node->bv[(2 * j)] = node->children[i]->bv[(2 * j)]; - - // update maximum + + // update maximum if (node->children[i]->bv[(2 * j) + 1] > node->bv[(2 * j) + 1]) node->bv[(2 * j) + 1] = node->children[i]->bv[(2 * j) + 1]; } @@ -478,6 +478,7 @@ static void node_join(BVHTree *tree, BVHNode *node) /* * Debug and information functions */ +#if 0 static void bvhtree_print_tree(BVHTree *tree, BVHNode *node, int depth) { int i; @@ -509,6 +510,7 @@ static void bvhtree_info(BVHTree *tree) // bvhtree_print_tree(tree, tree->nodes[tree->totleaf], 0); } +#endif #if 0 @@ -516,7 +518,7 @@ static void bvhtree_info(BVHTree *tree) static void verify_tree(BVHTree *tree) { int i, j, check = 0; - + // check the pointer list for(i = 0; i < tree->totleaf; i++) { @@ -536,7 +538,7 @@ static void verify_tree(BVHTree *tree) check = 0; } } - + // check the leaf list for(i = 0; i < tree->totleaf; i++) { @@ -556,7 +558,7 @@ static void verify_tree(BVHTree *tree) check = 0; } } - + printf("branches: %d, leafs: %d, total: %d\n", tree->totbranch, tree->totleaf, tree->totbranch + tree->totleaf); } #endif @@ -701,7 +703,7 @@ static void non_recursive_bvh_div_nodes(BVHTree *tree, BVHNode *branches_array, BVHBuildHelper data; int depth; - + // set parent from root node to NULL BVHNode *tmp = branches_array+0; tmp->parent = NULL; @@ -720,7 +722,7 @@ static void non_recursive_bvh_div_nodes(BVHTree *tree, BVHNode *branches_array, } branches_array--; //Implicit trees use 1-based indexs - + build_implicit_tree_helper(tree, &data); //Loop tree levels (log N) loops @@ -804,11 +806,11 @@ BVHTree *BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis) { BVHTree *tree; int numnodes, i; - + // theres not support for trees below binary-trees :P if(tree_type < 2) return NULL; - + if(tree_type > MAX_TREETYPE) return NULL; @@ -818,13 +820,13 @@ BVHTree *BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis) //so that tangent rays can still hit a bounding volume.. //this bug would show up when casting a ray aligned with a kdop-axis and with an edge of 2 faces epsilon = MAX2(FLT_EPSILON, epsilon); - + if(tree) { tree->epsilon = epsilon; - tree->tree_type = tree_type; + tree->tree_type = tree_type; tree->axis = axis; - + if(axis == 26) { tree->start_axis = 0; @@ -861,13 +863,13 @@ BVHTree *BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis) numnodes = maxsize + implicit_needed_branches(tree_type, maxsize) + tree_type; tree->nodes = (BVHNode **)MEM_callocN(sizeof(BVHNode *)*numnodes, "BVHNodes"); - + if(!tree->nodes) { MEM_freeN(tree); return NULL; } - + tree->nodebv = (float*)MEM_callocN(sizeof(float)* axis * numnodes, "BVHNodeBV"); if(!tree->nodebv) { @@ -884,7 +886,7 @@ BVHTree *BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis) } tree->nodearray = (BVHNode *)MEM_callocN(sizeof(BVHNode)* numnodes, "BVHNodeArray"); - + if(!tree->nodearray) { MEM_freeN(tree->nodechild); @@ -900,14 +902,14 @@ BVHTree *BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis) tree->nodearray[i].bv = tree->nodebv + i * axis; tree->nodearray[i].children = tree->nodechild + i * tree_type; } - + } return tree; } void BLI_bvhtree_free(BVHTree *tree) -{ +{ if(tree) { MEM_freeN(tree->nodes); @@ -944,27 +946,27 @@ int BLI_bvhtree_insert(BVHTree *tree, int index, float *co, int numpoints) { int i; BVHNode *node = NULL; - + // insert should only possible as long as tree->totbranch is 0 if(tree->totbranch > 0) return 0; - + if(tree->totleaf+1 >= MEM_allocN_len(tree->nodes)/sizeof(*(tree->nodes))) return 0; - + // TODO check if have enough nodes in array - + node = tree->nodes[tree->totleaf] = &(tree->nodearray[tree->totleaf]); tree->totleaf++; - + create_kdop_hull(tree, node, co, numpoints, 0); node->index= index; - + // inflate the bv with some epsilon for (i = tree->start_axis; i < tree->stop_axis; i++) { - node->bv[(2 * i)] -= tree->epsilon; // minimum - node->bv[(2 * i) + 1] += tree->epsilon; // maximum + node->bv[(2 * i)] -= tree->epsilon; // minimum + node->bv[(2 * i) + 1] += tree->epsilon; // maximum } return 1; @@ -976,23 +978,23 @@ int BLI_bvhtree_update_node(BVHTree *tree, int index, float *co, float *co_movin { int i; BVHNode *node= NULL; - + // check if index exists if(index > tree->totleaf) return 0; - + node = tree->nodearray + index; - + create_kdop_hull(tree, node, co, numpoints, 0); - + if(co_moving) create_kdop_hull(tree, node, co_moving, numpoints, 1); - + // inflate the bv with some epsilon for (i = tree->start_axis; i < tree->stop_axis; i++) { - node->bv[(2 * i)] -= tree->epsilon; // minimum - node->bv[(2 * i) + 1] += tree->epsilon; // maximum + node->bv[(2 * i)] -= tree->epsilon; // minimum + node->bv[(2 * i) + 1] += tree->epsilon; // maximum } return 1; @@ -1028,24 +1030,24 @@ static int tree_overlap(BVHNode *node1, BVHNode *node2, int start_axis, int stop float *bv2 = node2->bv; float *bv1_end = bv1 + (stop_axis<<1); - + bv1 += start_axis<<1; bv2 += start_axis<<1; - + // test all axis if min + max overlap for (; bv1 != bv1_end; bv1+=2, bv2+=2) { - if ((*(bv1) > *(bv2 + 1)) || (*(bv2) > *(bv1 + 1))) + if ((*(bv1) > *(bv2 + 1)) || (*(bv2) > *(bv1 + 1))) return 0; } - + return 1; } static void traverse(BVHOverlapData *data, BVHNode *node1, BVHNode *node2) { int j; - + if(tree_overlap(node1, node2, data->start_axis, data->stop_axis)) { // check if node1 is a leaf @@ -1054,17 +1056,17 @@ static void traverse(BVHOverlapData *data, BVHNode *node1, BVHNode *node2) // check if node2 is a leaf if(!node2->totnode) { - + if(node1 == node2) { return; } - + if(data->i >= data->max_overlap) - { + { // try to make alloc'ed memory bigger data->overlap = realloc(data->overlap, sizeof(BVHTreeOverlap)*data->max_overlap*2); - + if(!data->overlap) { printf("Out of Memory in traverse\n"); @@ -1072,7 +1074,7 @@ static void traverse(BVHOverlapData *data, BVHNode *node1, BVHNode *node2) } data->max_overlap *= 2; } - + // both leafs, insert overlap! data->overlap[data->i].indexA = node1->index; data->overlap[data->i].indexB = node2->index; @@ -1090,7 +1092,7 @@ static void traverse(BVHOverlapData *data, BVHNode *node1, BVHNode *node2) } else { - + for(j = 0; j < data->tree2->tree_type; j++) { if(node1->children[j]) @@ -1106,21 +1108,21 @@ BVHTreeOverlap *BLI_bvhtree_overlap(BVHTree *tree1, BVHTree *tree2, int *result) int j, total = 0; BVHTreeOverlap *overlap = NULL, *to = NULL; BVHOverlapData **data; - + // check for compatibility of both trees (can't compare 14-DOP with 18-DOP) if((tree1->axis != tree2->axis) && (tree1->axis == 14 || tree2->axis == 14) && (tree1->axis == 18 || tree2->axis == 18)) return 0; - + // fast check root nodes for collision before doing big splitting + traversal if(!tree_overlap(tree1->nodes[tree1->totleaf], tree2->nodes[tree2->totleaf], MIN2(tree1->start_axis, tree2->start_axis), MIN2(tree1->stop_axis, tree2->stop_axis))) return 0; data = MEM_callocN(sizeof(BVHOverlapData *)* tree1->tree_type, "BVHOverlapData_star"); - + for(j = 0; j < tree1->tree_type; j++) { data[j] = (BVHOverlapData *)MEM_callocN(sizeof(BVHOverlapData), "BVHOverlapData"); - + // init BVHOverlapData data[j]->overlap = (BVHTreeOverlap *)malloc(sizeof(BVHTreeOverlap)*MAX2(tree1->totleaf, tree2->totleaf)); data[j]->tree1 = tree1; @@ -1136,25 +1138,25 @@ BVHTreeOverlap *BLI_bvhtree_overlap(BVHTree *tree1, BVHTree *tree2, int *result) { traverse(data[j], tree1->nodes[tree1->totleaf]->children[j], tree2->nodes[tree2->totleaf]); } - + for(j = 0; j < tree1->tree_type; j++) total += data[j]->i; - + to = overlap = (BVHTreeOverlap *)MEM_callocN(sizeof(BVHTreeOverlap)*total, "BVHTreeOverlap"); - + for(j = 0; j < tree1->tree_type; j++) { memcpy(to, data[j]->overlap, data[j]->i*sizeof(BVHTreeOverlap)); to+=data[j]->i; } - + for(j = 0; j < tree1->tree_type; j++) { free(data[j]->overlap); MEM_freeN(data[j]); } MEM_freeN(data); - + (*result) = total; return overlap; } @@ -1171,7 +1173,7 @@ static float squared_dist(const float *a, const float *b) } //Determines the nearest point of the given node BV. Returns the squared distance to that point. -static float calc_nearest_point(const float *proj, BVHNode *node, float *nearest) +static float calc_nearest_point(BVHNearestData *data, BVHNode *node, float *nearest) { int i; const float *bv = node->bv; @@ -1179,12 +1181,12 @@ static float calc_nearest_point(const float *proj, BVHNode *node, float *nearest //nearest on AABB hull for(i=0; i != 3; i++, bv += 2) { - if(bv[0] > proj[i]) + if(bv[0] > data->proj[i]) nearest[i] = bv[0]; - else if(bv[1] < proj[i]) + else if(bv[1] < data->proj[i]) nearest[i] = bv[1]; else - nearest[i] = proj[i]; + nearest[i] = data->proj[i]; } /* @@ -1206,7 +1208,7 @@ static float calc_nearest_point(const float *proj, BVHNode *node, float *nearest } } */ - return squared_dist(proj, nearest); + return squared_dist(data->co, nearest); } @@ -1229,7 +1231,7 @@ static void dfs_find_nearest_dfs(BVHNearestData *data, BVHNode *node) else { data->nearest.index = node->index; - data->nearest.dist = calc_nearest_point(data->proj, node, data->nearest.co); + data->nearest.dist = calc_nearest_point(data, node, data->nearest.co); } } else @@ -1238,12 +1240,12 @@ static void dfs_find_nearest_dfs(BVHNearestData *data, BVHNode *node) int i; float nearest[3]; - if(data->proj[ node->main_axis ] <= node->children[0]->bv[node->main_axis*2+1]) + if(data->proj[ (int)node->main_axis ] <= node->children[0]->bv[(int)node->main_axis*2+1]) { for(i=0; i != node->totnode; i++) { - if( calc_nearest_point(data->proj, node->children[i], nearest) >= data->nearest.dist) continue; + if( calc_nearest_point(data, node->children[i], nearest) >= data->nearest.dist) continue; dfs_find_nearest_dfs(data, node->children[i]); } } @@ -1251,7 +1253,7 @@ static void dfs_find_nearest_dfs(BVHNearestData *data, BVHNode *node) { for(i=node->totnode-1; i >= 0 ; i--) { - if( calc_nearest_point(data->proj, node->children[i], nearest) >= data->nearest.dist) continue; + if( calc_nearest_point(data, node->children[i], nearest) >= data->nearest.dist) continue; dfs_find_nearest_dfs(data, node->children[i]); } } @@ -1261,12 +1263,13 @@ static void dfs_find_nearest_dfs(BVHNearestData *data, BVHNode *node) static void dfs_find_nearest_begin(BVHNearestData *data, BVHNode *node) { float nearest[3], sdist; - sdist = calc_nearest_point(data->proj, node, nearest); + sdist = calc_nearest_point(data, node, nearest); if(sdist >= data->nearest.dist) return; dfs_find_nearest_dfs(data, node); } +#if 0 static void NodeDistance_push_heap(NodeDistance *heap, int heap_size) PUSH_HEAP_BODY(NodeDistance, NodeDistance_priority, heap, heap_size) @@ -1298,7 +1301,7 @@ static void bfs_find_nearest(BVHNearestData *data, BVHNode *node) } current.node = node; - current.dist = calc_nearest_point(data->proj, node, nearest); + current.dist = calc_nearest_point(data, node, nearest); while(current.dist < data->nearest.dist) { @@ -1326,7 +1329,7 @@ static void bfs_find_nearest(BVHNearestData *data, BVHNode *node) } heap[heap_size].node = current.node->children[i]; - heap[heap_size].dist = calc_nearest_point(data->proj, current.node->children[i], nearest); + heap[heap_size].dist = calc_nearest_point(data, current.node->children[i], nearest); if(heap[heap_size].dist >= data->nearest.dist) continue; heap_size++; @@ -1336,7 +1339,7 @@ static void bfs_find_nearest(BVHNearestData *data, BVHNode *node) push_heaps++; } } - + if(heap_size == 0) break; current = heap[0]; @@ -1350,7 +1353,7 @@ static void bfs_find_nearest(BVHNearestData *data, BVHNode *node) if(heap != default_heap) free(heap); } - +#endif int BLI_bvhtree_find_nearest(BVHTree *tree, const float *co, BVHTreeNearest *nearest, BVHTree_NearestPointCallback callback, void *userdata) { @@ -1402,10 +1405,9 @@ int BLI_bvhtree_find_nearest(BVHTree *tree, const float *co, BVHTreeNearest *nea */ //Determines the distance that the ray must travel to hit the bounding volume of the given node -static float ray_nearest_hit(BVHRayCastData *data, BVHNode *node) +static float ray_nearest_hit(BVHRayCastData *data, float *bv) { int i; - const float *bv = node->bv; float low = 0, upper = data->hit.dist; @@ -1433,7 +1435,7 @@ static float ray_nearest_hit(BVHRayCastData *data, BVHNode *node) if(lu > low) low = lu; if(ll < upper) upper = ll; } - + if(low > upper) return FLT_MAX; } } @@ -1446,7 +1448,7 @@ static void dfs_raycast(BVHRayCastData *data, BVHNode *node) //ray-bv is really fast.. and simple tests revealed its worth to test it //before calling the ray-primitive functions - float dist = ray_nearest_hit(data, node); + float dist = ray_nearest_hit(data, node->bv); if(dist >= data->hit.dist) return; if(node->totnode == 0) @@ -1463,7 +1465,7 @@ static void dfs_raycast(BVHRayCastData *data, BVHNode *node) else { //pick loop direction to dive into the tree (based on ray direction and split axis) - if(data->ray_dot_axis[ node->main_axis ] > 0.0f) + if(data->ray_dot_axis[ (int)node->main_axis ] > 0.0f) { for(i=0; i != node->totnode; i++) { @@ -1524,6 +1526,38 @@ int BLI_bvhtree_ray_cast(BVHTree *tree, const float *co, const float *dir, float return data.hit.index; } +float BLI_bvhtree_bb_raycast(float *bv, float *light_start, float *light_end, float *pos) +{ + BVHRayCastData data; + float dist = 0.0; + int i; + + data.hit.dist = FLT_MAX; + + // get light direction + data.ray.direction[0] = light_end[0] - light_start[0]; + data.ray.direction[1] = light_end[1] - light_start[1]; + data.ray.direction[2] = light_end[2] - light_start[2]; + + data.ray.radius = 0.0; + + data.ray.origin[0] = light_start[0]; + data.ray.origin[1] = light_start[1]; + data.ray.origin[2] = light_start[2]; + + Normalize(data.ray.direction); + VECCOPY(data.ray_dot_axis, data.ray.direction); + + dist = ray_nearest_hit(&data, bv); + + if(dist > 0.0) + { + VECADDFAC(pos, light_start, data.ray.direction, dist); + } + return dist; + +} + /* * Range Query - as request by broken :P * diff --git a/source/blender/blenlib/intern/BLI_kdtree.c b/source/blender/blenlib/intern/BLI_kdtree.c index 94e958216f7..79a46da4c66 100644 --- a/source/blender/blenlib/intern/BLI_kdtree.c +++ b/source/blender/blenlib/intern/BLI_kdtree.c @@ -1,5 +1,5 @@ /** - * $Id: BLI_kdtree.c 19805 2009-04-20 00:19:16Z genscher $ + * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** * @@ -130,7 +130,7 @@ void BLI_kdtree_balance(KDTree *tree) tree->root= kdtree_balance(tree->nodes, tree->totnode, 0); } -static float squared_distance(float *v1, float *v2, float *n1, float *n2) +static float squared_distance(float *v2, float *v1, float *n1, float *n2) { float d[3], dist; @@ -140,7 +140,8 @@ static float squared_distance(float *v1, float *v2, float *n1, float *n2) dist= d[0]*d[0] + d[1]*d[1] + d[2]*d[2]; - if(n1 && n2 && n1[0]*n2[0] + n1[1]*n2[1] + n1[2]*n2[2] < 0.0f) + //if(n1 && n2 && n1[0]*n2[0] + n1[1]*n2[1] + n1[2]*n2[2] < 0.0f) + if(n2 && d[0]*n2[0] + d[1]*n2[1] + d[2]*n2[2] < 0.0f) dist *= 10.0f; return dist; @@ -336,3 +337,111 @@ 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) +{ + const KDTreeNearest *kda = a; + const KDTreeNearest *kdb = b; + + if(kda->dist < kdb->dist) + return -1; + else if(kda->dist > kdb->dist) + return 1; + else + return 0; +} +static void add_in_range(KDTreeNearest **ptn, int found, int *totfoundstack, int index, float dist, float *co) +{ + KDTreeNearest *to; + + if(found+1 > *totfoundstack) { + KDTreeNearest *temp=MEM_callocN((*totfoundstack+50)*sizeof(KDTreeNode), "psys_treefoundstack"); + memcpy(temp, *ptn, *totfoundstack * sizeof(KDTreeNearest)); + if(*ptn) + MEM_freeN(*ptn); + *ptn = temp; + *totfoundstack+=50; + } + + to = (*ptn) + found; + + to->index = index; + to->dist = sqrt(dist); + VecCopyf(to->co, co); +} +int BLI_kdtree_range_search(KDTree *tree, float range, float *co, float *nor, KDTreeNearest **nearest) +{ + KDTreeNode *root, *node=0; + KDTreeNode **stack, *defaultstack[100]; + KDTreeNearest *foundstack=NULL; + float range2 = range*range, dist2; + int i, totstack, cur=0, found=0, totfoundstack=0; + + if(!tree || !tree->root) + return 0; + + stack= defaultstack; + totstack= 100; + + root= tree->root; + + if(co[root->d] + range < root->co[root->d]) { + if(root->left) + stack[cur++]=root->left; + } + else if(co[root->d] - range > root->co[root->d]) { + if(root->right) + stack[cur++]=root->right; + } + else { + dist2 = squared_distance(root->co, co, root->nor, nor); + if(dist2 <= range2) + add_in_range(&foundstack, found++, &totfoundstack, root->index, dist2, root->co); + + if(root->left) + stack[cur++]=root->left; + if(root->right) + stack[cur++]=root->right; + } + + while(cur--) { + node=stack[cur]; + + if(co[node->d] + range < node->co[node->d]) { + if(node->left) + stack[cur++]=node->left; + } + else if(co[node->d] - range > node->co[node->d]) { + if(node->right) + stack[cur++]=node->right; + } + else { + dist2 = squared_distance(node->co, co, node->nor, nor); + if(dist2 <= range2) + add_in_range(&foundstack, found++, &totfoundstack, node->index, dist2, node->co); + + if(node->left) + stack[cur++]=node->left; + if(node->right) + stack[cur++]=node->right; + } + + if(cur+3 > totstack){ + KDTreeNode **temp=MEM_callocN((totstack+100)*sizeof(KDTreeNode*), "psys_treestack"); + memcpy(temp,stack,totstack*sizeof(KDTreeNode*)); + if(stack != defaultstack) + MEM_freeN(stack); + stack=temp; + totstack+=100; + } + } + + if(stack != defaultstack) + MEM_freeN(stack); + + if(found) + qsort(foundstack, found, sizeof(KDTreeNearest), range_compare); + + *nearest = foundstack; + + return found; +} diff --git a/source/blender/blenlib/intern/BLI_scanfill.h b/source/blender/blenlib/intern/BLI_scanfill.h deleted file mode 100644 index 43431dd5087..00000000000 --- a/source/blender/blenlib/intern/BLI_scanfill.h +++ /dev/null @@ -1,38 +0,0 @@ -/** - * blenlib/BLI_scanfill.h mar 2001 Nzc - * - * Filling meshes. - * - * $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: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ - -#ifndef BLI_SCANFILL_H -#define BLI_SCANFILL_H - -#endif - diff --git a/source/blender/blenlib/intern/BLI_util.h b/source/blender/blenlib/intern/BLI_util.h deleted file mode 100644 index c37a7fd803b..00000000000 --- a/source/blender/blenlib/intern/BLI_util.h +++ /dev/null @@ -1,42 +0,0 @@ -/** - * blenlib/BLI_storage_types.h - * - * Some types for dealing with directories - * - * $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: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - */ -#ifndef BLI_UTIL_H -#define BLI_UTIL_H - -#define mallocstructN(x,y,name) (x*)MEM_mallocN((y)* sizeof(x),name) -#define callocstructN(x,y,name) (x*)MEM_callocN((y)* sizeof(x),name) - -struct ListBase; - -#endif - diff --git a/source/blender/blenlib/intern/DLRB_tree.c b/source/blender/blenlib/intern/DLRB_tree.c new file mode 100644 index 00000000000..af9774c6afd --- /dev/null +++ b/source/blender/blenlib/intern/DLRB_tree.c @@ -0,0 +1,353 @@ +/** + * $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 Blender Foundation, Joshua Leung + * All rights reserved. + * + * Contributor(s): Joshua Leung (original author) + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_dlrbTree.h" + +#include "DNA_listBase.h" + +/* *********************************************** */ +/* Tree API */ + +/* Create a new tree, and initialise as necessary */ +DLRBT_Tree *BLI_dlrbTree_new (void) +{ + /* just allocate for now */ + return MEM_callocN(sizeof(DLRBT_Tree), "DLRBT_Tree"); +} + +/* Just zero out the pointers used */ +void BLI_dlrbTree_init (DLRBT_Tree *tree) +{ + if (tree == NULL) + return; + + tree->first= tree->last= tree->root= NULL; +} + +/* Helper for traversing tree and freeing sub-nodes */ +static void recursive_tree_free_nodes (DLRBT_Node *node) +{ + /* sanity check */ + if (node == NULL) + return; + + /* free child nodes + subtrees */ + recursive_tree_free_nodes(node->left); + recursive_tree_free_nodes(node->right); + + /* free self */ + MEM_freeN(node); +} + +/* Free the given tree's data but not the tree itself */ +void BLI_dlrbTree_free (DLRBT_Tree *tree) +{ + if (tree == NULL) + return; + + /* if the list-base stuff is set, just use that (and assume its set), + * otherwise, we'll need to traverse the tree... + */ + if (tree->first) { + /* free list */ + BLI_freelistN((ListBase *)tree); + } + else { + /* traverse tree, freeing sub-nodes */ + recursive_tree_free_nodes(tree->root); + } + + /* clear pointers */ + tree->first= tree->last= tree->root= NULL; +} + +/* ------- */ + +/* Helper function - used for traversing down the tree from the root to add nodes in order */ +static void linkedlist_sync_add_node (DLRBT_Tree *tree, DLRBT_Node *node) +{ + /* sanity checks */ + if ((tree == NULL) || (node == NULL)) + return; + + /* add left-node (and its subtree) */ + linkedlist_sync_add_node(tree, node->left); + + /* now add self + * - must remove detach from other links first + * (for now, only clear own pointers) + */ + node->prev= node->next= NULL; + BLI_addtail((ListBase *)tree, (Link *)node); + + /* finally, add right node (and its subtree) */ + linkedlist_sync_add_node(tree, node->right); +} + +/* Make sure the tree's Double-Linked list representation is valid */ +void BLI_dlrbTree_linkedlist_sync (DLRBT_Tree *tree) +{ + /* sanity checks */ + if (tree == NULL) + return; + + /* clear list-base pointers so that the new list can be added properly */ + tree->first= tree->last= NULL; + + /* start adding items from the root */ + linkedlist_sync_add_node(tree, tree->root); +} + +/* *********************************************** */ +/* Tree Relationships Utilities */ + +/* get the 'grandparent' - the parent of the parent - of the given node */ +static DLRBT_Node *get_grandparent (DLRBT_Node *node) +{ + if (node && node->parent) + return node->parent->parent; + else + return NULL; +} + +/* get the 'uncle' - the sibling of the parent - of the given node */ +static DLRBT_Node *get_uncle (DLRBT_Node *node) +{ + DLRBT_Node *gpn= get_grandparent(node); + + /* return the child of the grandparent which isn't the node's parent */ + if (gpn) { + if (gpn->left == node->parent) + return gpn->right; + else + return gpn->left; + } + + /* not found */ + return NULL; +} + +/* *********************************************** */ +/* Tree Rotation Utilities */ + +static void rotate_left (DLRBT_Tree *tree, DLRBT_Node *root) +{ + DLRBT_Node **root_slot, *pivot; + + /* pivot is simply the root's right child, to become the root's parent */ + pivot= root->right; + if (pivot == NULL) + return; + + if (root->parent) { + if (root == root->parent->left) + root_slot= &root->parent->left; + else + root_slot= &root->parent->right; + } + else + root_slot= ((DLRBT_Node**)&tree->root);//&((DLRBT_Node*)tree->root); + + /* - pivot's left child becomes root's right child + * - root now becomes pivot's left child + */ + root->right= pivot->left; + if (pivot->left) pivot->left->parent= root; + + pivot->left= root; + pivot->parent= root->parent; + root->parent= pivot; + + /* make the pivot the new root */ + if (root_slot) + *root_slot= pivot; +} + +static void rotate_right (DLRBT_Tree *tree, DLRBT_Node *root) +{ + DLRBT_Node **root_slot, *pivot; + + /* pivot is simply the root's left child, to become the root's parent */ + pivot= root->left; + if (pivot == NULL) + return; + + if (root->parent) { + if (root == root->parent->left) + root_slot= &root->parent->left; + else + root_slot= &root->parent->right; + } + else + root_slot= ((DLRBT_Node**)&tree->root);//&((DLRBT_Node*)tree->root); + + /* - pivot's right child becomes root's left child + * - root now becomes pivot's right child + */ + root->left= pivot->right; + if (pivot->right) pivot->right->parent= root; + + pivot->right= root; + pivot->parent= root->parent; + root->parent= pivot; + + /* make the pivot the new root */ + if (root_slot) + *root_slot= pivot; +} + +/* *********************************************** */ +/* Post-Insertion Balancing */ + +/* forward defines for insertion checks */ +static void insert_check_1(DLRBT_Tree *tree, DLRBT_Node *node); +static void insert_check_2(DLRBT_Tree *tree, DLRBT_Node *node); +static void insert_check_3(DLRBT_Tree *tree, DLRBT_Node *node); + +/* ----- */ + +/* W. 1) Root must be black (so that the 2nd-generation can have a black parent) */ +static void insert_check_1 (DLRBT_Tree *tree, DLRBT_Node *node) +{ + if (node) { + /* if this is the root, just ensure that it is black */ + if (node->parent == NULL) + node->tree_col= DLRBT_BLACK; + else + insert_check_2(tree, node); + } +} + +/* W. 2+3) Parent of node must be black, otherwise recolor and flush */ +static void insert_check_2 (DLRBT_Tree *tree, DLRBT_Node *node) +{ + /* if the parent is not black, we need to change that... */ + if (node && node->parent && node->parent->tree_col) { + DLRBT_Node *unc= get_uncle(node); + + /* if uncle and parent are both red, need to change them to black and make + * the parent black in order to satisfy the criteria of each node having the + * same number of black nodes to its leaves + */ + if (unc && unc->tree_col) { + DLRBT_Node *gp= get_grandparent(node); + + /* make the n-1 generation nodes black */ + node->parent->tree_col= unc->tree_col= DLRBT_BLACK; + + /* - make the grandparent red, so that we maintain alternating red/black property + * (it must exist, so no need to check for NULL here), + * - as the grandparent may now cause inconsistencies with the rest of the tree, + * we must flush up the tree and perform checks/rebalancing/repainting, using the + * grandparent as the node of interest + */ + gp->tree_col= DLRBT_RED; + insert_check_1(tree, gp); + } + else { + /* we've got an unbalanced branch going down the grandparent to the parent, + * so need to perform some rotations to re-balance the tree + */ + insert_check_3(tree, node); + } + } +} + +/* W. 4+5) Perform rotation on sub-tree containing the 'new' node, then do any */ +static void insert_check_3 (DLRBT_Tree *tree, DLRBT_Node *node) +{ + DLRBT_Node *gp= get_grandparent(node); + + /* check that grandparent and node->parent exist (jut in case... really shouldn't happen on a good tree) */ + if (node && node->parent && gp) { + /* a left rotation will switch the roles of node and its parent, assuming that + * the parent is the left child of the grandparent... otherwise, rotation direction + * should be swapped + */ + if ((node == node->parent->right) && (node->parent == gp->left)) { + rotate_left(tree, node); + node= node->left; + } + else if ((node == node->parent->left) && (node->parent == gp->right)) { + rotate_right(tree, node); + node= node->right; + } + + /* fix old parent's color-tagging, and perform rotation on the old parent in the + * opposite direction if needed for the current situation + * NOTE: in the code above, node pointer is changed to point to the old parent + */ + if (node) { + /* get 'new' grandparent (i.e. grandparent for old-parent (node)) */ + gp= get_grandparent(node); + + /* modify the coloring of the grandparent and parent so that they still satisfy the constraints */ + node->parent->tree_col= DLRBT_BLACK; + gp->tree_col= DLRBT_RED; + + /* if there are several nodes that all form a left chain, do a right rotation to correct this + * (or a rotation in the opposite direction if they all form a right chain) + */ + if ((node == node->parent->left) && (node->parent == gp->left)) + rotate_right(tree, gp); + else //if ((node == node->parent->right) && (node->parent == gp->right)) + rotate_left(tree, gp); + } + } +} + +/* ----- */ + +/* Balance the tree after the given element has been added to it + * (using custom code, in the Binary Tree way). + */ +void BLI_dlrbTree_insert(DLRBT_Tree *tree, DLRBT_Node *node) +{ + /* sanity checks */ + if ((tree == NULL) || (node == NULL)) + return; + + /* firstly, the node we just added should be red by default */ + node->tree_col= DLRBT_RED; + + /* start from case 1, an trek through the tail-recursive insertion checks */ + insert_check_1(tree, node); +} + +/* *********************************************** */ +/* Remove */ + +// TODO: this hasn't been coded yet, since this functionality was not needed by the author + +/* *********************************************** */ diff --git a/source/blender/blenlib/intern/Makefile b/source/blender/blenlib/intern/Makefile index 10e032ac654..f729a4e3fe0 100644 --- a/source/blender/blenlib/intern/Makefile +++ b/source/blender/blenlib/intern/Makefile @@ -33,7 +33,7 @@ DIR = $(OCGDIR)/blender/$(LIBNAME) include nan_compile.mk -# CPPFLAGS += $(LEVEL_2_CPP_WARNINGS) +CFLAGS += $(LEVEL_1_C_WARNINGS) # path to SDNA types CPPFLAGS += -I../../makesdna @@ -46,16 +46,13 @@ CPPFLAGS += -I$(NAN_FREETYPE)/include CPPFLAGS += -I$(NAN_FREETYPE)/include/freetype2 # path to blenkernel CPPFLAGS += -I$(SRCHOME)/blender/blenkernel -CPPFLAGS += -I../../include/ +CPPFLAGS += -I../../editors/include/ # path to zlib CPPFLAGS += -I$(NAN_ZLIB)/include ifdef NAN_PTHREADS CPPFLAGS += -I$(NAN_PTHREADS)/include endif -ifeq ($(WITH_FREETYPE2), true) - CPPFLAGS += -DWITH_FREETYPE2 -endif ifeq ($(OS),linux) CPPFLAGS += -I$(OCGDIR)/extern/binreloc/include -endif
\ No newline at end of file +endif diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c index 5c1a6f28d42..ebead4bce9b 100644 --- a/source/blender/blenlib/intern/arithb.c +++ b/source/blender/blenlib/intern/arithb.c @@ -34,6 +34,7 @@ /* ************************ FUNKTIES **************************** */ +#include <stdlib.h> #include <math.h> #include <sys/types.h> #include <string.h> @@ -62,13 +63,13 @@ #define SWAP(type, a, b) { type sw_ap; sw_ap=(a); (a)=(b); (b)=sw_ap; } #define CLAMP(a, b, c) if((a)<(b)) (a)=(b); else if((a)>(c)) (a)=(c) - -#if defined(WIN32) || defined(__APPLE__) -#include <stdlib.h> +#ifndef M_PI #define M_PI 3.14159265358979323846 -#define M_SQRT2 1.41421356237309504880 +#endif -#endif /* defined(WIN32) || defined(__APPLE__) */ +#ifndef M_SQRT2 +#define M_SQRT2 1.41421356237309504880 +#endif float saacos(float fac) @@ -91,21 +92,41 @@ float sasqrt(float fac) return (float)sqrt(fac); } +float saacosf(float fac) +{ + if(fac<= -1.0f) return (float)M_PI; + else if(fac>=1.0f) return 0.0f; + else return (float)acosf(fac); +} + +float saasinf(float fac) +{ + if(fac<= -1.0f) return (float)-M_PI/2.0f; + else if(fac>=1.0f) return (float)M_PI/2.0f; + else return (float)asinf(fac); +} + +float sasqrtf(float fac) +{ + if(fac<=0.0) return 0.0; + return (float)sqrtf(fac); +} + float Normalize(float *n) { float d; d= n[0]*n[0]+n[1]*n[1]+n[2]*n[2]; /* A larger value causes normalize errors in a scaled down models with camera xtreme close */ - if(d>1.0e-35F) { + if(d>1.0e-35f) { d= (float)sqrt(d); n[0]/=d; n[1]/=d; n[2]/=d; } else { - n[0]=n[1]=n[2]= 0.0; - d= 0.0; + n[0]=n[1]=n[2]= 0.0f; + d= 0.0f; } return d; } @@ -1087,6 +1108,10 @@ void printmatrix3( char *str, float m[][3]) /* **************** QUATERNIONS ********** */ +int QuatIsNul(float *q) +{ + return (q[0] == 0 && q[1] == 0 && q[2] == 0 && q[3] == 0); +} void QuatMul(float *q, float *q1, float *q2) { @@ -1594,16 +1619,16 @@ void QuatInterpolW(float *result, float *quat1, float *quat2, float t) cosom = quat1[0]*quat2[0] + quat1[1]*quat2[1] + quat1[2]*quat2[2] + quat1[3]*quat2[3] ; /* rotate around shortest angle */ - if ((1.0 + cosom) > 0.0001) { + if ((1.0f + cosom) > 0.0001f) { - if ((1.0 - cosom) > 0.0001) { - omega = acos(cosom); - sinom = sin(omega); - sc1 = sin((1.0 - t) * omega) / sinom; - sc2 = sin(t * omega) / sinom; + if ((1.0f - cosom) > 0.0001f) { + omega = (float)acos(cosom); + sinom = (float)sin(omega); + sc1 = (float)sin((1.0 - t) * omega) / sinom; + sc2 = (float)sin(t * omega) / sinom; } else { - sc1 = 1.0 - t; + sc1 = 1.0f - t; sc2 = t; } result[0] = sc1*quat1[0] + sc2*quat2[0]; @@ -1617,9 +1642,9 @@ void QuatInterpolW(float *result, float *quat1, float *quat2, float t) result[2] = quat2[1]; result[3] = -quat2[0]; - sc1 = sin((1.0 - t)*M_PI_2); - sc2 = sin(t*M_PI_2); - + sc1 = (float)sin((1.0 - t)*M_PI_2); + sc2 = (float)sin(t*M_PI_2); + result[0] = sc1*quat1[0] + sc2*result[0]; result[1] = sc1*quat1[1] + sc2*result[1]; result[2] = sc1*quat1[2] + sc2*result[2]; @@ -1634,7 +1659,7 @@ void QuatInterpol(float *result, float *quat1, float *quat2, float t) cosom = quat1[0]*quat2[0] + quat1[1]*quat2[1] + quat1[2]*quat2[2] + quat1[3]*quat2[3] ; /* rotate around shortest angle */ - if (cosom < 0.0) { + if (cosom < 0.0f) { cosom = -cosom; quat[0]= -quat1[0]; quat[1]= -quat1[1]; @@ -1648,13 +1673,13 @@ void QuatInterpol(float *result, float *quat1, float *quat2, float t) quat[3]= quat1[3]; } - if ((1.0 - cosom) > 0.0001) { - omega = acos(cosom); - sinom = sin(omega); - sc1 = sin((1 - t) * omega) / sinom; - sc2 = sin(t * omega) / sinom; + if ((1.0f - cosom) > 0.0001f) { + omega = (float)acos(cosom); + sinom = (float)sin(omega); + sc1 = (float)sin((1 - t) * omega) / sinom; + sc2 = (float)sin(t * omega) / sinom; } else { - sc1= 1.0 - t; + sc1= 1.0f - t; sc2= t; } @@ -1770,7 +1795,7 @@ void DQuatToMat4(DualQuat *dq, float mat[][4]) QuatCopy(q0, dq->quat); /* normalize */ - len= sqrt(QuatDot(q0, q0)); + len= (float)sqrt(QuatDot(q0, q0)); if(len != 0.0f) QuatMulf(q0, 1.0f/len); @@ -1779,9 +1804,9 @@ void DQuatToMat4(DualQuat *dq, float mat[][4]) /* translation */ t= dq->trans; - mat[3][0]= 2.0*(-t[0]*q0[1] + t[1]*q0[0] - t[2]*q0[3] + t[3]*q0[2]); - mat[3][1]= 2.0*(-t[0]*q0[2] + t[1]*q0[3] + t[2]*q0[0] - t[3]*q0[1]); - mat[3][2]= 2.0*(-t[0]*q0[3] - t[1]*q0[2] + t[2]*q0[1] + t[3]*q0[0]); + mat[3][0]= 2.0f*(-t[0]*q0[1] + t[1]*q0[0] - t[2]*q0[3] + t[3]*q0[2]); + mat[3][1]= 2.0f*(-t[0]*q0[2] + t[1]*q0[3] + t[2]*q0[0] - t[3]*q0[1]); + mat[3][2]= 2.0f*(-t[0]*q0[3] - t[1]*q0[2] + t[2]*q0[1] + t[3]*q0[0]); /* note: this does not handle scaling */ } @@ -1810,10 +1835,10 @@ void DQuatAddWeighted(DualQuat *dqsum, DualQuat *dq, float weight) /* interpolate scale - but only if needed */ if (dq->scale_weight) { float wmat[4][4]; - + if(flipped) /* we don't want negative weights for scaling */ weight= -weight; - + Mat4CpyMat4(wmat, dq->scale); Mat4MulFloat((float*)wmat, weight); Mat4AddMat4(dqsum->scale, dqsum->scale, wmat); @@ -1830,7 +1855,7 @@ void DQuatNormalize(DualQuat *dq, float totweight) if(dq->scale_weight) { float addweight= totweight - dq->scale_weight; - + if(addweight) { dq->scale[0][0] += addweight; dq->scale[1][1] += addweight; @@ -2199,25 +2224,23 @@ void VecNegf(float *v1) void VecOrthoBasisf(float *v, float *v1, float *v2) { - float f = sqrt(v[0]*v[0] + v[1]*v[1]); + const float f = (float)sqrt(v[0]*v[0] + v[1]*v[1]); if (f < 1e-35f) { // degenerate case - v1[0] = 0.0f; v1[1] = 1.0f; v1[2] = 0.0f; - if (v[2] > 0.0f) { - v2[0] = 1.0f; v2[1] = v2[2] = 0.0f; - } - else { - v2[0] = -1.0f; v2[1] = v2[2] = 0.0f; - } + v1[0] = (v[2] < 0.0f) ? -1.0f : 1.0f; + v1[1] = v1[2] = v2[0] = v2[2] = 0.0f; + v2[1] = 1.0f; } else { - f = 1.0f/f; - v1[0] = v[1]*f; - v1[1] = -v[0]*f; - v1[2] = 0.0f; + const float d= 1.0f/f; - Crossf(v2, v, v1); + v1[0] = v[1]*d; + v1[1] = -v[0]*d; + v1[2] = 0.0f; + v2[0] = -v[2]*v1[1]; + v2[1] = v[2]*v1[0]; + v2[2] = v[0]*v1[1] - v[1]*v1[0]; } } @@ -2351,9 +2374,9 @@ double Sqrt3d(double d) void NormalShortToFloat(float *out, short *in) { - out[0] = in[0] / 32767.0; - out[1] = in[1] / 32767.0; - out[2] = in[2] / 32767.0; + out[0] = in[0] / 32767.0f; + out[1] = in[1] / 32767.0f; + out[2] = in[2] / 32767.0f; } void NormalFloatToShort(short *out, float *in) @@ -2490,15 +2513,15 @@ short IsectLL2Ds(short *v1, short *v2, short *v3, short *v4) */ float div, labda, mu; - div= (v2[0]-v1[0])*(v4[1]-v3[1])-(v2[1]-v1[1])*(v4[0]-v3[0]); - if(div==0.0) return -1; + div= (float)((v2[0]-v1[0])*(v4[1]-v3[1])-(v2[1]-v1[1])*(v4[0]-v3[0])); + if(div==0.0f) return -1; labda= ((float)(v1[1]-v3[1])*(v4[0]-v3[0])-(v1[0]-v3[0])*(v4[1]-v3[1]))/div; mu= ((float)(v1[1]-v3[1])*(v2[0]-v1[0])-(v1[0]-v3[0])*(v2[1]-v1[1]))/div; - if(labda>=0.0 && labda<=1.0 && mu>=0.0 && mu<=1.0) { - if(labda==0.0 || labda==1.0 || mu==0.0 || mu==1.0) return 1; + if(labda>=0.0f && labda<=1.0f && mu>=0.0f && mu<=1.0f) { + if(labda==0.0f || labda==1.0f || mu==0.0f || mu==1.0f) return 1; return 2; } return 0; @@ -2657,9 +2680,9 @@ static int BarycentricWeights(float *v1, float *v2, float *v3, float *co, float /* find best projection of face XY, XZ or YZ: barycentric weights of the 2d projected coords are the same and faster to compute */ - xn= fabs(n[0]); - yn= fabs(n[1]); - zn= fabs(n[2]); + xn= (float)fabs(n[0]); + yn= (float)fabs(n[1]); + zn= (float)fabs(n[2]); if(zn>=xn && zn>=yn) {i= 0; j= 1;} else if(yn>=xn && yn>=zn) {i= 0; j= 2;} else {i= 1; j= 2;} @@ -2891,12 +2914,12 @@ void Mat4ToEul(float tmat[][4], float *eul) { float tempMat[3][3]; - Mat3CpyMat4 (tempMat, tmat); + Mat3CpyMat4(tempMat, tmat); Mat3Ortho(tempMat); Mat3ToEul(tempMat, eul); } -void QuatToEul( float *quat, float *eul) +void QuatToEul(float *quat, float *eul) { float mat[3][3]; @@ -2905,7 +2928,7 @@ void QuatToEul( float *quat, float *eul) } -void EulToQuat( float *eul, float *quat) +void EulToQuat(float *eul, float *quat) { float ti, tj, th, ci, cj, ch, si, sj, sh, cc, cs, sc, ss; @@ -2920,7 +2943,7 @@ void EulToQuat( float *eul, float *quat) quat[3] = cj*cs - sj*sc; } -void VecRotToMat3( float *vec, float phi, float mat[][3]) +void VecRotToMat3(float *vec, float phi, float mat[][3]) { /* rotation of phi radials around vec */ float vx, vx2, vy, vy2, vz, vz2, co, si; @@ -2946,7 +2969,7 @@ void VecRotToMat3( float *vec, float phi, float mat[][3]) } -void VecRotToMat4( float *vec, float phi, float mat[][4]) +void VecRotToMat4(float *vec, float phi, float mat[][4]) { float tmat[3][3]; @@ -2955,7 +2978,7 @@ void VecRotToMat4( float *vec, float phi, float mat[][4]) Mat4CpyMat3(mat, tmat); } -void VecRotToQuat( float *vec, float phi, float *quat) +void VecRotToQuat(float *vec, float phi, float *quat) { /* rotation of phi radials around vec */ float si; @@ -2964,7 +2987,7 @@ void VecRotToQuat( float *vec, float phi, float *quat) quat[2]= vec[1]; quat[3]= vec[2]; - if( Normalize(quat+1) == 0.0) { + if( Normalize(quat+1) == 0.0f) { QuatOne(quat); } else { @@ -2988,7 +3011,7 @@ float VecAngle3(float *v1, float *v2, float *v3) Normalize(vec1); Normalize(vec2); - return NormalizedVecAngle2(vec1, vec2) * 180.0/M_PI; + return NormalizedVecAngle2(vec1, vec2) * (float)(180.0/M_PI); } float VecAngle3_2D(float *v1, float *v2, float *v3) @@ -3004,7 +3027,7 @@ float VecAngle3_2D(float *v1, float *v2, float *v3) Normalize2(vec1); Normalize2(vec2); - return NormalizedVecAngle2_2D(vec1, vec2) * 180.0/M_PI; + return NormalizedVecAngle2_2D(vec1, vec2) * (float)(180.0/M_PI); } /* Return the shortest angle in degrees between the 2 vectors */ @@ -3017,7 +3040,7 @@ float VecAngle2(float *v1, float *v2) Normalize(vec1); Normalize(vec2); - return NormalizedVecAngle2(vec1, vec2)* 180.0/M_PI; + return NormalizedVecAngle2(vec1, vec2)* (float)(180.0/M_PI); } float NormalizedVecAngle2(float *v1, float *v2) @@ -3029,11 +3052,11 @@ float NormalizedVecAngle2(float *v1, float *v2) vec[0]= -v2[0]; vec[1]= -v2[1]; vec[2]= -v2[2]; - - return (float)M_PI - 2.0f*saasin(VecLenf(vec, v1)/2.0f); + + return (float)M_PI - 2.0f*(float)saasin(VecLenf(vec, v1)/2.0f); } else - return 2.0f*saasin(VecLenf(v2, v1)/2.0); + return 2.0f*(float)saasin(VecLenf(v2, v1)/2.0f); } float NormalizedVecAngle2_2D(float *v1, float *v2) @@ -3044,18 +3067,18 @@ float NormalizedVecAngle2_2D(float *v1, float *v2) vec[0]= -v2[0]; vec[1]= -v2[1]; - + return (float)M_PI - 2.0f*saasin(Vec2Lenf(vec, v1)/2.0f); } else - return 2.0f*saasin(Vec2Lenf(v2, v1)/2.0); + return 2.0f*(float)saasin(Vec2Lenf(v2, v1)/2.0f); } void euler_rot(float *beul, float ang, char axis) { float eul[3], mat1[3][3], mat2[3][3], totmat[3][3]; - eul[0]= eul[1]= eul[2]= 0.0; + eul[0]= eul[1]= eul[2]= 0.0f; if(axis=='x') eul[0]= ang; else if(axis=='y') eul[1]= ang; else eul[2]= ang; @@ -3075,33 +3098,32 @@ void compatible_eul(float *eul, float *oldrot) float dx, dy, dz; /* correct differences of about 360 degrees first */ - dx= eul[0] - oldrot[0]; dy= eul[1] - oldrot[1]; dz= eul[2] - oldrot[2]; - while( fabs(dx) > 5.1) { - if(dx > 0.0) eul[0] -= 2.0*M_PI; else eul[0]+= 2.0*M_PI; + while(fabs(dx) > 5.1) { + if(dx > 0.0f) eul[0] -= 2.0f*(float)M_PI; else eul[0]+= 2.0f*(float)M_PI; dx= eul[0] - oldrot[0]; } - while( fabs(dy) > 5.1) { - if(dy > 0.0) eul[1] -= 2.0*M_PI; else eul[1]+= 2.0*M_PI; + while(fabs(dy) > 5.1) { + if(dy > 0.0f) eul[1] -= 2.0f*(float)M_PI; else eul[1]+= 2.0f*(float)M_PI; dy= eul[1] - oldrot[1]; } - while( fabs(dz) > 5.1 ) { - if(dz > 0.0) eul[2] -= 2.0*M_PI; else eul[2]+= 2.0*M_PI; + while(fabs(dz) > 5.1) { + if(dz > 0.0f) eul[2] -= 2.0f*(float)M_PI; else eul[2]+= 2.0f*(float)M_PI; dz= eul[2] - oldrot[2]; } /* is 1 of the axis rotations larger than 180 degrees and the other small? NO ELSE IF!! */ if( fabs(dx) > 3.2 && fabs(dy)<1.6 && fabs(dz)<1.6 ) { - if(dx > 0.0) eul[0] -= 2.0*M_PI; else eul[0]+= 2.0*M_PI; + if(dx > 0.0) eul[0] -= 2.0f*(float)M_PI; else eul[0]+= 2.0f*(float)M_PI; } if( fabs(dy) > 3.2 && fabs(dz)<1.6 && fabs(dx)<1.6 ) { - if(dy > 0.0) eul[1] -= 2.0*M_PI; else eul[1]+= 2.0*M_PI; + if(dy > 0.0) eul[1] -= 2.0f*(float)M_PI; else eul[1]+= 2.0f*(float)M_PI; } if( fabs(dz) > 3.2 && fabs(dx)<1.6 && fabs(dy)<1.6 ) { - if(dz > 0.0) eul[2] -= 2.0*M_PI; else eul[2]+= 2.0*M_PI; + if(dz > 0.0) eul[2] -= 2.0f*(float)M_PI; else eul[2]+= 2.0f*(float)M_PI; } /* the method below was there from ancient days... but why! probably because the code sucks :) @@ -3144,8 +3166,8 @@ void Mat3ToCompatibleEul(float mat[][3], float *eul, float *oldrot) compatible_eul(eul1, oldrot); compatible_eul(eul2, oldrot); - d1= fabs(eul1[0]-oldrot[0]) + fabs(eul1[1]-oldrot[1]) + fabs(eul1[2]-oldrot[2]); - d2= fabs(eul2[0]-oldrot[0]) + fabs(eul2[1]-oldrot[1]) + fabs(eul2[2]-oldrot[2]); + d1= (float)fabs(eul1[0]-oldrot[0]) + (float)fabs(eul1[1]-oldrot[1]) + (float)fabs(eul1[2]-oldrot[2]); + d2= (float)fabs(eul2[0]-oldrot[0]) + (float)fabs(eul2[1]-oldrot[1]) + (float)fabs(eul2[2]-oldrot[2]); /* return best, which is just the one with lowest difference */ if( d1 > d2) { @@ -3162,14 +3184,14 @@ void Mat3ToCompatibleEul(float mat[][3], float *eul, float *oldrot) void SizeToMat3( float *size, float mat[][3]) { mat[0][0]= size[0]; - mat[0][1]= 0.0; - mat[0][2]= 0.0; + mat[0][1]= 0.0f; + mat[0][2]= 0.0f; mat[1][1]= size[1]; - mat[1][0]= 0.0; - mat[1][2]= 0.0; + mat[1][0]= 0.0f; + mat[1][2]= 0.0f; mat[2][2]= size[2]; - mat[2][1]= 0.0; - mat[2][0]= 0.0; + mat[2][1]= 0.0f; + mat[2][0]= 0.0f; } void SizeToMat4( float *size, float mat[][4]) @@ -3201,7 +3223,7 @@ void Mat4ToSize( float mat[][4], float *size) float Mat3ToScalef(float mat[][3]) { /* unit length vector */ - float unit_vec[3] = {0.577350269189626, 0.577350269189626, 0.577350269189626}; + float unit_vec[3] = {0.577350269189626f, 0.577350269189626f, 0.577350269189626f}; Mat3MulVecfl(mat, unit_vec); return VecLength(unit_vec); } @@ -3226,12 +3248,12 @@ void triatoquat( float *v1, float *v2, float *v3, float *quat) n[0]= vec[1]; n[1]= -vec[0]; - n[2]= 0.0; + n[2]= 0.0f; Normalize(n); - if(n[0]==0.0 && n[1]==0.0) n[0]= 1.0; + if(n[0]==0.0f && n[1]==0.0f) n[0]= 1.0f; - angle= -0.5f*saacos(vec[2]); + angle= -0.5f*(float)saacos(vec[2]); co= (float)cos(angle); si= (float)sin(angle); q1[0]= co; @@ -3246,7 +3268,7 @@ void triatoquat( float *v1, float *v2, float *v3, float *quat) Mat3MulVecfl(imat, vec); /* what angle has this line with x-axis? */ - vec[2]= 0.0; + vec[2]= 0.0f; Normalize(vec); angle= (float)(0.5*atan2(vec[1], vec[0])); @@ -3319,24 +3341,17 @@ float Normalize2(float *n) d= n[0]*n[0]+n[1]*n[1]; - if(d>1.0e-35F) { + if(d>1.0e-35f) { d= (float)sqrt(d); - n[0]/=d; n[1]/=d; } else { - n[0]=n[1]= 0.0; - d= 0.0; + n[0]=n[1]= 0.0f; + d= 0.0f; } return d; } -float rgb_to_luminance(float r, float g, float b) -{ - /* Rec. 709 HDTV */ - return (0.2126*r + 0.7152*g + 0.0722*b); -} - void hsv_to_rgb(float h, float s, float v, float *r, float *g, float *b) { int i; @@ -3344,15 +3359,15 @@ void hsv_to_rgb(float h, float s, float v, float *r, float *g, float *b) h *= 360.0f; - if(s==0.0) { + if(s==0.0f) { *r = v; *g = v; *b = v; } else { - if(h==360) h = 0; + if(h== 360.0f) h = 0.0f; - h /= 60; + h /= 60.0f; i = (int)floor(h); f = h - i; p = v*(1.0f-s); @@ -3397,9 +3412,9 @@ void hsv_to_rgb(float h, float s, float v, float *r, float *g, float *b) void rgb_to_yuv(float r, float g, float b, float *ly, float *lu, float *lv) { float y, u, v; - y= 0.299*r + 0.587*g + 0.114*b; - u=-0.147*r - 0.289*g + 0.436*b; - v= 0.615*r - 0.515*g - 0.100*b; + y= 0.299f*r + 0.587f*g + 0.114f*b; + u=-0.147f*r - 0.289f*g + 0.436f*b; + v= 0.615f*r - 0.515f*g - 0.100f*b; *ly=y; *lu=u; @@ -3409,9 +3424,9 @@ void rgb_to_yuv(float r, float g, float b, float *ly, float *lu, float *lv) void yuv_to_rgb(float y, float u, float v, float *lr, float *lg, float *lb) { float r, g, b; - r=y+1.140*v; - g=y-0.394*u - 0.581*v; - b=y+2.032*u; + r=y+1.140f*v; + g=y-0.394f*u - 0.581f*v; + b=y+2.032f*u; *lr=r; *lg=g; @@ -3423,14 +3438,14 @@ void rgb_to_ycc(float r, float g, float b, float *ly, float *lcb, float *lcr) float sr,sg, sb; float y, cr, cb; - sr=255.0*r; - sg=255.0*g; - sb=255.0*b; + sr=255.0f*r; + sg=255.0f*g; + sb=255.0f*b; - y=(0.257*sr)+(0.504*sg)+(0.098*sb)+16.0; - cb=(-0.148*sr)-(0.291*sg)+(0.439*sb)+128.0; - cr=(0.439*sr)-(0.368*sg)-(0.071*sb)+128.0; + 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; *ly=y; *lcb=cb; @@ -3441,13 +3456,13 @@ void ycc_to_rgb(float y, float cb, float cr, float *lr, float *lg, float *lb) { float r,g,b; - r=1.164*(y-16)+1.596*(cr-128); - g=1.164*(y-16)-0.813*(cr-128)-0.392*(cb-128); - b=1.164*(y-16)+2.017*(cb-128); + 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); - *lr=r/255.0; - *lg=g/255.0; - *lb=b/255.0; + *lr=r/255.0f; + *lg=g/255.0f; + *lb=b/255.0f; } void hex_to_rgb(char *hexcol, float *r, float *g, float *b) @@ -3457,9 +3472,9 @@ void hex_to_rgb(char *hexcol, float *r, float *g, float *b) if (hexcol[0] == '#') hexcol++; if (sscanf(hexcol, "%02x%02x%02x", &ri, &gi, &bi)) { - *r = ri / 255.0; - *g = gi / 255.0; - *b = bi / 255.0; + *r = ri / 255.0f; + *g = gi / 255.0f; + *b = bi / 255.0f; } } @@ -3477,14 +3492,14 @@ void rgb_to_hsv(float r, float g, float b, float *lh, float *ls, float *lv) cmin = (b<cmin ? b:cmin); v = cmax; /* value */ - if (cmax!=0.0) + if (cmax != 0.0f) s = (cmax - cmin)/cmax; else { - s = 0.0; - h = 0.0; + s = 0.0f; + h = 0.0f; } - if (s == 0.0) - h = -1.0; + if (s == 0.0f) + h = -1.0f; else { cdelta = cmax-cmin; rc = (cmax-r)/cdelta; @@ -3498,13 +3513,13 @@ void rgb_to_hsv(float r, float g, float b, float *lh, float *ls, float *lv) else h = 4.0f+gc-rc; h = h*60.0f; - if (h<0.0f) + if (h < 0.0f) h += 360.0f; } *ls = s; - *lh = h/360.0f; - if( *lh < 0.0) *lh= 0.0; + *lh = h / 360.0f; + if(*lh < 0.0f) *lh= 0.0f; *lv = v; } @@ -3514,14 +3529,14 @@ void xyz_to_rgb(float xc, float yc, float zc, float *r, float *g, float *b, int { switch (colorspace) { case BLI_CS_SMPTE: - *r = (3.50570 * xc) + (-1.73964 * yc) + (-0.544011 * zc); - *g = (-1.06906 * xc) + (1.97781 * yc) + (0.0351720 * zc); - *b = (0.0563117 * xc) + (-0.196994 * yc) + (1.05005 * zc); + *r = (3.50570f * xc) + (-1.73964f * yc) + (-0.544011f * zc); + *g = (-1.06906f * xc) + (1.97781f * yc) + (0.0351720f * zc); + *b = (0.0563117f * xc) + (-0.196994f * yc) + (1.05005f * zc); break; case BLI_CS_REC709: - *r = (3.240476 * xc) + (-1.537150 * yc) + (-0.498535 * zc); - *g = (-0.969256 * xc) + (1.875992 * yc) + (0.041556 * zc); - *b = (0.055648 * xc) + (-0.204043 * yc) + (1.057311 * zc); + *r = (3.240476f * xc) + (-1.537150f * yc) + (-0.498535f * zc); + *g = (-0.969256f * xc) + (1.875992f * yc) + (0.041556f * zc); + *b = (0.055648f * xc) + (-0.204043f * yc) + (1.057311f * zc); break; case BLI_CS_CIE: *r = (2.28783848734076f * xc) + (-0.833367677835217f * yc) + (-0.454470795871421f * zc); @@ -3552,34 +3567,10 @@ int constrain_rgb(float *r, float *g, float *b) if (w > 0) { *r += w; *g += w; *b += w; - return 1; /* Colour modified to fit RGB gamut */ + return 1; /* Color modified to fit RGB gamut */ } - return 0; /* Colour within RGB gamut */ -} - -/*Transform linear RGB values to nonlinear RGB values. Rec. - 709 is ITU-R Recommendation BT. 709 (1990) ``Basic - Parameter Values for the HDTV Standard for the Studio and - for International Programme Exchange'', formerly CCIR Rec. - 709.*/ -static void gamma_correct(float *c) -{ - /* Rec. 709 gamma correction. */ - float cc = 0.018; - - if (*c < cc) { - *c *= ((1.099 * pow(cc, 0.45)) - 0.099) / cc; - } else { - *c = (1.099 * pow(*c, 0.45)) - 0.099; - } -} - -void gamma_correct_rgb(float *r, float *g, float *b) -{ - gamma_correct(r); - gamma_correct(g); - gamma_correct(b); + return 0; /* Color within RGB gamut */ } @@ -3638,14 +3629,13 @@ void tubemap(float x, float y, float z, float *u, float *v) { float len; - *v = (z + 1.0) / 2.0; + *v = (z + 1.0f) / 2.0f; - len= sqrt(x*x+y*y); - if(len>0) { - *u = (1.0 - (atan2(x/len,y/len) / M_PI)) / 2.0; - } else { + len= (float)sqrt(x*x+y*y); + if(len > 0.0f) + *u = (float)((1.0 - (atan2(x/len,y/len) / M_PI)) / 2.0); + else *v = *u = 0.0f; /* to avoid un-initialized variables */ - } } /* ------------------------------------------------------------------------- */ @@ -3654,14 +3644,13 @@ void spheremap(float x, float y, float z, float *u, float *v) { float len; - len= sqrt(x*x+y*y+z*z); - if(len>0.0) { - - if(x==0.0 && y==0.0) *u= 0.0; /* othwise domain error */ - else *u = (1.0 - atan2(x,y)/M_PI )/2.0; + len= (float)sqrt(x*x+y*y+z*z); + if(len > 0.0f) { + if(x==0.0f && y==0.0f) *u= 0.0f; /* othwise domain error */ + else *u = (float)((1.0 - (float)atan2(x,y) / M_PI) / 2.0); z/=len; - *v = 1.0- saacos(z)/M_PI; + *v = 1.0f - (float)saacos(z)/(float)M_PI; } else { *v = *u = 0.0f; /* to avoid un-initialized variables */ } @@ -3972,7 +3961,7 @@ static int getLowestRoot(float a, float b, float c, float maxR, float* root) { // calculate the two roots: (if determinant == 0 then // x1==x2 but let’s disregard that slight optimization) - float sqrtD = sqrt(determinant); + float sqrtD = (float)sqrt(determinant); float r1 = (-b - sqrtD) / (2.0f*a); float r2 = (-b + sqrtD) / (2.0f*a); @@ -4391,6 +4380,7 @@ float lambda_cp_line_ex(float p[3], float l1[3], float l2[3], float cp[3]) return lambda; } +#if 0 /* little sister we only need to know lambda */ static float lambda_cp_line(float p[3], float l1[3], float l2[3]) { @@ -4399,6 +4389,7 @@ static float lambda_cp_line(float p[3], float l1[3], float l2[3]) VecSubf(h, p, l1); return(Inpf(u,h)/Inpf(u,u)); } +#endif /* 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) @@ -4526,6 +4517,79 @@ void PointInFace2DUV(int isquad, float v0[2], float v1[2], float v2[2], float v3 } } +int IsPointInTri2D(float v1[2], float v2[2], float v3[2], float pt[2]) +{ + float inp1, inp2, inp3; + + inp1= (v2[0]-v1[0])*(v1[1]-pt[1]) + (v1[1]-v2[1])*(v1[0]-pt[0]); + inp2= (v3[0]-v2[0])*(v2[1]-pt[1]) + (v2[1]-v3[1])*(v2[0]-pt[0]); + inp3= (v1[0]-v3[0])*(v3[1]-pt[1]) + (v3[1]-v1[1])*(v3[0]-pt[0]); + + if(inp1<=0.0f && inp2<=0.0f && inp3<=0.0f) return 1; + if(inp1>=0.0f && inp2>=0.0f && inp3>=0.0f) return 1; + + return 0; +} + +#if 0 +int IsPointInTri2D(float v0[2], float v1[2], float v2[2], float pt[2]) +{ + /* not for quads, use for our abuse of LineIntersectsTriangleUV */ + float p1_3d[3], p2_3d[3], v0_3d[3], v1_3d[3], v2_3d[3]; + /* not used */ + float lambda, uv[3]; + + p1_3d[0] = p2_3d[0] = uv[0]= pt[0]; + p1_3d[1] = p2_3d[1] = uv[1]= uv[2]= pt[1]; + p1_3d[2] = 1.0f; + p2_3d[2] = -1.0f; + v0_3d[2] = v1_3d[2] = v2_3d[2] = 0.0; + + /* generate a new fuv, (this is possibly a non optimal solution, + * since we only need 2d calculation but use 3d func's) + * + * this method makes an imaginary triangle in 2d space using the UV's from the derived mesh face + * Then find new uv coords using the fuv and this face with LineIntersectsTriangleUV. + * This means the new values will be correct in relation to the derived meshes face. + */ + Vec2Copyf(v0_3d, v0); + Vec2Copyf(v1_3d, v1); + Vec2Copyf(v2_3d, v2); + + /* Doing this in 3D is not nice */ + return LineIntersectsTriangle(p1_3d, p2_3d, v0_3d, v1_3d, v2_3d, &lambda, uv); +} +#endif + +/* + + x1,y2 + | \ + | \ .(a,b) + | \ + x1,y1-- x2,y1 + +*/ +int IsPointInTri2DInts(int x1, int y1, int x2, int y2, int a, int b) +{ + float v1[2], v2[2], v3[2], p[2]; + + v1[0]= (float)x1; + v1[1]= (float)y1; + + v2[0]= (float)x1; + v2[1]= (float)y2; + + v3[0]= (float)x2; + v3[1]= (float)y1; + + p[0]= (float)a; + p[1]= (float)b; + + return IsPointInTri2D(v1, v2, v3, p); + +} + /* (x1,v1)(t1=0)------(x2,v2)(t2=1), 0<t<1 --> (x,v)(t) */ void VecfCubicInterpol(float *x1, float *v1, float *x2, float *v2, float t, float *x, float *v) { @@ -4576,6 +4640,7 @@ but see a 'spat' which is a deformed cube with paired parallel planes needs only return 1; } +#if 0 /*adult sister defining the slice planes by the origin and the normal NOTE |normal| may not be 1 but defining the thickness of the slice*/ static int point_in_slice_as(float p[3],float origin[3],float normal[3]) @@ -4596,6 +4661,7 @@ static int point_in_slice_m(float p[3],float origin[3],float normal[3],float lns if (h < 0.0f || h > 1.0f) return 0; return 1; } +#endif int point_in_tri_prism(float p[3], float v1[3], float v2[3], float v3[3]) @@ -4753,5 +4819,5 @@ void tangent_from_uv(float *uv1, float *uv2, float *uv3, float *co1, float *co2, /* used for zoom values*/ float power_of_2(float val) { - return pow(2, ceil(log(val) / log(2))); + return (float)pow(2, ceil(log(val) / log(2))); } diff --git a/source/blender/blenlib/intern/bpath.c b/source/blender/blenlib/intern/bpath.c index ac0c4bf4efd..6c89afe7173 100644 --- a/source/blender/blenlib/intern/bpath.c +++ b/source/blender/blenlib/intern/bpath.c @@ -26,32 +26,32 @@ * ***** END GPL LICENSE BLOCK ***** */ -#include "BLI_bpath.h" -#include "BKE_global.h" -#include "BIF_screen.h" /* only for wait cursor */ +#include "MEM_guardedalloc.h" + #include "DNA_ID.h" /* Library */ #include "DNA_vfont_types.h" #include "DNA_image_types.h" #include "DNA_sound_types.h" #include "DNA_scene_types.h" /* to get the current frame */ #include "DNA_sequence_types.h" -#include <stdlib.h> -#include <string.h> +#include "DNA_text_types.h" -#include "BKE_main.h" /* so we can access G.main->*.first */ -#include "BKE_image.h" /* so we can check the image's type */ +#include "BLI_blenlib.h" +#include "BLI_bpath.h" -#include "blendef.h" +#include "BKE_global.h" +#include "BKE_image.h" /* so we can check the image's type */ +#include "BKE_main.h" /* so we can access G.main->*.first */ +#include "BKE_sequence.h" +#include "BKE_text.h" /* for writing to a textblock */ #include "BKE_utildefines.h" -#include "MEM_guardedalloc.h" +//XXX #include "BIF_screen.h" /* only for wait cursor */ +// /* for sequence */ -#include "BSE_sequence.h" - -/* for writing to a textblock */ -#include "BKE_text.h" -#include "BLI_blenlib.h" -#include "DNA_text_types.h" +//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) /* path/file handeling stuff */ #ifndef WIN32 @@ -69,7 +69,7 @@ #include <stdio.h> #include <string.h> #include <stdlib.h> - +#include <string.h> #define FILE_MAX 240 @@ -201,7 +201,9 @@ static struct bSound *snd_stepdata__internal(struct bSound *snd, int step_next) return snd; } -static struct Sequence *seq_stepdata__internal(struct BPathIterator *bpi, int step_next) { +static struct Sequence *seq_stepdata__internal(struct BPathIterator *bpi, int step_next) +{ + Editing *ed; Sequence *seq; /* Initializing */ @@ -214,11 +216,11 @@ static struct Sequence *seq_stepdata__internal(struct BPathIterator *bpi, int st } while (bpi->seqdata.scene) { - - if (bpi->seqdata.scene->ed) { + ed= seq_give_editing(bpi->seqdata.scene, 0); + if (ed) { if (bpi->seqdata.seqar == NULL) { /* allocate the sequencer array */ - build_seqar( &(((Editing *)bpi->seqdata.scene->ed)->seqbase), &bpi->seqdata.seqar, &bpi->seqdata.totseq); + seq_array(ed, &bpi->seqdata.seqar, &bpi->seqdata.totseq, 0); bpi->seqdata.seq = 0; } @@ -657,7 +659,7 @@ void findMissingFiles(char *str) { char dirname[FILE_MAX], filename[FILE_MAX], filename_new[FILE_MAX]; - waitcursor( 1 ); + //XXX waitcursor( 1 ); BLI_split_dirfile_basic(str, dirname, NULL); @@ -668,9 +670,9 @@ void findMissingFiles(char *str) { libpath = BLI_bpathIterator_getLib(&bpi); /* Check if esc was pressed because searching files can be slow */ - if (blender_test_break()) { + /*XXX if (blender_test_break()) { break; - } + }*/ if (libpath==NULL) { @@ -706,5 +708,5 @@ void findMissingFiles(char *str) { } BLI_bpathIterator_free(&bpi); - waitcursor( 0 ); + //XXX waitcursor( 0 ); } diff --git a/source/blender/blenlib/intern/dynamiclist.c b/source/blender/blenlib/intern/dynamiclist.c new file mode 100644 index 00000000000..4fe654cffb6 --- /dev/null +++ b/source/blender/blenlib/intern/dynamiclist.c @@ -0,0 +1,265 @@ +/* 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., 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: 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/dynamiclist.h b/source/blender/blenlib/intern/dynamiclist.h new file mode 100644 index 00000000000..e8c93fbcf23 --- /dev/null +++ b/source/blender/blenlib/intern/dynamiclist.h @@ -0,0 +1,55 @@ +/** + * $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. + * + * Contributor(s): Jiri Hnidek. + * + * Documentation of Two way dynamic list with access array can be found at: + * + * http://wiki.blender.org/bin/view.pl/Blenderwiki/DynamicListWithAccessArray + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef B_DYNAMIC_LIST_H +#define B_DYNAMIC_LIST_H + +#define PAGE_SIZE 4 + +struct ListBase; + +/* + * Access array using realloc + */ +typedef struct DynamicArray{ + unsigned int count; /* count of items in list */ + unsigned int max_item_index; /* max available index */ + unsigned int last_item_index; /* max used index */ + void **items; /* dynamicaly allocated array of pointers + pointing at items in list */ +} DynamicArray; + +/* + * Two way dynamic list with access array + */ +typedef struct DynamicList { + struct DynamicArray da; /* access array */ + struct ListBase lb; /* two way linked dynamic list */ +} DynamicList; + +#endif diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c index ebd8f4be1cf..0228032df01 100644 --- a/source/blender/blenlib/intern/fileops.c +++ b/source/blender/blenlib/intern/fileops.c @@ -1,10 +1,4 @@ /* - * blenlib/fileops.h - * - * cleaned up (a bit) mar-01 nzc - * - * More low-level file things. - * * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -37,16 +31,13 @@ #include <stdio.h> #include <stdlib.h> -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - #include "zlib.h" #ifdef WIN32 #include "BLI_winstuff.h" #include <io.h> #else +#include <unistd.h> // for read close #include <sys/param.h> #endif @@ -92,19 +83,22 @@ char *BLI_last_slash(const char *string) { } /* adds a slash if there isnt one there alredy */ -void BLI_add_slash(char *string) { +int BLI_add_slash(char *string) { int len = strlen(string); #ifdef WIN32 if (len==0 || string[len-1]!='\\') { string[len] = '\\'; string[len+1] = '\0'; + return len+1; } #else if (len==0 || string[len-1]!='/') { string[len] = '/'; string[len+1] = '\0'; + return len+1; } #endif + return len; } /* removes a slash if there is one */ @@ -162,10 +156,24 @@ int BLI_is_writable(char *filename) { int file; - file = open(filename, O_BINARY | O_RDWR | O_CREAT | O_TRUNC, 0666); + /* first try to open without creating */ + file = open(filename, O_BINARY | O_RDWR, 0666); - if (file < 0) - return 0; + if (file < 0) { + /* now try to open and create. a test without actually + * creating a file would be nice, but how? */ + file = open(filename, O_BINARY | O_RDWR | O_CREAT, 0666); + + if(file < 0) { + return 0; + } + else { + /* success, delete the file we create */ + close(file); + BLI_delete(filename, 0, 0); + return 1; + } + } else { close(file); return 1; @@ -306,7 +314,7 @@ int BLI_rename(char *from, char *to) { /* make sure the filenames are different (case insensitive) before removing */ if (BLI_exists(to) && BLI_strcasecmp(from, to)) if(BLI_delete(to, 0, 0)) return 1; - + return rename(from, to); } @@ -384,7 +392,7 @@ int BLI_rename(char *from, char *to) { if (!BLI_exists(from)) return 0; if (BLI_exists(to)) if(BLI_delete(to, 0, 0)) return 1; - + return rename(from, to); } diff --git a/source/blender/blenlib/intern/fnmatch.c b/source/blender/blenlib/intern/fnmatch.c index 54114ad3448..32065283bd0 100644 --- a/source/blender/blenlib/intern/fnmatch.c +++ b/source/blender/blenlib/intern/fnmatch.c @@ -240,10 +240,7 @@ fnmatch (const char *pattern, const char *string, int flags) #else -static void BLI_FNMATCH_C_IS_EMPTY_FOR_UNIX(void) -{ - /*intentionally empty*/ -} +/* intentionally empty for UNIX */ #endif /* WIN32 */ diff --git a/source/blender/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c index a97f2460ba1..bde4b561f26 100644 --- a/source/blender/blenlib/intern/freetypefont.c +++ b/source/blender/blenlib/intern/freetypefont.c @@ -30,8 +30,6 @@ * Code that uses exotic character maps is present but commented out. */ -#ifdef WITH_FREETYPE2 - #ifdef WIN32 #pragma warning (disable:4244) #endif @@ -49,9 +47,10 @@ #include "BLI_blenlib.h" #include "BLI_arithb.h" -#include "BIF_toolbox.h" +//XXX #include "BIF_toolbox.h" #include "BKE_global.h" +#include "BKE_font.h" #include "BKE_utildefines.h" #include "DNA_vfont_types.h" @@ -282,13 +281,7 @@ int objchr_to_ftvfontdata(VFont *vfont, FT_ULong charcode) struct TmpFont *tf; // Find the correct FreeType font - tf= G.ttfdata.first; - while(tf) - { - if(tf->vfont == vfont) - break; - tf= tf->next; - } + tf= vfont_find_tmpfont(vfont); // What, no font found. Something strange here if(!tf) return FALSE; @@ -301,9 +294,12 @@ int objchr_to_ftvfontdata(VFont *vfont, FT_ULong charcode) tf->pf->size, 0, &face); + if (err) return FALSE; + } + else { + err = TRUE; + return FALSE; } - else - err= TRUE; // Read the char freetypechar_to_vchar(face, charcode, vfont->data); @@ -432,7 +428,7 @@ static int check_freetypefont(PackedFile * pf) &face ); if(err) { success = 0; - error("This is not a valid font"); + //XXX error("This is not a valid font"); } else { /* @@ -461,7 +457,7 @@ static int check_freetypefont(PackedFile * pf) if (glyph->format == ft_glyph_format_outline ) { success = 1; } else { - error("Selected Font has no outline data"); + //XXX error("Selected Font has no outline data"); success = 0; } } @@ -479,7 +475,7 @@ VFontData *BLI_vfontdata_from_freetypefont(PackedFile *pf) //init Freetype err = FT_Init_FreeType( &library); if(err) { - error("Failed to load the Freetype font library"); + //XXX error("Failed to load the Freetype font library"); return 0; } @@ -504,7 +500,7 @@ int BLI_vfontchar_from_freetypefont(VFont *vfont, unsigned long character) // Init Freetype err = FT_Init_FreeType(&library); if(err) { - error("Failed to load the Freetype font library"); + //XXX error("Failed to load the Freetype font library"); return 0; } @@ -519,10 +515,6 @@ int BLI_vfontchar_from_freetypefont(VFont *vfont, unsigned long character) return TRUE; } -#endif // WITH_FREETYPE2 - - - #if 0 // Freetype2 Outline struct diff --git a/source/blender/blenlib/intern/graph.c b/source/blender/blenlib/intern/graph.c index 52277063a8f..cc15c499290 100644 --- a/source/blender/blenlib/intern/graph.c +++ b/source/blender/blenlib/intern/graph.c @@ -279,7 +279,7 @@ void BLI_removeDoubleNodes(BGraph *graph, float limit) BNode * BLI_FindNodeByPosition(BGraph *graph, float *p, float limit) { BNode *closest_node = NULL, *node; - float min_distance; + float min_distance = 0.0f; for(node = graph->nodes.first; node; node = node->next) { diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c new file mode 100644 index 00000000000..1064c8ac1bf --- /dev/null +++ b/source/blender/blenlib/intern/listbase.c @@ -0,0 +1,361 @@ +/* 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., 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: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +#include <string.h> +#include <stdlib.h> + + +#include "MEM_guardedalloc.h" + +#include "DNA_listBase.h" + +#include "BLI_listbase.h" + + +/* implementation */ + +/* Ripped this from blender.c */ +void addlisttolist(ListBase *list1, ListBase *list2) +{ + if (list2->first==0) return; + + if (list1->first==0) { + list1->first= list2->first; + list1->last= list2->last; + } + else { + ((Link *)list1->last)->next= list2->first; + ((Link *)list2->first)->prev= list1->last; + list1->last= list2->last; + } + list2->first= list2->last= 0; +} + +void BLI_addhead(ListBase *listbase, void *vlink) +{ + Link *link= vlink; + + if (link == NULL) return; + if (listbase == NULL) return; + + link->next = listbase->first; + link->prev = NULL; + + if (listbase->first) ((Link *)listbase->first)->prev = link; + if (listbase->last == NULL) listbase->last = link; + listbase->first = link; +} + + +void BLI_addtail(ListBase *listbase, void *vlink) +{ + Link *link= vlink; + + if (link == NULL) return; + if (listbase == NULL) return; + + link->next = NULL; + link->prev = listbase->last; + + if (listbase->last) ((Link *)listbase->last)->next = link; + if (listbase->first == 0) listbase->first = link; + listbase->last = link; +} + + +void BLI_remlink(ListBase *listbase, void *vlink) +{ + Link *link= vlink; + + if (link == NULL) return; + if (listbase == NULL) return; + + if (link->next) link->next->prev = link->prev; + if (link->prev) link->prev->next = link->next; + + if (listbase->last == link) listbase->last = link->prev; + if (listbase->first == link) listbase->first = link->next; +} + + +void BLI_freelinkN(ListBase *listbase, void *vlink) +{ + Link *link= vlink; + + if (link == NULL) return; + if (listbase == NULL) return; + + BLI_remlink(listbase,link); + MEM_freeN(link); +} + + +void BLI_insertlink(ListBase *listbase, void *vprevlink, void *vnewlink) +{ + Link *prevlink= vprevlink; + Link *newlink= vnewlink; + + /* newlink comes after prevlink */ + if (newlink == NULL) return; + if (listbase == NULL) return; + + /* empty list */ + if (listbase->first == NULL) { + + listbase->first= newlink; + listbase->last= newlink; + return; + } + + /* insert before first element */ + if (prevlink == NULL) { + newlink->next= listbase->first; + newlink->prev= 0; + newlink->next->prev= newlink; + listbase->first= newlink; + return; + } + + /* at end of list */ + if (listbase->last== prevlink) + listbase->last = newlink; + + newlink->next= prevlink->next; + prevlink->next= newlink; + if (newlink->next) newlink->next->prev= newlink; + newlink->prev= prevlink; +} + +/* This uses insertion sort, so NOT ok for large list */ +void BLI_sortlist(ListBase *listbase, int (*cmp)(void *, void *)) +{ + Link *current = NULL; + Link *previous = NULL; + Link *next = NULL; + + if (cmp == NULL) return; + if (listbase == NULL) return; + + if (listbase->first != listbase->last) + { + for( previous = listbase->first, current = previous->next; current; current = next ) + { + next = current->next; + previous = current->prev; + + BLI_remlink(listbase, current); + + while(previous && cmp(previous, current) == 1) + { + previous = previous->prev; + } + + BLI_insertlinkafter(listbase, previous, current); + } + } +} + +void BLI_insertlinkafter(ListBase *listbase, void *vprevlink, void *vnewlink) +{ + Link *prevlink= vprevlink; + Link *newlink= vnewlink; + + /* newlink before nextlink */ + if (newlink == NULL) return; + if (listbase == NULL) return; + + /* empty list */ + if (listbase->first == NULL) { + listbase->first= newlink; + listbase->last= newlink; + return; + } + + /* insert at head of list */ + if (prevlink == NULL) { + newlink->prev = NULL; + newlink->next = listbase->first; + ((Link *)listbase->first)->prev = newlink; + listbase->first = newlink; + return; + } + + /* at end of list */ + if (listbase->last == prevlink) + listbase->last = newlink; + + newlink->next = prevlink->next; + newlink->prev = prevlink; + prevlink->next = newlink; + if (newlink->next) newlink->next->prev = newlink; +} + +void BLI_insertlinkbefore(ListBase *listbase, void *vnextlink, void *vnewlink) +{ + Link *nextlink= vnextlink; + Link *newlink= vnewlink; + + /* newlink before nextlink */ + if (newlink == NULL) return; + if (listbase == NULL) return; + + /* empty list */ + if (listbase->first == NULL) { + listbase->first= newlink; + listbase->last= newlink; + return; + } + + /* insert at end of list */ + if (nextlink == NULL) { + newlink->prev= listbase->last; + newlink->next= 0; + ((Link *)listbase->last)->next= newlink; + listbase->last= newlink; + return; + } + + /* at beginning of list */ + if (listbase->first== nextlink) + listbase->first = newlink; + + newlink->next= nextlink; + newlink->prev= nextlink->prev; + nextlink->prev= newlink; + if (newlink->prev) newlink->prev->next= newlink; +} + + +void BLI_freelist(ListBase *listbase) +{ + Link *link, *next; + + if (listbase == NULL) + return; + + link= listbase->first; + while (link) { + next= link->next; + free(link); + link= next; + } + + listbase->first= NULL; + listbase->last= NULL; +} + +void BLI_freelistN(ListBase *listbase) +{ + Link *link, *next; + + if (listbase == NULL) return; + + link= listbase->first; + while (link) { + next= link->next; + MEM_freeN(link); + link= next; + } + + listbase->first= NULL; + listbase->last= NULL; +} + + +int BLI_countlist(ListBase *listbase) +{ + Link *link; + int count = 0; + + if (listbase) { + link = listbase->first; + while (link) { + count++; + link= link->next; + } + } + return count; +} + +void *BLI_findlink(ListBase *listbase, int number) +{ + Link *link = NULL; + + if (number >= 0) { + link = listbase->first; + while (link != NULL && number != 0) { + number--; + link = link->next; + } + } + + return link; +} + +int BLI_findindex(ListBase *listbase, void *vlink) +{ + Link *link= NULL; + int number= 0; + + if (listbase == NULL) return -1; + if (vlink == NULL) return -1; + + link= listbase->first; + while (link) { + if (link == vlink) + return number; + + number++; + link= link->next; + } + + return -1; +} + +void BLI_duplicatelist(ListBase *list1, ListBase *list2) /* copy from 2 to 1 */ +{ + struct Link *link1, *link2; + + list1->first= list1->last= 0; + + link2= list2->first; + while(link2) { + + link1= MEM_dupallocN(link2); + BLI_addtail(list1, link1); + + link2= link2->next; + } +} + diff --git a/source/blender/blenlib/intern/psfont.c b/source/blender/blenlib/intern/psfont.c deleted file mode 100644 index 39d38e4cf3a..00000000000 --- a/source/blender/blenlib/intern/psfont.c +++ /dev/null @@ -1,2126 +0,0 @@ -/** - * $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: all of this file. - * - * Contributor(s): none yet. - * - * ***** END GPL LICENSE BLOCK ***** - * fromtype1 - Convert an Adobe type 1 font into .of or .sf format. - * Paul Haeberli - 1990 - */ - -#include <stdio.h> -#include <string.h> -#include <ctype.h> -#include <stdlib.h> -#include <math.h> - -#include "MEM_guardedalloc.h" - -#include "BLI_vfontdata.h" -#include "BLI_blenlib.h" - -#include "DNA_packedFile_types.h" -#include "DNA_curve_types.h" - -#include "BLO_sys_types.h" // for intptr_t support - -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - - /* ObjFnt types */ - -typedef struct chardesc { - short movex, movey; /* advance */ - short llx, lly; /* bounding box */ - short urx, ury; - short *data; /* char data */ - intptr_t datalen; -} chardesc; - -typedef struct objfnt { - struct objfnt *freeaddr; /* if freeaddr != 0, objfnt is one chunck */ - short type; - short charmin, charmax; - short my_nchars; - short scale; - chardesc *my_chars; -} objfnt; - -#define OFMAGIC 0x93339333 - -#define TM_TYPE 1 -#define PO_TYPE 2 -#define SP_TYPE 3 - -/* ops for tmesh characters */ - -#define TM_BGNTMESH (1) -#define TM_SWAPTMESH (2) -#define TM_ENDBGNTMESH (3) -#define TM_RETENDTMESH (4) -#define TM_RET (5) - -/* ops for poly characters */ - -#define PO_BGNLOOP (1) -#define PO_ENDBGNLOOP (2) -#define PO_RETENDLOOP (3) -#define PO_RET (4) - -/* ops for spline characters */ - -#define SP_MOVETO (1) -#define SP_LINETO (2) -#define SP_CURVETO (3) -#define SP_CLOSEPATH (4) -#define SP_RETCLOSEPATH (5) -#define SP_RET (6) - - -#define MIN_ASCII ' ' -#define MAX_ASCII '~' -#define NASCII (256 - 32) - -#define NOBBOX (30000) - -typedef struct pschar { - char *name; - int code; - int prog; -} pschar; - - /***/ - -#define SKIP 4 -#define LINELEN 2048 -#define NOTHEX (100) -#define MC1 52845 -#define MC2 22719 -#define MAXSUBRS 4000 -#define MAXCHARS 4000 -#define MAXTRIES 30 - -/* some local thingies */ -static void rcurveto( int dx1, int dy1, int dx2, int dy2, int dx3, int dy3); -static void makeobjfont(int savesplines); -static void drawchar(int c); -static void runprog(void); -static int chartoindex(objfnt *fnt, int c); -static short STDtoISO(short c); -static char * newfgets(char * s, int n, PackedFile * pf); -static int readfontmatrix(PackedFile * pf, float mat[2][2]); -static char mdecrypt(char cipher); -static void decryptall(void); -static int decodetype1(PackedFile * pf, char *outname); -static void fakefopen(void); -static char *fakefread(int n); -static void setcharlist(void); -static void initpcstack(void); -static char *poppc(void); -static void initstack(void); -static void push(int val); -static int pop(void); -static void initretstack(void); -static void retpush(int val); -static int retpop(void); -static void subr1(void); -static void subr2(void); -static void subr0(void); -static void append_poly_offset(short ofsx, short ofsy, short * data); -static void append_spline_offset(short ofsx, short ofsy, short * data); -static void setwidth(int w, int x); -static void poly_beginchar(void); -static void poly_endchar(void); -static void poly_close(void); -static void poly_pnt(float x, float y); -static void spline_beginchar(void); -static void spline_endchar(void); -static void spline_close(void); -static void spline_line(float x0, float y0, float x1, float y1); -static void spline_curveto(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3); -static void savestart(int x, int y); -static void sbpoint( int x, int y); -static void rmoveto( int x, int y); -static void drawline(float x0, float y0, float x1, float y1, float dx0, float dy0, float dx1, float dy1); -static void rlineto( int x, int y); -static void closepath(void); -static void bezadapt( float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3, float beztol); -static void drawbez( float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3); -static int docommand(int cmd); - -/* some local vars */ -static int startx, starty; -static int curx, cury; -static int nextx, nexty; -static int delx, dely; -static int started; - - -/* postscript commands */ -#define HSTEM (1) -#define VSTEM (3) -#define VMOVETO (4) -#define RLINETO (5) -#define HLINETO (6) -#define VLINETO (7) -#define RRCURVETO (8) -#define CLOSEPATH (9) -#define CALLSUBR (10) -#define RETURN (11) -#define HSBW (13) -#define ENDCHAR (14) -#define RMOVETO (21) -#define HMOVETO (22) -#define VHCURVETO (30) -#define HVCURVETO (31) -#define DOTSECTION (256+0) -#define VSTEM3 (256+1) -#define HSTEM3 (256+2) -#define SEAC (256+6) -#define SBW (256+7) -#define DIV (256+12) -#define CALLOTHERSUBR (256+16) -#define POP (256+17) -#define SETCURRENTPOINT (256+33) -#define WHAT0 (0) - -static char oneline[LINELEN]; -static objfnt *fnt; - -static unsigned short int mr; - -static char *bindat; -static int datbytes; -static int firsted; -static short chardata[20000]; -static int nshorts; - -static int thecharwidth, thesidebearing; -static int npnts, nloops; -static int nvertpos; - -static int fakepos; -static int fakemax; - -static float beztol = 100.0; - -/* extern: from libfm */ - -static char *my_subrs[MAXSUBRS]; -static unsigned int my_sublen[MAXSUBRS]; -static char *my_chars[MAXCHARS]; -static unsigned int my_charlen[MAXCHARS]; -static char *my_charname[MAXCHARS]; -static int my_nsubrs, my_nchars; - -static short sidebearing[MAXCHARS]; -static char tok[LINELEN]; -static int sp_npnts, sp_nloops; - -/* - * interpreter globals - */ - - -static float mat[2][2]; -static char *pcstack[100]; -static char *pc; -static int pcsp; -static int coordpos; -static int coordsave[7][2]; -static int incusp; -static int retstack[1000]; -static int retsp; -static int stack[1000]; -static int sp; -static int savesplines = 1; - -static pschar ISOcharlist[NASCII] = { - {"/space", 040, 0}, - {"/exclam", 041, 0}, - {"/quotedbl", 042, 0}, - {"/numbersign", 043, 0}, - {"/dollar", 044, 0}, - {"/percent", 045, 0}, - {"/ampersand", 046, 0}, - {"/quoteright", 047, 0}, - - {"/parenleft", 050, 0}, - {"/parenright", 051, 0}, - {"/asterisk", 052, 0}, - {"/plus", 053, 0}, - {"/comma", 054, 0}, - {"/hyphen", 055, 0}, - {"/period", 056, 0}, - {"/slash", 057, 0}, - - {"/zero", 060, 0}, - {"/one", 061, 0}, - {"/two", 062, 0}, - {"/three", 063, 0}, - {"/four", 064, 0}, - {"/five", 065, 0}, - {"/six", 066, 0}, - {"/seven", 067, 0}, - - {"/eight", 070, 0}, - {"/nine", 071, 0}, - {"/colon", 072, 0}, - {"/semicolon", 073, 0}, - {"/less", 074, 0}, - {"/equal", 075, 0}, - {"/greater", 076, 0}, - {"/question", 077, 0}, - - {"/at", 0100, 0}, - {"/A", 0101, 0}, - {"/B", 0102, 0}, - {"/C", 0103, 0}, - {"/D", 0104, 0}, - {"/E", 0105, 0}, - {"/F", 0106, 0}, - {"/G", 0107, 0}, - - {"/H", 0110, 0}, - {"/I", 0111, 0}, - {"/J", 0112, 0}, - {"/K", 0113, 0}, - {"/L", 0114, 0}, - {"/M", 0115, 0}, - {"/N", 0116, 0}, - {"/O", 0117, 0}, - - {"/P", 0120, 0}, - {"/Q", 0121, 0}, - {"/R", 0122, 0}, - {"/S", 0123, 0}, - {"/T", 0124, 0}, - {"/U", 0125, 0}, - {"/V", 0126, 0}, - {"/W", 0127, 0}, - - {"/X", 0130, 0}, - {"/Y", 0131, 0}, - {"/Z", 0132, 0}, - {"/bracketleft", 0133, 0}, - {"/backslash", 0134, 0}, - {"/bracketright", 0135, 0}, - {"/asciicircum", 0136, 0}, - {"/underscore", 0137, 0}, - - {"/quoteleft", 0140, 0}, - {"/a", 0141, 0}, - {"/b", 0142, 0}, - {"/c", 0143, 0}, - {"/d", 0144, 0}, - {"/e", 0145, 0}, - {"/f", 0146, 0}, - {"/g", 0147, 0}, - - {"/h", 0150, 0}, - {"/i", 0151, 0}, - {"/j", 0152, 0}, - {"/k", 0153, 0}, - {"/l", 0154, 0}, - {"/m", 0155, 0}, - {"/n", 0156, 0}, - {"/o", 0157, 0}, - - {"/p", 0160, 0}, - {"/q", 0161, 0}, - {"/r", 0162, 0}, - {"/s", 0163, 0}, - {"/t", 0164, 0}, - {"/u", 0165, 0}, - {"/v", 0166, 0}, - {"/w", 0167, 0}, - - {"/x", 0170, 0}, - {"/y", 0171, 0}, - {"/z", 0172, 0}, - {"/braceleft", 0173, 0}, - {"/bar", 0174, 0}, - {"/braceright", 0175, 0}, - {"/asciitilde", 0176, 0}, - {"/", 0177, 0}, - - - /* nonstandard defs */ - - {"/quotedblleft", 0200, 0}, - {"/quotedblright", 0201, 0}, - {"/quotedblbase", 0202, 0}, - {"/quotesinglbase", 0203, 0}, - {"/guilsinglleft", 0204, 0}, - {"/guilsinglright", 0205, 0}, - {"/endash", 0206, 0}, - {"/dagger", 0207, 0}, - - {"/daggerdbl", 0210, 0}, - {"/trademark", 0211, 0}, - {"/bullet", 0212, 0}, - {"/perthousand", 0213, 0}, - {"/Lslash", 0214, 0}, - {"/OE", 0215, 0}, - {"/lslash", 0216, 0}, - {"/oe", 0217, 0}, - - /* endnonstandard defs */ - - {"/dotlessi", 0220, 0}, - {"/grave", 0221, 0}, - {"/acute", 0222, 0}, - {"/circumflex", 0223, 0}, - {"/tilde", 0224, 0}, - {"/", 0225, 0}, - {"/breve", 0226, 0}, - {"/dotaccent", 0227, 0}, - - {"/", 0230, 0}, - {"/", 0231, 0}, - {"/ring", 0232, 0}, - {"/", 0233, 0}, - {"/", 0234, 0}, - {"/hungarumlaut", 0235, 0}, - {"/ogonek", 0236, 0}, - {"/caron", 0237, 0}, - - {"/", 0240, 0}, - {"/exclamdown", 0241, 0}, - {"/cent", 0242, 0}, - {"/sterling", 0243, 0}, - {"/florin", 0244, 0}, - {"/yen", 0245, 0}, - {"/brokenbar", 0246, 0}, - {"/section", 0247, 0}, - - {"/dieresis", 0250, 0}, - {"/copyright", 0251, 0}, - {"/ordfeminine", 0252, 0}, - {"/guillemotleft", 0253, 0}, - {"/logicalnot", 0254, 0}, - {"/hyphen", 0255, 0}, - {"/registered", 0256, 0}, - {"/macron", 0257, 0}, - - {"/degree", 0260, 0}, - {"/plusminus", 0261, 0}, - {"/twosuperior", 0262, 0}, - {"/threesuperior", 0263, 0}, - {"/acute", 0264, 0}, - {"/mu", 0265, 0}, - {"/paragraph", 0266, 0}, - {"/periodcentered", 0267, 0}, - - {"/cedilla", 0270, 0}, - {"/onesuperior", 0271, 0}, - {"/ordmasculine", 0272, 0}, - {"/guillemotright", 0273, 0}, - {"/onequarter", 0274, 0}, - {"/onehalf", 0275, 0}, - {"/threequarters", 0276, 0}, - {"/questiondown", 0277, 0}, - - {"/Agrave", 0300, 0}, - {"/Aacute", 0301, 0}, - {"/Acircumflex", 0302, 0}, - {"/Atilde", 0303, 0}, - {"/Adieresis", 0304, 0}, - {"/Aring", 0305, 0}, - {"/AE", 0306, 0}, - {"/Ccedilla", 0307, 0}, - - {"/Egrave", 0310, 0}, - {"/Eacute", 0311, 0}, - {"/Ecircumflex", 0312, 0}, - {"/Edieresis", 0313, 0}, - {"/Igrave", 0314, 0}, - {"/Iacute", 0315, 0}, - {"/Icircumflex", 0316, 0}, - {"/Idieresis", 0317, 0}, - - {"/Eth", 0320, 0}, - {"/Ntilde", 0321, 0}, - {"/Ograve", 0322, 0}, - {"/Oacute", 0323, 0}, - {"/Ocircumflex", 0324, 0}, - {"/Otilde", 0325, 0}, - {"/Odieresis", 0326, 0}, - {"/multiply", 0327, 0}, - - {"/Oslash", 0330, 0}, - {"/Ugrave", 0331, 0}, - {"/Uacute", 0332, 0}, - {"/Ucircumflex",0333, 0}, - {"/Udieresis", 0334, 0}, - {"/Yacute", 0335, 0}, - {"/Thorn", 0336, 0}, - {"/germandbls", 0337, 0}, - - {"/agrave", 0340, 0}, - {"/aacute", 0341, 0}, - {"/acircumflex",0342, 0}, - {"/atilde", 0343, 0}, - {"/adieresis", 0344, 0}, - {"/aring", 0345, 0}, - {"/ae", 0346, 0}, - {"/ccedilla", 0347, 0}, - - {"/egrave", 0350, 0}, - {"/eacute", 0351, 0}, - {"/ecircumflex", 0352, 0}, - {"/edieresis", 0353, 0}, - {"/igrave", 0354, 0}, - {"/iacute", 0355, 0}, - {"/icircumflex", 0356, 0}, - {"/idieresis", 0357, 0}, - - {"/eth", 0360, 0}, - {"/ntilde", 0361, 0}, - {"/ograve", 0362, 0}, - {"/oacute", 0363, 0}, - {"/ocircumflex",0364, 0}, - {"/otilde", 0365, 0}, - {"/odieresis", 0366, 0}, - {"/divide", 0367, 0}, - - {"/oslash", 0370, 0}, - {"/ugrave", 0371, 0}, - {"/uacute", 0372, 0}, - {"/ucircumflex",0373, 0}, - {"/udieresis", 0374, 0}, - {"/yacute", 0375, 0}, - {"/thorn", 0376, 0}, - {"/ydieresis", 0377, 0}, -}; - - -static short STDvsISO [][2] = { - {0341, 0306}, /* AE */ - {0351, 0330}, /* Oslash */ - {0302, 0222}, /* acute */ - {0361, 0346}, /* ae */ - {0306, 0226}, /* breve */ - {0317, 0237}, /* caron */ - {0313, 0270}, /* cedilla */ - {0303, 0223}, /* circumflex */ - {0250, 0244}, /* currency */ - {0310, 0250}, /* dieresis */ - {0307, 0227}, /* dotaccent */ - {0365, 0220}, /* dotlessi */ - {0373, 0337}, /* germandbls */ - {0301, 0221}, /* grave */ - {0315, 0235}, /* hungarumlaut */ - {0055, 0255}, /* hyphen */ - {0305, 0257}, /* macron */ - {0316, 0236}, /* ogenek */ - {0343, 0252}, /* ordfeminine */ - {0353, 0272}, /* ordmasculine */ - {0371, 0370}, /* oslash */ - {0264, 0267}, /* periodcentered */ - {0312, 0232}, /* ring */ - {0304, 0224}, /* tilde */ -}; - -/* from objfont.c, rest is in lfm_s !!*/ - -/* START 5.2 */ - -static int chartoindex(objfnt *fnt, int c) -{ - if(c<fnt->charmin) - return -1; - if(c>fnt->charmax) - return -1; - return c-fnt->charmin; -} - - -static chardesc *getchardesc(objfnt *fnt, int c) -{ - int index; - - index = chartoindex(fnt,c); - if(index<0) - return 0; - return fnt->my_chars+index; -} - -static objfnt *newobjfnt(int type, int charmin, int charmax, int fscale) -{ - objfnt *fnt; - - fnt = (objfnt *)MEM_mallocN(sizeof(objfnt), "newobjfnt"); - fnt->freeaddr = 0; - fnt->type = type; - fnt->charmin = charmin; - fnt->charmax = charmax; - fnt->my_nchars = fnt->charmax-fnt->charmin+1; - fnt->scale = fscale; - fnt->my_chars = (chardesc *)MEM_mallocN(fnt->my_nchars*sizeof(chardesc), "newobjfnt2"); - memset(fnt->my_chars, 0, fnt->my_nchars*sizeof(chardesc)); - return fnt; -} - - -static void addchardata (objfnt * fnt, int c, short * data, int nshorts) -{ - int index; - chardesc *cd; - - index = chartoindex(fnt,c); - if(index<0) { - fprintf(stderr,"Addchardata bad poop\n"); - return; - } - cd = fnt->my_chars+index; - fnt->freeaddr = 0; - cd->datalen = nshorts*sizeof(short); - cd->data = (short *)MEM_mallocN(cd->datalen, "addchardata"); - memcpy(cd->data, data, cd->datalen); -} - -static void addcharmetrics(objfnt *fnt, int c, int movex, int movey) -{ - int index; - chardesc *cd; - - index = chartoindex(fnt,c); - if(index<0) { - fprintf(stderr,"Addcharmetrics bad poop\n"); - return; - } - cd = fnt->my_chars+index; - cd->movex = movex; - cd->movey = movey; -} - - -static void fakechar(objfnt *fnt, int c, int width) -{ - short chardata[1]; - - chardata[0] = PO_RET; - addchardata(fnt,c,chardata,1); - addcharmetrics(fnt,c,width,0); -} - - -static void freeobjfnt(objfnt * fnt) -{ - int i; - chardesc *cd; - - cd = fnt->my_chars; - for(i=0; i<fnt->my_nchars; i++) { - if(cd->data) - MEM_freeN(cd->data); - cd++; - } - MEM_freeN(fnt->my_chars); - MEM_freeN(fnt); -} - - -/* END 5.2 */ - -static short STDtoISO(short c) -{ - short i = (sizeof(STDvsISO) / (2 * sizeof(short))) - 1; - - for (;i >= 0; i--){ - if (STDvsISO[i][0] == c) return (STDvsISO[i][1]); - } - return(c); -} - - -/* - * read the font matrix out of the font file - * - */ - -static char * newfgets(char * s, int n, PackedFile * pf){ - int c; - char * p; - - p = s; - while (n > 0){ - c = ((char *) pf->data)[pf->seek]; - pf->seek++; - if (pf->seek > pf->size){ - return (0); - } - if (c == 10 || c == 13){ - *p = 0; - return(s); - } - *p++ = c; - n--; - } - *p = 0; - return(s); -} - -static int readfontmatrix(PackedFile * pf, float mat[2][2]) -{ - char *cptr; - float a, b, c, d, e, f; - - pf->seek = 0; - - /* look for the FontMatrix def */ - while(1) { - if(!newfgets(oneline, LINELEN, pf)) { - fprintf(stderr,"fromtype1: no FontMatrix found\n"); - return(-1); - } - cptr = strchr(oneline,'/'); - if(cptr) { - if(strncmp(cptr,"/FontMatrix",11) == 0) { - cptr = strchr(cptr,'['); - if(!cptr) { - fprintf(stderr,"fromtype1: bad FontMatrix line\n"); - return(-1); - } - sscanf(cptr+1,"%f %f %f %f %f %f\n",&a,&b,&c,&d,&e,&f); - break; - } - } - } - - mat[0][0] = 1000.0*a; - mat[1][0] = 1000.0*b; - mat[0][1] = 1000.0*c; - mat[1][1] = 1000.0*d; - - return(0); -} - -/* - * Decryption support - * - * - */ -static void resetdecrypt(int n) -{ - mr = n; -} - - - -/* - * decryption subroutines - * - */ - -static char mdecrypt(char cipher) -{ - char plain; - - plain = (cipher^(mr>>8)); - mr = (cipher+mr)*MC1 + MC2; - return plain; -} - -static void decryptdata(char * cptr, int n) -{ - while(n--) { - *cptr = mdecrypt(*cptr); - cptr++; - } -} - -static int decryptprogram(char *buf, int len) -{ - int i; - - resetdecrypt(4330); - for(i=0; i<len; i++) { - if(i<SKIP) { - mdecrypt(buf[i]); - } - else { - buf[i-SKIP] = mdecrypt(buf[i]); - } - } - return len-SKIP; -} - -static void decryptall(void) -{ - int i; - - for(i=0; i<my_nsubrs; i++) - my_sublen[i] = decryptprogram(my_subrs[i],my_sublen[i]); - for(i=0; i<my_nchars; i++) - my_charlen[i] = decryptprogram(my_chars[i],my_charlen[i]); -} - - -/* - * decode the eexec part of the file - * - */ - -static int decodetype1(PackedFile * pf, char *outname) -{ - char *hptr, *bptr; - int i, totlen, hexbytes, c; - char *hexdat; - char hextab[256]; - - /* make hex table */ - if(!firsted) { - for(i=0; i<256; i++) { - if(i>='0' && i<='9') - hextab[i] = i-'0'; - else if(i>='a' && i<='f') - hextab[i] = 10+i-'a'; - else if(i>='A' && i<='F') - hextab[i] = 10+i-'A'; - else - hextab[i] = NOTHEX; - } - } - - pf->seek = 0; - - /* allocate buffers */ - totlen = pf->size; - hexdat = (char *)MEM_mallocN(totlen, "hexdat"); - bindat = (char *)MEM_mallocN(totlen, "bindat"); - - /* look for eexec part of file */ - while(1) { - if(!newfgets(oneline, LINELEN, pf)) { - fprintf(stderr,"fromtype1: no currentfile eexec found\n"); - return(-1); - } - oneline[16] = 0; - if(strcmp(oneline,"currentfile eexe") == 0) - break; - } - - /* initialize decryption variables */ - mr = 55665; - - /* first byte == 0 for binary data (???) */ - - c = ((char *) pf->data)[pf->seek]; - - if (hextab[c] != NOTHEX){ - /* read all the hex bytes into the hex buffer */ - hexbytes = 0; - while(newfgets(oneline, LINELEN, pf)) { - hptr = (char *)oneline; - while(*hptr) { - if(hextab[*hptr] != NOTHEX) - hexdat[hexbytes++] = *hptr; - hptr++; - } - } - - /* check number of hex bytes */ - if(hexbytes & 1) - hexbytes--; - datbytes = hexbytes/2; - - /* translate hex data to binary */ - hptr = hexdat; - bptr = bindat; - c = datbytes; - while(c--) { - *bptr++ = (hextab[hptr[0]]<<4)+hextab[hptr[1]]; - hptr += 2; - } - - /* decrypt the data */ - decryptdata(bindat,datbytes); - - } else { - datbytes = pf->size - pf->seek; - memcpy(bindat, ((char *) pf->data) + pf->seek, datbytes); - - if ((bindat[2] << (8 + bindat[3])) == 0x800){ - /* order data (remove 6 bytes headers) */ - i = datbytes; - hptr = bptr = bindat + 4; - hptr += 2; - - while (i > 0){ - if (i > 2046) c = 2046; - else c = i; - - memcpy(bptr, hptr, c); - bptr += 2046; - hptr += 2046 + 6; - i -= 2046 + 6; - datbytes -= 6; - } - - /* decrypt the data */ - decryptdata(bindat+4,datbytes); - } else{ - decryptdata(bindat+6,datbytes-6); - } - } - -#ifdef DEBUG - outf = fopen(outname,"wb"); - fwrite(bindat,datbytes,1,outf); - fclose(outf); -#endif - - MEM_freeN(hexdat); - - return 1; -} - -/* - * fake file reading funcs - * - * - */ - -static void fakefopen(void) -{ - fakepos = 0; - fakemax = datbytes; -} - - -static void fakegettoken(char *str) -{ - int c; - char *cptr; - char *start; - - start = (char *) str; - cptr = bindat+fakepos; - c = *cptr++; - fakepos++; - if(c != '\n') { - while(isspace(c)) { - c = *cptr++; - fakepos++; - } - while (fakepos<fakemax && !isspace(c)) { - *str++ = c; - c = *cptr++; - fakepos++; - } - if(c == '\n') - fakepos--; - } - *str = 0; - if(fakepos>fakemax) { - fprintf(stderr,"fromtype1: unexpected eof\n"); - strcpy(start, "end"); - } -} - -static int fakefgets(char *buf,int max) -{ - char *cptr; - - cptr = (char *)(bindat+fakepos); - while(max--) { - *buf++ = *cptr; - fakepos++; - if(*cptr == 10 || *cptr == 13) - return 1; - cptr++; - if(fakepos>fakemax) - return 0; - } - return 0; -} - -static char *fakefread(int n) -{ - fakepos += n; - return bindat+fakepos-n; -} - -static void applymat(float mat[][2], float *x, float *y) -{ - float tx, ty; - - tx = ((*x)*mat[0][0])+((*y)*mat[0][1]); - ty = ((*x)*mat[1][0])+((*y)*mat[1][1]); - *x = tx; - *y = ty; -} - -static void setcharlist(void) -{ - char *name; /*found;*/ - int i, j; - - for(i=0; i<NASCII; i++) ISOcharlist[i].prog = -1; - - for(j=0; j<my_nchars; j++) { - name = my_charname[j]; - if(name) { - /*found = 0;*/ - for(i=0; i<NASCII; i++) { - if(ISOcharlist[i].name && (strcmp(name,ISOcharlist[i].name) == 0)){ - ISOcharlist[i].prog = j; - /*found = 1;*/ - } - } - /*if (found == 0) printf("no match found for: %s\n", name);*/ - MEM_freeN(name); - my_charname[j] = 0; - } - } -} - - -static objfnt * objfnt_from_psfont(PackedFile * pf) -{ - int i, k, index; - int nread, namelen; - char *cptr; - - fnt = 0; - bindat = 0; - - /* read the font matrix from the font */ - if (readfontmatrix(pf,mat)) return(0); - - /* decode the font data */ - decodetype1(pf, "/usr/tmp/type1.dec"); - - /* open the input file */ - fakefopen(); - - /* look for the /Subrs def and get my_nsubrs */ - while(1) { - if(!fakefgets(oneline,LINELEN)) { - fprintf(stderr,"fromtype1: no /Subrs found\n"); - my_nsubrs = 0; - fakefopen(); - break; - } - cptr = strchr(oneline,'/'); - if(cptr) { - if(strncmp(cptr,"/Subrs",6) == 0) { - my_nsubrs = atoi(cptr+6); - break; - } - } - } - - /* read the Subrs in one by one */ - for(i=0; i<my_nsubrs; i++) - my_sublen[i] = 0; - for(i=0; i<my_nsubrs; i++) { - for(k=0; k<MAXTRIES; k++) { - fakegettoken(tok); - if(strcmp(tok,"dup") == 0) - break; - } - if(k == MAXTRIES) { - fprintf(stderr,"dup for subr %d not found in range\n", i); - /*exit(1);*/ - } - - /* get the Subr index here */ - fakegettoken(tok); - index = atoi(tok); - - /* check to make sure it is in range */ - if(index<0 || index>my_nsubrs) { - fprintf(stderr,"bad Subr index %d\n",index); - /*exit(1);*/ - } - - /* get the number of bytes to read */ - fakegettoken(tok); - nread = atoi(tok); - fakegettoken(tok); - - /* read in the subroutine */ - my_sublen[index] = nread; - my_subrs[index] = fakefread(nread); - fakegettoken(tok); - } - - /* look for the CharStrings */ - while(1) { - fakegettoken(tok); - cptr = strchr(tok,'/'); - if(cptr && strcmp(cptr,"/CharStrings") == 0) - break; - } - - fakegettoken(tok); /* skip my_ncharscrings */ - fakegettoken(tok); /* skip dict */ - fakegettoken(tok); /* skip dup */ - fakegettoken(tok); /* skip begin */ - fakegettoken(tok); /* skip newline */ - - /* read the CharStrings one by one */ - my_nchars = 0; - for(i=0; i<MAXCHARS; i++) { - - /* check for end */ - fakegettoken(tok); - if(strcmp(tok,"end") == 0) - break; - - /* get the char name and allocate space for it */ - namelen = strlen(tok); - my_charname[i] = (char *)MEM_mallocN(namelen+1, "my_charname"); - strcpy(my_charname[i],tok); - - /* get the number of bytes to read */ - fakegettoken(tok); - nread = atoi(tok); - fakegettoken(tok); - - /* read in the char description */ - my_charlen[i] = nread; - my_chars[i] = fakefread(nread); - - /* skip the end of line */ - fakegettoken(tok); - fakegettoken(tok); - my_nchars++; - } - - /* decrypt the character descriptions */ - decryptall(); - setcharlist(); - - /* make the obj font */ - makeobjfont(savesplines); - - if (bindat) MEM_freeN(bindat); - /* system("rm /usr/tmp/type1.dec"); */ - - return (fnt); -} - - - - -/* - * pc stack support - * - */ - -static void initpcstack(void) -{ - pcsp = 0; -} - -static void pushpc(char *pc) -{ - pcstack[pcsp] = pc; - pcsp++; -} - -static char *poppc(void) -{ - pcsp--; - if(pcsp<0) { - fprintf(stderr,"\nYUCK: pc stack under flow\n"); - pcsp = 0; - return 0; - } - return pcstack[pcsp]; -} - -/* - * Data stack support - * - */ - -static void initstack(void) -{ - sp = 0; -} - -static void push(int val) -/* int val; */ -{ - stack[sp] = val; - sp++; -} - -static int pop(void) -{ - sp--; - if(sp<0) { - fprintf(stderr,"\nYUCK: stack under flow\n"); - sp = 0; - return 0; - } - return stack[sp]; -} - -/* - * call/return data stack - * - */ - -static void initretstack(void) -{ - retsp = 0; -} - -static void retpush(int val) -/* int val; */ -{ - retstack[retsp] = val; - retsp++; -} - -static int retpop(void) -{ - retsp--; - if(retsp<0) { - fprintf(stderr,"\nYUCK: ret stack under flow\n"); - retsp = 0; - return 0; - } - return retstack[retsp]; -} - - -/* - * execute the program: - * - * - */ - -static void getmove(int *x, int *y) -{ - *x = delx; - *y = dely; - /* printf("ingetmove\n"); */ -} - -static void getpos(int *x, int *y) -{ - *x = curx; - *y = cury; -} - -static void subr1(void) -{ - coordpos = 0; - incusp = 1; -} - -static void subr2(void) -{ - int x, y; - - getmove(&x,&y); - if(coordpos>=7) { - fprintf(stderr,"subr2: bad poop\n"); - /*exit(1);*/ - } - coordsave[coordpos][0] = x; - coordsave[coordpos][1] = y; - coordpos++; -} - -static void subr0(void) -{ - int x0, y0; - int x1, y1; - int x2, y2; - int x3, y3; - int noise; - - pop(); /* xpos, unused */ - pop(); /* ypos, unused */ - noise = pop(); - if(coordpos!=7) { - fprintf(stderr,"subr0: bad poop\n"); - /*exit(1);*/ - } - x0 = coordsave[0][0]; - y0 = coordsave[0][1]; - - x1 = coordsave[1][0]+x0; - y1 = coordsave[1][1]+y0; - x2 = coordsave[2][0]; - y2 = coordsave[2][1]; - x3 = coordsave[3][0]; - y3 = coordsave[3][1]; - rcurveto(x1,y1,x1+x2,y1+y2,x1+x2+x3,y1+y2+y3); - x1 = coordsave[4][0]; - y1 = coordsave[4][1]; - x2 = coordsave[5][0]; - y2 = coordsave[5][1]; - x3 = coordsave[6][0]; - y3 = coordsave[6][1]; - rcurveto(x1,y1,x1+x2,y1+y2,x1+x2+x3,y1+y2+y3); - getpos(&x0,&y0); - retpush(y0); - retpush(x0); - incusp = 0; -} - -static void append_poly_offset(short ofsx, short ofsy, short * data) -{ - int nverts; - - if (data == 0) return; - - while(1) { - switch(chardata[nshorts++] = *data++) { - case PO_BGNLOOP: - nshorts --; /* for the first time */ - break; - case PO_RETENDLOOP: - case PO_RET: - return; - } - nverts = chardata[nshorts++] = *data++; - while(nverts--) { - chardata[nshorts++] = (*data++) + ofsx; - chardata[nshorts++] = (*data++) + ofsy; - } - } -} - - -static void append_spline_offset(short ofsx, short ofsy, short * data) -{ - int nverts = 0; - - if (data == 0) return; - - while(1) { - switch(chardata[nshorts++] = *data++) { - case SP_MOVETO: - case SP_LINETO: - nverts = 1; - break; - case SP_CURVETO: - nverts = 3; - break; - case SP_RETCLOSEPATH: - case SP_RET: - return; - } - - for (; nverts > 0; nverts--) { - chardata[nshorts++] = (*data++) + ofsx; - chardata[nshorts++] = (*data++) + ofsy; - } - } -} - - - -/* - * graphics follows - * - * - */ - - -/* poly output stuff */ - -static void setwidth(int w, int x) -{ - thecharwidth = w; - thesidebearing = x; -} - -static void poly_beginchar(void) -{ - npnts = 0; - nloops = 0; -} - -static void poly_endchar(void) -{ - if(nloops == 0) - chardata[nshorts++] = PO_RET; - else - chardata[nshorts++] = PO_RETENDLOOP; -} - -static void poly_close(void) -{ - chardata[nvertpos] = npnts; - npnts = 0; -} - -static void poly_pnt(float x, float y) -{ - int ix, iy; - - applymat(mat,&x,&y); - ix = floor(x); - iy = floor(y); - if(npnts == 0) { - if(nloops == 0) { - chardata[nshorts++] = PO_BGNLOOP; - nvertpos = nshorts++; - } else { - chardata[nshorts++] = PO_ENDBGNLOOP; - nvertpos = nshorts++; - } - nloops++; - } - chardata[nshorts++] = ix; - chardata[nshorts++] = iy; - npnts++; - -} - -/* spline output stuff */ - -static void spline_beginchar(void) -{ - sp_npnts = 0; - sp_nloops = 0; -} - -static void spline_endchar(void) -{ - if(sp_nloops == 0) - chardata[nshorts++] = SP_RET; - else - chardata[nshorts++] = SP_RETCLOSEPATH; -} - -static void spline_close(void) -{ - chardata[nshorts++] = SP_CLOSEPATH; - sp_npnts = 0; - sp_nloops = 0; -} - -static void spline_line(float x0, float y0, float x1, float y1) -{ - applymat(mat,&x0,&y0); - applymat(mat,&x1,&y1); - - if(sp_npnts == 0) { - chardata[nshorts++] = SP_MOVETO; - chardata[nshorts++] = floor(x0); - chardata[nshorts++] = floor(y0); - sp_npnts++; - sp_nloops++; - } - chardata[nshorts++] = SP_LINETO; - chardata[nshorts++] = floor(x1); - chardata[nshorts++] = floor(y1); - sp_npnts++; -} - -static void spline_curveto(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3) -{ - applymat(mat,&x0,&y0); - - applymat(mat,&x1,&y1); - applymat(mat,&x2,&y2); - applymat(mat,&x3,&y3); - if(sp_npnts == 0) { - chardata[nshorts++] = SP_MOVETO; - chardata[nshorts++] = floor(x0); - chardata[nshorts++] = floor(y0); - sp_npnts++; - sp_nloops++; - } - chardata[nshorts++] = SP_CURVETO; - chardata[nshorts++] = floor(x1); - chardata[nshorts++] = floor(y1); - chardata[nshorts++] = floor(x2); - chardata[nshorts++] = floor(y2); - chardata[nshorts++] = floor(x3); - chardata[nshorts++] = floor(y3); -} - -static void savestart(int x, int y) -{ - startx = x; - starty = y; - started = 1; -} - -static void sbpoint( int x, int y) -{ - curx = x; - cury = y; -} - -static void rmoveto( int x, int y) -{ - if(incusp) { - delx = x; - dely = y; - } else { - curx += x; - cury += y; - savestart(curx,cury); - } -} - -static void drawline(float x0, float y0, float x1, float y1, float dx0, float dy0, float dx1, float dy1) -{ - if(x0!=x1 || y0!=y1) - poly_pnt(x1,y1); -} - - -static void rlineto( int x, int y) -{ - float dx, dy; - - nextx = curx + x; - nexty = cury + y; - dx = nextx-curx; - dy = nexty-cury; - if (savesplines) spline_line( curx, cury, nextx, nexty); - else drawline( curx, cury, nextx, nexty,dx,dy,dx,dy); - curx = nextx; - cury = nexty; -} - -static void closepath(void) -{ - float dx, dy; - - if(started) { - dx = startx-curx; - dy = starty-cury; - if (savesplines) { - spline_close(); - } else { - drawline( curx, cury, startx, starty,dx,dy,dx,dy); - poly_close(); - } - started = 0; - } -} - -static void bezadapt( float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3, float beztol) -{ - float ax0,ay0,ax1,ay1,ax2,ay2,ax3,ay3; - float bx0,by0,bx1,by1,bx2,by2,bx3,by3; - float midx, midy; - float linx, liny, dx, dy, mag; - - midx = (x0+3*x1+3*x2+x3)/8.0; - midy = (y0+3*y1+3*y2+y3)/8.0; - linx = (x0+x3)/2.0; - liny = (y0+y3)/2.0; - dx = midx-linx; - dy = midy-liny; - mag = dx*dx+dy*dy; - if(mag<(beztol*beztol)) - drawline(x0,y0,x3,y3,x1-x0,y1-y0,x3-x2,y3-y2); - else { - ax0 = x0; - ay0 = y0; - ax1 = (x0+x1)/2; - ay1 = (y0+y1)/2; - ax2 = (x0+2*x1+x2)/4; - ay2 = (y0+2*y1+y2)/4; - ax3 = midx; - ay3 = midy; - bezadapt(ax0,ay0,ax1,ay1,ax2,ay2,ax3,ay3,beztol); - - bx0 = midx; - by0 = midy; - bx1 = (x1+2*x2+x3)/4; - by1 = (y1+2*y2+y3)/4; - bx2 = (x2+x3)/2; - by2 = (y2+y3)/2; - bx3 = x3; - by3 = y3; - bezadapt(bx0,by0,bx1,by1,bx2,by2,bx3,by3,beztol); - } -} - -static void drawbez( float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3) -{ - bezadapt(x0,y0,x1,y1,x2,y2,x3,y3,beztol); -} - - -static void rcurveto( int dx1, int dy1, int dx2, int dy2, int dx3, int dy3) -{ - int x0, y0; - int x1, y1; - int x2, y2; - int x3, y3; - - x0 = curx; - y0 = cury; - x1 = curx+dx1; - y1 = cury+dy1; - x2 = curx+dx2; - y2 = cury+dy2; - x3 = curx+dx3; - y3 = cury+dy3; - - if (savesplines) { - spline_curveto( x0, y0, x1, y1, x2, y2, x3, y3); - } else{ - drawbez( x0, y0, x1, y1, x2, y2, x3, y3); - } - curx = x3; - cury = y3; -} - -/* - * saveobjfont - - * save an object font. - * - */ - -/* generic routines */ - -static void makeobjfont(int savesplines) -{ - int i, c; - - if(savesplines) - fnt = newobjfnt(SP_TYPE, 32, 32+NASCII-1, 9840); - else - fnt = newobjfnt(PO_TYPE, 32, 32+NASCII-1, 9840); - - for(i=0; i<NASCII; i++) { - c = i+32; - if(ISOcharlist[i].prog>=0) { - /*printf("decoding %s\n", ISOcharlist[i].name);*/ - - nshorts = 0; - drawchar(ISOcharlist[i].prog); - addchardata(fnt,c,chardata,nshorts); - addcharmetrics(fnt,c,thecharwidth,0); - sidebearing[c] = thesidebearing; - } else if(c == ' ') { - printf("faking space %d\n",i); - fakechar(fnt,' ',400); - } - } -} - -/* - * run the character program - * - * - */ - -static void drawchar(int c) -{ - if (savesplines) { - spline_beginchar(); - } else { - poly_beginchar(); - } - initstack(); - initpcstack(); - initretstack(); - pc = my_chars[c]; - runprog(); - if (savesplines){ - spline_endchar(); - } else { - poly_endchar(); - } -} - -static int docommand(int cmd) -{ - int x, y, w, c1, c2; - int dx1, dy1; - int dx2, dy2; - int dx3, dy3; - float fdx1, fdy1; - int i, sub, n; - char *subpc; - chardesc *cd; - short *ndata; - - switch(cmd) { - case WHAT0: - fprintf(stderr,"\nYUCK: WHAT0\n"); - break; - case HSTEM: - pop(); - pop(); - /*printf("hstem: %d %d\n", pop(), pop());*/ - break; - case VSTEM: - pop(); - pop(); - /*printf("vstem: %d %d\n", pop(), pop());*/ - break; - case VMOVETO: - y = pop(); - rmoveto(0,y); - break; - case RLINETO: - y = pop(); - x = pop(); - rlineto(x,y); - break; - case HLINETO: - x = pop(); - rlineto(x,0); - break; - case VLINETO: - y = pop(); - rlineto(0,y); - break; - case RRCURVETO: - dy3 = pop(); - dx3 = pop(); - dy2 = pop(); - dx2 = pop(); - dy1 = pop(); - dx1 = pop(); - rcurveto(dx1,dy1,dx1+dx2,dy1+dy2,dx1+dx2+dx3,dy1+dy2+dy3); - break; - case CLOSEPATH: - closepath(); - break; - case CALLSUBR: - sub = pop(); - subpc = my_subrs[sub]; - if(!subpc) { - fprintf(stderr,"\nYUCK no sub addr\n"); - } - pushpc(pc); - pc = subpc; - break; - case RETURN: - pc = poppc(); - break; - case HSBW: - w = pop(); - x = pop(); - setwidth(w, x); - sbpoint(x,0); - break; - case ENDCHAR: - closepath(); - break; - case RMOVETO: - y = pop(); - x = pop(); - rmoveto(x,y); - break; - case HMOVETO: - x = pop(); - rmoveto(x,0); - break; - case VHCURVETO: - dy3 = 0; - dx3 = pop(); - dy2 = pop(); - dx2 = pop(); - dy1 = pop(); - dx1 = 0; - rcurveto(dx1,dy1,dx1+dx2,dy1+dy2,dx1+dx2+dx3,dy1+dy2+dy3); - break; - case HVCURVETO: - dy3 = pop(); - dx3 = 0; - dy2 = pop(); - dx2 = pop(); - dy1 = 0; - dx1 = pop(); - rcurveto(dx1,dy1,dx1+dx2,dy1+dy2,dx1+dx2+dx3,dy1+dy2+dy3); - break; - case DOTSECTION: - break; - case VSTEM3: - /*printf("vstem3\n");*/ - pop(); - pop(); - pop(); - pop(); - pop(); - pop(); - break; - case HSTEM3: - /*printf("hstem3\n");*/ - pop(); - pop(); - pop(); - pop(); - pop(); - pop(); - break; - case SEAC: - if (0) { - printf("seac: %3d %3d %3d %3d %3d\n", pop(), pop(), pop(), pop(), pop()); - } else{ - c2 = STDtoISO(pop()); /* accent */ - c1 = STDtoISO(pop()); /* letter */ - - cd = getchardesc(fnt, c1); - if (cd) { - memcpy(chardata, cd->data, cd->datalen); - nshorts = cd->datalen / sizeof(short); - } - - cd = getchardesc(fnt, c2); - if (cd && cd->data && cd->datalen) { - ndata = cd->data; - - if (nshorts) { - if (savesplines) { - switch (chardata[nshorts - 1]){ - case SP_RET: - nshorts--; - break; - case SP_RETCLOSEPATH: - chardata[nshorts - 1] = SP_CLOSEPATH; - break; - } - } else { - switch (chardata[nshorts - 1]){ - case PO_RET: - printf("PO_RET in character disription ?\n"); - nshorts--; - break; - case PO_RETENDLOOP: - if (ndata[0] == PO_BGNLOOP) { - chardata[nshorts - 1] = PO_ENDBGNLOOP; - } else { - printf("new character doesn't start with PO_BGNLOOP ?\n"); - } - break; - } - } - } - - /* instead of the sidebearing[c1] maybe thesidebearing should be used */ - - dy1 = pop(); - dx1 = pop() + sidebearing[c1] - sidebearing[c2]; - pop(); - - fdx1 = dx1; - fdy1 = dy1; - applymat(mat, &fdx1, &fdy1); - dx1 = floor(fdx1); - dy1 = floor(fdy1); - - if (savesplines) { - append_spline_offset(dx1, dy1, ndata); - } else{ - append_poly_offset(dx1, dy1, ndata); - } - - /*printf("first: %d %d\n", cd->data[0], cd->data[1]);*/ - } - fflush(stdout); - } - break; - case SBW: - w = pop(); - y = pop(); - fprintf(stderr,"sbw: width: %d %d\n",w,y); - y = pop(); - x = pop(); - fprintf(stderr,"sbw: side: %d %d\n",x,y); - setwidth(w, x); - sbpoint(x,y); - break; - case DIV: - x = pop(); - y = pop(); - push(x/y); - break; - case CALLOTHERSUBR: - sub = pop(); - n = pop(); - if(sub == 0) - subr0(); - else if(sub == 1) - subr1(); - else if(sub == 2) - subr2(); - else { - for(i=0; i<n; i++) { - retpush(pop()); - } - } - break; - case POP: - push(retpop()); - break; - case SETCURRENTPOINT: - y = pop(); - x = pop(); - sbpoint(x,y); - break; - default: - /*fprintf(stderr,"\nYUCK bad instruction %d\n",cmd);*/ - break; - } - if(pc == 0 || cmd == ENDCHAR || cmd == WHAT0 || cmd == SEAC) - return 0; - else - return 1; -} - - -/* - * Character interpreter - * - */ - -static void runprog(void) -{ - int v, w, num, cmd; - - while(1) { - v = *pc++; - if(v>=0 && v<=31) { - if(v == 12) { - w = *pc++; - cmd = 256+w; - } else - cmd = v; - if(!docommand(cmd)) { - return; - } - } else if(v>=32 && v<=246) { - num = v-139; - push(num); - } else if(v>=247 && v<=250) { - w = *pc++; - num = (v-247)*256+w+108; - push(num); - } else if(v>=251 && v<=254) { - w = *pc++; - num = -(v-251)*256-w-108; - push(num); - } else if(v == 255) { - num = *pc++; - num <<= 8; - num |= *pc++; - num <<= 8; - num |= *pc++; - num <<= 8; - num |= *pc++; - push(num); - } - } -} - -/***/ - -static VFontData *objfnt_to_vfontdata(objfnt *fnt) -{ - VFontData *vfd; - chardesc *cd; - short *_data, *data; - int a, i, count, stop, ready, meet; - short first[2]={0,0}, last[2]={0,0}; - struct Nurb *nu; - struct BezTriple *bezt, *bez2; - float scale, dx, dy; - struct VChar *che; - - if (!fnt || (fnt->type!=SP_TYPE)) { - return NULL; - } - - vfd= MEM_callocN(sizeof(*vfd), "VFontData"); - scale = 10.0/(float)fnt->scale; /* after IRIX 6.2, scaling went wrong */ - - for (i = 0; i < MAX_VF_CHARS; i++) { - cd = getchardesc(fnt, i); - if (cd && cd->data && cd->datalen) { - che = (VChar *) MEM_callocN(sizeof(VChar), "objfnt_char"); - BLI_addtail(&vfd->characters, che); - che->index = i; - che->width = scale * cd->movex; - - _data = data = cd->data; - - do{ - /* count first */ - _data = data; - count = 0; - ready = stop = 0; - - do{ - switch(*data++){ - case SP_MOVETO: - first[0] = data[0]; - first[1] = data[1]; - case SP_LINETO: - count++; - last[0] = data[0]; - last[1] = data[1]; - data += 2; - break; - case SP_CURVETO: - count++; - last[0] = data[4]; - last[1] = data[5]; - data += 6; - break; - case SP_RET: - case SP_RETCLOSEPATH: - stop = 1; - ready = 1; - break; - case SP_CLOSEPATH: - stop = 1; - break; - } - } while (!stop); - - if ((count>0) && last[0] == first[0] && last[1] == first[1]) meet = 1; - else meet = 0; - - /* is there more than 1 unique point ?*/ - - if (count - meet > 0) { - data = _data; - nu = (Nurb*)MEM_callocN(sizeof(struct Nurb),"objfnt_nurb"); - bezt = (BezTriple*)MEM_callocN((count)* sizeof(BezTriple),"objfnt_bezt") ; - if (nu != 0 && bezt != 0) { - BLI_addtail(&che->nurbsbase, nu); - nu->type= CU_BEZIER+CU_2D; - nu->pntsu = count; - nu->resolu= 8; - nu->flagu= CU_CYCLIC; - nu->bezt = bezt; - stop = 0; - - /* read points */ - do { - switch(*data++){ - case SP_MOVETO: - bezt->vec[1][0] = scale * *data++; - bezt->vec[1][1] = scale * *data++; - - break; - case SP_LINETO: - bez2 = bezt++; - bezt->vec[1][0] = scale * *data++; - bezt->vec[1][1] = scale * *data++; - /* vector handles */ - bezt->h1= HD_VECT; - bez2->h2= HD_VECT; - dx = (bezt->vec[1][0] - bez2->vec[1][0]) / 3.0; - dy = (bezt->vec[1][1] - bez2->vec[1][1]) / 3.0; - bezt->vec[0][0] = bezt->vec[1][0] - dx; - bezt->vec[0][1] = bezt->vec[1][1] - dy; - bez2->vec[2][0] = bez2->vec[1][0] + dx; - bez2->vec[2][1] = bez2->vec[1][1] + dy; - break; - - case SP_CURVETO: - bezt->vec[2][0] = scale * *data++; - bezt->vec[2][1] = scale * *data++; - bezt->h2= HD_ALIGN; - bezt++; - bezt->vec[0][0] = scale * *data++; - bezt->vec[0][1] = scale * *data++; - bezt->vec[1][0] = scale * *data++; - bezt->vec[1][1] = scale * *data++; - bezt->h1= HD_ALIGN; - break; - - case SP_RET: - case SP_RETCLOSEPATH: - stop = 1; - ready = 1; - break; - case SP_CLOSEPATH: - stop = 1; - break; - } - } while (stop == 0); - - if (meet) { - /* copy handles */ - nu->bezt->vec[0][0] = bezt->vec[0][0]; - nu->bezt->vec[0][1] = bezt->vec[0][1]; - /* and forget last point */ - nu->pntsu--; - } - else { - /* vector handles */ - bez2 = nu->bezt; - dx = (bezt->vec[1][0] - bez2->vec[1][0]) / 3.0; - dy = (bezt->vec[1][1] - bez2->vec[1][1]) / 3.0; - bezt->vec[2][0] = bezt->vec[1][0] - dx; - bezt->vec[2][1] = bezt->vec[1][1] - dy; - bez2->vec[0][0] = bez2->vec[1][0] + dx; - bez2->vec[0][1] = bez2->vec[1][1] + dy; - bezt->h2= bez2->h1= HD_VECT; - } - - /* forbidden handle combinations */ - a= nu->pntsu; - bezt= nu->bezt; - while(a--) { - if(bezt->h1!=HD_ALIGN && bezt->h2==HD_ALIGN) bezt->h2= 0; - else if(bezt->h2!=HD_ALIGN && bezt->h1==HD_ALIGN) bezt->h1= 0; - bezt->radius= 1.0f; - bezt++; - } - - } - else { - if (nu) MEM_freeN(nu); - if (bezt) MEM_freeN(bezt); - } - } - _data = data; - } while (ready == 0); - } - } - - return vfd; -} - -VFontData *BLI_vfontdata_from_psfont(PackedFile *pf) -{ - objfnt *fnt= objfnt_from_psfont(pf); - VFontData *vfd= NULL; - - if (fnt) { - vfd= objfnt_to_vfontdata(fnt); - freeobjfnt(fnt); - } - - return vfd; -} diff --git a/source/blender/blenlib/intern/rct.c b/source/blender/blenlib/intern/rct.c index 0dc61db2342..915a93e8e0b 100644 --- a/source/blender/blenlib/intern/rct.c +++ b/source/blender/blenlib/intern/rct.c @@ -70,7 +70,16 @@ int BLI_in_rctf(rctf *rect, float x, float y) void BLI_union_rctf(rctf *rct1, rctf *rct2) { + + if(rct1->xmin>rct2->xmin) rct1->xmin= rct2->xmin; + if(rct1->xmax<rct2->xmax) rct1->xmax= rct2->xmax; + if(rct1->ymin>rct2->ymin) rct1->ymin= rct2->ymin; + if(rct1->ymax<rct2->ymax) rct1->ymax= rct2->ymax; +} +void BLI_union_rcti(rcti *rct1, rcti *rct2) +{ + if(rct1->xmin>rct2->xmin) rct1->xmin= rct2->xmin; if(rct1->xmax<rct2->xmax) rct1->xmax= rct2->xmax; if(rct1->ymin>rct2->ymin) rct1->ymin= rct2->ymin; @@ -79,17 +88,42 @@ void BLI_union_rctf(rctf *rct1, rctf *rct2) void BLI_init_rctf(rctf *rect, float xmin, float xmax, float ymin, float ymax) { - rect->xmin= xmin; - rect->xmax= xmax; - rect->ymin= ymin; - rect->ymax= ymax; + if(xmin <= xmax) { + rect->xmin= xmin; + rect->xmax= xmax; + } + else { + rect->xmax= xmin; + rect->xmin= xmax; + } + if(ymin <= ymax) { + rect->ymin= ymin; + rect->ymax= ymax; + } + else { + rect->ymax= ymin; + rect->ymin= ymax; + } } + void BLI_init_rcti(rcti *rect, int xmin, int xmax, int ymin, int ymax) { - rect->xmin= xmin; - rect->xmax= xmax; - rect->ymin= ymin; - rect->ymax= ymax; + if(xmin <= xmax) { + rect->xmin= xmin; + rect->xmax= xmax; + } + else { + rect->xmax= xmin; + rect->xmin= xmax; + } + if(ymin <= ymax) { + rect->ymin= ymin; + rect->ymax= ymax; + } + else { + rect->ymax= ymin; + rect->ymin= ymax; + } } void BLI_translate_rcti(rcti *rect, int x, int y) diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c index 8ba03ad1343..0a416e624cb 100644 --- a/source/blender/blenlib/intern/storage.c +++ b/source/blender/blenlib/intern/storage.c @@ -62,13 +62,6 @@ #include <sys/vfs.h> #endif -#ifdef __BeOS -struct statfs { - int f_bsize; - int f_bfree; -}; -#endif - #ifdef __APPLE__ /* For statfs */ #include <sys/param.h> @@ -77,7 +70,7 @@ struct statfs { #include <fcntl.h> -#if !defined(__BeOS) && !defined(WIN32) +#if !defined(WIN32) #include <sys/mtio.h> /* tape comando's */ #endif #include <string.h> /* strcpy etc.. */ @@ -152,8 +145,9 @@ int BLI_compare(struct direntry *entry1, struct direntry *entry2) if( strcmp(entry1->relname, ".")==0 ) return (-1); if( strcmp(entry2->relname, ".")==0 ) return (1); if( strcmp(entry1->relname, "..")==0 ) return (-1); - - return (BLI_strcasecmp(entry1->relname,entry2->relname)); + if( strcmp(entry2->relname, "..")==0 ) return (1); + + return (BLI_natstrcmp(entry1->relname,entry2->relname)); } @@ -200,9 +194,6 @@ double BLI_diskfree(char *dir) #if defined (__FreeBSD__) || defined (linux) || defined (__OpenBSD__) || defined (__APPLE__) if (statfs(name, &disk)) return(-1); #endif -#ifdef __BeOS - return -1; -#endif #if defined (__sun__) || defined (__sun) || defined (__sgi) if (statvfs(name, &disk)) return(-1); @@ -227,7 +218,7 @@ void BLI_builddir(char *dirname, char *relname) { struct dirent *fname; struct dirlink *dlink; - int rellen, newnum = 0, seen_ = 0, seen__ = 0; + int rellen, newnum = 0, len; char buf[256]; DIR *dir; @@ -246,22 +237,16 @@ void BLI_builddir(char *dirname, char *relname) if ( (dir = (DIR *)opendir(".")) ){ 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); + 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); - - if (dlink->name[0] == '.') { - if (dlink->name[1] == 0) seen_ = 1; - else if (dlink->name[1] == '.') { - if (dlink->name[2] == 0) seen__ = 1; - } - } BLI_addhead(dirbase,dlink); newnum++; } @@ -269,30 +254,6 @@ void BLI_builddir(char *dirname, char *relname) } if (newnum){ -#ifndef WIN32 - if (seen_ == 0) { /* Cachefs PATCH */ - dlink = (struct dirlink *)malloc(sizeof(struct dirlink)); - strcpy(buf+rellen,"./."); - dlink->name = BLI_strdup(buf); - BLI_addhead(dirbase,dlink); - newnum++; - } - if (seen__ == 0) { /* MAC PATCH */ - dlink = (struct dirlink *)malloc(sizeof(struct dirlink)); - strcpy(buf+rellen,"./.."); - dlink->name = BLI_strdup(buf); - BLI_addhead(dirbase,dlink); - newnum++; - } -#else // WIN32 - if (seen_ == 0) { /* should only happen for root paths like "C:\" */ - dlink = (struct dirlink *)malloc(sizeof(struct dirlink)); - strcpy(buf+rellen,"."); - dlink->name = BLI_strdup(buf); - BLI_addhead(dirbase,dlink); - newnum++; - } -#endif if (files) files=(struct direntry *)realloc(files,(totnum+newnum) * sizeof(struct direntry)); else files=(struct direntry *)malloc(newnum * sizeof(struct direntry)); @@ -302,7 +263,13 @@ void BLI_builddir(char *dirname, char *relname) while(dlink){ memset(&files[actnum], 0 , sizeof(struct direntry)); files[actnum].relname = dlink->name; +// use 64 bit file size, only needed for WIN32 and WIN64. +// Excluding other than current MSVC compiler until able to test. +#if (defined(WIN32) || defined(WIN64)) && (_MSC_VER>=1500) + _stat64(dlink->name,&files[actnum].s); +#else stat(dlink->name,&files[actnum].s); +#endif files[actnum].type=files[actnum].s.st_mode; files[actnum].flags = 0; totnum++; @@ -329,11 +296,10 @@ void BLI_builddir(char *dirname, char *relname) void BLI_adddirstrings() { char datum[100]; - char buf[250]; + char buf[512]; char size[250]; static char * types[8] = {"---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx"}; int num, mode; - off_t num1, num2, num3, num4, num5; #ifdef WIN32 __int64 st_size; #else @@ -399,25 +365,20 @@ void BLI_adddirstrings() * will buy us some time until files get bigger than 4GB or until * everyone starts using __USE_FILE_OFFSET64 or equivalent. */ - st_size= (off_t)files[num].s.st_size; - - num1= st_size % 1000; - num2= st_size/1000; - num2= num2 % 1000; - num3= st_size/(1000*1000); - num3= num3 % 1000; - num4= st_size/(1000*1000*1000); - num4= num4 % 1000; - num5= st_size/(1000000000000LL); - num5= num5 % 1000; - - if(num5) - sprintf(files[num].size, "%1d %03d %03d %03d K", (int)num5, (int)num4, (int)num3, (int)num2); - else if(num4) sprintf(files[num].size, "%3d %03d %03d %03d", (int)num4, (int)num3, (int)num2, (int)num1); - else if(num3) sprintf(files[num].size, "%7d %03d %03d", (int)num3, (int)num2, (int)num1); - else if(num2) sprintf(files[num].size, "%11d %03d", (int)num2, (int)num1); - else if(num1) sprintf(files[num].size, "%15d", (int)num1); - else sprintf(files[num].size, "0"); + st_size= files[num].s.st_size; + + if (st_size > 1024*1024*1024) { + sprintf(files[num].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)); + } + else if (st_size > 1024) { + sprintf(files[num].size, "%d KB", (int)(st_size/1024)); + } + else { + sprintf(files[num].size, "%d B", (int)st_size); + } strftime(datum, 32, "%d-%b-%y %H:%M", tm); @@ -432,9 +393,6 @@ void BLI_adddirstrings() sprintf(size, "%10d", (int) st_size); } - sprintf(buf,"%s %s %10s %s", 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, files[num].owner, files[num].date, files[num].time, size, files[num].relname); diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c new file mode 100644 index 00000000000..4cd04aa232c --- /dev/null +++ b/source/blender/blenlib/intern/string.c @@ -0,0 +1,236 @@ +/* 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., 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: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + * + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <stdarg.h> +#include <ctype.h> + +#include "MEM_guardedalloc.h" + +#include "BLI_dynstr.h" +#include "BLI_string.h" + +char *BLI_strdupn(const char *str, int len) { + char *n= MEM_mallocN(len+1, "strdup"); + memcpy(n, str, len); + n[len]= '\0'; + + return n; +} +char *BLI_strdup(const char *str) { + return BLI_strdupn(str, strlen(str)); +} + +char *BLI_strncpy(char *dst, const char *src, int maxncpy) { + int srclen= strlen(src); + int cpylen= (srclen>(maxncpy-1))?(maxncpy-1):srclen; + + memcpy(dst, src, cpylen); + dst[cpylen]= '\0'; + + return dst; +} + +int BLI_snprintf(char *buffer, size_t count, const char *format, ...) +{ + int n; + va_list arg; + + va_start(arg, format); + n = vsnprintf(buffer, count, format, arg); + + if (n != -1 && n < count) { + buffer[n] = '\0'; + } else { + buffer[count-1] = '\0'; + } + + va_end(arg); + return n; +} + +char *BLI_sprintfN(const char *format, ...) +{ + DynStr *ds; + va_list arg; + char *n; + + va_start(arg, format); + + ds= BLI_dynstr_new(); + BLI_dynstr_vappendf(ds, format, arg); + n= BLI_dynstr_get_cstring(ds); + BLI_dynstr_free(ds); + + va_end(arg); + + return n; +} + +int BLI_streq(const char *a, const char *b) +{ + return (strcmp(a, b)==0); +} + +int BLI_strcaseeq(const char *a, const char *b) +{ + return (BLI_strcasecmp(a, b)==0); +} + +/* strcasestr not available in MSVC */ +char *BLI_strcasestr(const char *s, const char *find) +{ + register char c, sc; + register size_t len; + + if ((c = *find++) != 0) { + c= tolower(c); + len = strlen(find); + do { + do { + if ((sc = *s++) == 0) + return (NULL); + sc= tolower(sc); + } while (sc != c); + } while (BLI_strncasecmp(s, find, len) != 0); + s--; + } + return ((char *) s); +} + + +int BLI_strcasecmp(const char *s1, const char *s2) { + int i; + + for (i=0; ; i++) { + char c1 = tolower(s1[i]); + char c2 = tolower(s2[i]); + + if (c1<c2) { + return -1; + } else if (c1>c2) { + return 1; + } else if (c1==0) { + break; + } + } + + return 0; +} + +int BLI_strncasecmp(const char *s1, const char *s2, int n) { + int i; + + for (i=0; i<n; i++) { + char c1 = tolower(s1[i]); + char c2 = tolower(s2[i]); + + if (c1<c2) { + return -1; + } else if (c1>c2) { + return 1; + } else if (c1==0) { + break; + } + } + + return 0; +} + +/* natural string compare, keeping numbers in order */ +int BLI_natstrcmp(const char *s1, const char *s2) +{ + int d1= 0, d2= 0; + + /* if both chars are numeric, to a strtol(). + then increase string deltas as long they are + numeric, else do a tolower and char compare */ + + while(1) { + char c1 = tolower(s1[d1]); + char c2 = tolower(s2[d2]); + + if( isdigit(c1) && isdigit(c2) ) { + int val1, val2; + + val1= (int)strtol(s1+d1, (char **)NULL, 10); + val2= (int)strtol(s2+d2, (char **)NULL, 10); + + if (val1<val2) { + return -1; + } else if (val1>val2) { + return 1; + } + d1++; + while( isdigit(s1[d1]) ) + d1++; + d2++; + while( isdigit(s2[d2]) ) + d2++; + + c1 = tolower(s1[d1]); + c2 = tolower(s2[d2]); + } + + if (c1<c2) { + return -1; + } else if (c1>c2) { + return 1; + } else if (c1==0) { + break; + } + d1++; + d2++; + } + return 0; +} + +void BLI_timestr(double _time, char *str) +{ + /* format 00:00:00.00 (hr:min:sec) string has to be 12 long */ + int hr= ( (int) _time) / (60*60); + int min= (((int) _time) / 60 ) % 60; + int sec= ( (int) (_time)) % 60; + int hun= ( (int) (_time * 100.0)) % 100; + + if (hr) { + sprintf(str, "%.2d:%.2d:%.2d.%.2d",hr,min,sec,hun); + } else { + sprintf(str, "%.2d:%.2d.%.2d",min,sec,hun); + } + + str[11]=0; +} diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c index 07c02b8024f..2812f17d58f 100644 --- a/source/blender/blenlib/intern/threads.c +++ b/source/blender/blenlib/intern/threads.c @@ -35,6 +35,8 @@ #include "MEM_guardedalloc.h" +#include "DNA_listBase.h" + #include "BLI_blenlib.h" #include "BLI_threads.h" @@ -110,12 +112,12 @@ typedef struct ThreadSlot { int avail; } ThreadSlot; -static void BLI_lock_malloc_thread(void) +void BLI_lock_malloc_thread(void) { pthread_mutex_lock(&_malloc_lock); } -static void BLI_unlock_malloc_thread(void) +void BLI_unlock_malloc_thread(void) { pthread_mutex_unlock(&_malloc_lock); } diff --git a/source/blender/blenlib/intern/util.c b/source/blender/blenlib/intern/util.c index 013b9e0bb1b..3c441a81d6b 100644 --- a/source/blender/blenlib/intern/util.c +++ b/source/blender/blenlib/intern/util.c @@ -102,23 +102,6 @@ static int add_win32_extension(char *name); /* implementation */ -/* Ripped this from blender.c */ -void addlisttolist(ListBase *list1, ListBase *list2) -{ - if (list2->first==0) return; - - if (list1->first==0) { - list1->first= list2->first; - list1->last= list2->last; - } - else { - ((Link *)list1->last)->next= list2->first; - ((Link *)list2->first)->prev= list1->last; - list1->last= list2->last; - } - list2->first= list2->last= 0; -} - int BLI_stringdec(char *string, char *kop, char *start, unsigned short *numlen) { unsigned short len, len2, nums = 0, nume = 0; @@ -241,8 +224,9 @@ void BLI_newname(char *name, int add) * name_offs: should be calculated using offsetof(structname, membername) macro from stddef.h * len: maximum length of string (to prevent overflows, etc.) * defname: the name that should be used by default if none is specified already + * delim: the character which acts as a delimeter between parts of the name */ -void BLI_uniquename(ListBase *list, void *vlink, char defname[], short name_offs, short len) +void BLI_uniquename(ListBase *list, void *vlink, char defname[], char delim, short name_offs, short len) { Link *link; char tempname[128]; @@ -278,12 +262,12 @@ void BLI_uniquename(ListBase *list, void *vlink, char defname[], short name_offs return; /* Strip off the suffix */ - dot = strchr(GIVE_STRADDR(vlink, name_offs), '.'); + dot = strchr(GIVE_STRADDR(vlink, name_offs), delim); if (dot) *dot=0; for (number = 1; number <= 999; number++) { - BLI_snprintf(tempname, 128, "%s.%03d", GIVE_STRADDR(vlink, name_offs), number); + BLI_snprintf(tempname, 128, "%s%c%03d", GIVE_STRADDR(vlink, name_offs), delim, number); exists = 0; for (link= list->first; link; link= link->next) { @@ -301,557 +285,6 @@ void BLI_uniquename(ListBase *list, void *vlink, char defname[], short name_offs } } - -void BLI_addhead(ListBase *listbase, void *vlink) -{ - Link *link= vlink; - - if (link == NULL) return; - if (listbase == NULL) return; - - link->next = listbase->first; - link->prev = NULL; - - if (listbase->first) ((Link *)listbase->first)->prev = link; - if (listbase->last == NULL) listbase->last = link; - listbase->first = link; -} - - -void BLI_addtail(ListBase *listbase, void *vlink) -{ - Link *link= vlink; - - if (link == NULL) return; - if (listbase == NULL) return; - - link->next = NULL; - link->prev = listbase->last; - - if (listbase->last) ((Link *)listbase->last)->next = link; - if (listbase->first == 0) listbase->first = link; - listbase->last = link; -} - - -void BLI_remlink(ListBase *listbase, void *vlink) -{ - Link *link= vlink; - - if (link == NULL) return; - if (listbase == NULL) return; - - if (link->next) link->next->prev = link->prev; - if (link->prev) link->prev->next = link->next; - - if (listbase->last == link) listbase->last = link->prev; - if (listbase->first == link) listbase->first = link->next; -} - - -void BLI_freelinkN(ListBase *listbase, void *vlink) -{ - Link *link= vlink; - - if (link == NULL) return; - if (listbase == NULL) return; - - BLI_remlink(listbase,link); - MEM_freeN(link); -} - - -void BLI_insertlink(ListBase *listbase, void *vprevlink, void *vnewlink) -{ - Link *prevlink= vprevlink; - Link *newlink= vnewlink; - - /* newlink comes after prevlink */ - if (newlink == NULL) return; - if (listbase == NULL) return; - - /* empty list */ - if (listbase->first == NULL) { - - listbase->first= newlink; - listbase->last= newlink; - return; - } - - /* insert before first element */ - if (prevlink == NULL) { - newlink->next= listbase->first; - newlink->prev= 0; - newlink->next->prev= newlink; - listbase->first= newlink; - return; - } - - /* at end of list */ - if (listbase->last== prevlink) - listbase->last = newlink; - - newlink->next= prevlink->next; - prevlink->next= newlink; - if (newlink->next) newlink->next->prev= newlink; - newlink->prev= prevlink; -} - -/* This uses insertion sort, so NOT ok for large list */ -void BLI_sortlist(ListBase *listbase, int (*cmp)(void *, void *)) -{ - Link *current = NULL; - Link *previous = NULL; - Link *next = NULL; - - if (cmp == NULL) return; - if (listbase == NULL) return; - - if (listbase->first != listbase->last) - { - for( previous = listbase->first, current = previous->next; current; current = next ) - { - next = current->next; - previous = current->prev; - - BLI_remlink(listbase, current); - - while(previous && cmp(previous, current) == 1) - { - previous = previous->prev; - } - - BLI_insertlinkafter(listbase, previous, current); - } - } -} - -void BLI_insertlinkafter(ListBase *listbase, void *vprevlink, void *vnewlink) -{ - Link *prevlink= vprevlink; - Link *newlink= vnewlink; - - /* newlink before nextlink */ - if (newlink == NULL) return; - if (listbase == NULL) return; - - /* empty list */ - if (listbase->first == NULL) { - listbase->first= newlink; - listbase->last= newlink; - return; - } - - /* insert at head of list */ - if (prevlink == NULL) { - newlink->prev = NULL; - newlink->next = listbase->first; - ((Link *)listbase->first)->prev = newlink; - listbase->first = newlink; - return; - } - - /* at end of list */ - if (listbase->last == prevlink) - listbase->last = newlink; - - newlink->next = prevlink->next; - newlink->prev = prevlink; - prevlink->next = newlink; - if (newlink->next) newlink->next->prev = newlink; -} - -void BLI_insertlinkbefore(ListBase *listbase, void *vnextlink, void *vnewlink) -{ - Link *nextlink= vnextlink; - Link *newlink= vnewlink; - - /* newlink before nextlink */ - if (newlink == NULL) return; - if (listbase == NULL) return; - - /* empty list */ - if (listbase->first == NULL) { - listbase->first= newlink; - listbase->last= newlink; - return; - } - - /* insert at end of list */ - if (nextlink == NULL) { - newlink->prev= listbase->last; - newlink->next= 0; - ((Link *)listbase->last)->next= newlink; - listbase->last= newlink; - return; - } - - /* at beginning of list */ - if (listbase->first== nextlink) - listbase->first = newlink; - - newlink->next= nextlink; - newlink->prev= nextlink->prev; - nextlink->prev= newlink; - if (newlink->prev) newlink->prev->next= newlink; -} - - -void BLI_freelist(ListBase *listbase) -{ - Link *link, *next; - - if (listbase == NULL) - return; - - link= listbase->first; - while (link) { - next= link->next; - free(link); - link= next; - } - - listbase->first= NULL; - listbase->last= NULL; -} - -void BLI_freelistN(ListBase *listbase) -{ - Link *link, *next; - - if (listbase == NULL) return; - - link= listbase->first; - while (link) { - next= link->next; - MEM_freeN(link); - link= next; - } - - listbase->first= NULL; - listbase->last= NULL; -} - - -int BLI_countlist(ListBase *listbase) -{ - Link *link; - int count = 0; - - if (listbase) { - link = listbase->first; - while (link) { - count++; - link= link->next; - } - } - return count; -} - -void *BLI_findlink(ListBase *listbase, int number) -{ - Link *link = NULL; - - if (number >= 0) { - link = listbase->first; - while (link != NULL && number != 0) { - number--; - link = link->next; - } - } - - return link; -} - -int BLI_findindex(ListBase *listbase, void *vlink) -{ - Link *link= NULL; - int number= 0; - - if (listbase == NULL) return -1; - if (vlink == NULL) return -1; - - link= listbase->first; - while (link) { - if (link == vlink) - return number; - - number++; - link= link->next; - } - - return -1; -} - -/*=====================================================================================*/ -/* 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)); -} - -/*=====================================================================================*/ - -char *BLI_strdupn(const char *str, int len) { - char *n= MEM_mallocN(len+1, "strdup"); - memcpy(n, str, len); - n[len]= '\0'; - - return n; -} -char *BLI_strdup(const char *str) { - return BLI_strdupn(str, strlen(str)); -} - -char *BLI_strncpy(char *dst, const char *src, int maxncpy) { - int srclen= strlen(src); - int cpylen= (srclen>(maxncpy-1))?(maxncpy-1):srclen; - - memcpy(dst, src, cpylen); - dst[cpylen]= '\0'; - - return dst; -} - -int BLI_snprintf(char *buffer, size_t count, const char *format, ...) -{ - int n; - va_list arg; - - va_start(arg, format); - n = vsnprintf(buffer, count, format, arg); - - if (n != -1 && n < count) { - buffer[n] = '\0'; - } else { - buffer[count-1] = '\0'; - } - - va_end(arg); - return n; -} - -int BLI_streq(char *a, char *b) { - return (strcmp(a, b)==0); -} -int BLI_strcaseeq(char *a, char *b) { - return (BLI_strcasecmp(a, b)==0); -} - /* ******************** string encoding ***************** */ /* This is quite an ugly function... its purpose is to @@ -1061,6 +494,21 @@ void BLI_makestringcode(const char *relfile, char *file) } } +int BLI_has_parent(char *path) +{ + int len; + int slashes = 0; + BLI_clean(path); + len = BLI_add_slash(path) - 1; + + while (len>=0) { + if ((path[len] == '\\') || (path[len] == '/')) + slashes++; + len--; + } + return slashes > 1; +} + int BLI_parent_dir(char *path) { #ifdef WIN32 @@ -1303,11 +751,27 @@ void BLI_splitdirstring(char *di, char *fi) } } -char *BLI_gethome(void) { - #ifdef __BeOS - return "/boot/home/"; /* BeOS 4.5: doubleclick at icon doesnt give home env */ +void BLI_getlastdir(const char* dir, char *last, int maxlen) +{ + const char *s = dir; + const char *lslash = NULL; + const char *prevslash = NULL; + while (*s) { + if ((*s == '\\') || (*s == '/')) { + prevslash = lslash; + lslash = s; + } + s++; + } + if (prevslash) { + BLI_strncpy(last, prevslash+1, maxlen); + } else { + BLI_strncpy(last, dir, maxlen); + } +} - #elif !defined(WIN32) +char *BLI_gethome(void) { + #if !defined(WIN32) return getenv("HOME"); #else /* Windows */ @@ -1395,6 +859,117 @@ 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. */ + +char *BLI_gethome_folder(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 *s; + int i; + + /* 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 (in svn) */ + if(folder_name) { + BLI_snprintf(fulldir, sizeof(fulldir), "./release/%s", folder_name); + if (BLI_exists(fulldir)) return fulldir; + else fulldir[0] = '\0'; + } + + /* BLI_gethome() can return NULL if env vars are not set */ + s = BLI_gethome(); + + if(!s) { /* bail if no $HOME */ + printf("$HOME is NOT set\n"); + return NULL; + } + + if(strstr(s, ".blender")) + BLI_strncpy(homedir, s, FILE_MAXDIR); + else + BLI_make_file_string("/", homedir, s, ".blender"); + + /* 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; + } + + return NULL; +} + +void BLI_setenv(const char *env, const char*val) +{ + /* SGI or free windows */ +#if (defined(__sgi) || ((defined(WIN32) || defined(WIN64)) && defined(FREE_WINDOWS))) + char *envstr= malloc(sizeof(char) * (strlen(env) + strlen(val) + 2)); /* one for = another for \0 */ + + sprintf(envstr, "%s=%s", env, val); + putenv(envstr); + free(envstr); + + /* non-free windows */ +#elif (defined(WIN32) || defined(WIN64)) /* not free windows */ + _putenv_s(env, val); +#else + /* linux/osx/bsd */ + setenv(env, val, 1); +#endif +} + void BLI_clean(char *path) { if(path==0) return; @@ -1718,22 +1293,12 @@ void BLI_split_dirfile(char *string, char *dir, char *file) /* simple appending of filename to dir, does not check for valid path! */ void BLI_join_dirfile(char *string, const char *dir, const char *file) { - int sl_dir = strlen(dir); - BLI_strncpy(string, dir, FILE_MAX); - if (sl_dir > FILE_MAX-1) sl_dir = FILE_MAX-1; + int sl_dir; - /* only add seperator if needed */ -#ifdef WIN32 - if (string[sl_dir-1] != '\\') { - string[sl_dir] = '\\'; - sl_dir++; - } -#else - if (string[sl_dir-1] != '/') { - string[sl_dir] = '/'; - sl_dir++; - } -#endif + if(string != dir) /* compare pointers */ + BLI_strncpy(string, dir, FILE_MAX); + + sl_dir= BLI_add_slash(string); if (sl_dir <FILE_MAX) { BLI_strncpy(string + sl_dir, file, FILE_MAX-sl_dir); @@ -1785,13 +1350,13 @@ void BLI_where_am_i(char *fullname, const char *name) { char filename[FILE_MAXDIR+FILE_MAXFILE]; char *path = NULL, *temp; - int len; + #ifdef _WIN32 char *seperator = ";"; - char *slash = "\\"; + char slash = '\\'; #else char *seperator = ":"; - char *slash = "/"; + char slash = '/'; #endif @@ -1811,11 +1376,13 @@ void BLI_where_am_i(char *fullname, const char *name) if (name[0] == '.') { // relative path, prepend cwd BLI_getwdN(fullname); - len = strlen(fullname); - if (len && fullname[len -1] != slash[0]) { - strcat(fullname, slash); - } - strcat(fullname, name); + + // not needed but avoids annoying /./ in name + if(name && name[0]=='.' && name[1]==slash) + BLI_join_dirfile(fullname, fullname, name+2); + else + BLI_join_dirfile(fullname, fullname, name); + add_win32_extension(fullname); } else if (BLI_last_slash(name)) { // full path @@ -1834,11 +1401,7 @@ void BLI_where_am_i(char *fullname, const char *name) } else { strncpy(filename, path, sizeof(filename)); } - len = strlen(filename); - if (len && filename[len - 1] != slash[0]) { - strcat(filename, slash); - } - strcat(filename, name); + BLI_join_dirfile(fullname, fullname, name); if (add_win32_extension(filename)) { strcpy(fullname, filename); break; @@ -1907,6 +1470,27 @@ void BLI_where_is_temp(char *fullname, int usertemp) } } +char *get_install_dir(void) { + extern char bprogname[]; + char *tmpname = BLI_strdup(bprogname); + char *cut; + +#ifdef __APPLE__ + cut = strstr(tmpname, ".app"); + if (cut) cut[0] = 0; +#endif + + cut = BLI_last_slash(tmpname); + + if (cut) { + cut[0] = 0; + return tmpname; + } else { + MEM_freeN(tmpname); + return NULL; + } +} + /* * returns absolute path to the app bundle * only useful on OS X @@ -1925,67 +1509,6 @@ char* BLI_getbundle(void) { } #endif -/* strcasestr not available in MSVC */ -char *BLI_strcasestr(const char *s, const char *find) -{ - register char c, sc; - register size_t len; - - if ((c = *find++) != 0) { - c= tolower(c); - len = strlen(find); - do { - do { - if ((sc = *s++) == 0) - return (NULL); - sc= tolower(sc); - } while (sc != c); - } while (BLI_strncasecmp(s, find, len) != 0); - s--; - } - return ((char *) s); -} - - -int BLI_strcasecmp(const char *s1, const char *s2) { - int i; - - for (i=0; ; i++) { - char c1 = tolower(s1[i]); - char c2 = tolower(s2[i]); - - if (c1<c2) { - return -1; - } else if (c1>c2) { - return 1; - } else if (c1==0) { - break; - } - } - - return 0; -} - -int BLI_strncasecmp(const char *s1, const char *s2, int n) { - int i; - - for (i=0; i<n; i++) { - char c1 = tolower(s1[i]); - char c2 = tolower(s2[i]); - - if (c1<c2) { - return -1; - } else if (c1>c2) { - return 1; - } else if (c1==0) { - break; - } - } - - return 0; -} - - #ifdef WITH_ICONV #include "iconv.h" #include "localcharset.h" @@ -2017,68 +1540,4 @@ void BLI_string_to_utf8(char *original, char *utf_8, const char *code) } #endif // WITH_ICONV -void BLI_timestr(double _time, char *str) -{ - /* format 00:00:00.00 (hr:min:sec) string has to be 12 long */ - int hr= ( (int) _time) / (60*60); - int min= (((int) _time) / 60 ) % 60; - int sec= ( (int) (_time)) % 60; - int hun= ( (int) (_time * 100.0)) % 100; - - if (hr) { - sprintf(str, "%.2d:%.2d:%.2d.%.2d",hr,min,sec,hun); - } else { - sprintf(str, "%.2d:%.2d.%.2d",min,sec,hun); - } - - str[11]=0; -} - -/* ************** 64 bits magic, trick to support up to 32 gig of address space *************** */ -/* only works for malloced pointers (8 aligned) */ - -#ifdef __LP64__ - -#if defined(WIN32) && !defined(FREE_WINDOWS) -#define PMASK 0x07FFFFFFFFi64 -#else -#define PMASK 0x07FFFFFFFFll -#endif - - -int BLI_int_from_pointer(void *poin) -{ - intptr_t lval= (intptr_t)poin; - - return (int)(lval>>3); -} - -void *BLI_pointer_from_int(int val) -{ - static int firsttime= 1; - static intptr_t basevalue= 0; - - if(firsttime) { - void *poin= malloc(10000); - basevalue= (intptr_t)poin; - basevalue &= ~PMASK; - printf("base: %d pointer %p\n", basevalue, poin); /* debug */ - firsttime= 0; - free(poin); - } - return (void *)(basevalue | (((intptr_t)val)<<3)); -} - -#else - -int BLI_int_from_pointer(void *poin) -{ - return (int)poin; -} -void *BLI_pointer_from_int(int val) -{ - return (void *)val; -} - -#endif diff --git a/source/blender/blenlib/intern/voxel.c b/source/blender/blenlib/intern/voxel.c index 8a1ca6e59ff..b5b2ae793f9 100644 --- a/source/blender/blenlib/intern/voxel.c +++ b/source/blender/blenlib/intern/voxel.c @@ -176,19 +176,7 @@ static void tricubic_get_coeff_stacked(float a[64], float x[64]) { } } -static void point2xyz(int p, int *x, int *y, int *z) { - switch (p) { - case 0: *x=0; *y=0; *z=0; break; - case 1: *x=1; *y=0; *z=0; break; - case 2: *x=0; *y=1; *z=0; break; - case 3: *x=1; *y=1; *z=0; break; - case 4: *x=0; *y=0; *z=1; break; - case 5: *x=1; *y=0; *z=1; break; - case 6: *x=0; *y=1; *z=1; break; - case 7: *x=1; *y=1; *z=1; break; - default:*x=0; *y=0; *z=0; - } -} + static void tricubic_get_coeff(float a[64], float f[8], float dfdx[8], float dfdy[8], float dfdz[8], float d2fdxdy[8], float d2fdxdz[8], float d2fdydz[8], float d3fdxdydz[8]) { diff --git a/source/blender/blenlib/intern/winstuff.c b/source/blender/blenlib/intern/winstuff.c index 666a54b54cc..2f96f7b6af1 100644 --- a/source/blender/blenlib/intern/winstuff.c +++ b/source/blender/blenlib/intern/winstuff.c @@ -219,9 +219,6 @@ int check_file_chars(char *filename) #else -static void BLI_WINSTUFF_C_IS_EMPTY_FOR_UNIX(void) -{ - /*intentionally empty*/ -} +/* intentionally empty for UNIX */ #endif |