From 12315f4d0e0ae993805f141f64cb8c73c5297311 Mon Sep 17 00:00:00 2001 From: Hans Lambermont Date: Sat, 12 Oct 2002 11:37:38 +0000 Subject: Initial revision --- source/blender/blenlib/BLI_arithb.h | 758 ++++++++ source/blender/blenlib/BLI_blenlib.h | 325 ++++ source/blender/blenlib/BLI_dynstr.h | 89 + source/blender/blenlib/BLI_editVert.h | 73 + source/blender/blenlib/BLI_ghash.h | 59 + source/blender/blenlib/BLI_gsqueue.h | 95 + source/blender/blenlib/BLI_linklist.h | 60 + source/blender/blenlib/BLI_memarena.h | 58 + source/blender/blenlib/BLI_rand.h | 68 + source/blender/blenlib/BLI_storage_types.h | 79 + source/blender/blenlib/BLI_vfontdata.h | 66 + source/blender/blenlib/BLI_winstuff.h | 96 + source/blender/blenlib/MTC_matrixops.h | 164 ++ source/blender/blenlib/MTC_vectorops.h | 60 + source/blender/blenlib/Makefile | 37 + source/blender/blenlib/PIL_dynlib.h | 54 + source/blender/blenlib/PIL_time.h | 61 + source/blender/blenlib/intern/BLI_callbacks.h | 44 + source/blender/blenlib/intern/BLI_dynstr.c | 115 ++ source/blender/blenlib/intern/BLI_fileops.h | 49 + source/blender/blenlib/intern/BLI_ghash.c | 184 ++ source/blender/blenlib/intern/BLI_linklist.c | 98 + source/blender/blenlib/intern/BLI_memarena.c | 80 + source/blender/blenlib/intern/BLI_scanfill.h | 41 + source/blender/blenlib/intern/BLI_storage.h | 40 + source/blender/blenlib/intern/BLI_util.h | 47 + source/blender/blenlib/intern/Makefile | 51 + source/blender/blenlib/intern/arithb.c | 2355 +++++++++++++++++++++++++ source/blender/blenlib/intern/dynlib.c | 146 ++ source/blender/blenlib/intern/fileops.c | 293 +++ source/blender/blenlib/intern/gsqueue.c | 112 ++ source/blender/blenlib/intern/matrixops.c | 440 +++++ source/blender/blenlib/intern/noise.c | 390 ++++ source/blender/blenlib/intern/psfont.c | 2124 ++++++++++++++++++++++ source/blender/blenlib/intern/rand.c | 84 + source/blender/blenlib/intern/rct.c | 115 ++ source/blender/blenlib/intern/scanfill.c | 1234 +++++++++++++ source/blender/blenlib/intern/storage.c | 568 ++++++ source/blender/blenlib/intern/time.c | 101 ++ source/blender/blenlib/intern/util.c | 828 +++++++++ source/blender/blenlib/intern/vectorops.c | 165 ++ source/blender/blenlib/intern/winstuff.c | 193 ++ 42 files changed, 12099 insertions(+) create mode 100644 source/blender/blenlib/BLI_arithb.h create mode 100644 source/blender/blenlib/BLI_blenlib.h create mode 100644 source/blender/blenlib/BLI_dynstr.h create mode 100644 source/blender/blenlib/BLI_editVert.h create mode 100644 source/blender/blenlib/BLI_ghash.h create mode 100644 source/blender/blenlib/BLI_gsqueue.h create mode 100644 source/blender/blenlib/BLI_linklist.h create mode 100644 source/blender/blenlib/BLI_memarena.h create mode 100644 source/blender/blenlib/BLI_rand.h create mode 100644 source/blender/blenlib/BLI_storage_types.h create mode 100644 source/blender/blenlib/BLI_vfontdata.h create mode 100644 source/blender/blenlib/BLI_winstuff.h create mode 100644 source/blender/blenlib/MTC_matrixops.h create mode 100644 source/blender/blenlib/MTC_vectorops.h create mode 100644 source/blender/blenlib/Makefile create mode 100644 source/blender/blenlib/PIL_dynlib.h create mode 100644 source/blender/blenlib/PIL_time.h create mode 100644 source/blender/blenlib/intern/BLI_callbacks.h create mode 100644 source/blender/blenlib/intern/BLI_dynstr.c create mode 100644 source/blender/blenlib/intern/BLI_fileops.h create mode 100644 source/blender/blenlib/intern/BLI_ghash.c create mode 100644 source/blender/blenlib/intern/BLI_linklist.c create mode 100644 source/blender/blenlib/intern/BLI_memarena.c create mode 100644 source/blender/blenlib/intern/BLI_scanfill.h create mode 100644 source/blender/blenlib/intern/BLI_storage.h create mode 100644 source/blender/blenlib/intern/BLI_util.h create mode 100644 source/blender/blenlib/intern/Makefile create mode 100644 source/blender/blenlib/intern/arithb.c create mode 100644 source/blender/blenlib/intern/dynlib.c create mode 100644 source/blender/blenlib/intern/fileops.c create mode 100644 source/blender/blenlib/intern/gsqueue.c create mode 100644 source/blender/blenlib/intern/matrixops.c create mode 100644 source/blender/blenlib/intern/noise.c create mode 100644 source/blender/blenlib/intern/psfont.c create mode 100644 source/blender/blenlib/intern/rand.c create mode 100644 source/blender/blenlib/intern/rct.c create mode 100644 source/blender/blenlib/intern/scanfill.c create mode 100644 source/blender/blenlib/intern/storage.c create mode 100644 source/blender/blenlib/intern/time.c create mode 100644 source/blender/blenlib/intern/util.c create mode 100644 source/blender/blenlib/intern/vectorops.c create mode 100644 source/blender/blenlib/intern/winstuff.c (limited to 'source/blender/blenlib') diff --git a/source/blender/blenlib/BLI_arithb.h b/source/blender/blenlib/BLI_arithb.h new file mode 100644 index 00000000000..3c3fad3dcf2 --- /dev/null +++ b/source/blender/blenlib/BLI_arithb.h @@ -0,0 +1,758 @@ +#undef TEST_ACTIVE +//#define ACTIVE 1 +/** + * blenlib/BLI_arithb.h mar 2001 Nzc + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + * + * The old math stuff from Ton. These will slowly phase out in favour + * of MTC calls. (or even MoTO :) ) + * */ + +#ifndef BLI_ARITHB_H +#define BLI_ARITHB_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAT4_UNITY {{ 1.0, 0.0, 0.0, 0.0},\ + { 0.0, 1.0, 0.0, 0.0},\ + { 0.0, 0.0, 1.0, 0.0},\ + { 0.0, 0.0, 0.0, 1.0}} + +#define MAT3_UNITY {{ 1.0, 0.0, 0.0},\ + { 0.0, 1.0, 0.0},\ + { 0.0, 0.0, 1.0}} + + +/* matrix operations */ +/* void Mat4MulMat4(float m1[][4], float m2[][4], float m3[][4]); */ +/* void Mat3MulVecfl(float mat[][3], float *vec); */ +/* or **mat, but it's the same */ +/*void Mat3MulVecd(float mat[][3], double *vec); */ + +/* void Mat4MulVecfl(float mat[][4], float *vec); */ +/* void Mat4MulSerie(float answ[][4], float m1[][4], float m2[][4], */ +/* float m3[][4], float m4[][4], float m5[][4], */ +/* float m6[][4], float m7[][4], float m8[][4]); */ +/* int Mat4Invert(float inverse[][4], float mat[][4]); */ + +/* m2 to m1 */ +/* void Mat3CpyMat4(float m1p[][3], float m2p[][4]); */ +/* void Mat3CpyMat4(float *m1p, float *m2p); */ + +/* m1 to m2 */ +/* void Mat3CpyMat3(float m1p[][3], float m2p[][3]); */ +/* void Mat3CpyMat3(float *m1p, float *m2p); */ + +/* m2 to m1 */ +/* void Mat4CpyMat3(float m1p[][4], float m2p[][3]); */ + +/* M1 = M3*M2 */ +/* void Mat3MulMat3(float m1[][3], float m2[][3], float m3[][3]); */ +/*void Mat3MulMat3(float *m1, float *m3, float *m2); */ + +/* m1 = m2 * m3, ignore the elements on the 4th row/column of m3 */ +/*void Mat3IsMat3MulMat4(float m1[][3], float m2[][3], float m3[][4]); */ + +/* m1 to m2 */ +/* void Mat4CpyMat4(float m1[][4], float m2[][4]); */ +/* void Mat4CpyMat4(float *m1, float *m2); */ + + +/* void Mat4Ortho(float mat[][4]); */ +/* void Mat4Mul3Vecfl(float mat[][4], float *vec); */ +/* void Mat4MulVec4fl(float mat[][4], float *vec); */ +/* void Mat4SwapMat4(float *m1, float *m2); */ + +/* void Mat3Inv(float m1[][3], float m2[][3]); */ +/* void Mat4One(float m[][4]); */ +/* void Mat3One(float m[][3]); */ + + + void +CalcCent3f( + float *cent, const float *v1, const float *v2, const float *v3 +); + + void +CalcCent4f( + float *cent, const float *v1, + const float *v2, const float *v3, + const float *v4 +); + + void +Crossf( + float *c, const float *a, const float *b +); + +/** + * Euler conversion routines + */ + + void +EulToMat3( + const float *eul, + float mat[][3] +); + void +EulToMat4( + const float* eul, + float mat[][4] +); + + void +Mat3ToEul( + const float tmat[][3], + float *eul +); + +/** + * @section Quaternion arithmetic routines + */ + + void +QuatToEul( + const float *quat, + float *eul +); + void +QuatOne( + float * +); + void +QuatMul( + float *, + const float *, + const float * +); + void +NormalQuat( + float * +); + void +VecRotToQuat( + const float *vec, + float phi, + float *quat +); + void +QuatSub( + float *q, + const float *q1, + float *q2 +); + +/** + * @section matrix multiplication can copying routines + */ + + void +Mat3MulFloat( + float *m, + float f +); + void +Mat4MulFloat( + float *m, + float f +); + void +Mat4MulFloat3( + float *m, + float f +); + void +Mat3Transp( + float mat[][3] +); + void +Mat4Transp( + float mat[][4] +); + int +Mat4Invert( + float inverse[][4], + const float mat[][4] +); + void +Mat4InvertSimp( + float inverse[][4], + const float mat[][4] +); + void +Mat4Inv( + float *m1, + const float *m2 +); + void +Mat4InvGG( + float out[][4], + const float in[][4] +); + void +Mat3CpyMat4( + float m1[][3], + const float m2[][4] +); + + void +Mat3Inv( + float m1[][3], + const float m2[][3] +); + + void +Mat4CpyMat3( + float m1[][4], + const float m2[][3] +); + + float +Det2x2( + float a,float b,float c,float d +); + + float +Det3x3( + float a1, float a2, float a3, + float b1, float b2, float b3, + float c1, float c2, float c3 +); + + float +Det4x4( + const float m[][4] +); + + void +Mat4Adj( + float out[][4], + const float in[][4] +); + void +Mat3Adj( + float m1[][3], + const float m[][3] +); + void +Mat4MulMat4( + float m1[][4], + const float m2[][4], + const float m3[][4] +); + void +subMat4MulMat4( + float *m1, + const float *m2, + const float *m3 +); +#ifndef TEST_ACTIVE + void +Mat3MulMat3( + float m1[][3], + const float m3[][3], + const float m2[][3] +); +#else + void +Mat3MulMat3( + float *m1, + const float *m3, + const float *m2 +); +#endif + void +Mat4MulMat34( + float (*m1)[4], + const float (*m3)[3], + const float (*m2)[4] +); + void +Mat4CpyMat4( + float m1[][4], + const float m2[][4] +); + void +Mat4SwapMat4( + float *m1, + float *m2 +); + void +Mat3CpyMat3( + float m1[][3], + const float m2[][3] +); + void +Mat3MulSerie( + float answ[][3], + const float m1[][3], const float m2[][3], const float m3[][3], + const float m4[][3], const float m5[][3], const float m6[][3], + const float m7[][3], const float m8[][3] +); + void +Mat4MulSerie( + float answ[][4], + const float m1[][4], + const float m2[][4], const float m3[][4], const float m4[][4], + const float m5[][4], const float m6[][4], const float m7[][4], + const float m8[][4] +); + void +Mat4Clr( + float *m +); + void +Mat3Clr( + float *m +); + void +Mat3One( + float m[][3] +); + void +Mat4MulVec( + const float mat[][4], + int *vec +); + void +VecMat4MulVecfl( + float *in, + const float mat[][4], + const float *vec +); + void +Mat4MulMat43( + float (*m1)[4], + const float (*m3)[4], + const float (*m2)[3] +); + + void +Mat3IsMat3MulMat4( + float m1[][3], + const float m2[][3], + const float m3[][4] +); + void +Mat4One( + float m[][4] +); + void +Mat4Mul3Vecfl( + const float mat[][4], + float *vec +); + void +Mat4MulVec4fl( + const float mat[][4], + float *vec +); + void +Mat3MulVec( + const float mat[][3], + int *vec +); + void +Mat4MulVecfl( + const float mat[][4], + float *vec +); + void +Mat4ToQuat( + const float m[][4], + float *q +); + void +VecUpMat3old( + const float *vec, + float mat[][3], + short axis +); + int +FloatCompare( + const float *v1, + const float *v2, + float limit +); + float +Normalise( + float *n +); + float +CalcNormFloat( + const float *v1, + const float *v2, + const float *v3, + float *n +); + + float +CalcNormFloat4( + const float *v1, + const float *v2, + const float *v3, + const float *v4, + float *n +); + float +VecLenf( + const float *v1, + const float *v2 +); + void +VecMulf( + float *v1, + float f +); + int +VecCompare( + const float *v1, + const float *v2, + float limit +); + float +Sqrt3f( + float f +); + double +Sqrt3d( + double d +); + + void +euler_rot( + float *beul, + float ang, + char axis +); + float +saacos( + float fac +); + float +sasqrt( + float fac +); + float +Inpf( + const float *v1, + const float *v2 +); + void +VecSubf( + float *v, + const float *v1, + const float *v2 +); + void +VecAddf( + float *v, + const float *v1, + const float *v2 +); + void +VecUpMat3( + float *vec, + float mat[][3], + short axis +); + float +DistVL2Dfl( + const float *v1, + const float *v2, + const float *v3 +); + float +PdistVL2Dfl( + const float *v1, + const float *v2, + const float *v3 +); + float +AreaF2Dfl( + const float *v1, + const float *v2, + const float *v3 +); + float +AreaQ3Dfl( + const float *v1, + const float *v2, + const float *v3, + const float *v4 +); + float +AreaT3Dfl( + const float *v1, + const float *v2, + const float *v3 +); + float +AreaPoly3Dfl( + int nr, + const float *verts, + const float *normal +); + void +VecRotToMat3( + const float *vec, + float phi, + float mat[][3] +); + float * +vectoquat( + const float *vec, + short axis, + short upflag +); + + void +i_lookat( + float vx, float vy, + float vz, float px, + float py, float pz, + float twist, float mat[][4] +); + void +i_window( + float left, float right, + float bottom, float top, + float nearClip, float farClip, + float mat[][4] +); + + void +hsv_to_rgb( + float h, float s, + float v, float *r, + float *g, float *b +); + + void +rgb_to_hsv( + float r, float g, float b, + float *lh, float *ls, float *lv +); + 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 +); + + void +EulToQuat( + const float *eul, + float *quat +); + + void +Mat3MulVecfl( + const float mat[][3], + float *vec +); + void +Mat3MulVecd( + const float mat[][3], + double *vec +); + void +Mat3TransMulVecfl( + const float mat[][3], + float *vec +); + void +VecStar( + float mat[][3], + const float *vec +); + short +EenheidsMat( + float mat[][3] +); + void +printmatrix3( + const char *str, const float m[][3] +); + void +QuatToMat3( + const float *q, + float m[][3] +); + void +QuatToMat4( + const float *q, + float m[][4] +); + void +QuatToSpher( + const float *quat, + float *sph +); + void +Mat3ToSpher( + const float *mat, + float *sph +); + void +Mat3ToQuat_is_ok( + const float wmat[][3], + float *q +); + void +i_ortho( + float left, float right, + float bottom, float top, + float nearClip, float farClip, + float matrix[][4] +); + void +i_polarview( + float dist, float azimuth, float incidence, float twist, + float Vm[][4] +); + void +Mat3Ortho( + float mat[][3] +); + void +Mat4Ortho( + float mat[][4] +); + void +VecCopyf( + float *v1, + const float *v2 +); + int +VecLen( + const int *v1, + const int *v2 +); + void +CalcNormShort( + const short *v1, + const short *v2, + const short *v3, + float *n +) /* is ook uitprodukt */; + + void +CalcNormLong( + const int* v1, + const int*v2, + const int*v3, + float *n +); + void +MinMax3( + float *min, + float *max, + const float *vec +); + void +Mat3ToEuln( + const float tmat[][3], + float *eul +); + void +SizeToMat3( + const float *size, + float mat[][3] +); + void +printmatrix4( + const char *str, + const float m[][4] +); +/* uit Sig.Proc.85 pag 253 */ + void +Mat3ToQuat( + const float wmat[][3], + float *q +); + void +i_translate( + float Tx, + float Ty, + float Tz, + float mat[][4] +); + void +i_multmatrix( + const float icand[][4], + float Vm[][4] +); + void +i_rotate( + float angle, + char axis, + float mat[][4] +); + void +VecMidf( + float *v, const float *v1, const float *v2 +); + void +Mat3ToSize( + const float mat[][3], float *size +); + void +Mat4ToSize( + const float mat[][4], float *size +); + void +triatoquat( + const float *v1, + const float *v2, + const float *v3, float *quat +); + void +MinMaxRGB( + short c[] +); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/source/blender/blenlib/BLI_blenlib.h b/source/blender/blenlib/BLI_blenlib.h new file mode 100644 index 00000000000..5d27f60e95f --- /dev/null +++ b/source/blender/blenlib/BLI_blenlib.h @@ -0,0 +1,325 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + * + * @mainpage BLI - Blender LIbrary external interface + * + * @section about About the BLI module + * + * This is the external interface of the Blender Library. If you find + * a call to a BLI function that is not prototyped here, please add a + * prototype here. The library offers mathematical operations (mainly + * vector and matrix calculus), an abstraction layer for file i/o, + * functions for calculating Perlin noise, scanfilling services for + * triangles, and a system for guarded memory + * allocation/deallocation. There is also a patch to make MS Windows + * behave more or less Posix-compliant. + * + * @section issues Known issues with BLI + * + * - blenlib is written in C. + * - The posix-compliancy may move to a separate lib that deals with + * platform dependencies. (There are other platform-dependent + * fixes as well.) + * - The file i/o has some redundant code. It should be cleaned. + * - arithb.c is a very messy matrix library. We need a better + * solution. + * - vectorops.c is close to superfluous. It may disappear in the + * near future. + * + * @section dependencies Dependencies + * + * - The blenlib uses type defines from makesdna/, and functions from + * standard libraries. + * + * $Id$ +*/ + +#ifndef BLI_BLENLIB_H +#define BLI_BLENLIB_H + +#include "DNA_listBase.h" /* braindamage for the masses... needed + because fillvlakbase and fillvertbase are + used outside */ + +extern ListBase fillvlakbase; +extern ListBase fillvertbase; +/** + * @attention Defined in scanfill.c + */ +extern ListBase filledgebase; +extern int totblock; + +struct chardesc; +struct direntry; +struct rctf; +struct rcti; +struct EditVert; +struct PackedFile; +struct LinkNode; + +#ifdef __cplusplus +extern "C" { +#endif + +/* BLI_util.h */ +char *BLI_gethome(void); +void BLI_make_file_string(char *relabase, char *string, char *dir, char *file); +void BLI_make_exist(char *dir); +void BLI_split_dirfile(char *string, char *dir, char *file); +int BLI_testextensie(char *str, 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); +void BLI_freelistN(struct ListBase *listbase); +void BLI_addtail(struct ListBase *listbase, void *vlink); +void BLI_remlink(struct ListBase *listbase, void *vlink); +void BLI_newname(char * name, int add); +int BLI_stringdec(char *string, char *kop, char *staart, unsigned short *numlen); +void BLI_stringenc(char *string, char *kop, char *staart, 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_freelist(struct ListBase *listbase); +int BLI_countlist(struct ListBase *listbase); +void BLI_freelinkN(ListBase *listbase, void *vlink); +void BLI_splitdirstring(char *di,char *fi); + + /** + * 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, char *basepath, int framenum); + +void BLI_makestringcode(char *fromfile, char *str); + + /** + * 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(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(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, char *src, int maxncpy); + + /** + * 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); + + /** + * 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); + + /** + * 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, char *name); + +/* BLI_storage.h */ +int BLI_filesize(int file); +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); + +/* BLI_fileops.h */ +void BLI_recurdir_fileops(char *dirname); +int BLI_link(char *file, char *to); +int BLI_backup(char *file, char *from, char *to); + + +/** + * @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_delete(char *file, int dir, int recursive); +int BLI_move(char *file, char *to); +int BLI_touch(char *file); +char *BLI_last_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); +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); +/* why oh why doesn't this work? */ +//void BLI_union_rctf(struct rctf *rct1, struct rctf *rct2); +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); /* DE HOOFD FILL ROUTINE */ +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); + +/* 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)); + +/** + * Before scanfilling is done, these two references need to be set. If + * the object reference is NULL, the function will fail. If the object + * is set, but no colour is available, colour can be omitted. + * + * @attention Also see BLI_setScanFillColourRef + */ +void BLI_setScanFillObjectRef(void* ob); + +/** + * Before scanfilling is done, these two references need to be set. If + * the object reference is NULL, the function will fail. If the object + * is set, but no colour is available, colour can be omitted. + * + * @attention Also see BLI_setScanFillObjectRef + */ +void BLI_setScanFillColourRef(char* c); + +#define PRNTSUB(type,arg) printf(#arg ": %" #type " ", arg) +#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");} + +/** + * @param array The array in question + * @retval The number of elements in the array. + */ +#define BLI_ARRAY_NELEMS(array) (sizeof((array))/sizeof((array)[0])) + +/** + * @param strct The structure of interest + * @param member The name of a member field of @a strct + * @retval The offset in bytes of @a member within @a strct + */ +#define BLI_STRUCT_OFFSET(strct, member) (((struct) 0).(membr)) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/source/blender/blenlib/BLI_dynstr.h b/source/blender/blenlib/BLI_dynstr.h new file mode 100644 index 00000000000..ada4a41b7f8 --- /dev/null +++ b/source/blender/blenlib/BLI_dynstr.h @@ -0,0 +1,89 @@ +/** + * @file BLI_dynstr.h + * + * A dynamically sized string ADT. + * This ADT is designed purely for dynamic string creation + * through appending, not for general usage, the intent is + * to build up dynamic strings using a DynStr object, then + * convert it to a c-string and work with that. + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + */ + +#ifndef BLI_DYNSTR_H +#define BLI_DYNSTR_H + +struct DynStr; + + /** The abstract DynStr type */ +typedef struct DynStr DynStr; + + /** + * Create a new DynStr. + * + * @return Pointer to a new DynStr. + */ +DynStr* BLI_dynstr_new (void); + + /** + * Append a c-string to a DynStr. + * + * @param ds The DynStr to append to. + * @param cstr The c-string to append. + */ +void BLI_dynstr_append (DynStr *ds, char *cstr); + + /** + * Find the length of a DynStr. + * + * @param ds The DynStr of interest. + * @return The length of @a ds. + */ +int BLI_dynstr_get_len (DynStr *ds); + + /** + * Get a DynStr's contents as a c-string. + * The returned c-string should be free'd + * using BLI_freeN. + * + * @param ds The DynStr of interest. + * @return The contents of @a ds as a c-string. + */ +char* BLI_dynstr_get_cstring (DynStr *ds); + + /** + * Free the DynStr + * + * @param ds The DynStr to free. + */ +void BLI_dynstr_free (DynStr *ds); + +#endif diff --git a/source/blender/blenlib/BLI_editVert.h b/source/blender/blenlib/BLI_editVert.h new file mode 100644 index 00000000000..4ee30493113 --- /dev/null +++ b/source/blender/blenlib/BLI_editVert.h @@ -0,0 +1,73 @@ +/** + * blenlib/BLI_editVert.h mar 2001 Nzc + * + * Some editing types needed in the lib (unfortunately) for + * scanfill.c + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + */ + +#ifndef BLI_EDITVERT_H +#define BLI_EDITVERT_H + +typedef struct EditVert +{ + struct EditVert *next, *prev, *vn; + float no[3]; + float co[3]; + short xs, ys; + char f, h, f1, hash; + int totweight; /* __NLA */ + struct MDeformWeight *dw; /* __NLA */ +} EditVert; + +typedef struct EditEdge +{ + struct EditEdge *next, *prev; + struct EditVert *v1, *v2, *vn; + short f,h; + short f1, dir; +} EditEdge; + +typedef struct EditVlak +{ + struct EditVlak *next, *prev; + struct EditVert *v1, *v2, *v3, *v4; + struct EditEdge *e1, *e2, *e3, *e4; + float n[3]; + float uv[4][2]; + unsigned int col[4]; + struct TFace *tface; /* a pointer to original tface. */ + char mat_nr, flag; + char f, f1; +} EditVlak; + +#endif diff --git a/source/blender/blenlib/BLI_ghash.h b/source/blender/blenlib/BLI_ghash.h new file mode 100644 index 00000000000..7af59a504f3 --- /dev/null +++ b/source/blender/blenlib/BLI_ghash.h @@ -0,0 +1,59 @@ +/** + * A general (pointer -> pointer) hash table ADT + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + */ + +#ifndef BLI_GHASH_H +#define BLI_GHASH_H + +struct GHash; +typedef struct GHash GHash; + +typedef unsigned int (*GHashHashFP) (void *key); +typedef int (*GHashCmpFP) (void *a, void *b); +typedef void (*GHashKeyFreeFP) (void *key); +typedef void (*GHashValFreeFP) (void *val); + +GHash* BLI_ghash_new (GHashHashFP hashfp, GHashCmpFP cmpfp); +void BLI_ghash_free (GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp); + +void BLI_ghash_insert (GHash *gh, void *key, void *val); +void* BLI_ghash_lookup (GHash *gh, void *key); +int BLI_ghash_haskey (GHash *gh, void *key); + +unsigned int BLI_ghashutil_ptrhash (void *key); +int BLI_ghashutil_ptrcmp (void *a, void *b); + +unsigned int BLI_ghashutil_strhash (void *key); +int BLI_ghashutil_strcmp (void *a, void *b); + +#endif diff --git a/source/blender/blenlib/BLI_gsqueue.h b/source/blender/blenlib/BLI_gsqueue.h new file mode 100644 index 00000000000..483f58a0185 --- /dev/null +++ b/source/blender/blenlib/BLI_gsqueue.h @@ -0,0 +1,95 @@ +/* + * A generic structure queue (a queue for fixed length + * (generally small) structures. + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + */ + +#ifndef BLI_GSQUEUE_H +#define BLI_GSQUEUE_H + +typedef struct _GSQueue GSQueue; + + /** + * Create a new GSQueue. + * + * @param elem_size The size of the structures in the queue. + * @retval The new queue + */ +GSQueue* BLI_gsqueue_new (int elem_size); + + /** + * Query if the queue is empty + */ +int BLI_gsqueue_is_empty(GSQueue *gq); + + /** + * Access the item at the head of the queue + * without removing it. + * + * @param item_r A pointer to an appropriatly + * sized structure (the size passed to BLI_gsqueue_new) + */ +void BLI_gsqueue_peek (GSQueue *gq, void *item_r); + + /** + * Access the item at the head of the queue + * and remove it. + * + * @param item_r A pointer to an appropriatly + * sized structure (the size passed to BLI_gsqueue_new). + * Can be NULL if desired. + */ +void BLI_gsqueue_pop (GSQueue *gq, void *item_r); + + /** + * Push an element onto the tail of the queue. + * + * @param item A pointer to an appropriatly + * sized structure (the size passed to BLI_gsqueue_new). + */ +void BLI_gsqueue_push (GSQueue *gq, void *item); + + /** + * Push an element back onto the head of the queue (so + * it would be returned from the next call to BLI_gsqueue_pop). + * + * @param item A pointer to an appropriatly + * sized structure (the size passed to BLI_gsqueue_new). + */ +void BLI_qsueue_pushback (GSQueue *gq, void *item); + + /** + * Free the queue + */ +void BLI_gsqueue_free (GSQueue *gq); + +#endif /* BLI_GSQUEUE_H */ diff --git a/source/blender/blenlib/BLI_linklist.h b/source/blender/blenlib/BLI_linklist.h new file mode 100644 index 00000000000..eaa3a0ad2c5 --- /dev/null +++ b/source/blender/blenlib/BLI_linklist.h @@ -0,0 +1,60 @@ +/* + * Routines for working with singly linked lists + * of 'links' - pointers to other data. + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + */ + +#ifndef BLI_LINKLIST_H +#define BLI_LINKLIST_H + +struct MemArena; + +typedef void (*LinkNodeFreeFP)(void *link); +typedef void (*LinkNodeApplyFP)(void *link); + +struct LinkNode; +typedef struct LinkNode { + struct LinkNode *next; + void *link; +} LinkNode; + +int BLI_linklist_length (struct LinkNode *list); + +void BLI_linklist_reverse (struct LinkNode **listp); + +void BLI_linklist_prepend (struct LinkNode **listp, void *ptr); +void BLI_linklist_prepend_arena (struct LinkNode **listp, void *ptr, struct MemArena *ma); + +void BLI_linklist_free (struct LinkNode *list, LinkNodeFreeFP freefunc); +void BLI_linklist_apply (struct LinkNode *list, LinkNodeApplyFP applyfunc); + +#endif diff --git a/source/blender/blenlib/BLI_memarena.h b/source/blender/blenlib/BLI_memarena.h new file mode 100644 index 00000000000..4aa2c21452e --- /dev/null +++ b/source/blender/blenlib/BLI_memarena.h @@ -0,0 +1,58 @@ +/* + * Memory arena ADT + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + * + * Memory arena's are commonly used when the program + * needs to quickly allocate lots of little bits of + * data, which are all freed at the same moment. + * + */ + +#ifndef BLI_MEMARENA_H +#define BLI_MEMARENA_H + + /* A reasonable standard buffer size, big + * enough to not cause much internal fragmentation, + * small enough not to waste resources + */ +#define BLI_MEMARENA_STD_BUFSIZE 4096 + +struct MemArena; +typedef struct MemArena MemArena; + + +struct MemArena* BLI_memarena_new (int bufsize); +void BLI_memarena_free (struct MemArena *ma); + +void* BLI_memarena_alloc (struct MemArena *ma, int size); + +#endif diff --git a/source/blender/blenlib/BLI_rand.h b/source/blender/blenlib/BLI_rand.h new file mode 100644 index 00000000000..05dc746e7e0 --- /dev/null +++ b/source/blender/blenlib/BLI_rand.h @@ -0,0 +1,68 @@ +/** + * @file BLI_rand.h + * + * Random number functions. + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + */ + +#ifndef BLI_RAND_H +#define BLI_RAND_H + + /** Seed the random number generator */ +void BLI_srand (unsigned int seed); + + /** Return a pseudo-random number N where 0<=N<(2^31) */ +int BLI_rand (void); + + /** Return a pseudo-random number N where 0.0<=N<1.0 */ +double BLI_drand (void); + + /** Return a pseudo-random number N where 0.0f<=N<1.0f */ +float BLI_frand (void); + + /** Fills a block of memory starting at @a addr + * and extending @a len bytes with pseudo-random + * contents. This routine does not use nor modify + * the state of the BLI random number generator. + */ +void BLI_fillrand (void *addr, int len); + + /** Stores the BLI randum number generator state + * into the buffer in @a loc_r. + */ +void BLI_storerand (unsigned int loc_r[2]); + + /** Retores the BLI randum number generator state + * from the buffer in @a loc. + */ +void BLI_restorerand (unsigned int loc[2]); + +#endif diff --git a/source/blender/blenlib/BLI_storage_types.h b/source/blender/blenlib/BLI_storage_types.h new file mode 100644 index 00000000000..9d5264c4cd1 --- /dev/null +++ b/source/blender/blenlib/BLI_storage_types.h @@ -0,0 +1,79 @@ +/** + * blenlib/BLI_storage_types.h + * + * Some types for dealing with directories + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + */ +#ifndef BLI_STORAGE_TYPES_H +#define BLI_STORAGE_TYPES_H + +#include + +#define HDRSIZE 512 +#define NAMSIZE 200 + +struct header{ + char name[NAMSIZE]; + unsigned int size; + unsigned int chksum; + char fill[HDRSIZE-NAMSIZE-2*sizeof(unsigned int)]; +}; + +#ifdef WIN32 +typedef unsigned int mode_t; +#endif + +struct direntry{ + char *string; + mode_t type; + char *relname; + struct stat s; + unsigned int flags; + char size[16]; + char mode1[4]; + char mode2[4]; + char mode3[4]; + char owner[16]; + char time[8]; + char date[16]; + char extra[16]; + void *poin; + int nr; +}; + +struct dirlink +{ + struct dirlink *next,*prev; + char *name; +}; + +#endif /* BLI_STORAGE_TYPES_H */ diff --git a/source/blender/blenlib/BLI_vfontdata.h b/source/blender/blenlib/BLI_vfontdata.h new file mode 100644 index 00000000000..3f2b03cba05 --- /dev/null +++ b/source/blender/blenlib/BLI_vfontdata.h @@ -0,0 +1,66 @@ +/** + * @file BLI_vfontdata.h + * + * A structure to represent vector fonts, + * and to load them from PostScript fonts. + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + */ + +#ifndef BLI_VFONTDATA_H +#define BLI_VFONTDATA_H + +#include "DNA_listBase.h" + +struct PackedFile; + +#define MAX_VF_CHARS 256 + +typedef struct VFontData { + ListBase nurbsbase[MAX_VF_CHARS]; + float resol[MAX_VF_CHARS]; + float width[MAX_VF_CHARS]; + float *points[MAX_VF_CHARS]; +} VFontData; + +/** + * 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); + +#endif diff --git a/source/blender/blenlib/BLI_winstuff.h b/source/blender/blenlib/BLI_winstuff.h new file mode 100644 index 00000000000..c376709ab84 --- /dev/null +++ b/source/blender/blenlib/BLI_winstuff.h @@ -0,0 +1,96 @@ +/** + * Compatibility-like things for windows. + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + */ +#pragma warning(once: 4761 4305 4244 4018) + +#define WIN32_LEAN_AND_MEAN +#include + +#undef near +#undef far +#undef rad +#undef rad1 +#undef rad2 +#undef rad3 +#undef vec +#undef rect +#undef rct1 +#undef rct2 + +#define near clipsta +#define far clipend + +#undef small + +#ifndef __WINSTUFF_H__ +#define __WINSTUFF_H__ + +#define M_PI 3.14159265358979323846 +#define M_PI_2 1.57079632679489661923 +#define M_SQRT2 1.41421356237309504880 +#define M_SQRT1_2 0.70710678118654752440 + +#define MAXPATHLEN MAX_PATH + +#define S_ISREG(x) ((x&S_IFMT) == S_IFREG) +#define S_ISDIR(x) ((x&S_IFMT) == S_IFDIR) + +typedef unsigned int mode_t; + +struct dirent { + int d_ino; + int d_off; + unsigned short d_reclen; + char *d_name; +}; + +typedef struct _DIR { + HANDLE handle; + WIN32_FIND_DATA data; + char path[MAX_PATH]; + long dd_loc; + long dd_size; + char dd_buf[4096]; + void *dd_direct; + + struct dirent direntry; +} DIR; + +void RegisterBlendExtension(char * str); +int strcasecmp (char *s1, char *s2); +int strncasecmp (char *s1, char *s2, int n); +DIR *opendir (const char *path); +struct dirent *readdir(DIR *dp); +int closedir (DIR *dp); + +#endif /* __WINSTUFF_H__ */ diff --git a/source/blender/blenlib/MTC_matrixops.h b/source/blender/blenlib/MTC_matrixops.h new file mode 100644 index 00000000000..2a57ba34136 --- /dev/null +++ b/source/blender/blenlib/MTC_matrixops.h @@ -0,0 +1,164 @@ +/* + * matrixops.h + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + */ + +#ifndef MATRIXOPS_H +#define MATRIXOPS_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* ------------------------------------------------------------------------- */ +/* need rewriting: */ +/** + * copy the left upp3 3 by 3 of m2 to m1 + */ +void MTC_Mat3CpyMat4(float m1[][3], float m2[][4]); + +/* ------------------------------------------------------------------------- */ +/* operations based on 4 by 4 matrices */ + +/** + * Copy m1 to m2 + */ +void MTC_Mat4CpyMat4(float m1[][4], float m2[][4]); + +/** + * Multiply all matrices after the first, leave the result in the + * first argument + */ +void MTC_Mat4MulSerie(float answ[][4], + float m1[][4], float m2[][4], float m3[][4], + float m4[][4], float m5[][4], float m6[][4], + float m7[][4], float m8[][4]); + +/** + * m1 = m2 matprod m3 + */ +void MTC_Mat4MulMat4(float m1[][4], float m2[][4], float m3[][4]); + +/** + * Do vec^t prod mat, result in vec. Ignore vec[3] (vec is a + * float[3]) + */ +void MTC_Mat4MulVecfl(float mat[][4], float *vec); + +/** + * Invert mat, result in inverse. Always returns 1 + */ +int MTC_Mat4Invert(float inverse[][4], float mat[][4]); + +/** + * Make the set of mat orthonormal (mat should already be orthogonal)? + * (doesn't appear to normalise properly?) + */ +void MTC_Mat4Ortho(float mat[][4]); + +/** + * vec = mat prod vec, result in vec, ignore fourth component entirely + * (4th component is _not_ accessed!!! vec is 3d) + */ +void MTC_Mat4Mul3Vecfl(float mat[][4], float *vec); + +/** + * vec = mat prod vec, result in vec + */ +void MTC_Mat4MulVec4fl(float mat[][4], float *vec); + +/** + * Set to the 4-D unity matrix + */ +void MTC_Mat4One(float m[][4]); + +/** + * Swap matrices m1 and m2 + */ +void MTC_Mat4SwapMat4(float m1[][4], float m2[][4]); + +/** + * Copy m2 to the top-left 3x3 of m1, don't touch the remaining elements. + */ +void MTC_Mat4CpyMat3nc(float m1[][4], float m2[][3]); + +/** + * m1 = m2 * m3, but only the top-left 3x3 + */ +void MTC_Mat4MulMat33(float m1[][3], float m2[][4], float m3[][3]); + +/* ------------------------------------------------------------------------- */ +/* Operations based on 3 by 3 matrices */ +/** + * Do vec^t prod mat, result in vec.(vex is 3d) + */ +void MTC_Mat3MulVecfl(float mat[][3], float *vec); + +/** + * Copy m1 to m2 + */ +void MTC_Mat3CpyMat3(float m1[][3], float m2[][3]); + +/** + * m1 = m2 prod m3 + */ +void MTC_Mat3MulMat3(float m1[][3], float m3[][3], float m2[][3]); + +/** + * vec = vec prod mat + */ +void MTC_Mat3MulVecd(float mat[][3], double *vec); + +/** + * Guess: invert matrix + * result goes to m1 + */ +void MTC_Mat3Inv(float m1[][3], float m2[][3]); + +/** + * Sort of a determinant matrix? Doesn't seem very adjoint to me... + * result goes to m1 + */ +void MTC_Mat3Adj(float m1[][3], float m[][3]); + +/** + * Set to the 3D unity matrix + */ +void MTC_Mat3One(float m[][3]); + +/* ------------------------------------------------------------------------- */ + +#ifdef __cplusplus +} +#endif + +#endif /* MATRIXOPS_H */ diff --git a/source/blender/blenlib/MTC_vectorops.h b/source/blender/blenlib/MTC_vectorops.h new file mode 100644 index 00000000000..34cff44b9ae --- /dev/null +++ b/source/blender/blenlib/MTC_vectorops.h @@ -0,0 +1,60 @@ +/* + * vectorops.h + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + */ + +#ifndef VECTOROPS_H +#define VECTOROPS_H + +/* ------------------------------------------------------------------------- */ + +void MTC_diff3Int(int v1[3], int v2[3], int v3[3]); +void MTC_cross3Int(int v1[3], int v2[3], int v3[3]); +int MTC_dot3Int(int v1[3], int v2[3]); + +void MTC_diff3Float(float v1[3], float v2[3], float v3[3]); +void MTC_cross3Float(float v1[3], float v2[3], float v3[3]); +float MTC_dot3Float(float v1[3], float v2[3]); +void MTC_cp3Float(float v1[3], float v2[3]); +/** + * Copy vector with a minus sign (so a = -b) + */ +void MTC_cp3FloatInv(float v1[3], float v2[3]); + +void MTC_swapInt(int *i1, int *i2); + +void MTC_diff3DFF(double v1[3], float v2[3], float v3[3]); +void MTC_cross3Double(double v1[3], double v2[3], double v3[3]); +float MTC_normalise3DF(float n[3]); + +/* ------------------------------------------------------------------------- */ +#endif /* VECTOROPS_H */ diff --git a/source/blender/blenlib/Makefile b/source/blender/blenlib/Makefile new file mode 100644 index 00000000000..12ee8c5ad8c --- /dev/null +++ b/source/blender/blenlib/Makefile @@ -0,0 +1,37 @@ +# +# $Id$ +# +# ***** BEGIN GPL/BL DUAL 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. The Blender +# Foundation also sells licenses for use in proprietary software under +# the Blender License. See http://www.blender.org/BL/ for information +# about this. +# +# 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/BL DUAL LICENSE BLOCK ***** +# +# Bounces make to subdirectories. + +SOURCEDIR = source/blender/blenlib +DIRS = intern + +include nan_subdirs.mk diff --git a/source/blender/blenlib/PIL_dynlib.h b/source/blender/blenlib/PIL_dynlib.h new file mode 100644 index 00000000000..2831b749385 --- /dev/null +++ b/source/blender/blenlib/PIL_dynlib.h @@ -0,0 +1,54 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + */ +#ifndef __PIL_DYNLIB_H__ +#define __PIL_DYNLIB_H__ + +typedef struct PILdynlib PILdynlib; + + PILdynlib* +PIL_dynlib_open( + char *name); + + void* +PIL_dynlib_find_symbol( + PILdynlib* lib, + char *symname); + + char* +PIL_dynlib_get_error_as_string( + PILdynlib* lib); + + void +PIL_dynlib_close( + PILdynlib* lib); + +#endif /* __PIL_DYNLIB_H__ */ diff --git a/source/blender/blenlib/PIL_time.h b/source/blender/blenlib/PIL_time.h new file mode 100644 index 00000000000..dbb4f5d5bbe --- /dev/null +++ b/source/blender/blenlib/PIL_time.h @@ -0,0 +1,61 @@ +/** + * @file PIL_time.h + * + * Platform independant time functions. + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + */ + +#ifndef PIL_TIME_H +#define PIL_TIME_H + +#ifdef __cplusplus +extern "C" { +#endif + +extern + /** Return an indication of time, expressed as + * seconds since some fixed point. Successive calls + * are guarenteed to generate values greator than or + * equal to the last call. + */ +double PIL_check_seconds_timer (void); + + /** + * Platform-independant sleep function. + * @param ms Number of milliseconds to sleep + */ +void PIL_sleep_ms (int ms); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/source/blender/blenlib/intern/BLI_callbacks.h b/source/blender/blenlib/intern/BLI_callbacks.h new file mode 100644 index 00000000000..072a274176d --- /dev/null +++ b/source/blender/blenlib/intern/BLI_callbacks.h @@ -0,0 +1,44 @@ +/** + * blenlib/BLI_editVert.h mar 2001 Nzc + * + * These callbacks are needed in the lib + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + */ + +#ifndef BLI_CALLBACKS_H +#define BLI_CALLBACKS_H + +// This is blenlib internal only +void callLocalErrorCallBack(char* msg); +int callLocalInterruptCallBack(void); + +#endif diff --git a/source/blender/blenlib/intern/BLI_dynstr.c b/source/blender/blenlib/intern/BLI_dynstr.c new file mode 100644 index 00000000000..c9b7737427a --- /dev/null +++ b/source/blender/blenlib/intern/BLI_dynstr.c @@ -0,0 +1,115 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + * Dynamically sized string ADT + */ + +#include +#include + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_dynstr.h" + +/***/ + +typedef struct DynStrElem DynStrElem; +struct DynStrElem { + DynStrElem *next; + + char *str; +}; + +struct DynStr { + DynStrElem *elems, *last; + int curlen; +}; + +/***/ + +DynStr *BLI_dynstr_new(void) { + DynStr *ds= MEM_mallocN(sizeof(*ds), "DynStr"); + ds->elems= ds->last= NULL; + ds->curlen= 0; + + return ds; +} + +void BLI_dynstr_append(DynStr *ds, char *cstr) { + DynStrElem *dse= malloc(sizeof(*dse)); + int cstrlen= strlen(cstr); + + dse->str= malloc(cstrlen+1); + memcpy(dse->str, cstr, cstrlen+1); + dse->next= NULL; + + if (!ds->last) + ds->last= ds->elems= dse; + else + ds->last= ds->last->next= dse; + + ds->curlen+= cstrlen; +} + +int BLI_dynstr_get_len(DynStr *ds) { + return ds->curlen; +} + +char *BLI_dynstr_get_cstring(DynStr *ds) { + char *s, *rets= MEM_mallocN(ds->curlen+1, "dynstr_cstring"); + DynStrElem *dse; + + for (s= rets, dse= ds->elems; dse; dse= dse->next) { + int slen= strlen(dse->str); + + memcpy(s, dse->str, slen); + + s+= slen; + } + rets[ds->curlen]= '\0'; + + return rets; +} + +void BLI_dynstr_free(DynStr *ds) { + DynStrElem *dse; + + for (dse= ds->elems; dse; ) { + DynStrElem *n= dse->next; + + free(dse->str); + free(dse); + + dse= n; + } + + MEM_freeN(ds); +} diff --git a/source/blender/blenlib/intern/BLI_fileops.h b/source/blender/blenlib/intern/BLI_fileops.h new file mode 100644 index 00000000000..22248d4f5e6 --- /dev/null +++ b/source/blender/blenlib/intern/BLI_fileops.h @@ -0,0 +1,49 @@ +/** + * blenlib/BLI_listBase.h mar 2001 Nzc + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + * + * More low-level fileops from Daniel Dunbar. Two functions were also + * defined in storage.c. These are the old fop_ prefixes. There is + * definitely some redundancy here! + * */ + +#ifndef BLI_FILEOPS_H +#define BLI_FILEOPS_H + +char *first_slash(char *string); + +/* only for the sane unix world: direct calls to system functions :( */ +#ifndef WIN32 +void BLI_setCmdCallBack(int (*f)(char*)); +#endif + +#endif diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c new file mode 100644 index 00000000000..d0f1f78fb73 --- /dev/null +++ b/source/blender/blenlib/intern/BLI_ghash.c @@ -0,0 +1,184 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + * A general (pointer -> pointer) hash table ADT + */ + +#include +#include + +#include "MEM_guardedalloc.h" + +#include "BLI_ghash.h" + +/***/ + +static unsigned int hashsizes[]= { + 1, 3, 5, 11, 17, 37, 67, 131, 257, 521, 1031, 2053, 4099, 8209, + 16411, 32771, 65537, 131101, 262147, 524309, 1048583, 2097169, + 4194319, 8388617, 16777259, 33554467, 67108879, 134217757, + 268435459 +}; + +/***/ + +typedef struct Entry Entry; +struct Entry { + Entry *next; + + void *key, *val; +}; + +struct GHash { + GHashHashFP hashfp; + GHashCmpFP cmpfp; + + Entry **buckets; + int nbuckets, nentries, cursize; +}; + +/***/ + +GHash *BLI_ghash_new(GHashHashFP hashfp, GHashCmpFP cmpfp) { + GHash *gh= MEM_mallocN(sizeof(*gh), "GHash"); + gh->hashfp= hashfp; + gh->cmpfp= cmpfp; + + gh->cursize= 0; + gh->nentries= 0; + gh->nbuckets= hashsizes[gh->cursize]; + + gh->buckets= malloc(gh->nbuckets*sizeof(*gh->buckets)); + memset(gh->buckets, 0, gh->nbuckets*sizeof(*gh->buckets)); + + return gh; +} + +void BLI_ghash_insert(GHash *gh, void *key, void *val) { + unsigned int hash= gh->hashfp(key)%gh->nbuckets; + Entry *e= malloc(sizeof(*e)); + + e->key= key; + e->val= val; + e->next= gh->buckets[hash]; + gh->buckets[hash]= e; + + if (++gh->nentries>gh->nbuckets*3) { + Entry *e, **old= gh->buckets; + int i, nold= gh->nbuckets; + + gh->nbuckets= hashsizes[++gh->cursize]; + gh->buckets= malloc(gh->nbuckets*sizeof(*gh->buckets)); + memset(gh->buckets, 0, gh->nbuckets*sizeof(*gh->buckets)); + + for (i=0; inext; + + hash= gh->hashfp(e->key)%gh->nbuckets; + e->next= gh->buckets[hash]; + gh->buckets[hash]= e; + + e= n; + } + } + + free(old); + } +} + +void* BLI_ghash_lookup(GHash *gh, void *key) { + unsigned int hash= gh->hashfp(key)%gh->nbuckets; + Entry *e; + + for (e= gh->buckets[hash]; e; e= e->next) + if (gh->cmpfp(key, e->key)==0) + return e->val; + + return NULL; +} + +int BLI_ghash_haskey(GHash *gh, void *key) { + unsigned int hash= gh->hashfp(key)%gh->nbuckets; + Entry *e; + + for (e= gh->buckets[hash]; e; e= e->next) + if (gh->cmpfp(key, e->key)==0) + return 1; + + return 0; +} + +void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp) { + int i; + + for (i=0; inbuckets; i++) { + Entry *e; + + for (e= gh->buckets[i]; e; ) { + Entry *n= e->next; + + if (keyfreefp) keyfreefp(e->key); + if (valfreefp) valfreefp(e->val); + free(e); + + e= n; + } + } + + free(gh->buckets); + MEM_freeN(gh); +} + +/***/ + +unsigned int BLI_ghashutil_ptrhash(void *key) { + return (unsigned int) key; +} +int BLI_ghashutil_ptrcmp(void *a, void *b) { + if (a==b) + return 0; + else + return (anext)):0; + } else { + int len; + + for (len=0; list; list= list->next) + len++; + + return len; + } +} + +void BLI_linklist_reverse(LinkNode **listp) { + LinkNode *rhead= NULL, *cur= *listp; + + while (cur) { + LinkNode *next= cur->next; + + cur->next= rhead; + rhead= cur; + + cur= next; + } + + *listp= rhead; +} + +void BLI_linklist_prepend(LinkNode **listp, void *ptr) { + LinkNode *nlink= MEM_mallocN(sizeof(*nlink), "nlink"); + nlink->link= ptr; + + nlink->next= *listp; + *listp= nlink; +} + +void BLI_linklist_prepend_arena(LinkNode **listp, void *ptr, MemArena *ma) { + LinkNode *nlink= BLI_memarena_alloc(ma, sizeof(*nlink)); + nlink->link= ptr; + + nlink->next= *listp; + *listp= nlink; +} + +void BLI_linklist_free(LinkNode *list, LinkNodeFreeFP freefunc) { + while (list) { + LinkNode *next= list->next; + + if (freefunc) + freefunc(list->link); + MEM_freeN(list); + + list= next; + } +} + +void BLI_linklist_apply(LinkNode *list, LinkNodeApplyFP applyfunc) { + for (; list; list= list->next) + applyfunc(list->link); +} diff --git a/source/blender/blenlib/intern/BLI_memarena.c b/source/blender/blenlib/intern/BLI_memarena.c new file mode 100644 index 00000000000..596624fcc9e --- /dev/null +++ b/source/blender/blenlib/intern/BLI_memarena.c @@ -0,0 +1,80 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + * Efficient memory allocation for lots of similar small chunks. + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_memarena.h" +#include "BLI_linklist.h" + +struct MemArena { + unsigned char *curbuf; + int bufsize, cursize; + + LinkNode *bufs; +}; + +MemArena *BLI_memarena_new(int bufsize) { + MemArena *ma= MEM_callocN(sizeof(*ma), "memarena"); + ma->bufsize= bufsize; + + return ma; +} +void BLI_memarena_free(MemArena *ma) { + BLI_linklist_free(ma->bufs, MEM_freeN); + MEM_freeN(ma); +} + + /* amt must be power of two */ +#define PADUP(num, amt) ((num+(amt-1))&~(amt-1)) + +void *BLI_memarena_alloc(MemArena *ma, int size) { + void *ptr; + + /* ensure proper alignment by rounding + * size up to multiple of 8 */ + size= PADUP(size, 8); + + if (size>=ma->cursize) { + ma->cursize= (size>ma->bufsize)?size:ma->bufsize; + ma->curbuf= MEM_mallocN(ma->cursize, "ma->curbuf"); + + BLI_linklist_prepend(&ma->bufs, ma->curbuf); + } + + ptr= ma->curbuf; + ma->curbuf+= size; + ma->cursize-= size; + + return ptr; +} diff --git a/source/blender/blenlib/intern/BLI_scanfill.h b/source/blender/blenlib/intern/BLI_scanfill.h new file mode 100644 index 00000000000..405830b7a39 --- /dev/null +++ b/source/blender/blenlib/intern/BLI_scanfill.h @@ -0,0 +1,41 @@ +/** + * blenlib/BLI_scanfill.h mar 2001 Nzc + * + * Filling meshes. + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + */ + +#ifndef BLI_SCANFILL_H +#define BLI_SCANFILL_H + + +#endif diff --git a/source/blender/blenlib/intern/BLI_storage.h b/source/blender/blenlib/intern/BLI_storage.h new file mode 100644 index 00000000000..ba5385f70bf --- /dev/null +++ b/source/blender/blenlib/intern/BLI_storage.h @@ -0,0 +1,40 @@ +/* $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + */ +#ifndef BLI_STORAGE_H +#define BLI_STORAGE_H + +#include "BLI_storage_types.h" + +void BLI_adddirstrings(void); +void BLI_builddir(char *dirname, char *relname); +int BLI_compare(struct direntry *entry1, struct direntry *entry2); + +#endif /* BLI_STORAGE_H */ diff --git a/source/blender/blenlib/intern/BLI_util.h b/source/blender/blenlib/intern/BLI_util.h new file mode 100644 index 00000000000..2f78c1acc0c --- /dev/null +++ b/source/blender/blenlib/intern/BLI_util.h @@ -0,0 +1,47 @@ +/** + * blenlib/BLI_storage_types.h + * + * Some types for dealing with directories + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL 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; + +/* void addlisttolist(struct ListBase *list1, struct ListBase *list2); */ + +#endif diff --git a/source/blender/blenlib/intern/Makefile b/source/blender/blenlib/intern/Makefile new file mode 100644 index 00000000000..ccca2fccf11 --- /dev/null +++ b/source/blender/blenlib/intern/Makefile @@ -0,0 +1,51 @@ +# +# $Id$ +# +# ***** BEGIN GPL/BL DUAL 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. The Blender +# Foundation also sells licenses for use in proprietary software under +# the Blender License. See http://www.blender.org/BL/ for information +# about this. +# +# 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/BL DUAL LICENSE BLOCK ***** +# +# + +LIBNAME = blenlib +DIR = $(OCGDIR)/blender/$(LIBNAME) + +include nan_compile.mk + +ifeq ($(OS),$(findstring $(OS), "beos darwin freebsd linux openbsd solaris windows")) + CFLAGS += -funsigned-char +endif + +CPPFLAGS += $(LEVEL_2_C_WARNINGS) + +# path to SDNA types +CPPFLAGS += -I../../makesdna +# path to our own external headerfiles +CPPFLAGS += -I.. +# path to the guarded memory allocator +CPPFLAGS += -I$(NAN_GUARDEDALLOC)/include + diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c new file mode 100644 index 00000000000..49f5772c6c3 --- /dev/null +++ b/source/blender/blenlib/intern/arithb.c @@ -0,0 +1,2355 @@ + +/* formules voor blender + * + * sort of cleaned up mar-01 nzc + * + * Functions here get counterparts with MTC prefixes. Basically, we phase + * out the calls here in favour of fully prototyped versions. + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + */ + +/* ************************ FUNKTIES **************************** */ + +#include +#include +#include +#include + +#ifdef __sun__ +#include +#endif + +#if !defined(__sgi) && !defined(WIN32) +#include +#include +#endif + +#include +#include "BLI_arithb.h" + +/* A few small defines. Keep'em local! */ +#define SMALL_NUMBER 1.e-8 +#define ABS(x) ((x) < 0 ? -(x) : (x)) +#define SWAP(type, a, b) { type sw_ap; sw_ap=(a); (a)=(b); (b)=sw_ap; } + + +#if defined(WIN32) || defined(__APPLE__) +#include +#define M_PI 3.14159265358979323846 +#define M_SQRT2 1.41421356237309504880 + +#endif /* defined(WIN32) || defined(__APPLE__) */ + + +float saacos(float fac) +{ + if(fac<= -1.0f) return (float)M_PI; + else if(fac>=1.0f) return 0.0; + else return (float)acos(fac); +} + +float sasqrt(float fac) +{ + if(fac<=0.0) return 0.0; + return (float)sqrt(fac); +} + +float Normalise(float *n) +{ + float d; + + d= n[0]*n[0]+n[1]*n[1]+n[2]*n[2]; + /* FLT_EPSILON is too large! A larger value causes normalise errors in a scaled down utah teapot */ + if(d>0.0000000000001) { + 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; + } + return d; +} + +void Crossf(float *c, const float *a, const float *b) +{ + c[0] = a[1] * b[2] - a[2] * b[1]; + c[1] = a[2] * b[0] - a[0] * b[2]; + c[2] = a[0] * b[1] - a[1] * b[0]; +} + +float Inpf(const float *v1, const float *v2) +{ + return v1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2]; +} + +void Mat3Transp(float mat[][3]) +{ + float t; + + t = mat[0][1] ; + mat[0][1] = mat[1][0] ; + mat[1][0] = t; + t = mat[0][2] ; + mat[0][2] = mat[2][0] ; + mat[2][0] = t; + t = mat[1][2] ; + mat[1][2] = mat[2][1] ; + mat[2][1] = t; +} + +void Mat4Transp(float mat[][4]) +{ + float t; + + t = mat[0][1] ; + mat[0][1] = mat[1][0] ; + mat[1][0] = t; + t = mat[0][2] ; + mat[0][2] = mat[2][0] ; + mat[2][0] = t; + t = mat[0][3] ; + mat[0][3] = mat[3][0] ; + mat[3][0] = t; + + t = mat[1][2] ; + mat[1][2] = mat[2][1] ; + mat[2][1] = t; + t = mat[1][3] ; + mat[1][3] = mat[3][1] ; + mat[3][1] = t; + + t = mat[2][3] ; + mat[2][3] = mat[3][2] ; + mat[3][2] = t; +} + + +/* + * invertmat - + * computes the inverse of mat and puts it in inverse. Returns + * TRUE on success (i.e. can always find a pivot) and FALSE on failure. + * Uses Gaussian Elimination with partial (maximal column) pivoting. + * + * Mark Segal - 1992 + */ + +int Mat4Invert(float inverse[][4], const float mat[][4]) +{ + int i, j, k; + double temp; + float tempmat[4][4]; + float max; + int maxj; + + /* Set inverse to identity */ + for (i=0; i<4; i++) + for (j=0; j<4; j++) + inverse[i][j] = 0; + for (i=0; i<4; i++) + inverse[i][i] = 1; + + /* Copy original matrix so we don't mess it up */ + for(i = 0; i < 4; i++) + for(j = 0; j <4; j++) + tempmat[i][j] = mat[i][j]; + + for(i = 0; i < 4; i++) { + /* Look for row with max pivot */ + max = ABS(tempmat[i][i]); + maxj = i; + for(j = i + 1; j < 4; j++) { + if(ABS(tempmat[j][i]) > max) { + max = ABS(tempmat[j][i]); + maxj = j; + } + } + /* Swap rows if necessary */ + if (maxj != i) { + for( k = 0; k < 4; k++) { + SWAP(float, tempmat[i][k], tempmat[maxj][k]); + SWAP(float, inverse[i][k], inverse[maxj][k]); + } + } + + temp = tempmat[i][i]; + if (temp == 0) + return 0; /* No non-zero pivot */ + for(k = 0; k < 4; k++) { + tempmat[i][k] = (float)(tempmat[i][k]/temp); + inverse[i][k] = (float)(inverse[i][k]/temp); + } + for(j = 0; j < 4; j++) { + if(j != i) { + temp = tempmat[j][i]; + for(k = 0; k < 4; k++) { + tempmat[j][k] -= (float)(tempmat[i][k]*temp); + inverse[j][k] -= (float)(inverse[i][k]*temp); + } + } + } + } + return 1; +} +#ifdef TEST_ACTIVE +void Mat4InvertSimp(float inverse[][4], const float mat[][4]) +{ + /* alleen HOEK bewarende Matrices */ + /* gebaseerd op GG IV pag 205 */ + float scale; + + scale= mat[0][0]*mat[0][0] + mat[1][0]*mat[1][0] + mat[2][0]*mat[2][0]; + if(scale==0.0) return; + + scale= 1.0/scale; + + /* transpose en scale */ + inverse[0][0]= scale*mat[0][0]; + inverse[1][0]= scale*mat[0][1]; + inverse[2][0]= scale*mat[0][2]; + inverse[0][1]= scale*mat[1][0]; + inverse[1][1]= scale*mat[1][1]; + inverse[2][1]= scale*mat[1][2]; + inverse[0][2]= scale*mat[2][0]; + inverse[1][2]= scale*mat[2][1]; + inverse[2][2]= scale*mat[2][2]; + + inverse[3][0]= -(inverse[0][0]*mat[3][0] + inverse[1][0]*mat[3][1] + inverse[2][0]*mat[3][2]); + inverse[3][1]= -(inverse[0][1]*mat[3][0] + inverse[1][1]*mat[3][1] + inverse[2][1]*mat[3][2]); + inverse[3][2]= -(inverse[0][2]*mat[3][0] + inverse[1][2]*mat[3][1] + inverse[2][2]*mat[3][2]); + + inverse[0][3]= inverse[1][3]= inverse[2][3]= 0.0; + inverse[3][3]= 1.0; +} +#endif +/* struct Matrix4; */ + +#ifdef TEST_ACTIVE +/* this seems to be unused.. */ + +void Mat4Inv(float *m1, const float *m2) +{ + +/* This gets me into trouble: */ + float mat1[3][3], mat2[3][3]; + +/* void Mat3Inv(); */ +/* void Mat3CpyMat4(); */ +/* void Mat4CpyMat3(); */ + + Mat3CpyMat4((float*)mat2,m2); + Mat3Inv((float*)mat1, (float*) mat2); + Mat4CpyMat3(m1, mat1); + +} +#endif + + +float Det2x2(float a,float b,float c,float d) +{ + + return a*d - b*c; +} + + + +float Det3x3(float a1, float a2, float a3, + float b1, float b2, float b3, + float c1, float c2, float c3 ) +{ + float ans; + + ans = a1 * Det2x2( b2, b3, c2, c3 ) + - b1 * Det2x2( a2, a3, c2, c3 ) + + c1 * Det2x2( a2, a3, b2, b3 ); + + return ans; +} + +float Det4x4(const float m[][4]) +{ + float ans; + float a1,a2,a3,a4,b1,b2,b3,b4,c1,c2,c3,c4,d1,d2,d3,d4; + + a1= m[0][0]; + b1= m[0][1]; + c1= m[0][2]; + d1= m[0][3]; + + a2= m[1][0]; + b2= m[1][1]; + c2= m[1][2]; + d2= m[1][3]; + + a3= m[2][0]; + b3= m[2][1]; + c3= m[2][2]; + d3= m[2][3]; + + a4= m[3][0]; + b4= m[3][1]; + c4= m[3][2]; + d4= m[3][3]; + + ans = a1 * Det3x3( b2, b3, b4, c2, c3, c4, d2, d3, d4) + - b1 * Det3x3( a2, a3, a4, c2, c3, c4, d2, d3, d4) + + c1 * Det3x3( a2, a3, a4, b2, b3, b4, d2, d3, d4) + - d1 * Det3x3( a2, a3, a4, b2, b3, b4, c2, c3, c4); + + return ans; +} + + +void Mat4Adj(float out[][4], const float in[][4]) /* out = ADJ(in) */ +{ + float a1, a2, a3, a4, b1, b2, b3, b4; + float c1, c2, c3, c4, d1, d2, d3, d4; + + a1= in[0][0]; + b1= in[0][1]; + c1= in[0][2]; + d1= in[0][3]; + + a2= in[1][0]; + b2= in[1][1]; + c2= in[1][2]; + d2= in[1][3]; + + a3= in[2][0]; + b3= in[2][1]; + c3= in[2][2]; + d3= in[2][3]; + + a4= in[3][0]; + b4= in[3][1]; + c4= in[3][2]; + d4= in[3][3]; + + + out[0][0] = Det3x3( b2, b3, b4, c2, c3, c4, d2, d3, d4); + out[1][0] = - Det3x3( a2, a3, a4, c2, c3, c4, d2, d3, d4); + out[2][0] = Det3x3( a2, a3, a4, b2, b3, b4, d2, d3, d4); + out[3][0] = - Det3x3( a2, a3, a4, b2, b3, b4, c2, c3, c4); + + out[0][1] = - Det3x3( b1, b3, b4, c1, c3, c4, d1, d3, d4); + out[1][1] = Det3x3( a1, a3, a4, c1, c3, c4, d1, d3, d4); + out[2][1] = - Det3x3( a1, a3, a4, b1, b3, b4, d1, d3, d4); + out[3][1] = Det3x3( a1, a3, a4, b1, b3, b4, c1, c3, c4); + + out[0][2] = Det3x3( b1, b2, b4, c1, c2, c4, d1, d2, d4); + out[1][2] = - Det3x3( a1, a2, a4, c1, c2, c4, d1, d2, d4); + out[2][2] = Det3x3( a1, a2, a4, b1, b2, b4, d1, d2, d4); + out[3][2] = - Det3x3( a1, a2, a4, b1, b2, b4, c1, c2, c4); + + out[0][3] = - Det3x3( b1, b2, b3, c1, c2, c3, d1, d2, d3); + out[1][3] = Det3x3( a1, a2, a3, c1, c2, c3, d1, d2, d3); + out[2][3] = - Det3x3( a1, a2, a3, b1, b2, b3, d1, d2, d3); + out[3][3] = Det3x3( a1, a2, a3, b1, b2, b3, c1, c2, c3); +} + +void Mat4InvGG(float out[][4], const float in[][4]) /* van Graphic Gems I, out= INV(in) */ +{ + int i, j; + float det; + + /* calculate the adjoint matrix */ + + Mat4Adj(out,in); + + det = Det4x4(out); + + if ( fabs( det ) < SMALL_NUMBER) { + return; + } + + /* scale the adjoint matrix to get the inverse */ + + for (i=0; i<4; i++) + for(j=0; j<4; j++) + out[i][j] = out[i][j] / det; + + /* de laatste factor is niet altijd 1. Hierdoor moet eigenlijk nog gedeeld worden */ +} + + +void Mat3Inv(float m1[][3], const float m2[][3]) +{ + short a,b; + float det; + + /* eerst adjoint */ + Mat3Adj(m1,m2); + + /* dan det oude mat! */ + det= m2[0][0]* (m2[1][1]*m2[2][2] - m2[1][2]*m2[2][1]) + -m2[1][0]* (m2[0][1]*m2[2][2] - m2[0][2]*m2[2][1]) + +m2[2][0]* (m2[0][1]*m2[1][2] - m2[0][2]*m2[1][1]); + + if(det==0) det=1; + det= 1/det; + for(a=0;a<3;a++) { + for(b=0;b<3;b++) { + m1[a][b]*=det; + } + } +} + +void Mat3Adj(float m1[][3], const float m[][3]) +{ + m1[0][0]=m[1][1]*m[2][2]-m[1][2]*m[2][1]; + m1[0][1]= -m[0][1]*m[2][2]+m[0][2]*m[2][1]; + m1[0][2]=m[0][1]*m[1][2]-m[0][2]*m[1][1]; + + m1[1][0]= -m[1][0]*m[2][2]+m[1][2]*m[2][0]; + m1[1][1]=m[0][0]*m[2][2]-m[0][2]*m[2][0]; + m1[1][2]= -m[0][0]*m[1][2]+m[0][2]*m[1][0]; + + m1[2][0]=m[1][0]*m[2][1]-m[1][1]*m[2][0]; + m1[2][1]= -m[0][0]*m[2][1]+m[0][1]*m[2][0]; + m1[2][2]=m[0][0]*m[1][1]-m[0][1]*m[1][0]; +} + +void Mat4MulMat4(float m1[][4], const float m2[][4], const float m3[][4]) +{ + /* matrix product: m1[j][k] = m2[j][i].m3[i][k] */ + + m1[0][0] = m2[0][0]*m3[0][0] + m2[0][1]*m3[1][0] + m2[0][2]*m3[2][0] + m2[0][3]*m3[3][0]; + m1[0][1] = m2[0][0]*m3[0][1] + m2[0][1]*m3[1][1] + m2[0][2]*m3[2][1] + m2[0][3]*m3[3][1]; + m1[0][2] = m2[0][0]*m3[0][2] + m2[0][1]*m3[1][2] + m2[0][2]*m3[2][2] + m2[0][3]*m3[3][2]; + m1[0][3] = m2[0][0]*m3[0][3] + m2[0][1]*m3[1][3] + m2[0][2]*m3[2][3] + m2[0][3]*m3[3][3]; + + m1[1][0] = m2[1][0]*m3[0][0] + m2[1][1]*m3[1][0] + m2[1][2]*m3[2][0] + m2[1][3]*m3[3][0]; + m1[1][1] = m2[1][0]*m3[0][1] + m2[1][1]*m3[1][1] + m2[1][2]*m3[2][1] + m2[1][3]*m3[3][1]; + m1[1][2] = m2[1][0]*m3[0][2] + m2[1][1]*m3[1][2] + m2[1][2]*m3[2][2] + m2[1][3]*m3[3][2]; + m1[1][3] = m2[1][0]*m3[0][3] + m2[1][1]*m3[1][3] + m2[1][2]*m3[2][3] + m2[1][3]*m3[3][3]; + + m1[2][0] = m2[2][0]*m3[0][0] + m2[2][1]*m3[1][0] + m2[2][2]*m3[2][0] + m2[2][3]*m3[3][0]; + m1[2][1] = m2[2][0]*m3[0][1] + m2[2][1]*m3[1][1] + m2[2][2]*m3[2][1] + m2[2][3]*m3[3][1]; + m1[2][2] = m2[2][0]*m3[0][2] + m2[2][1]*m3[1][2] + m2[2][2]*m3[2][2] + m2[2][3]*m3[3][2]; + m1[2][3] = m2[2][0]*m3[0][3] + m2[2][1]*m3[1][3] + m2[2][2]*m3[2][3] + m2[2][3]*m3[3][3]; + + m1[3][0] = m2[3][0]*m3[0][0] + m2[3][1]*m3[1][0] + m2[3][2]*m3[2][0] + m2[3][3]*m3[3][0]; + m1[3][1] = m2[3][0]*m3[0][1] + m2[3][1]*m3[1][1] + m2[3][2]*m3[2][1] + m2[3][3]*m3[3][1]; + m1[3][2] = m2[3][0]*m3[0][2] + m2[3][1]*m3[1][2] + m2[3][2]*m3[2][2] + m2[3][3]*m3[3][2]; + m1[3][3] = m2[3][0]*m3[0][3] + m2[3][1]*m3[1][3] + m2[3][2]*m3[2][3] + m2[3][3]*m3[3][3]; + +} +#ifdef TEST_ACTIVE +void subMat4MulMat4(float *m1, const float *m2, const float *m3) +{ + + m1[0]= m2[0]*m3[0] + m2[1]*m3[4] + m2[2]*m3[8]; + m1[1]= m2[0]*m3[1] + m2[1]*m3[5] + m2[2]*m3[9]; + m1[2]= m2[0]*m3[2] + m2[1]*m3[6] + m2[2]*m3[10]; + m1[3]= m2[0]*m3[3] + m2[1]*m3[7] + m2[2]*m3[11] + m2[3]; + m1+=4; + m2+=4; + m1[0]= m2[0]*m3[0] + m2[1]*m3[4] + m2[2]*m3[8]; + m1[1]= m2[0]*m3[1] + m2[1]*m3[5] + m2[2]*m3[9]; + m1[2]= m2[0]*m3[2] + m2[1]*m3[6] + m2[2]*m3[10]; + m1[3]= m2[0]*m3[3] + m2[1]*m3[7] + m2[2]*m3[11] + m2[3]; + m1+=4; + m2+=4; + m1[0]= m2[0]*m3[0] + m2[1]*m3[4] + m2[2]*m3[8]; + m1[1]= m2[0]*m3[1] + m2[1]*m3[5] + m2[2]*m3[9]; + m1[2]= m2[0]*m3[2] + m2[1]*m3[6] + m2[2]*m3[10]; + m1[3]= m2[0]*m3[3] + m2[1]*m3[7] + m2[2]*m3[11] + m2[3]; +} +#endif + +#ifndef TEST_ACTIVE +void Mat3MulMat3(float m1[][3], const float m3[][3], const float m2[][3]) +#else +void Mat3MulMat3(float *m1, const float *m3, const float *m2) +#endif +{ + /* m1[i][j] = m2[i][k]*m3[k][j], args are flipped! */ +#ifndef TEST_ACTIVE + m1[0][0]= m2[0][0]*m3[0][0] + m2[0][1]*m3[1][0] + m2[0][2]*m3[2][0]; + m1[0][1]= m2[0][0]*m3[0][1] + m2[0][1]*m3[1][1] + m2[0][2]*m3[2][1]; + m1[0][2]= m2[0][0]*m3[0][2] + m2[0][1]*m3[1][2] + m2[0][2]*m3[2][2]; + + m1[1][0]= m2[1][0]*m3[0][0] + m2[1][1]*m3[1][0] + m2[1][2]*m3[2][0]; + m1[1][1]= m2[1][0]*m3[0][1] + m2[1][1]*m3[1][1] + m2[1][2]*m3[2][1]; + m1[1][2]= m2[1][0]*m3[0][2] + m2[1][1]*m3[1][2] + m2[1][2]*m3[2][2]; + + m1[2][0]= m2[2][0]*m3[0][0] + m2[2][1]*m3[1][0] + m2[2][2]*m3[2][0]; + m1[2][1]= m2[2][0]*m3[0][1] + m2[2][1]*m3[1][1] + m2[2][2]*m3[2][1]; + m1[2][2]= m2[2][0]*m3[0][2] + m2[2][1]*m3[1][2] + m2[2][2]*m3[2][2]; +#else + m1[0]= m2[0]*m3[0] + m2[1]*m3[3] + m2[2]*m3[6]; + m1[1]= m2[0]*m3[1] + m2[1]*m3[4] + m2[2]*m3[7]; + m1[2]= m2[0]*m3[2] + m2[1]*m3[5] + m2[2]*m3[8]; + m1+=3; + m2+=3; + m1[0]= m2[0]*m3[0] + m2[1]*m3[3] + m2[2]*m3[6]; + m1[1]= m2[0]*m3[1] + m2[1]*m3[4] + m2[2]*m3[7]; + m1[2]= m2[0]*m3[2] + m2[1]*m3[5] + m2[2]*m3[8]; + m1+=3; + m2+=3; + m1[0]= m2[0]*m3[0] + m2[1]*m3[3] + m2[2]*m3[6]; + m1[1]= m2[0]*m3[1] + m2[1]*m3[4] + m2[2]*m3[7]; + m1[2]= m2[0]*m3[2] + m2[1]*m3[5] + m2[2]*m3[8]; +#endif +} /* end of void Mat3MulMat3(float m1[][3], float m3[][3], float m2[][3]) */ + +void Mat4MulMat43(float (*m1)[4], const float (*m3)[4], const float (*m2)[3]) +{ + m1[0][0]= m2[0][0]*m3[0][0] + m2[0][1]*m3[1][0] + m2[0][2]*m3[2][0]; + m1[0][1]= m2[0][0]*m3[0][1] + m2[0][1]*m3[1][1] + m2[0][2]*m3[2][1]; + m1[0][2]= m2[0][0]*m3[0][2] + m2[0][1]*m3[1][2] + m2[0][2]*m3[2][2]; + m1[1][0]= m2[1][0]*m3[0][0] + m2[1][1]*m3[1][0] + m2[1][2]*m3[2][0]; + m1[1][1]= m2[1][0]*m3[0][1] + m2[1][1]*m3[1][1] + m2[1][2]*m3[2][1]; + m1[1][2]= m2[1][0]*m3[0][2] + m2[1][1]*m3[1][2] + m2[1][2]*m3[2][2]; + m1[2][0]= m2[2][0]*m3[0][0] + m2[2][1]*m3[1][0] + m2[2][2]*m3[2][0]; + m1[2][1]= m2[2][0]*m3[0][1] + m2[2][1]*m3[1][1] + m2[2][2]*m3[2][1]; + m1[2][2]= m2[2][0]*m3[0][2] + m2[2][1]*m3[1][2] + m2[2][2]*m3[2][2]; +} +/* m1 = m2 * m3, ignore the elements on the 4th row/column of m3*/ +void Mat3IsMat3MulMat4(float m1[][3], const float m2[][3], const float m3[][4]) +{ + /* m1[i][j] = m2[i][k] * m3[k][j] */ + m1[0][0] = m2[0][0] * m3[0][0] + m2[0][1] * m3[1][0] +m2[0][2] * m3[2][0]; + m1[0][1] = m2[0][0] * m3[0][1] + m2[0][1] * m3[1][1] +m2[0][2] * m3[2][1]; + m1[0][2] = m2[0][0] * m3[0][2] + m2[0][1] * m3[1][2] +m2[0][2] * m3[2][2]; + + m1[1][0] = m2[1][0] * m3[0][0] + m2[1][1] * m3[1][0] +m2[1][2] * m3[2][0]; + m1[1][1] = m2[1][0] * m3[0][1] + m2[1][1] * m3[1][1] +m2[1][2] * m3[2][1]; + m1[1][2] = m2[1][0] * m3[0][2] + m2[1][1] * m3[1][2] +m2[1][2] * m3[2][2]; + + m1[2][0] = m2[2][0] * m3[0][0] + m2[2][1] * m3[1][0] +m2[2][2] * m3[2][0]; + m1[2][1] = m2[2][0] * m3[0][1] + m2[2][1] * m3[1][1] +m2[2][2] * m3[2][1]; + m1[2][2] = m2[2][0] * m3[0][2] + m2[2][1] * m3[1][2] +m2[2][2] * m3[2][2]; +} + + + +void Mat4MulMat34(float (*m1)[4], const float (*m3)[3], const float (*m2)[4]) +{ + m1[0][0]= m2[0][0]*m3[0][0] + m2[0][1]*m3[1][0] + m2[0][2]*m3[2][0]; + m1[0][1]= m2[0][0]*m3[0][1] + m2[0][1]*m3[1][1] + m2[0][2]*m3[2][1]; + m1[0][2]= m2[0][0]*m3[0][2] + m2[0][1]*m3[1][2] + m2[0][2]*m3[2][2]; + m1[1][0]= m2[1][0]*m3[0][0] + m2[1][1]*m3[1][0] + m2[1][2]*m3[2][0]; + m1[1][1]= m2[1][0]*m3[0][1] + m2[1][1]*m3[1][1] + m2[1][2]*m3[2][1]; + m1[1][2]= m2[1][0]*m3[0][2] + m2[1][1]*m3[1][2] + m2[1][2]*m3[2][2]; + m1[2][0]= m2[2][0]*m3[0][0] + m2[2][1]*m3[1][0] + m2[2][2]*m3[2][0]; + m1[2][1]= m2[2][0]*m3[0][1] + m2[2][1]*m3[1][1] + m2[2][2]*m3[2][1]; + m1[2][2]= m2[2][0]*m3[0][2] + m2[2][1]*m3[1][2] + m2[2][2]*m3[2][2]; +} + +void Mat4CpyMat4(float m1[][4], const float m2[][4]) +{ + memcpy(m1, m2, 4*4*sizeof(float)); +} + +void Mat4SwapMat4(float *m1, float *m2) +{ + float t; + int i; + + for(i=0;i<16;i++) { + t= *m1; + *m1= *m2; + *m2= t; + m1++; + m2++; + } +} + +typedef float Mat3Row[3]; +typedef float Mat4Row[4]; + +#ifdef TEST_ACTIVE +void Mat3CpyMat4(float *m1p, const float *m2p) +#else +void Mat3CpyMat4(float m1[][3], const float m2[][4]) +#endif +{ +#ifdef TEST_ACTIVE + int i, j; + Mat3Row *m1= (Mat3Row *)m1p; + Mat4Row *m2= (Mat4Row *)m2p; + for ( i = 0; i++; i < 3) { + for (j = 0; j++; j < 3) { + m1p[3*i + j] = m2p[4*i + j]; + } + } +#endif + m1[0][0]= m2[0][0]; + m1[0][1]= m2[0][1]; + m1[0][2]= m2[0][2]; + + m1[1][0]= m2[1][0]; + m1[1][1]= m2[1][1]; + m1[1][2]= m2[1][2]; + + m1[2][0]= m2[2][0]; + m1[2][1]= m2[2][1]; + m1[2][2]= m2[2][2]; +} + +/* Butched. See .h for comment */ +/* void Mat4CpyMat3(float m1[][4], float m2[][3]) */ +#ifdef TEST_ACTIVE +void Mat4CpyMat3(float* m1, const float *m2) +{ + int i; + for (i = 0; i < 3; i++) { + m1[(4*i)] = m2[(3*i)]; + m1[(4*i) + 1]= m2[(3*i) + 1]; + m1[(4*i) + 2]= m2[(3*i) + 2]; + m1[(4*i) + 3]= 0.0; + i++; + } + + m1[12]=m1[13]= m1[14]= 0.0; + m1[15]= 1.0; +} +#else + +void Mat4CpyMat3(float m1[][4], const float m2[][3]) /* no clear */ +{ + m1[0][0]= m2[0][0]; + m1[0][1]= m2[0][1]; + m1[0][2]= m2[0][2]; + + m1[1][0]= m2[1][0]; + m1[1][1]= m2[1][1]; + m1[1][2]= m2[1][2]; + + m1[2][0]= m2[2][0]; + m1[2][1]= m2[2][1]; + m1[2][2]= m2[2][2]; + + /* Reevan's Bugfix */ + m1[0][3]=0.0F; + m1[1][3]=0.0F; + m1[2][3]=0.0F; + + m1[3][0]=0.0F; + m1[3][1]=0.0F; + m1[3][2]=0.0F; + m1[3][3]=1.0F; + + +} +#endif + +void Mat3CpyMat3(float m1[][3], const float m2[][3]) +{ + /* destination comes first: */ + memcpy(&m1[0], &m2[0], 9*sizeof(float)); +} + +void Mat3MulSerie(float answ[][3], + const float m1[][3], const float m2[][3], const float m3[][3], + const float m4[][3], const float m5[][3], const float m6[][3], + const float m7[][3], const float m8[][3]) +{ + float temp[3][3]; + + if(m1==0 || m2==0) return; + + + Mat3MulMat3(answ, m2, m1); + if(m3) { + Mat3MulMat3(temp, m3, answ); + if(m4) { + Mat3MulMat3(answ, m4, temp); + if(m5) { + Mat3MulMat3(temp, m5, answ); + if(m6) { + Mat3MulMat3(answ, m6, temp); + if(m7) { + Mat3MulMat3(temp, m7, answ); + if(m8) { + Mat3MulMat3(answ, m8, temp); + } + else Mat3CpyMat3(answ, temp); + } + } + else Mat3CpyMat3(answ, temp); + } + } + else Mat3CpyMat3(answ, temp); + } +} + +void Mat4MulSerie(float answ[][4], const float m1[][4], + const float m2[][4], const float m3[][4], const float m4[][4], + const float m5[][4], const float m6[][4], const float m7[][4], + const float m8[][4]) +{ + float temp[4][4]; + + if(m1==0 || m2==0) return; + + Mat4MulMat4(answ, m2, m1); + if(m3) { + Mat4MulMat4(temp, m3, answ); + if(m4) { + Mat4MulMat4(answ, m4, temp); + if(m5) { + Mat4MulMat4(temp, m5, answ); + if(m6) { + Mat4MulMat4(answ, m6, temp); + if(m7) { + Mat4MulMat4(temp, m7, answ); + if(m8) { + Mat4MulMat4(answ, m8, temp); + } + else Mat4CpyMat4(answ, temp); + } + } + else Mat4CpyMat4(answ, temp); + } + } + else Mat4CpyMat4(answ, temp); + } +} + + + +void Mat4Clr(float *m) +{ + memset(m, 0, 4*4*sizeof(float)); +} + +void Mat3Clr(float *m) +{ + memset(m, 0, 3*3*sizeof(float)); +} + +void Mat4One(float m[][4]) +{ + + m[0][0]= m[1][1]= m[2][2]= m[3][3]= 1.0; + m[0][1]= m[0][2]= m[0][3]= 0.0; + m[1][0]= m[1][2]= m[1][3]= 0.0; + m[2][0]= m[2][1]= m[2][3]= 0.0; + m[3][0]= m[3][1]= m[3][2]= 0.0; +} + +void Mat3One(float m[][3]) +{ + + m[0][0]= m[1][1]= m[2][2]= 1.0; + m[0][1]= m[0][2]= 0.0; + m[1][0]= m[1][2]= 0.0; + m[2][0]= m[2][1]= 0.0; +} + +void Mat4MulVec(const float mat[][4], int *vec) +{ + int x,y; + + x=vec[0]; + y=vec[1]; + vec[0]=(int)(x*mat[0][0] + y*mat[1][0] + mat[2][0]*vec[2] + mat[3][0]); + vec[1]=(int)(x*mat[0][1] + y*mat[1][1] + mat[2][1]*vec[2] + mat[3][1]); + vec[2]=(int)(x*mat[0][2] + y*mat[1][2] + mat[2][2]*vec[2] + mat[3][2]); +} + +void Mat4MulVecfl(const float mat[][4], float *vec) +{ + float x,y; + + x=vec[0]; + y=vec[1]; + vec[0]=x*mat[0][0] + y*mat[1][0] + mat[2][0]*vec[2] + mat[3][0]; + vec[1]=x*mat[0][1] + y*mat[1][1] + mat[2][1]*vec[2] + mat[3][1]; + vec[2]=x*mat[0][2] + y*mat[1][2] + mat[2][2]*vec[2] + mat[3][2]; +} + +void VecMat4MulVecfl(float *in, const float mat[][4], const float *vec) +{ + float x,y; + + x=vec[0]; + y=vec[1]; + in[0]= x*mat[0][0] + y*mat[1][0] + mat[2][0]*vec[2] + mat[3][0]; + in[1]= x*mat[0][1] + y*mat[1][1] + mat[2][1]*vec[2] + mat[3][1]; + in[2]= x*mat[0][2] + y*mat[1][2] + mat[2][2]*vec[2] + mat[3][2]; +} + +void Mat4Mul3Vecfl(const float mat[][4], float *vec) +{ + float x,y; + + x= vec[0]; + y= vec[1]; + vec[0]= x*mat[0][0] + y*mat[1][0] + mat[2][0]*vec[2]; + vec[1]= x*mat[0][1] + y*mat[1][1] + mat[2][1]*vec[2]; + vec[2]= x*mat[0][2] + y*mat[1][2] + mat[2][2]*vec[2]; +} + +void Mat4MulVec4fl(const float mat[][4], float *vec) +{ + float x,y,z; + + x=vec[0]; + y=vec[1]; + z= vec[2]; + vec[0]=x*mat[0][0] + y*mat[1][0] + z*mat[2][0] + mat[3][0]*vec[3]; + vec[1]=x*mat[0][1] + y*mat[1][1] + z*mat[2][1] + mat[3][1]*vec[3]; + vec[2]=x*mat[0][2] + y*mat[1][2] + z*mat[2][2] + mat[3][2]*vec[3]; + vec[3]=x*mat[0][3] + y*mat[1][3] + z*mat[2][3] + mat[3][3]*vec[3]; +} + +void Mat3MulVec(const float mat[][3], int *vec) +{ + int x,y; + + x=vec[0]; + y=vec[1]; + vec[0]= (int)(x*mat[0][0] + y*mat[1][0] + mat[2][0]*vec[2]); + vec[1]= (int)(x*mat[0][1] + y*mat[1][1] + mat[2][1]*vec[2]); + vec[2]= (int)(x*mat[0][2] + y*mat[1][2] + mat[2][2]*vec[2]); +} + +void Mat3MulVecfl(const float mat[][3], float *vec) +{ + float x,y; + + x=vec[0]; + y=vec[1]; + vec[0]= x*mat[0][0] + y*mat[1][0] + mat[2][0]*vec[2]; + vec[1]= x*mat[0][1] + y*mat[1][1] + mat[2][1]*vec[2]; + vec[2]= x*mat[0][2] + y*mat[1][2] + mat[2][2]*vec[2]; +} + +void Mat3MulVecd(const float mat[][3], double *vec) +{ + double x,y; + + x=vec[0]; + y=vec[1]; + vec[0]= x*mat[0][0] + y*mat[1][0] + mat[2][0]*vec[2]; + vec[1]= x*mat[0][1] + y*mat[1][1] + mat[2][1]*vec[2]; + vec[2]= x*mat[0][2] + y*mat[1][2] + mat[2][2]*vec[2]; +} + +void Mat3TransMulVecfl(const float mat[][3], float *vec) +{ + float x,y; + + x=vec[0]; + y=vec[1]; + vec[0]= x*mat[0][0] + y*mat[0][1] + mat[0][2]*vec[2]; + vec[1]= x*mat[1][0] + y*mat[1][1] + mat[1][2]*vec[2]; + vec[2]= x*mat[2][0] + y*mat[2][1] + mat[2][2]*vec[2]; +} + +void Mat3MulFloat(float *m, float f) +{ + int i; + + for(i=0;i<9;i++) m[i]*=f; +} + +void Mat4MulFloat(float *m, float f) +{ + int i; + + for(i=0;i<12;i++) m[i]*=f; /* tot 12 tellen: zonder vector */ +} + + +void Mat4MulFloat3(float *m, float f) /* alleen de scale component */ +{ + int i,j; + + for(i=0; i<3; i++) { + for(j=0; j<3; j++) { + + m[4*i+j] *= f; + } + } +} + +void VecStar(float mat[][3], const float *vec) +{ + + mat[0][0]= mat[1][1]= mat[2][2]= 0.0; + mat[0][1]= -vec[2]; + mat[0][2]= vec[1]; + mat[1][0]= vec[2]; + mat[1][2]= -vec[0]; + mat[2][0]= -vec[1]; + mat[2][1]= vec[0]; + +} +#ifdef TEST_ACTIVE +short EenheidsMat(float mat[][3]) +{ + + if(mat[0][0]==1.0 && mat[0][1]==0.0 && mat[0][2]==0.0) + if(mat[1][0]==0.0 && mat[1][1]==1.0 && mat[1][2]==0.0) + if(mat[2][0]==0.0 && mat[2][1]==0.0 && mat[2][2]==1.0) + return 1; + return 0; +} +#endif + +int FloatCompare(const float *v1, const float *v2, float limit) +{ + + if( fabs(v1[0]-v2[0])FLT_EPSILON) { + s= sqrt( tr); + q[0]= (float)s; + s*= 4.0; + q[1]= (float)((mat[1][2]-mat[2][1])/s); + q[2]= (float)((mat[2][0]-mat[0][2])/s); + q[3]= (float)((mat[0][1]-mat[1][0])/s); + } + else { + q[0]= 0.0f; + s= -0.5*(mat[1][1]+mat[2][2]); + + if(s>FLT_EPSILON) { + s= sqrt(s); + q[1]= (float)s; + q[2]= (float)(mat[0][1]/(2*s)); + q[3]= (float)(mat[0][2]/(2*s)); + } + else { + q[1]= 0.0f; + s= 0.5*(1.0-mat[2][2]); + + if(s>FLT_EPSILON) { + s= sqrt(s); + q[2]= (float)s; + q[3]= (float)(mat[1][2]/(2*s)); + } + else { + q[2]= 0.0f; + q[3]= 1.0f; + } + } + } + NormalQuat(q); +} + +void Mat3ToQuat_is_ok(const float wmat[][3], float *q) +{ + float mat[3][3], matr[3][3], matn[3][3], q1[4], q2[4], hoek, si, co, nor[3]; + + /* voor de netheid: op kopie werken */ + Mat3CpyMat3(mat, wmat); + Mat3Ortho(mat); + + /* roteer z-as matrix op z-as */ + + nor[0] = mat[2][1]; /* uitprodukt met (0,0,1) */ + nor[1] = -mat[2][0]; + nor[2] = 0.0; + Normalise(nor); + + co= mat[2][2]; + hoek= 0.5f*saacos(co); + + co= (float)cos(hoek); + si= (float)sin(hoek); + q1[0]= co; + q1[1]= -nor[0]*si; /* hier negatief, waarom is een raadsel */ + q1[2]= -nor[1]*si; + q1[3]= -nor[2]*si; + + /* roteer x-as van mat terug volgens inverse q1 */ + QuatToMat3(q1, matr); + Mat3Inv(matn, matr); + Mat3MulVecfl(matn, mat[0]); + + /* en zet de x-asssen gelijk */ + hoek= (float)(0.5*atan2(mat[0][1], mat[0][0])); + + co= (float)cos(hoek); + si= (float)sin(hoek); + q2[0]= co; + q2[1]= 0.0f; + q2[2]= 0.0f; + q2[3]= si; + + QuatMul(q, q1, q2); +} + + +void Mat4ToQuat(const float m[][4], float *q) +{ + float mat[3][3]; + + Mat3CpyMat4(mat, m); + Mat3ToQuat(mat, q); + +} + +void QuatOne(float *q) +{ + q[0]= q[2]= q[3]= 0.0; + q[1]= 1.0; +} + +void NormalQuat(float *q) +{ + float len; + + len= (float)sqrt(q[0]*q[0]+q[1]*q[1]+q[2]*q[2]+q[3]*q[3]); + if(len!=0.0) { + q[0]/= len; + q[1]/= len; + q[2]/= len; + q[3]/= len; + } else { + q[1]= 1.0f; + q[0]= q[2]= q[3]= 0.0f; + } +} + +float *vectoquat(const float *vec, short axis, short upflag) +{ + static float q1[4]; + float q2[4], nor[3], *fp, mat[3][3], hoek, si, co, x2, y2, z2, len1; + + /* eerst roteer naar as */ + if(axis>2) { + x2= vec[0] ; y2= vec[1] ; z2= vec[2]; + axis-= 3; + } + else { + x2= -vec[0] ; y2= -vec[1] ; z2= -vec[2]; + } + + q1[0]=1.0; + q1[1]=q1[2]=q1[3]= 0.0; + + len1= (float)sqrt(x2*x2+y2*y2+z2*z2); + if(len1 == 0.0) return(q1); + + /* nasty! I need a good routine for this... + * problem is a rotation of an Y axis to the negative Y-axis for example. + */ + + if(axis==0) { /* x-as */ + nor[0]= 0.0; + nor[1]= -z2; + nor[2]= y2; + + if( fabs(y2)+fabs(z2)<0.0001 ) { + nor[1]= 1.0; + } + + co= x2; + } + else if(axis==1) { /* y-as */ + nor[0]= z2; + nor[1]= 0.0; + nor[2]= -x2; + + if( fabs(x2)+fabs(z2)<0.0001 ) { + nor[2]= 1.0; + } + + co= y2; + } + else { /* z-as */ + nor[0]= -y2; + nor[1]= x2; + nor[2]= 0.0; + + if( fabs(x2)+fabs(y2)<0.0001 ) { + nor[0]= 1.0; + } + + co= z2; + } + co/= len1; + + Normalise(nor); + + hoek= 0.5f*saacos(co); + si= (float)sin(hoek); + q1[0]= (float)cos(hoek); + q1[1]= nor[0]*si; + q1[2]= nor[1]*si; + q1[3]= nor[2]*si; + + if(axis!=upflag) { + QuatToMat3(q1, mat); + + fp= mat[2]; + if(axis==0) { + if(upflag==1) hoek= (float)(0.5*atan2(fp[2], fp[1])); + else hoek= (float)(-0.5*atan2(fp[1], fp[2])); + } + else if(axis==1) { + if(upflag==0) hoek= (float)(-0.5*atan2(fp[2], fp[0])); + else hoek= (float)(0.5*atan2(fp[0], fp[2])); + } + else { + if(upflag==0) hoek= (float)(0.5*atan2(-fp[1], -fp[0])); + else hoek= (float)(-0.5*atan2(-fp[0], -fp[1])); + } + + co= (float)cos(hoek); + si= (float)(sin(hoek)/len1); + q2[0]= co; + q2[1]= x2*si; + q2[2]= y2*si; + q2[3]= z2*si; + + QuatMul(q1,q2,q1); + } + + return(q1); +} + +void VecUpMat3old(const float *vec, float mat[][3], short axis) +{ + float inp, up[3]; + short cox = 0, coy = 0, coz = 0; + + /* up varieeren heeft geen zin, is eigenlijk helemaal geen up! + */ + + up[0]= 0.0; + up[1]= 0.0; + up[2]= 1.0; + + if(axis==0) { + cox= 0; coy= 1; coz= 2; /* Y up Z tr */ + } + if(axis==1) { + cox= 1; coy= 2; coz= 0; /* Z up X tr */ + } + if(axis==2) { + cox= 2; coy= 0; coz= 1; /* X up Y tr */ + } + if(axis==3) { + cox= 0; coy= 2; coz= 1; /* */ + } + if(axis==4) { + cox= 1; coy= 0; coz= 2; /* */ + } + if(axis==5) { + cox= 2; coy= 1; coz= 0; /* Y up X tr */ + } + + mat[coz][0]= vec[0]; + mat[coz][1]= vec[1]; + mat[coz][2]= vec[2]; + Normalise((float *)mat[coz]); + + inp= mat[coz][0]*up[0] + mat[coz][1]*up[1] + mat[coz][2]*up[2]; + mat[coy][0]= up[0] - inp*mat[coz][0]; + mat[coy][1]= up[1] - inp*mat[coz][1]; + mat[coy][2]= up[2] - inp*mat[coz][2]; + + Normalise((float *)mat[coy]); + + Crossf(mat[cox], mat[coy], mat[coz]); + +} + +void VecUpMat3(float *vec, float mat[][3], short axis) +{ + float inp; + short cox = 0, coy = 0, coz = 0; + + /* up varieeren heeft geen zin, is eigenlijk helemaal geen up! + * zie VecUpMat3old + */ + + if(axis==0) { + cox= 0; coy= 1; coz= 2; /* Y up Z tr */ + } + if(axis==1) { + cox= 1; coy= 2; coz= 0; /* Z up X tr */ + } + if(axis==2) { + cox= 2; coy= 0; coz= 1; /* X up Y tr */ + } + if(axis==3) { + cox= 0; coy= 1; coz= 2; /* Y op -Z tr */ + vec[0]= -vec[0]; + vec[1]= -vec[1]; + vec[2]= -vec[2]; + } + if(axis==4) { + cox= 1; coy= 0; coz= 2; /* */ + } + if(axis==5) { + cox= 2; coy= 1; coz= 0; /* Y up X tr */ + } + + mat[coz][0]= vec[0]; + mat[coz][1]= vec[1]; + mat[coz][2]= vec[2]; + Normalise((float *)mat[coz]); + + inp= mat[coz][2]; + mat[coy][0]= - inp*mat[coz][0]; + mat[coy][1]= - inp*mat[coz][1]; + mat[coy][2]= 1.0f - inp*mat[coz][2]; + + Normalise((float *)mat[coy]); + + Crossf(mat[cox], mat[coy], mat[coz]); + +} + + +/* **************** VIEW / PROJEKTIE ******************************** */ + + +void i_ortho( + float left, float right, + float bottom, float top, + float nearClip, float farClip, + float matrix[][4] +){ + float Xdelta, Ydelta, Zdelta; + + Xdelta = right - left; + Ydelta = top - bottom; + Zdelta = farClip - nearClip; + if (Xdelta == 0.0 || Ydelta == 0.0 || Zdelta == 0.0) { + return; + } + Mat4One(matrix); + matrix[0][0] = 2.0f/Xdelta; + matrix[3][0] = -(right + left)/Xdelta; + matrix[1][1] = 2.0f/Ydelta; + matrix[3][1] = -(top + bottom)/Ydelta; + matrix[2][2] = -2.0f/Zdelta; /* note: negate Z */ + matrix[3][2] = -(farClip + nearClip)/Zdelta; +} + +void i_window( + float left, float right, + float bottom, float top, + float nearClip, float farClip, + float mat[][4] +){ + float Xdelta, Ydelta, Zdelta; + + Xdelta = right - left; + Ydelta = top - bottom; + Zdelta = farClip - nearClip; + + if (Xdelta == 0.0 || Ydelta == 0.0 || Zdelta == 0.0) { + return; + } + mat[0][0] = nearClip * 2.0f/Xdelta; + mat[1][1] = nearClip * 2.0f/Ydelta; + mat[2][0] = (right + left)/Xdelta; /* note: negate Z */ + mat[2][1] = (top + bottom)/Ydelta; + mat[2][2] = -(farClip + nearClip)/Zdelta; + mat[2][3] = -1.0f; + mat[3][2] = (-2.0f * nearClip * farClip)/Zdelta; + mat[0][1] = mat[0][2] = mat[0][3] = + mat[1][0] = mat[1][2] = mat[1][3] = + mat[3][0] = mat[3][1] = mat[3][3] = 0.0; + +} + +void i_translate(float Tx, float Ty, float Tz, float mat[][4]) +{ + mat[3][0] += (Tx*mat[0][0] + Ty*mat[1][0] + Tz*mat[2][0]); + mat[3][1] += (Tx*mat[0][1] + Ty*mat[1][1] + Tz*mat[2][1]); + mat[3][2] += (Tx*mat[0][2] + Ty*mat[1][2] + Tz*mat[2][2]); +} + +void i_multmatrix(const float icand[][4], float Vm[][4]) +{ + int row, col; + float temp[4][4]; + + for(row=0 ; row<4 ; row++) + for(col=0 ; col<4 ; col++) + temp[row][col] = icand[row][0] * Vm[0][col] + + icand[row][1] * Vm[1][col] + + icand[row][2] * Vm[2][col] + + icand[row][3] * Vm[3][col]; + Mat4CpyMat4(Vm, temp); +} + +void i_rotate(float angle, char axis, float mat[][4]) +{ + int col; + float temp[4]; + float cosine, sine; + + for(col=0; col<4 ; col++) /* init temp to zero matrix */ + temp[col] = 0; + + angle = (float)(angle*(3.1415926535/180.0)); + cosine = (float)cos(angle); + sine = (float)sin(angle); + switch(axis){ + case 'x': + case 'X': + for(col=0 ; col<4 ; col++) + temp[col] = cosine*mat[1][col] + sine*mat[2][col]; + for(col=0 ; col<4 ; col++) { + mat[2][col] = - sine*mat[1][col] + cosine*mat[2][col]; + mat[1][col] = temp[col]; + } + break; + + case 'y': + case 'Y': + for(col=0 ; col<4 ; col++) + temp[col] = cosine*mat[0][col] - sine*mat[2][col]; + for(col=0 ; col<4 ; col++) { + mat[2][col] = sine*mat[0][col] + cosine*mat[2][col]; + mat[0][col] = temp[col]; + } + break; + + case 'z': + case 'Z': + for(col=0 ; col<4 ; col++) + temp[col] = cosine*mat[0][col] + sine*mat[1][col]; + for(col=0 ; col<4 ; col++) { + mat[1][col] = - sine*mat[0][col] + cosine*mat[1][col]; + mat[0][col] = temp[col]; + } + break; + } +} + +void i_polarview(float dist, float azimuth, float incidence, float twist, float Vm[][4]) +{ + + Mat4One(Vm); + + i_translate(0.0, 0.0, -dist, Vm); + i_rotate(-twist,'z', Vm); + i_rotate(-incidence,'x', Vm); + i_rotate(-azimuth,'z', Vm); +} + +void i_lookat(float vx, float vy, float vz, float px, float py, float pz, float twist, float mat[][4]) +{ + float sine, cosine, hyp, hyp1, dx, dy, dz; + float mat1[4][4]; + + Mat4One(mat); + Mat4One(mat1); + + i_rotate(-twist,'z', mat); + + dx = px - vx; + dy = py - vy; + dz = pz - vz; + hyp = dx * dx + dz * dz; /* hyp squared */ + hyp1 = (float)sqrt(dy*dy + hyp); + hyp = (float)sqrt(hyp); /* the real hyp */ + + if (hyp1 != 0.0) { /* rotate X */ + sine = -dy / hyp1; + cosine = hyp /hyp1; + } else { + sine = 0; + cosine = 1.0f; + } + mat1[1][1] = cosine; + mat1[1][2] = sine; + mat1[2][1] = -sine; + mat1[2][2] = cosine; + + i_multmatrix(mat1, mat); + + mat1[1][1] = mat1[2][2] = 1.0f; /* be careful here to reinit */ + mat1[1][2] = mat1[2][1] = 0.0; /* those modified by the last */ + + /* paragraph */ + if (hyp != 0.0f) { /* rotate Y */ + sine = dx / hyp; + cosine = -dz / hyp; + } else { + sine = 0; + cosine = 1.0f; + } + mat1[0][0] = cosine; + mat1[0][2] = -sine; + mat1[2][0] = sine; + mat1[2][2] = cosine; + + i_multmatrix(mat1, mat); + i_translate(-vx,-vy,-vz, mat); /* translate viewpoint to origin */ +} + + + + + +/* ************************************************ */ + +void Mat3Ortho(float mat[][3]) +{ + Normalise(mat[0]); + Normalise(mat[1]); + Normalise(mat[2]); +} + +void Mat4Ortho(float mat[][4]) +{ + float len; + + len= Normalise(mat[0]); + if(len!=0.0) mat[0][3]/= len; + len= Normalise(mat[1]); + if(len!=0.0) mat[1][3]/= len; + len= Normalise(mat[2]); + if(len!=0.0) mat[2][3]/= len; +} + +void VecCopyf(float *v1, const float *v2) +{ + + v1[0]= v2[0]; + v1[1]= v2[1]; + v1[2]= v2[2]; +} + +int VecLen(const int *v1, const int *v2) +{ + float x,y,z; + + x=(float)(v1[0]-v2[0]); + y=(float)(v1[1]-v2[1]); + z=(float)(v1[2]-v2[2]); + return (int)floor(sqrt(x*x+y*y+z*z)); +} + +float VecLenf(const float *v1, const float *v2) +{ + float x,y,z; + + x=v1[0]-v2[0]; + y=v1[1]-v2[1]; + z=v1[2]-v2[2]; + return (float)sqrt(x*x+y*y+z*z); +} + +void VecAddf(float *v, const float *v1, const float *v2) +{ + v[0]= v1[0]+ v2[0]; + v[1]= v1[1]+ v2[1]; + v[2]= v1[2]+ v2[2]; +} + +void VecSubf(float *v, const float *v1, const float *v2) +{ + v[0]= v1[0]- v2[0]; + v[1]= v1[1]- v2[1]; + v[2]= v1[2]- v2[2]; +} + +void VecMidf(float *v, const float *v1, const float *v2) +{ + v[0]= 0.5f*(v1[0]+ v2[0]); + v[1]= 0.5f*(v1[1]+ v2[1]); + v[2]= 0.5f*(v1[2]+ v2[2]); +} + +void VecMulf(float *v1, float f) +{ + + v1[0]*= f; + v1[1]*= f; + v1[2]*= f; +} + +int VecCompare(const float *v1, const float *v2, float limit) +{ + if( fabs(v1[0]-v2[0])=1.0) { + pt[0]= v3[0]; + pt[1]= v3[1]; + } + else { + pt[0]= labda*rc[0]+v2[0]; + pt[1]= labda*rc[1]+v2[1]; + } + + rc[0]= pt[0]-v1[0]; + rc[1]= pt[1]-v1[1]; + return (float)sqrt(rc[0]*rc[0]+ rc[1]*rc[1]); +} + +float AreaF2Dfl(const float *v1,const float *v2,const float *v3) +{ + return (float)(0.5*fabs( (v1[0]-v2[0])*(v2[1]-v3[1]) + (v1[1]-v2[1])*(v3[0]-v2[0]) )); +} + + +float AreaQ3Dfl(const float *v1,const float *v2,const float *v3, const float *v4) /* only convex Quadrilaterals */ +{ + float len, vec1[3], vec2[3], n[3]; + + VecSubf(vec1, v2, v1); + VecSubf(vec2, v4, v1); + Crossf(n, vec1, vec2); + len= Normalise(n); + + VecSubf(vec1, v4, v3); + VecSubf(vec2, v2, v3); + Crossf(n, vec1, vec2); + len+= Normalise(n); + + return (len/2.0f); +} + +float AreaT3Dfl(const float *v1,const float *v2,const float *v3) /* Triangles */ +{ + float len, vec1[3], vec2[3], n[3]; + + VecSubf(vec1, v3, v2); + VecSubf(vec2, v1, v2); + Crossf(n, vec1, vec2); + len= Normalise(n); + + return (len/2.0f); +} + +#define MAX2(x,y) ( (x)>(y) ? (x) : (y) ) +#define MAX3(x,y,z) MAX2( MAX2((x),(y)) , (z) ) + + +float AreaPoly3Dfl(int nr, const float *verts, const float *normal) +{ + float x, y, z, area, max; + const float *cur, *prev; + int a, px=0, py=1; + + /* first: find dominant axis: 0==X, 1==Y, 2==Z */ + x= (float)fabs(normal[0]); + y= (float)fabs(normal[1]); + z= (float)fabs(normal[2]); + max = MAX3(x, y, z); + if(max==y) py=2; + else if(max==x) { + px=1; + py= 2; + } + + /* The Trapezium Area Rule */ + prev= verts+3*(nr-1); + cur= verts; + area= 0; + for(a=0; avec[0]) min[0]= vec[0]; + if(min[1]>vec[1]) min[1]= vec[1]; + if(min[2]>vec[2]) min[2]= vec[2]; + + if(max[0] 16.0*FLT_EPSILON) { + eul[0] = (float)atan2(mat[1][2], mat[2][2]); + eul[1] = (float)atan2(-mat[0][2], cy); + eul[2] = (float)atan2(mat[0][1], mat[0][0]); + } else { + eul[0] = (float)atan2(-mat[2][1], mat[1][1]); + eul[1] = (float)atan2(-mat[0][2], cy); + eul[2] = 0.0f; + } +} + +void Mat3ToEuln(const float tmat[][3], float *eul) +{ + float sin1, cos1, sin2, cos2, sin3, cos3; + + sin1 = -tmat[2][0]; + cos1 = (float)sqrt(1 - sin1*sin1); + + if ( fabs(cos1) > FLT_EPSILON ) { + sin2 = tmat[2][1] / cos1; + cos2 = tmat[2][2] / cos1; + sin3 = tmat[1][0] / cos1; + cos3 = tmat[0][0] / cos1; + } + else { + sin2 = -tmat[1][2]; + cos2 = tmat[1][1]; + sin3 = 0.0; + cos3 = 1.0; + } + + eul[0] = (float)atan2(sin3, cos3); + eul[1] = (float)atan2(sin1, cos1); + eul[2] = (float)atan2(sin2, cos2); + +} + + +void QuatToEul(const float *quat, float *eul) +{ + float mat[3][3]; + + QuatToMat3(quat, mat); + Mat3ToEul(mat, eul); +} + +void QuatToSpher(const float *quat, float *sph) +/* Not working 100% yet I don't think... */ +{ + float tx, ty, tz; + float qw, qx, qy, qz; + float cos_theta; + float sin_theta; + + qx = quat[0]; + qy = quat[1]; + qz = quat[2]; + qw = quat[3]; + + cos_theta = qw; + sin_theta = (float)sqrt(1.0 - cos_theta * cos_theta); + + if (fabs(sin_theta) < 0.0005) + sin_theta = 1.0; + + tx = qx / sin_theta; + ty = qy / sin_theta; + tz = qz / sin_theta; + + /* Lattitude */ + sph[0] = -(float)asin(ty); + + /* Longitude */ + if (tx*tx + tz*tz <0.0005) + sph[1] = 0.0; + else + sph[1] = (float)atan2(tx, tz); + + if (sph[1] < 0.0) + sph[1] +=(float)(M_PI*2); + + /* Roll */ + sph[2] = (float)(acos(cos_theta) * 2.0) ; +} + +void Mat3ToSpher (const float *mat3, float *sph) +{ + float quat[4]; + + Mat3ToQuat(mat3, quat); + QuatToSpher(quat, sph); +} + + +void EulToQuat(const float *eul, float *quat) +{ + float ti, tj, th, ci, cj, ch, si, sj, sh, cc, cs, sc, ss; + + ti = eul[0]*0.5f; tj = eul[1]*0.5f; th = eul[2]*0.5f; + ci = (float)cos(ti); cj = (float)cos(tj); ch = (float)cos(th); + si = (float)sin(ti); sj = (float)sin(tj); sh = (float)sin(th); + cc = ci*ch; cs = ci*sh; sc = si*ch; ss = si*sh; + + quat[0] = cj*cc + sj*ss; + quat[1] = cj*sc - sj*cs; + quat[2] = cj*ss + sj*cc; + quat[3] = cj*cs - sj*sc; +} + +void VecRotToMat3(const float *vec, float phi, float mat[][3]) +{ + /* rotation of phi radials around vec */ + float vx, vx2, vy, vy2, vz, vz2, co, si; + + vx= vec[0]; + vy= vec[1]; + vz= vec[2]; + vx2= vx*vx; + vy2= vy*vy; + vz2= vz*vz; + co= (float)cos(phi); + si= (float)sin(phi); + + mat[0][0]= vx2+co*(1.0f-vx2); + mat[0][1]= vx*vy*(1.0f-co)+vz*si; + mat[0][2]= vz*vx*(1.0f-co)-vy*si; + mat[1][0]= vx*vy*(1.0f-co)-vz*si; + mat[1][1]= vy2+co*(1.0f-vy2); + mat[1][2]= vy*vz*(1.0f-co)+vx*si; + mat[2][0]= vz*vx*(1.0f-co)+vy*si; + mat[2][1]= vy*vz*(1.0f-co)-vx*si; + mat[2][2]= vz2+co*(1.0f-vz2); + +} + +void VecRotToQuat(const float *vec, float phi, float *quat) +{ + /* rotation of phi radials around vec */ + float si; + + quat[1]= vec[0]; + quat[2]= vec[1]; + quat[3]= vec[2]; + + if( Normalise(quat+1) == 0.0) { + QuatOne(quat); + } + else { + quat[0]= (float)cos( phi/2.0 ); + si= (float)sin( phi/2.0 ); + quat[1] *= si; + quat[2] *= si; + quat[3] *= si; + } +} + +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; + if(axis=='x') eul[0]= ang; + else if(axis=='y') eul[1]= ang; + else eul[2]= ang; + + EulToMat3(eul, mat1); + EulToMat3(beul, mat2); + + Mat3MulMat3(totmat, mat2, mat1); + + Mat3ToEul(totmat, beul); + +} + + + +void SizeToMat3(const float *size, float mat[][3]) +{ + mat[0][0]= size[0]; + mat[0][1]= 0.0; + mat[0][2]= 0.0; + mat[1][1]= size[1]; + mat[1][0]= 0.0; + mat[1][2]= 0.0; + mat[2][2]= size[2]; + mat[2][1]= 0.0; + mat[2][0]= 0.0; +} + +void Mat3ToSize(const float mat[][3], float *size) +{ + float vec[3]; + + + VecCopyf(vec, mat[0]); + size[0]= Normalise(vec); + VecCopyf(vec, mat[1]); + size[1]= Normalise(vec); + VecCopyf(vec, mat[2]); + size[2]= Normalise(vec); + +} + +void Mat4ToSize(const float mat[][4], float *size) +{ + float vec[3]; + + + VecCopyf(vec, mat[0]); + size[0]= Normalise(vec); + VecCopyf(vec, mat[1]); + size[1]= Normalise(vec); + VecCopyf(vec, mat[2]); + size[2]= Normalise(vec); +} + +/* ************* SPECIALS ******************* */ + +void triatoquat(const float *v1, const float *v2, const float *v3, float *quat) +{ + /* denkbeeldige x-as, y-as driehoek wordt geroteerd */ + float vec[3], q1[4], q2[4], n[3], si, co, hoek, mat[3][3], imat[3][3]; + + /* eerst z-as op vlaknormaal */ + CalcNormFloat(v1, v2, v3, vec); + + n[0]= vec[1]; + n[1]= -vec[0]; + n[2]= 0.0; + Normalise(n); + + if(n[0]==0.0 && n[1]==0.0) n[0]= 1.0; + + hoek= -0.5f*saacos(vec[2]); + co= (float)cos(hoek); + si= (float)sin(hoek); + q1[0]= co; + q1[1]= n[0]*si; + q1[2]= n[1]*si; + q1[3]= 0.0f; + + /* v1-v2 lijn terug roteren */ + QuatToMat3(q1, mat); + Mat3Inv(imat, mat); + VecSubf(vec, v2, v1); + Mat3MulVecfl(imat, vec); + + /* welke hoek maakt deze lijn met x-as? */ + vec[2]= 0.0; + Normalise(vec); + + hoek= (float)(0.5*atan2(vec[1], vec[0])); + co= (float)cos(hoek); + si= (float)sin(hoek); + q2[0]= co; + q2[1]= 0.0f; + q2[2]= 0.0f; + q2[3]= si; + + QuatMul(quat, q1, q2); +} + +void MinMaxRGB(short c[]) +{ + if(c[0]>255) c[0]=255; + else if(c[0]<0) c[0]=0; + if(c[1]>255) c[1]=255; + else if(c[1]<0) c[1]=0; + if(c[2]>255) c[2]=255; + else if(c[2]<0) c[2]=0; +} + +void hsv_to_rgb(float h, float s, float v, float *r, float *g, float *b) +{ + int i; + float f, p, q, t; + + h *= 360.0f; + + if(s==0 && 0) { + *r = v; + *g = v; + *b = v; + } + else { + if(h==360) h = 0; + + h /= 60; + i = (int)floor(h); + f = h - i; + p = v*(1.0f-s); + q = v*(1.0f-(s*f)); + t = v*(1.0f-(s*(1.0f-f))); + + switch (i) { + case 0 : + *r = v; + *g = t; + *b = p; + break; + case 1 : + *r = q; + *g = v; + *b = p; + break; + case 2 : + *r = p; + *g = v; + *b = t; + break; + case 3 : + *r = p; + *g = q; + *b = v; + break; + case 4 : + *r = t; + *g = p; + *b = v; + break; + case 5 : + *r = v; + *g = p; + *b = q; + break; + } + } +} + +void rgb_to_hsv(float r, float g, float b, float *lh, float *ls, float *lv) +{ + float h, s, v; + float cmax, cmin, cdelta; + float rc, gc, bc; + + cmax = r; + cmin = r; + cmax = (g>cmax ? g:cmax); + cmin = (gcmax ? b:cmax); + cmin = (b255) ir= 255; + ig= (int)floor(255.0*g); + if(ig<0) ig= 0; else if(ig>255) ig= 255; + ib= (int)floor(255.0*b); + if(ib<0) ib= 0; else if(ib>255) ib= 255; + + return (ir+ (ig*256) + (ib*256*256)); +} + +void cpack_to_rgb(unsigned int col, float *r, float *g, float *b) +{ + + *r= (float)((col)&0xFF); + *r /= 255.0f; + + *g= (float)(((col)>>8)&0xFF); + *g /= 255.0f; + + *b= (float)(((col)>>16)&0xFF); + *b /= 255.0f; +} diff --git a/source/blender/blenlib/intern/dynlib.c b/source/blender/blenlib/intern/dynlib.c new file mode 100644 index 00000000000..c232be3c206 --- /dev/null +++ b/source/blender/blenlib/intern/dynlib.c @@ -0,0 +1,146 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + */ +#include + +#include "../PIL_dynlib.h" + +/* + * XXX, should use mallocN so we can see + * handle's not being released. fixme zr + */ + +#ifdef WIN32 + +#include + +struct PILdynlib { + void *handle; +}; + +PILdynlib *PIL_dynlib_open(char *name) { + void *handle= LoadLibrary(name); + + if (handle) { + PILdynlib *lib= malloc(sizeof(*lib)); + lib->handle= handle; + + return lib; + } else { + return NULL; + } +} + +void *PIL_dynlib_find_symbol(PILdynlib* lib, char *symname) { + return GetProcAddress(lib->handle, symname); +} + +char *PIL_dynlib_get_error_as_string(PILdynlib* lib) { + int err= GetLastError(); + + if (err) { + static char buf[1024]; + + if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + err, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + buf, + sizeof(buf), + NULL)) + return buf; + } + + return NULL; +} + +void PIL_dynlib_close(PILdynlib *lib) { + FreeLibrary(lib->handle); + + free(lib); +} + +#else +#ifdef __APPLE__ + +PILdynlib *PIL_dynlib_open(char *name) { + return NULL; +} + +void *PIL_dynlib_find_symbol(PILdynlib* lib, char *symname) { + return NULL; +} + +char *PIL_dynlib_get_error_as_string(PILdynlib* lib) { + return "Plugins are currently unsupported on OSX"; +} + +void PIL_dynlib_close(PILdynlib *lib) { + ; +} + +#else /* Unix */ + +#include + +struct PILdynlib { + void *handle; +}; + +PILdynlib *PIL_dynlib_open(char *name) { + void *handle= dlopen(name, RTLD_LAZY); + + if (handle) { + PILdynlib *lib= malloc(sizeof(*lib)); + lib->handle= handle; + + return lib; + } else { + return NULL; + } +} + +void *PIL_dynlib_find_symbol(PILdynlib* lib, char *symname) { + return dlsym(lib->handle, symname); +} + +char *PIL_dynlib_get_error_as_string(PILdynlib* lib) { + return dlerror(); +} + +void PIL_dynlib_close(PILdynlib *lib) { + dlclose(lib->handle); + + free(lib); +} + +#endif +#endif diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c new file mode 100644 index 00000000000..02f54e60df6 --- /dev/null +++ b/source/blender/blenlib/intern/fileops.c @@ -0,0 +1,293 @@ +/* + * blenlib/fileops.h + * + * cleaned up (a bit) mar-01 nzc + * + * More low-level file things. + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + */ + +#include +#include + +#ifdef WIN32 +#include "BLI_winstuff.h" +#else +#include +#endif + +#include "BLI_blenlib.h" +#include "BLI_storage.h" +#include "BLI_fileops.h" +#include "BLI_callbacks.h" + +/* implementations: */ +char *first_slash(char *string) { + char *ffslash, *fbslash; + + ffslash= strchr(string, '/'); + fbslash= strchr(string, '\\'); + + if (!ffslash) return fbslash; + else if (!fbslash) return ffslash; + + if ((int)ffslash < (int)fbslash) return ffslash; + else return fbslash; +} + +char *BLI_last_slash(char *string) { + char *lfslash, *lbslash; + + lfslash= strrchr(string, '/'); + lbslash= strrchr(string, '\\'); + + if (!lfslash) return lbslash; + else if (!lbslash) return lfslash; + + if ((int)lfslash < (int)lbslash) return lbslash; + else return lfslash; +} + +#ifdef WIN32 + +static char str[MAXPATHLEN+12]; + +int BLI_delete(char *file, int dir, int recursive) { + int err; + + if (recursive) { + callLocalErrorCallBack("Recursive delete is unsupported on Windows"); + err= 1; + } else if (dir) { + err= !RemoveDirectory(file); + if (err) printf ("Unable to remove directory"); + } else { + err= !DeleteFile(file); + if (err) callLocalErrorCallBack("Unable to delete file"); + } + + return err; +} + +int BLI_touch(char *file) { + callLocalErrorCallBack("Touching files is unsupported on Windows"); + + return 1; +} + +int BLI_move(char *file, char *to) { + int err; + + // windows doesn't support moveing to a directory + // it has to be 'mv filename filename' and not + // 'mv filename destdir' + + strcpy(str, to); + // points 'to' to a directory ? + if (BLI_last_slash(str) == (str + strlen(str) - 1)) { + if (BLI_last_slash(file) != NULL) { + strcat(str, BLI_last_slash(file) + 1); + } + } + + err= !MoveFile(file, str); + if (err) { + callLocalErrorCallBack("Unable to move file"); + printf(" Move from '%s' to '%s' failed\n", file, str); + } + + return err; +} + + +int BLI_copy_fileops(char *file, char *to) { + int err; + + // windows doesn't support copying to a directory + // it has to be 'cp filename filename' and not + // 'cp filename destdir' + + strcpy(str, to); + // points 'to' to a directory ? + if (BLI_last_slash(str) == (str + strlen(str) - 1)) { + if (BLI_last_slash(file) != NULL) { + strcat(str, BLI_last_slash(file) + 1); + } + } + + err= !CopyFile(file,str,FALSE); + + if (err) { + callLocalErrorCallBack("Unable to copy file!"); + printf(" Copy from '%s' to '%s' failed\n", file, str); + } + + return err; +} + +int BLI_link(char *file, char *to) { + callLocalErrorCallBack("Linking files is unsupported on Windows"); + + return 1; +} + +int BLI_backup(char *file, char *from, char *to) { + callLocalErrorCallBack("Backing up files is unsupported on Windows"); + + return 1; +} + +int BLI_exists(char *file) { + return (GetFileAttributes(file) != 0xFFFFFFFF); +} + +void BLI_recurdir_fileops(char *dirname) { + char *lslash; + char tmp[MAXPATHLEN]; + + // First remove possible slash at the end of the dirname. + // This routine otherwise tries to create + // blah1/blah2/ (with slash) after creating + // blah1/blah2 (without slash) + + strcpy(tmp, dirname); + lslash= BLI_last_slash(tmp); + + if (lslash == tmp + strlen(tmp) - 1) { + *lslash = 0; + } + + if (BLI_exists(tmp)) return; + + lslash= BLI_last_slash(tmp); + if (lslash) { + /* Split about the last slash and recurse */ + *lslash = 0; + BLI_recurdir_fileops(tmp); + } + + if (!CreateDirectory(dirname, NULL)) + callLocalErrorCallBack("Unable to create directory\n"); +} + +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); +} + +#else /* The sane UNIX world */ + +/* + * but the sane UNIX world is tied to the interface, and the system + * timer, and... We implement a callback mechanism. The system will + * have to initialise the callback before the functions will work! + * */ +static char str[MAXPATHLEN+12]; + +int BLI_delete(char *file, int dir, int recursive) { + if (recursive) sprintf(str, "/bin/rm -rf %s", file); + else if (dir) sprintf(str, "/bin/rmdir \"%s\"", file); + else sprintf(str, "/bin/rm -f \"%s\"", file); + + return system(str); +} + +int BLI_touch(char *file) +{ + + if( BLI_exists("/bin/touch") ) + sprintf(str, "/bin/touch %s", file); + else + sprintf(str, "/usr/bin/touch %s", file); + + return system(str); +} + +int BLI_move(char *file, char *to) { + sprintf(str, "/bin/mv -f %s %s", file, to); + + return system(str); +} + +int BLI_copy_fileops(char *file, char *to) { + sprintf(str, "/bin/cp -rf \"%s\" %s", file, to); + + return system(str); +} + +int BLI_link(char *file, char *to) { + sprintf(str, "/bin/ln -f %s %s", file, to); + + return system(str); +} + +int BLI_backup(char *file, char *from, char *to) { + sprintf(str, "/bin/su root -c 'cd %s; /bin/tar cf - \"%s\" | (/bin/cd %s; /bin/tar xf -)'", from, file, to); + + return system(str); +} + +int BLI_exists(char *file) { + return BLI_exist(file); +} + +void BLI_recurdir_fileops(char *dirname) { + char *lslash; + char tmp[MAXPATHLEN]; + + if (BLI_exists(dirname)) return; + + strcpy(tmp, dirname); + + lslash= BLI_last_slash(tmp); + if (lslash) { + /* Split about the last slash and recurse */ + *lslash = 0; + BLI_recurdir_fileops(tmp); + } + + mkdir(dirname, 0777); +} + +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); +} + +#endif diff --git a/source/blender/blenlib/intern/gsqueue.c b/source/blender/blenlib/intern/gsqueue.c new file mode 100644 index 00000000000..eb49fe92cb1 --- /dev/null +++ b/source/blender/blenlib/intern/gsqueue.c @@ -0,0 +1,112 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + */ +#include + +#include "MEM_guardedalloc.h" + +#include "BLI_gsqueue.h" + +typedef struct _GSQueueElem GSQueueElem; +struct _GSQueueElem { + GSQueueElem *next; +}; + +struct _GSQueue { + GSQueueElem *head; + GSQueueElem *tail; + int elem_size; +}; + +GSQueue *BLI_gsqueue_new(int elem_size) +{ + GSQueue *gq= MEM_mallocN(sizeof(*gq), "gqueue_new"); + gq->head= gq->tail= NULL; + gq->elem_size= elem_size; + + return gq; +} + +int BLI_gsqueue_is_empty(GSQueue *gq) +{ + return (gq->head==NULL); +} + +void BLI_gsqueue_peek(GSQueue *gq, void *item_r) +{ + memcpy(item_r, &gq->head[1], gq->elem_size); +} +void BLI_gsqueue_pop(GSQueue *gq, void *item_r) +{ + GSQueueElem *elem= gq->head; + if (elem==gq->tail) { + gq->head= gq->tail= NULL; + } else { + gq->head= gq->head->next; + } + + if (item_r) memcpy(item_r, &elem[1], gq->elem_size); + MEM_freeN(elem); +} +void BLI_gsqueue_push(GSQueue *gq, void *item) +{ + GSQueueElem *elem= MEM_mallocN(sizeof(*elem)+gq->elem_size, "gqueue_push"); + memcpy(&elem[1], item, gq->elem_size); + elem->next= NULL; + + if (BLI_gsqueue_is_empty(gq)) { + gq->tail= gq->head= elem; + } else { + gq->tail= gq->tail->next= elem; + } +} +void BLI_gsqueue_pushback(GSQueue *gq, void *item) +{ + GSQueueElem *elem= MEM_mallocN(sizeof(*elem)+gq->elem_size, "gqueue_push"); + memcpy(&elem[1], item, gq->elem_size); + elem->next= gq->head; + + if (BLI_gsqueue_is_empty(gq)) { + gq->head= gq->tail= elem; + } else { + gq->head= elem; + } +} + +void BLI_gsqueue_free(GSQueue *gq) +{ + while (gq->head) { + BLI_gsqueue_pop(gq, NULL); + } + MEM_freeN(gq); +} + + diff --git a/source/blender/blenlib/intern/matrixops.c b/source/blender/blenlib/intern/matrixops.c new file mode 100644 index 00000000000..f33596d803a --- /dev/null +++ b/source/blender/blenlib/intern/matrixops.c @@ -0,0 +1,440 @@ +/* + * + * Some matrix operations. + * + * Always use + * - vector with x components : float x[3], int x[3], etc + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + */ + +/* ------------------------------------------------------------------------- */ +#include +#include "MTC_matrixops.h" +#include "MTC_vectorops.h" +/* ------------------------------------------------------------------------- */ +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif + +#ifdef __sun__ +#include +#endif + +#define ABS(x) ((x) < 0 ? -(x) : (x)) +#define SWAP(type, a, b) { type sw_ap; sw_ap=(a); (a)=(b); (b)=sw_ap; } + +void MTC_Mat4CpyMat4(float m1[][4], float m2[][4]) +{ + memcpy(m1, m2, 4*4*sizeof(float)); +} + +/* ------------------------------------------------------------------------- */ + +void MTC_Mat4MulSerie(float answ[][4], + float m1[][4], float m2[][4], float m3[][4], + float m4[][4], float m5[][4], float m6[][4], + float m7[][4], float m8[][4]) +{ + float temp[4][4]; + + if(m1==0 || m2==0) return; + + MTC_Mat4MulMat4(answ, m2, m1); + if(m3) { + MTC_Mat4MulMat4(temp, m3, answ); + if(m4) { + MTC_Mat4MulMat4(answ, m4, temp); + if(m5) { + MTC_Mat4MulMat4(temp, m5, answ); + if(m6) { + MTC_Mat4MulMat4(answ, m6, temp); + if(m7) { + MTC_Mat4MulMat4(temp, m7, answ); + if(m8) { + MTC_Mat4MulMat4(answ, m8, temp); + } + else MTC_Mat4CpyMat4(answ, temp); + } + } + else MTC_Mat4CpyMat4(answ, temp); + } + } + else MTC_Mat4CpyMat4(answ, temp); + } +} + +/* ------------------------------------------------------------------------- */ +void MTC_Mat4MulMat4(float m1[][4], float m2[][4], float m3[][4]) +{ + /* matrix product: c[j][k] = a[j][i].b[i][k] */ + + m1[0][0] = m2[0][0]*m3[0][0] + m2[0][1]*m3[1][0] + m2[0][2]*m3[2][0] + m2[0][3]*m3[3][0]; + m1[0][1] = m2[0][0]*m3[0][1] + m2[0][1]*m3[1][1] + m2[0][2]*m3[2][1] + m2[0][3]*m3[3][1]; + m1[0][2] = m2[0][0]*m3[0][2] + m2[0][1]*m3[1][2] + m2[0][2]*m3[2][2] + m2[0][3]*m3[3][2]; + m1[0][3] = m2[0][0]*m3[0][3] + m2[0][1]*m3[1][3] + m2[0][2]*m3[2][3] + m2[0][3]*m3[3][3]; + + m1[1][0] = m2[1][0]*m3[0][0] + m2[1][1]*m3[1][0] + m2[1][2]*m3[2][0] + m2[1][3]*m3[3][0]; + m1[1][1] = m2[1][0]*m3[0][1] + m2[1][1]*m3[1][1] + m2[1][2]*m3[2][1] + m2[1][3]*m3[3][1]; + m1[1][2] = m2[1][0]*m3[0][2] + m2[1][1]*m3[1][2] + m2[1][2]*m3[2][2] + m2[1][3]*m3[3][2]; + m1[1][3] = m2[1][0]*m3[0][3] + m2[1][1]*m3[1][3] + m2[1][2]*m3[2][3] + m2[1][3]*m3[3][3]; + + m1[2][0] = m2[2][0]*m3[0][0] + m2[2][1]*m3[1][0] + m2[2][2]*m3[2][0] + m2[2][3]*m3[3][0]; + m1[2][1] = m2[2][0]*m3[0][1] + m2[2][1]*m3[1][1] + m2[2][2]*m3[2][1] + m2[2][3]*m3[3][1]; + m1[2][2] = m2[2][0]*m3[0][2] + m2[2][1]*m3[1][2] + m2[2][2]*m3[2][2] + m2[2][3]*m3[3][2]; + m1[2][3] = m2[2][0]*m3[0][3] + m2[2][1]*m3[1][3] + m2[2][2]*m3[2][3] + m2[2][3]*m3[3][3]; + + m1[3][0] = m2[3][0]*m3[0][0] + m2[3][1]*m3[1][0] + m2[3][2]*m3[2][0] + m2[3][3]*m3[3][0]; + m1[3][1] = m2[3][0]*m3[0][1] + m2[3][1]*m3[1][1] + m2[3][2]*m3[2][1] + m2[3][3]*m3[3][1]; + m1[3][2] = m2[3][0]*m3[0][2] + m2[3][1]*m3[1][2] + m2[3][2]*m3[2][2] + m2[3][3]*m3[3][2]; + m1[3][3] = m2[3][0]*m3[0][3] + m2[3][1]*m3[1][3] + m2[3][2]*m3[2][3] + m2[3][3]*m3[3][3]; + +} +/* ------------------------------------------------------------------------- */ + +void MTC_Mat4MulVecfl(float mat[][4], float *vec) +{ + float x,y; + + x=vec[0]; + y=vec[1]; + vec[0]=x*mat[0][0] + y*mat[1][0] + mat[2][0]*vec[2] + mat[3][0]; + vec[1]=x*mat[0][1] + y*mat[1][1] + mat[2][1]*vec[2] + mat[3][1]; + vec[2]=x*mat[0][2] + y*mat[1][2] + mat[2][2]*vec[2] + mat[3][2]; +} + +/* ------------------------------------------------------------------------- */ +void MTC_Mat3MulVecfl(float mat[][3], float *vec) +{ + float x,y; + + x=vec[0]; + y=vec[1]; + vec[0]= x*mat[0][0] + y*mat[1][0] + mat[2][0]*vec[2]; + vec[1]= x*mat[0][1] + y*mat[1][1] + mat[2][1]*vec[2]; + vec[2]= x*mat[0][2] + y*mat[1][2] + mat[2][2]*vec[2]; +} + +/* ------------------------------------------------------------------------- */ + +int MTC_Mat4Invert(float inverse[][4], float mat[][4]) +{ + int i, j, k; + double temp; + float tempmat[4][4]; + float max; + int maxj; + + /* Set inverse to identity */ + for (i=0; i<4; i++) + for (j=0; j<4; j++) + inverse[i][j] = 0; + for (i=0; i<4; i++) + inverse[i][i] = 1; + + /* Copy original matrix so we don't mess it up */ + for(i = 0; i < 4; i++) + for(j = 0; j <4; j++) + tempmat[i][j] = mat[i][j]; + + for(i = 0; i < 4; i++) { + /* Look for row with max pivot */ + max = ABS(tempmat[i][i]); + maxj = i; + for(j = i + 1; j < 4; j++) { + if(ABS(tempmat[j][i]) > max) { + max = ABS(tempmat[j][i]); + maxj = j; + } + } + /* Swap rows if necessary */ + if (maxj != i) { + for( k = 0; k < 4; k++) { + SWAP(float, tempmat[i][k], tempmat[maxj][k]); + SWAP(float, inverse[i][k], inverse[maxj][k]); + } + } + + temp = tempmat[i][i]; + if (temp == 0) + return 0; /* No non-zero pivot */ + for(k = 0; k < 4; k++) { + tempmat[i][k] /= temp; + inverse[i][k] /= temp; + } + for(j = 0; j < 4; j++) { + if(j != i) { + temp = tempmat[j][i]; + for(k = 0; k < 4; k++) { + tempmat[j][k] -= tempmat[i][k]*temp; + inverse[j][k] -= inverse[i][k]*temp; + } + } + } + } + return 1; +} + +/* ------------------------------------------------------------------------- */ +void MTC_Mat3CpyMat4(float m1[][3], float m2[][4]) +{ + + m1[0][0]= m2[0][0]; + m1[0][1]= m2[0][1]; + m1[0][2]= m2[0][2]; + + m1[1][0]= m2[1][0]; + m1[1][1]= m2[1][1]; + m1[1][2]= m2[1][2]; + + m1[2][0]= m2[2][0]; + m1[2][1]= m2[2][1]; + m1[2][2]= m2[2][2]; +} + +/* ------------------------------------------------------------------------- */ + +void MTC_Mat3CpyMat3(float m1[][3], float m2[][3]) +{ + memcpy(m1, m2, 3*3*sizeof(float)); +} + +/* ------------------------------------------------------------------------- */ +/* void Mat3MulMat3(float m1[][3], float m3[][3], float m2[][3]) */ +void MTC_Mat3MulMat3(float m1[][3], float m3[][3], float m2[][3]) +{ + /* be careful about this rewrite... */ + /* m1[i][j] = m2[i][k]*m3[k][j], args are flipped! */ + m1[0][0]= m2[0][0]*m3[0][0] + m2[0][1]*m3[1][0] + m2[0][2]*m3[2][0]; + m1[0][1]= m2[0][0]*m3[0][1] + m2[0][1]*m3[1][1] + m2[0][2]*m3[2][1]; + m1[0][2]= m2[0][0]*m3[0][2] + m2[0][1]*m3[1][2] + m2[0][2]*m3[2][2]; + + m1[1][0]= m2[1][0]*m3[0][0] + m2[1][1]*m3[1][0] + m2[1][2]*m3[2][0]; + m1[1][1]= m2[1][0]*m3[0][1] + m2[1][1]*m3[1][1] + m2[1][2]*m3[2][1]; + m1[1][2]= m2[1][0]*m3[0][2] + m2[1][1]*m3[1][2] + m2[1][2]*m3[2][2]; + + m1[2][0]= m2[2][0]*m3[0][0] + m2[2][1]*m3[1][0] + m2[2][2]*m3[2][0]; + m1[2][1]= m2[2][0]*m3[0][1] + m2[2][1]*m3[1][1] + m2[2][2]*m3[2][1]; + m1[2][2]= m2[2][0]*m3[0][2] + m2[2][1]*m3[1][2] + m2[2][2]*m3[2][2]; + +/* m1[0]= m2[0]*m3[0] + m2[1]*m3[3] + m2[2]*m3[6]; */ +/* m1[1]= m2[0]*m3[1] + m2[1]*m3[4] + m2[2]*m3[7]; */ +/* m1[2]= m2[0]*m3[2] + m2[1]*m3[5] + m2[2]*m3[8]; */ +/* m1+=3; */ +/* m2+=3; */ +/* m1[0]= m2[0]*m3[0] + m2[1]*m3[3] + m2[2]*m3[6]; */ +/* m1[1]= m2[0]*m3[1] + m2[1]*m3[4] + m2[2]*m3[7]; */ +/* m1[2]= m2[0]*m3[2] + m2[1]*m3[5] + m2[2]*m3[8]; */ +/* m1+=3; */ +/* m2+=3; */ +/* m1[0]= m2[0]*m3[0] + m2[1]*m3[3] + m2[2]*m3[6]; */ +/* m1[1]= m2[0]*m3[1] + m2[1]*m3[4] + m2[2]*m3[7]; */ +/* m1[2]= m2[0]*m3[2] + m2[1]*m3[5] + m2[2]*m3[8]; */ +} /* end of void Mat3MulMat3(float m1[][3], float m3[][3], float m2[][3]) */ + +/* ------------------------------------------------------------------------- */ + +void MTC_Mat4Ortho(float mat[][4]) +{ + float len; + + len= MTC_normalise3DF(mat[0]); + if(len!=0.0) mat[0][3]/= len; + len= MTC_normalise3DF(mat[1]); + if(len!=0.0) mat[1][3]/= len; + len= MTC_normalise3DF(mat[2]); + if(len!=0.0) mat[2][3]/= len; +} + +/* ------------------------------------------------------------------------- */ + +void MTC_Mat4Mul3Vecfl(float mat[][4], float *vec) +{ + float x,y; + /* vec = mat^T dot vec !!! or vec a row, then vec = vec dot mat*/ + + x= vec[0]; + y= vec[1]; + vec[0]= x*mat[0][0] + y*mat[1][0] + mat[2][0]*vec[2]; + vec[1]= x*mat[0][1] + y*mat[1][1] + mat[2][1]*vec[2]; + vec[2]= x*mat[0][2] + y*mat[1][2] + mat[2][2]*vec[2]; +} + +/* ------------------------------------------------------------------------- */ + +void MTC_Mat4One(float m[][4]) +{ + + m[0][0]= m[1][1]= m[2][2]= m[3][3]= 1.0; + m[0][1]= m[0][2]= m[0][3]= 0.0; + m[1][0]= m[1][2]= m[1][3]= 0.0; + m[2][0]= m[2][1]= m[2][3]= 0.0; + m[3][0]= m[3][1]= m[3][2]= 0.0; +} + + +/* ------------------------------------------------------------------------- */ +/* Result is a 3-vector!*/ +void MTC_Mat3MulVecd(float mat[][3], double *vec) +{ + double x,y; + + /* vec = mat^T dot vec !!! or vec a row, then vec = vec dot mat*/ + x=vec[0]; + y=vec[1]; + vec[0]= x * mat[0][0] + y * mat[1][0] + mat[2][0] * vec[2]; + vec[1]= x * mat[0][1] + y * mat[1][1] + mat[2][1] * vec[2]; + vec[2]= x * mat[0][2] + y * mat[1][2] + mat[2][2] * vec[2]; +} + +/* ------------------------------------------------------------------------- */ + +void MTC_Mat3Inv(float m1[][3], float m2[][3]) +{ + short a,b; + float det; + + /* eerst adjoint */ + MTC_Mat3Adj(m1,m2); + + /* dan det oude mat! */ + det= m2[0][0]* (m2[1][1]*m2[2][2] - m2[1][2]*m2[2][1]) + -m2[1][0]* (m2[0][1]*m2[2][2] - m2[0][2]*m2[2][1]) + +m2[2][0]* (m2[0][1]*m2[1][2] - m2[0][2]*m2[1][1]); + + if(det==0) det=1; + det= 1/det; + for(a=0;a<3;a++) { + for(b=0;b<3;b++) { + m1[a][b]*=det; + } + } +} + +/* ------------------------------------------------------------------------- */ + +void MTC_Mat3Adj(float m1[][3], float m[][3]) +{ + m1[0][0]=m[1][1]*m[2][2]-m[1][2]*m[2][1]; + m1[0][1]= -m[0][1]*m[2][2]+m[0][2]*m[2][1]; + m1[0][2]=m[0][1]*m[1][2]-m[0][2]*m[1][1]; + + m1[1][0]= -m[1][0]*m[2][2]+m[1][2]*m[2][0]; + m1[1][1]=m[0][0]*m[2][2]-m[0][2]*m[2][0]; + m1[1][2]= -m[0][0]*m[1][2]+m[0][2]*m[1][0]; + + m1[2][0]=m[1][0]*m[2][1]-m[1][1]*m[2][0]; + m1[2][1]= -m[0][0]*m[2][1]+m[0][1]*m[2][0]; + m1[2][2]=m[0][0]*m[1][1]-m[0][1]*m[1][0]; +} + +/* ------------------------------------------------------------------------- */ + +void MTC_Mat3One(float m[][3]) +{ + + m[0][0]= m[1][1]= m[2][2]= 1.0; + m[0][1]= m[0][2]= 0.0; + m[1][0]= m[1][2]= 0.0; + m[2][0]= m[2][1]= 0.0; +} + +/* ------------------------------------------------------------------------- */ + +void MTC_Mat4SwapMat4(float m1[][4], float m2[][4]) +{ + float t; + int i, j; + + for(i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + t = m1[i][j]; + m1[i][j] = m2[i][j]; + m2[i][j] = t; + } + } +} + +/* ------------------------------------------------------------------------- */ + +void MTC_Mat4MulVec4fl(float mat[][4], float *vec) +{ + float x,y,z; + + x = vec[0]; + y = vec[1]; + z = vec[2]; + vec[0] = x*mat[0][0] + y*mat[1][0] + z*mat[2][0] + mat[3][0]*vec[3]; + vec[1] = x*mat[0][1] + y*mat[1][1] + z*mat[2][1] + mat[3][1]*vec[3]; + vec[2] = x*mat[0][2] + y*mat[1][2] + z*mat[2][2] + mat[3][2]*vec[3]; + vec[3] = x*mat[0][3] + y*mat[1][3] + z*mat[2][3] + mat[3][3]*vec[3]; +} + +/* ------------------------------------------------------------------------- */ + +void MTC_Mat4CpyMat3nc(float m1[][4], float m2[][3]) /* no clear */ +{ + m1[0][0]= m2[0][0]; + m1[0][1]= m2[0][1]; + m1[0][2]= m2[0][2]; + + m1[1][0]= m2[1][0]; + m1[1][1]= m2[1][1]; + m1[1][2]= m2[1][2]; + + m1[2][0]= m2[2][0]; + m1[2][1]= m2[2][1]; + m1[2][2]= m2[2][2]; +} + +/* ------------------------------------------------------------------------- */ + +void MTC_Mat4MulMat33(float m1[][3], float m2[][4], float m3[][3]) +{ + /* m1_i_j = m2_i_k * m3_k_j ? */ + + m1[0][0] = m2[0][0]*m3[0][0] + m2[0][1]*m3[1][0] + m2[0][2]*m3[2][0]; + m1[0][1] = m2[0][0]*m3[0][1] + m2[0][1]*m3[1][1] + m2[0][2]*m3[2][1]; + m1[0][2] = m2[0][0]*m3[0][2] + m2[0][1]*m3[1][2] + m2[0][2]*m3[2][2]; + + m1[1][0] = m2[1][0]*m3[0][0] + m2[1][1]*m3[1][0] + m2[1][2]*m3[2][0]; + m1[1][1] = m2[1][0]*m3[0][1] + m2[1][1]*m3[1][1] + m2[1][2]*m3[2][1]; + m1[1][2] = m2[1][0]*m3[0][2] + m2[1][1]*m3[1][2] + m2[1][2]*m3[2][2]; + + m1[2][0] = m2[2][0]*m3[0][0] + m2[2][1]*m3[1][0] + m2[2][2]*m3[2][0]; + m1[2][1] = m2[2][0]*m3[0][1] + m2[2][1]*m3[1][1] + m2[2][2]*m3[2][1]; + m1[2][2] = m2[2][0]*m3[0][2] + m2[2][1]*m3[1][2] + m2[2][2]*m3[2][2]; + +} + +/* ------------------------------------------------------------------------- */ + +/* eof */ diff --git a/source/blender/blenlib/intern/noise.c b/source/blender/blenlib/intern/noise.c new file mode 100644 index 00000000000..124b520ed11 --- /dev/null +++ b/source/blender/blenlib/intern/noise.c @@ -0,0 +1,390 @@ +/* + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + * + */ + +#include +#include "BLI_blenlib.h" + +#ifdef _WIN32 +#pragma warning (once : 4244) // "conversion from double to float" +#pragma warning (once : 4305) // "truncation from const double to float" +#endif + +/* local */ +float noise3_perlin(float vec[3]); +float turbulence_perlin(float *point, float lofreq, float hifreq); +float turbulencep(float noisesize, float x, float y, float z, int nr); + + +#define HASHVEC(x,y,z) hashvectf+3*hash[ (hash[ (hash[(z) & 255]+(y)) & 255]+(x)) & 255] + + +unsigned char hash[512]= { +0xA2,0xA0,0x19,0x3B,0xF8,0xEB,0xAA,0xEE,0xF3,0x1C,0x67,0x28,0x1D,0xED,0x0,0xDE,0x95,0x2E,0xDC,0x3F,0x3A,0x82,0x35,0x4D,0x6C,0xBA,0x36,0xD0,0xF6,0xC,0x79,0x32,0xD1,0x59,0xF4,0x8,0x8B,0x63,0x89,0x2F,0xB8,0xB4,0x97,0x83,0xF2,0x8F,0x18,0xC7,0x51,0x14,0x65,0x87,0x48,0x20,0x42,0xA8,0x80,0xB5,0x40,0x13,0xB2,0x22,0x7E,0x57, +0xBC,0x7F,0x6B,0x9D,0x86,0x4C,0xC8,0xDB,0x7C,0xD5,0x25,0x4E,0x5A,0x55,0x74,0x50,0xCD,0xB3,0x7A,0xBB,0xC3,0xCB,0xB6,0xE2,0xE4,0xEC,0xFD,0x98,0xB,0x96,0xD3,0x9E,0x5C,0xA1,0x64,0xF1,0x81,0x61,0xE1,0xC4,0x24,0x72,0x49,0x8C,0x90,0x4B,0x84,0x34,0x38,0xAB,0x78,0xCA,0x1F,0x1,0xD7,0x93,0x11,0xC1,0x58,0xA9,0x31,0xF9,0x44,0x6D, +0xBF,0x33,0x9C,0x5F,0x9,0x94,0xA3,0x85,0x6,0xC6,0x9A,0x1E,0x7B,0x46,0x15,0x30,0x27,0x2B,0x1B,0x71,0x3C,0x5B,0xD6,0x6F,0x62,0xAC,0x4F,0xC2,0xC0,0xE,0xB1,0x23,0xA7,0xDF,0x47,0xB0,0x77,0x69,0x5,0xE9,0xE6,0xE7,0x76,0x73,0xF,0xFE,0x6E,0x9B,0x56,0xEF,0x12,0xA5,0x37,0xFC,0xAE,0xD9,0x3,0x8E,0xDD,0x10,0xB9,0xCE,0xC9,0x8D, +0xDA,0x2A,0xBD,0x68,0x17,0x9F,0xBE,0xD4,0xA,0xCC,0xD2,0xE8,0x43,0x3D,0x70,0xB7,0x2,0x7D,0x99,0xD8,0xD,0x60,0x8A,0x4,0x2C,0x3E,0x92,0xE5,0xAF,0x53,0x7,0xE0,0x29,0xA6,0xC5,0xE3,0xF5,0xF7,0x4A,0x41,0x26,0x6A,0x16,0x5E,0x52,0x2D,0x21,0xAD,0xF0,0x91,0xFF,0xEA,0x54,0xFA,0x66,0x1A,0x45,0x39,0xCF,0x75,0xA4,0x88,0xFB,0x5D, +0xA2,0xA0,0x19,0x3B,0xF8,0xEB,0xAA,0xEE,0xF3,0x1C,0x67,0x28,0x1D,0xED,0x0,0xDE,0x95,0x2E,0xDC,0x3F,0x3A,0x82,0x35,0x4D,0x6C,0xBA,0x36,0xD0,0xF6,0xC,0x79,0x32,0xD1,0x59,0xF4,0x8,0x8B,0x63,0x89,0x2F,0xB8,0xB4,0x97,0x83,0xF2,0x8F,0x18,0xC7,0x51,0x14,0x65,0x87,0x48,0x20,0x42,0xA8,0x80,0xB5,0x40,0x13,0xB2,0x22,0x7E,0x57, +0xBC,0x7F,0x6B,0x9D,0x86,0x4C,0xC8,0xDB,0x7C,0xD5,0x25,0x4E,0x5A,0x55,0x74,0x50,0xCD,0xB3,0x7A,0xBB,0xC3,0xCB,0xB6,0xE2,0xE4,0xEC,0xFD,0x98,0xB,0x96,0xD3,0x9E,0x5C,0xA1,0x64,0xF1,0x81,0x61,0xE1,0xC4,0x24,0x72,0x49,0x8C,0x90,0x4B,0x84,0x34,0x38,0xAB,0x78,0xCA,0x1F,0x1,0xD7,0x93,0x11,0xC1,0x58,0xA9,0x31,0xF9,0x44,0x6D, +0xBF,0x33,0x9C,0x5F,0x9,0x94,0xA3,0x85,0x6,0xC6,0x9A,0x1E,0x7B,0x46,0x15,0x30,0x27,0x2B,0x1B,0x71,0x3C,0x5B,0xD6,0x6F,0x62,0xAC,0x4F,0xC2,0xC0,0xE,0xB1,0x23,0xA7,0xDF,0x47,0xB0,0x77,0x69,0x5,0xE9,0xE6,0xE7,0x76,0x73,0xF,0xFE,0x6E,0x9B,0x56,0xEF,0x12,0xA5,0x37,0xFC,0xAE,0xD9,0x3,0x8E,0xDD,0x10,0xB9,0xCE,0xC9,0x8D, +0xDA,0x2A,0xBD,0x68,0x17,0x9F,0xBE,0xD4,0xA,0xCC,0xD2,0xE8,0x43,0x3D,0x70,0xB7,0x2,0x7D,0x99,0xD8,0xD,0x60,0x8A,0x4,0x2C,0x3E,0x92,0xE5,0xAF,0x53,0x7,0xE0,0x29,0xA6,0xC5,0xE3,0xF5,0xF7,0x4A,0x41,0x26,0x6A,0x16,0x5E,0x52,0x2D,0x21,0xAD,0xF0,0x91,0xFF,0xEA,0x54,0xFA,0x66,0x1A,0x45,0x39,0xCF,0x75,0xA4,0x88,0xFB,0x5D, +}; + + +float hashvectf[768]= { +0.33783,0.715698,-0.611206,-0.944031,-0.326599,-0.045624,-0.101074,-0.416443,-0.903503,0.799286,0.49411,-0.341949,-0.854645,0.518036,0.033936,0.42514,-0.437866,-0.792114,-0.358948,0.597046,0.717377,-0.985413,0.144714,0.089294,-0.601776,-0.33728,-0.723907,-0.449921,0.594513,0.666382,0.208313,-0.10791, +0.972076,0.575317,0.060425,0.815643,0.293365,-0.875702,-0.383453,0.293762,0.465759,0.834686,-0.846008,-0.233398,-0.47934,-0.115814,0.143036,-0.98291,0.204681,-0.949036,-0.239532,0.946716,-0.263947,0.184326,-0.235596,0.573822,0.784332,0.203705,-0.372253,-0.905487,0.756989,-0.651031,0.055298,0.497803, +0.814697,-0.297363,-0.16214,0.063995,-0.98468,-0.329254,0.834381,0.441925,0.703827,-0.527039,-0.476227,0.956421,0.266113,0.119781,0.480133,0.482849,0.7323,-0.18631,0.961212,-0.203125,-0.748474,-0.656921,-0.090393,-0.085052,-0.165253,0.982544,-0.76947,0.628174,-0.115234,0.383148,0.537659,0.751068, +0.616486,-0.668488,-0.415924,-0.259979,-0.630005,0.73175,0.570953,-0.087952,0.816223,-0.458008,0.023254,0.888611,-0.196167,0.976563,-0.088287,-0.263885,-0.69812,-0.665527,0.437134,-0.892273,-0.112793,-0.621674,-0.230438,0.748566,0.232422,0.900574,-0.367249,0.22229,-0.796143,0.562744,-0.665497,-0.73764, +0.11377,0.670135,0.704803,0.232605,0.895599,0.429749,-0.114655,-0.11557,-0.474243,0.872742,0.621826,0.604004,-0.498444,-0.832214,0.012756,0.55426,-0.702484,0.705994,-0.089661,-0.692017,0.649292,0.315399,-0.175995,-0.977997,0.111877,0.096954,-0.04953,0.994019,0.635284,-0.606689,-0.477783,-0.261261, +-0.607422,-0.750153,0.983276,0.165436,0.075958,-0.29837,0.404083,-0.864655,-0.638672,0.507721,0.578156,0.388214,0.412079,0.824249,0.556183,-0.208832,0.804352,0.778442,0.562012,0.27951,-0.616577,0.781921,-0.091522,0.196289,0.051056,0.979187,-0.121216,0.207153,-0.970734,-0.173401,-0.384735,0.906555, +0.161499,-0.723236,-0.671387,0.178497,-0.006226,-0.983887,-0.126038,0.15799,0.97934,0.830475,-0.024811,0.556458,-0.510132,-0.76944,0.384247,0.81424,0.200104,-0.544891,-0.112549,-0.393311,-0.912445,0.56189,0.152222,-0.813049,0.198914,-0.254517,-0.946381,-0.41217,0.690979,-0.593811,-0.407257,0.324524, +0.853668,-0.690186,0.366119,-0.624115,-0.428345,0.844147,-0.322296,-0.21228,-0.297546,-0.930756,-0.273071,0.516113,0.811798,0.928314,0.371643,0.007233,0.785828,-0.479218,-0.390778,-0.704895,0.058929,0.706818,0.173248,0.203583,0.963562,0.422211,-0.904297,-0.062469,-0.363312,-0.182465,0.913605,0.254028, +-0.552307,-0.793945,-0.28891,-0.765747,-0.574554,0.058319,0.291382,0.954803,0.946136,-0.303925,0.111267,-0.078156,0.443695,-0.892731,0.182098,0.89389,0.409515,-0.680298,-0.213318,0.701141,0.062469,0.848389,-0.525635,-0.72879,-0.641846,0.238342,-0.88089,0.427673,0.202637,-0.532501,-0.21405,0.818878, +0.948975,-0.305084,0.07962,0.925446,0.374664,0.055817,0.820923,0.565491,0.079102,0.25882,0.099792,-0.960724,-0.294617,0.910522,0.289978,0.137115,0.320038,-0.937408,-0.908386,0.345276,-0.235718,-0.936218,0.138763,0.322754,0.366577,0.925934,-0.090637,0.309296,-0.686829,-0.657684,0.66983,0.024445, +0.742065,-0.917999,-0.059113,-0.392059,0.365509,0.462158,-0.807922,0.083374,0.996399,-0.014801,0.593842,0.253143,-0.763672,0.974976,-0.165466,0.148285,0.918976,0.137299,0.369537,0.294952,0.694977,0.655731,0.943085,0.152618,-0.295319,0.58783,-0.598236,0.544495,0.203796,0.678223,0.705994,-0.478821, +-0.661011,0.577667,0.719055,-0.1698,-0.673828,-0.132172,-0.965332,0.225006,-0.981873,-0.14502,0.121979,0.763458,0.579742,0.284546,-0.893188,0.079681,0.442474,-0.795776,-0.523804,0.303802,0.734955,0.67804,-0.007446,0.15506,0.986267,-0.056183,0.258026,0.571503,-0.778931,-0.681549,-0.702087,-0.206116, +-0.96286,-0.177185,0.203613,-0.470978,-0.515106,0.716095,-0.740326,0.57135,0.354095,-0.56012,-0.824982,-0.074982,-0.507874,0.753204,0.417969,-0.503113,0.038147,0.863342,0.594025,0.673553,-0.439758,-0.119873,-0.005524,-0.992737,0.098267,-0.213776,0.971893,-0.615631,0.643951,0.454163,0.896851,-0.441071, +0.032166,-0.555023,0.750763,-0.358093,0.398773,0.304688,0.864929,-0.722961,0.303589,0.620544,-0.63559,-0.621948,-0.457306,-0.293243,0.072327,0.953278,-0.491638,0.661041,-0.566772,-0.304199,-0.572083,-0.761688,0.908081,-0.398956,0.127014,-0.523621,-0.549683,-0.650848,-0.932922,-0.19986,0.299408,0.099426, +0.140869,0.984985,-0.020325,-0.999756,-0.002319,0.952667,0.280853,-0.11615,-0.971893,0.082581,0.220337,0.65921,0.705292,-0.260651,0.733063,-0.175537,0.657043,-0.555206,0.429504,-0.712189,0.400421,-0.89859,0.179352,0.750885,-0.19696,0.630341,0.785675,-0.569336,0.241821,-0.058899,-0.464111,0.883789, +0.129608,-0.94519,0.299622,-0.357819,0.907654,0.219238,-0.842133,-0.439117,-0.312927,-0.313477,0.84433,0.434479,-0.241211,0.053253,0.968994,0.063873,0.823273,0.563965,0.476288,0.862152,-0.172516,0.620941,-0.298126,0.724915,0.25238,-0.749359,-0.612122,-0.577545,0.386566,0.718994,-0.406342,-0.737976, +0.538696,0.04718,0.556305,0.82959,-0.802856,0.587463,0.101166,-0.707733,-0.705963,0.026428,0.374908,0.68457,0.625092,0.472137,0.208405,-0.856506,-0.703064,-0.581085,-0.409821,-0.417206,-0.736328,0.532623,-0.447876,-0.20285,-0.870728,0.086945,-0.990417,0.107086,0.183685,0.018341,-0.982788,0.560638, +-0.428864,0.708282,0.296722,-0.952576,-0.0672,0.135773,0.990265,0.030243,-0.068787,0.654724,0.752686,0.762604,-0.551758,0.337585,-0.819611,-0.407684,0.402466,-0.727844,-0.55072,-0.408539,-0.855774,-0.480011,0.19281,0.693176,-0.079285,0.716339,0.226013,0.650116,-0.725433,0.246704,0.953369,-0.173553, +-0.970398,-0.239227,-0.03244,0.136383,-0.394318,0.908752,0.813232,0.558167,0.164368,0.40451,0.549042,-0.731323,-0.380249,-0.566711,0.730865,0.022156,0.932739,0.359741,0.00824,0.996552,-0.082306,0.956635,-0.065338,-0.283722,-0.743561,0.008209,0.668579,-0.859589,-0.509674,0.035767,-0.852234,0.363678, +-0.375977,-0.201965,-0.970795,-0.12915,0.313477,0.947327,0.06546,-0.254028,-0.528259,0.81015,0.628052,0.601105,0.49411,-0.494385,0.868378,0.037933,0.275635,-0.086426,0.957336,-0.197937,0.468903,-0.860748,0.895599,0.399384,0.195801,0.560791,0.825012,-0.069214,0.304199,-0.849487,0.43103,0.096375, +0.93576,0.339111,-0.051422,0.408966,-0.911072,0.330444,0.942841,-0.042389,-0.452362,-0.786407,0.420563,0.134308,-0.933472,-0.332489,0.80191,-0.566711,-0.188934,-0.987946,-0.105988,0.112518,-0.24408,0.892242,-0.379791,-0.920502,0.229095,-0.316376,0.7789,0.325958,0.535706,-0.912872,0.185211,-0.36377, +-0.184784,0.565369,-0.803833,-0.018463,0.119537,0.992615,-0.259247,-0.935608,0.239532,-0.82373,-0.449127,-0.345947,-0.433105,0.659515,0.614349,-0.822754,0.378845,-0.423676,0.687195,-0.674835,-0.26889,-0.246582,-0.800842,0.545715,-0.729187,-0.207794,0.651978,0.653534,-0.610443,-0.447388,0.492584,-0.023346, +0.869934,0.609039,0.009094,-0.79306,0.962494,-0.271088,-0.00885,0.2659,-0.004913,0.963959,0.651245,0.553619,-0.518951,0.280548,-0.84314,0.458618,-0.175293,-0.983215,0.049805,0.035339,-0.979919,0.196045,-0.982941,0.164307,-0.082245,0.233734,-0.97226,-0.005005,-0.747253,-0.611328,0.260437,0.645599, +0.592773,0.481384,0.117706,-0.949524,-0.29068,-0.535004,-0.791901,-0.294312,-0.627167,-0.214447,0.748718,-0.047974,-0.813477,-0.57959,-0.175537,0.477264,-0.860992,0.738556,-0.414246,-0.53183,0.562561,-0.704071,0.433289,-0.754944,0.64801,-0.100586,0.114716,0.044525,-0.992371,0.966003,0.244873,-0.082764, +}; + + +float BLI_hnoise(float noisesize, float x, float y, float z) +{ + register float cn1, cn2, cn3, cn4, cn5, cn6, i, *h; + float ox, oy, oz, jx, jy, jz; + float n= 0.5; + int ix, iy, iz, b00, b01, b10, b11, b20, b21; + + if(noisesize==0.0) return 0.0; + + x= (1.0+x)/noisesize; + y= (1.0+y)/noisesize; + z= (1.0+z)/noisesize; + + ox= (x- (ix= (int)floor(x)) ); + oy= (y- (iy= (int)floor(y)) ); + oz= (z- (iz= (int)floor(z)) ); + + jx= ox-1; + jy= oy-1; + jz= oz-1; + + cn1=ox*ox; cn2=oy*oy; cn3=oz*oz; + cn4=jx*jx; cn5=jy*jy; cn6=jz*jz; + + cn1= 1.0-3.0*cn1+2.0*cn1*ox; + cn2= 1.0-3.0*cn2+2.0*cn2*oy; + cn3= 1.0-3.0*cn3+2.0*cn3*oz; + cn4= 1.0-3.0*cn4-2.0*cn4*jx; + cn5= 1.0-3.0*cn5-2.0*cn5*jy; + cn6= 1.0-3.0*cn6-2.0*cn6*jz; + + b00= hash[ hash[ix & 255]+(iy & 255)]; + b10= hash[ hash[(ix+1) & 255]+(iy & 255)]; + b01= hash[ hash[ix & 255]+((iy+1) & 255)]; + b11= hash[ hash[(ix+1) & 255]+((iy+1) & 255)]; + + b20=iz & 255; b21= (iz+1) & 255; + + /* 0 */ + i= (cn1*cn2*cn3); + h=hashvectf+ 3*hash[b20+b00]; + n+= i*(h[0]*ox+h[1]*oy+h[2]*oz); + /* 1 */ + i= (cn1*cn2*cn6); + h=hashvectf+ 3*hash[b21+b00]; + n+= i*(h[0]*ox+h[1]*oy+h[2]*jz); + /* 2 */ + i= (cn1*cn5*cn3); + h=hashvectf+ 3*hash[b20+b01]; + n+= i*(h[0]*ox+h[1]*jy+h[2]*oz); + /* 3 */ + i= (cn1*cn5*cn6); + h=hashvectf+ 3*hash[b21+b01]; + n+= i*(h[0]*ox+h[1]*jy+h[2]*jz); + /* 4 */ + i= cn4*cn2*cn3; + h=hashvectf+ 3*hash[b20+b10]; + n+= i*(h[0]*jx+h[1]*oy+h[2]*oz); + /* 5 */ + i= cn4*cn2*cn6; + h=hashvectf+ 3*hash[b21+b10]; + n+= i*(h[0]*jx+h[1]*oy+h[2]*jz); + /* 6 */ + i= cn4*cn5*cn3; + h=hashvectf+ 3*hash[b20+b11]; + n+= i*(h[0]*jx+h[1]*jy+h[2]*oz); + /* 7 */ + i= (cn4*cn5*cn6); + h=hashvectf+ 3*hash[b21+b11]; + n+= i*(h[0]*jx+h[1]*jy+h[2]*jz); + + if(n<0.0) n=0.0; else if(n>1.0) n=1.0 ; + return n; +} + + + + +float BLI_turbulence(float noisesize, float x, float y, float z, int nr) +{ + float s, d= 0.5, div=1.0; + + s= BLI_hnoise(noisesize, x, y, z); + + while(nr>0) { + + s+= d*BLI_hnoise(noisesize*d, x, y, z); + div+= d; + d*= 0.5; + + nr--; + } + return s/div; +} + +float BLI_turbulence1(float noisesize, float x, float y, float z, int nr) +{ + float s, d= 0.5, div=1.0; + + s= fabs( (-1.0+2.0*BLI_hnoise(noisesize, x, y, z))); + + while(nr>0) { + + s+= fabs(d* (-1.0+2.0*BLI_hnoise(noisesize*d, x, y, z))); + div+= d; + d*= 0.5; + + nr--; + } + return s/div; +} + + + + +/* ********************* VAN PERLIN HIMSELF: ******************** */ + + +static char p[512+2]= { +0xA2,0xA0,0x19,0x3B,0xF8,0xEB,0xAA,0xEE,0xF3,0x1C,0x67,0x28,0x1D,0xED,0x0,0xDE,0x95,0x2E,0xDC,0x3F,0x3A,0x82,0x35,0x4D,0x6C,0xBA,0x36,0xD0,0xF6,0xC,0x79,0x32,0xD1,0x59,0xF4,0x8,0x8B,0x63,0x89,0x2F,0xB8,0xB4,0x97,0x83,0xF2,0x8F,0x18,0xC7,0x51,0x14,0x65,0x87,0x48,0x20,0x42,0xA8,0x80,0xB5,0x40,0x13,0xB2,0x22,0x7E,0x57, +0xBC,0x7F,0x6B,0x9D,0x86,0x4C,0xC8,0xDB,0x7C,0xD5,0x25,0x4E,0x5A,0x55,0x74,0x50,0xCD,0xB3,0x7A,0xBB,0xC3,0xCB,0xB6,0xE2,0xE4,0xEC,0xFD,0x98,0xB,0x96,0xD3,0x9E,0x5C,0xA1,0x64,0xF1,0x81,0x61,0xE1,0xC4,0x24,0x72,0x49,0x8C,0x90,0x4B,0x84,0x34,0x38,0xAB,0x78,0xCA,0x1F,0x1,0xD7,0x93,0x11,0xC1,0x58,0xA9,0x31,0xF9,0x44,0x6D, +0xBF,0x33,0x9C,0x5F,0x9,0x94,0xA3,0x85,0x6,0xC6,0x9A,0x1E,0x7B,0x46,0x15,0x30,0x27,0x2B,0x1B,0x71,0x3C,0x5B,0xD6,0x6F,0x62,0xAC,0x4F,0xC2,0xC0,0xE,0xB1,0x23,0xA7,0xDF,0x47,0xB0,0x77,0x69,0x5,0xE9,0xE6,0xE7,0x76,0x73,0xF,0xFE,0x6E,0x9B,0x56,0xEF,0x12,0xA5,0x37,0xFC,0xAE,0xD9,0x3,0x8E,0xDD,0x10,0xB9,0xCE,0xC9,0x8D, +0xDA,0x2A,0xBD,0x68,0x17,0x9F,0xBE,0xD4,0xA,0xCC,0xD2,0xE8,0x43,0x3D,0x70,0xB7,0x2,0x7D,0x99,0xD8,0xD,0x60,0x8A,0x4,0x2C,0x3E,0x92,0xE5,0xAF,0x53,0x7,0xE0,0x29,0xA6,0xC5,0xE3,0xF5,0xF7,0x4A,0x41,0x26,0x6A,0x16,0x5E,0x52,0x2D,0x21,0xAD,0xF0,0x91,0xFF,0xEA,0x54,0xFA,0x66,0x1A,0x45,0x39,0xCF,0x75,0xA4,0x88,0xFB,0x5D, +0xA2,0xA0,0x19,0x3B,0xF8,0xEB,0xAA,0xEE,0xF3,0x1C,0x67,0x28,0x1D,0xED,0x0,0xDE,0x95,0x2E,0xDC,0x3F,0x3A,0x82,0x35,0x4D,0x6C,0xBA,0x36,0xD0,0xF6,0xC,0x79,0x32,0xD1,0x59,0xF4,0x8,0x8B,0x63,0x89,0x2F,0xB8,0xB4,0x97,0x83,0xF2,0x8F,0x18,0xC7,0x51,0x14,0x65,0x87,0x48,0x20,0x42,0xA8,0x80,0xB5,0x40,0x13,0xB2,0x22,0x7E,0x57, +0xBC,0x7F,0x6B,0x9D,0x86,0x4C,0xC8,0xDB,0x7C,0xD5,0x25,0x4E,0x5A,0x55,0x74,0x50,0xCD,0xB3,0x7A,0xBB,0xC3,0xCB,0xB6,0xE2,0xE4,0xEC,0xFD,0x98,0xB,0x96,0xD3,0x9E,0x5C,0xA1,0x64,0xF1,0x81,0x61,0xE1,0xC4,0x24,0x72,0x49,0x8C,0x90,0x4B,0x84,0x34,0x38,0xAB,0x78,0xCA,0x1F,0x1,0xD7,0x93,0x11,0xC1,0x58,0xA9,0x31,0xF9,0x44,0x6D, +0xBF,0x33,0x9C,0x5F,0x9,0x94,0xA3,0x85,0x6,0xC6,0x9A,0x1E,0x7B,0x46,0x15,0x30,0x27,0x2B,0x1B,0x71,0x3C,0x5B,0xD6,0x6F,0x62,0xAC,0x4F,0xC2,0xC0,0xE,0xB1,0x23,0xA7,0xDF,0x47,0xB0,0x77,0x69,0x5,0xE9,0xE6,0xE7,0x76,0x73,0xF,0xFE,0x6E,0x9B,0x56,0xEF,0x12,0xA5,0x37,0xFC,0xAE,0xD9,0x3,0x8E,0xDD,0x10,0xB9,0xCE,0xC9,0x8D, +0xDA,0x2A,0xBD,0x68,0x17,0x9F,0xBE,0xD4,0xA,0xCC,0xD2,0xE8,0x43,0x3D,0x70,0xB7,0x2,0x7D,0x99,0xD8,0xD,0x60,0x8A,0x4,0x2C,0x3E,0x92,0xE5,0xAF,0x53,0x7,0xE0,0x29,0xA6,0xC5,0xE3,0xF5,0xF7,0x4A,0x41,0x26,0x6A,0x16,0x5E,0x52,0x2D,0x21,0xAD,0xF0,0x91,0xFF,0xEA,0x54,0xFA,0x66,0x1A,0x45,0x39,0xCF,0x75,0xA4,0x88,0xFB,0x5D, +0xA2,0xA0}; + + +float g[512+2][3]= { +0.33783,0.715698,-0.611206,-0.944031,-0.326599,-0.045624,-0.101074,-0.416443,-0.903503,0.799286,0.49411,-0.341949,-0.854645,0.518036,0.033936,0.42514,-0.437866,-0.792114,-0.358948,0.597046,0.717377,-0.985413,0.144714,0.089294,-0.601776,-0.33728,-0.723907,-0.449921,0.594513,0.666382,0.208313,-0.10791, +0.972076,0.575317,0.060425,0.815643,0.293365,-0.875702,-0.383453,0.293762,0.465759,0.834686,-0.846008,-0.233398,-0.47934,-0.115814,0.143036,-0.98291,0.204681,-0.949036,-0.239532,0.946716,-0.263947,0.184326,-0.235596,0.573822,0.784332,0.203705,-0.372253,-0.905487,0.756989,-0.651031,0.055298,0.497803, +0.814697,-0.297363,-0.16214,0.063995,-0.98468,-0.329254,0.834381,0.441925,0.703827,-0.527039,-0.476227,0.956421,0.266113,0.119781,0.480133,0.482849,0.7323,-0.18631,0.961212,-0.203125,-0.748474,-0.656921,-0.090393,-0.085052,-0.165253,0.982544,-0.76947,0.628174,-0.115234,0.383148,0.537659,0.751068, +0.616486,-0.668488,-0.415924,-0.259979,-0.630005,0.73175,0.570953,-0.087952,0.816223,-0.458008,0.023254,0.888611,-0.196167,0.976563,-0.088287,-0.263885,-0.69812,-0.665527,0.437134,-0.892273,-0.112793,-0.621674,-0.230438,0.748566,0.232422,0.900574,-0.367249,0.22229,-0.796143,0.562744,-0.665497,-0.73764, +0.11377,0.670135,0.704803,0.232605,0.895599,0.429749,-0.114655,-0.11557,-0.474243,0.872742,0.621826,0.604004,-0.498444,-0.832214,0.012756,0.55426,-0.702484,0.705994,-0.089661,-0.692017,0.649292,0.315399,-0.175995,-0.977997,0.111877,0.096954,-0.04953,0.994019,0.635284,-0.606689,-0.477783,-0.261261, +-0.607422,-0.750153,0.983276,0.165436,0.075958,-0.29837,0.404083,-0.864655,-0.638672,0.507721,0.578156,0.388214,0.412079,0.824249,0.556183,-0.208832,0.804352,0.778442,0.562012,0.27951,-0.616577,0.781921,-0.091522,0.196289,0.051056,0.979187,-0.121216,0.207153,-0.970734,-0.173401,-0.384735,0.906555, +0.161499,-0.723236,-0.671387,0.178497,-0.006226,-0.983887,-0.126038,0.15799,0.97934,0.830475,-0.024811,0.556458,-0.510132,-0.76944,0.384247,0.81424,0.200104,-0.544891,-0.112549,-0.393311,-0.912445,0.56189,0.152222,-0.813049,0.198914,-0.254517,-0.946381,-0.41217,0.690979,-0.593811,-0.407257,0.324524, +0.853668,-0.690186,0.366119,-0.624115,-0.428345,0.844147,-0.322296,-0.21228,-0.297546,-0.930756,-0.273071,0.516113,0.811798,0.928314,0.371643,0.007233,0.785828,-0.479218,-0.390778,-0.704895,0.058929,0.706818,0.173248,0.203583,0.963562,0.422211,-0.904297,-0.062469,-0.363312,-0.182465,0.913605,0.254028, +-0.552307,-0.793945,-0.28891,-0.765747,-0.574554,0.058319,0.291382,0.954803,0.946136,-0.303925,0.111267,-0.078156,0.443695,-0.892731,0.182098,0.89389,0.409515,-0.680298,-0.213318,0.701141,0.062469,0.848389,-0.525635,-0.72879,-0.641846,0.238342,-0.88089,0.427673,0.202637,-0.532501,-0.21405,0.818878, +0.948975,-0.305084,0.07962,0.925446,0.374664,0.055817,0.820923,0.565491,0.079102,0.25882,0.099792,-0.960724,-0.294617,0.910522,0.289978,0.137115,0.320038,-0.937408,-0.908386,0.345276,-0.235718,-0.936218,0.138763,0.322754,0.366577,0.925934,-0.090637,0.309296,-0.686829,-0.657684,0.66983,0.024445, +0.742065,-0.917999,-0.059113,-0.392059,0.365509,0.462158,-0.807922,0.083374,0.996399,-0.014801,0.593842,0.253143,-0.763672,0.974976,-0.165466,0.148285,0.918976,0.137299,0.369537,0.294952,0.694977,0.655731,0.943085,0.152618,-0.295319,0.58783,-0.598236,0.544495,0.203796,0.678223,0.705994,-0.478821, +-0.661011,0.577667,0.719055,-0.1698,-0.673828,-0.132172,-0.965332,0.225006,-0.981873,-0.14502,0.121979,0.763458,0.579742,0.284546,-0.893188,0.079681,0.442474,-0.795776,-0.523804,0.303802,0.734955,0.67804,-0.007446,0.15506,0.986267,-0.056183,0.258026,0.571503,-0.778931,-0.681549,-0.702087,-0.206116, +-0.96286,-0.177185,0.203613,-0.470978,-0.515106,0.716095,-0.740326,0.57135,0.354095,-0.56012,-0.824982,-0.074982,-0.507874,0.753204,0.417969,-0.503113,0.038147,0.863342,0.594025,0.673553,-0.439758,-0.119873,-0.005524,-0.992737,0.098267,-0.213776,0.971893,-0.615631,0.643951,0.454163,0.896851,-0.441071, +0.032166,-0.555023,0.750763,-0.358093,0.398773,0.304688,0.864929,-0.722961,0.303589,0.620544,-0.63559,-0.621948,-0.457306,-0.293243,0.072327,0.953278,-0.491638,0.661041,-0.566772,-0.304199,-0.572083,-0.761688,0.908081,-0.398956,0.127014,-0.523621,-0.549683,-0.650848,-0.932922,-0.19986,0.299408,0.099426, +0.140869,0.984985,-0.020325,-0.999756,-0.002319,0.952667,0.280853,-0.11615,-0.971893,0.082581,0.220337,0.65921,0.705292,-0.260651,0.733063,-0.175537,0.657043,-0.555206,0.429504,-0.712189,0.400421,-0.89859,0.179352,0.750885,-0.19696,0.630341,0.785675,-0.569336,0.241821,-0.058899,-0.464111,0.883789, +0.129608,-0.94519,0.299622,-0.357819,0.907654,0.219238,-0.842133,-0.439117,-0.312927,-0.313477,0.84433,0.434479,-0.241211,0.053253,0.968994,0.063873,0.823273,0.563965,0.476288,0.862152,-0.172516,0.620941,-0.298126,0.724915,0.25238,-0.749359,-0.612122,-0.577545,0.386566,0.718994,-0.406342,-0.737976, +0.538696,0.04718,0.556305,0.82959,-0.802856,0.587463,0.101166,-0.707733,-0.705963,0.026428,0.374908,0.68457,0.625092,0.472137,0.208405,-0.856506,-0.703064,-0.581085,-0.409821,-0.417206,-0.736328,0.532623,-0.447876,-0.20285,-0.870728,0.086945,-0.990417,0.107086,0.183685,0.018341,-0.982788,0.560638, +-0.428864,0.708282,0.296722,-0.952576,-0.0672,0.135773,0.990265,0.030243,-0.068787,0.654724,0.752686,0.762604,-0.551758,0.337585,-0.819611,-0.407684,0.402466,-0.727844,-0.55072,-0.408539,-0.855774,-0.480011,0.19281,0.693176,-0.079285,0.716339,0.226013,0.650116,-0.725433,0.246704,0.953369,-0.173553, +-0.970398,-0.239227,-0.03244,0.136383,-0.394318,0.908752,0.813232,0.558167,0.164368,0.40451,0.549042,-0.731323,-0.380249,-0.566711,0.730865,0.022156,0.932739,0.359741,0.00824,0.996552,-0.082306,0.956635,-0.065338,-0.283722,-0.743561,0.008209,0.668579,-0.859589,-0.509674,0.035767,-0.852234,0.363678, +-0.375977,-0.201965,-0.970795,-0.12915,0.313477,0.947327,0.06546,-0.254028,-0.528259,0.81015,0.628052,0.601105,0.49411,-0.494385,0.868378,0.037933,0.275635,-0.086426,0.957336,-0.197937,0.468903,-0.860748,0.895599,0.399384,0.195801,0.560791,0.825012,-0.069214,0.304199,-0.849487,0.43103,0.096375, +0.93576,0.339111,-0.051422,0.408966,-0.911072,0.330444,0.942841,-0.042389,-0.452362,-0.786407,0.420563,0.134308,-0.933472,-0.332489,0.80191,-0.566711,-0.188934,-0.987946,-0.105988,0.112518,-0.24408,0.892242,-0.379791,-0.920502,0.229095,-0.316376,0.7789,0.325958,0.535706,-0.912872,0.185211,-0.36377, +-0.184784,0.565369,-0.803833,-0.018463,0.119537,0.992615,-0.259247,-0.935608,0.239532,-0.82373,-0.449127,-0.345947,-0.433105,0.659515,0.614349,-0.822754,0.378845,-0.423676,0.687195,-0.674835,-0.26889,-0.246582,-0.800842,0.545715,-0.729187,-0.207794,0.651978,0.653534,-0.610443,-0.447388,0.492584,-0.023346, +0.869934,0.609039,0.009094,-0.79306,0.962494,-0.271088,-0.00885,0.2659,-0.004913,0.963959,0.651245,0.553619,-0.518951,0.280548,-0.84314,0.458618,-0.175293,-0.983215,0.049805,0.035339,-0.979919,0.196045,-0.982941,0.164307,-0.082245,0.233734,-0.97226,-0.005005,-0.747253,-0.611328,0.260437,0.645599, +0.592773,0.481384,0.117706,-0.949524,-0.29068,-0.535004,-0.791901,-0.294312,-0.627167,-0.214447,0.748718,-0.047974,-0.813477,-0.57959,-0.175537,0.477264,-0.860992,0.738556,-0.414246,-0.53183,0.562561,-0.704071,0.433289,-0.754944,0.64801,-0.100586,0.114716,0.044525,-0.992371,0.966003,0.244873,-0.082764, +0.33783,0.715698,-0.611206,-0.944031,-0.326599,-0.045624,-0.101074,-0.416443,-0.903503,0.799286,0.49411,-0.341949,-0.854645,0.518036,0.033936,0.42514,-0.437866,-0.792114,-0.358948,0.597046,0.717377,-0.985413,0.144714,0.089294,-0.601776,-0.33728,-0.723907,-0.449921,0.594513,0.666382,0.208313,-0.10791, +0.972076,0.575317,0.060425,0.815643,0.293365,-0.875702,-0.383453,0.293762,0.465759,0.834686,-0.846008,-0.233398,-0.47934,-0.115814,0.143036,-0.98291,0.204681,-0.949036,-0.239532,0.946716,-0.263947,0.184326,-0.235596,0.573822,0.784332,0.203705,-0.372253,-0.905487,0.756989,-0.651031,0.055298,0.497803, +0.814697,-0.297363,-0.16214,0.063995,-0.98468,-0.329254,0.834381,0.441925,0.703827,-0.527039,-0.476227,0.956421,0.266113,0.119781,0.480133,0.482849,0.7323,-0.18631,0.961212,-0.203125,-0.748474,-0.656921,-0.090393,-0.085052,-0.165253,0.982544,-0.76947,0.628174,-0.115234,0.383148,0.537659,0.751068, +0.616486,-0.668488,-0.415924,-0.259979,-0.630005,0.73175,0.570953,-0.087952,0.816223,-0.458008,0.023254,0.888611,-0.196167,0.976563,-0.088287,-0.263885,-0.69812,-0.665527,0.437134,-0.892273,-0.112793,-0.621674,-0.230438,0.748566,0.232422,0.900574,-0.367249,0.22229,-0.796143,0.562744,-0.665497,-0.73764, +0.11377,0.670135,0.704803,0.232605,0.895599,0.429749,-0.114655,-0.11557,-0.474243,0.872742,0.621826,0.604004,-0.498444,-0.832214,0.012756,0.55426,-0.702484,0.705994,-0.089661,-0.692017,0.649292,0.315399,-0.175995,-0.977997,0.111877,0.096954,-0.04953,0.994019,0.635284,-0.606689,-0.477783,-0.261261, +-0.607422,-0.750153,0.983276,0.165436,0.075958,-0.29837,0.404083,-0.864655,-0.638672,0.507721,0.578156,0.388214,0.412079,0.824249,0.556183,-0.208832,0.804352,0.778442,0.562012,0.27951,-0.616577,0.781921,-0.091522,0.196289,0.051056,0.979187,-0.121216,0.207153,-0.970734,-0.173401,-0.384735,0.906555, +0.161499,-0.723236,-0.671387,0.178497,-0.006226,-0.983887,-0.126038,0.15799,0.97934,0.830475,-0.024811,0.556458,-0.510132,-0.76944,0.384247,0.81424,0.200104,-0.544891,-0.112549,-0.393311,-0.912445,0.56189,0.152222,-0.813049,0.198914,-0.254517,-0.946381,-0.41217,0.690979,-0.593811,-0.407257,0.324524, +0.853668,-0.690186,0.366119,-0.624115,-0.428345,0.844147,-0.322296,-0.21228,-0.297546,-0.930756,-0.273071,0.516113,0.811798,0.928314,0.371643,0.007233,0.785828,-0.479218,-0.390778,-0.704895,0.058929,0.706818,0.173248,0.203583,0.963562,0.422211,-0.904297,-0.062469,-0.363312,-0.182465,0.913605,0.254028, +-0.552307,-0.793945,-0.28891,-0.765747,-0.574554,0.058319,0.291382,0.954803,0.946136,-0.303925,0.111267,-0.078156,0.443695,-0.892731,0.182098,0.89389,0.409515,-0.680298,-0.213318,0.701141,0.062469,0.848389,-0.525635,-0.72879,-0.641846,0.238342,-0.88089,0.427673,0.202637,-0.532501,-0.21405,0.818878, +0.948975,-0.305084,0.07962,0.925446,0.374664,0.055817,0.820923,0.565491,0.079102,0.25882,0.099792,-0.960724,-0.294617,0.910522,0.289978,0.137115,0.320038,-0.937408,-0.908386,0.345276,-0.235718,-0.936218,0.138763,0.322754,0.366577,0.925934,-0.090637,0.309296,-0.686829,-0.657684,0.66983,0.024445, +0.742065,-0.917999,-0.059113,-0.392059,0.365509,0.462158,-0.807922,0.083374,0.996399,-0.014801,0.593842,0.253143,-0.763672,0.974976,-0.165466,0.148285,0.918976,0.137299,0.369537,0.294952,0.694977,0.655731,0.943085,0.152618,-0.295319,0.58783,-0.598236,0.544495,0.203796,0.678223,0.705994,-0.478821, +-0.661011,0.577667,0.719055,-0.1698,-0.673828,-0.132172,-0.965332,0.225006,-0.981873,-0.14502,0.121979,0.763458,0.579742,0.284546,-0.893188,0.079681,0.442474,-0.795776,-0.523804,0.303802,0.734955,0.67804,-0.007446,0.15506,0.986267,-0.056183,0.258026,0.571503,-0.778931,-0.681549,-0.702087,-0.206116, +-0.96286,-0.177185,0.203613,-0.470978,-0.515106,0.716095,-0.740326,0.57135,0.354095,-0.56012,-0.824982,-0.074982,-0.507874,0.753204,0.417969,-0.503113,0.038147,0.863342,0.594025,0.673553,-0.439758,-0.119873,-0.005524,-0.992737,0.098267,-0.213776,0.971893,-0.615631,0.643951,0.454163,0.896851,-0.441071, +0.032166,-0.555023,0.750763,-0.358093,0.398773,0.304688,0.864929,-0.722961,0.303589,0.620544,-0.63559,-0.621948,-0.457306,-0.293243,0.072327,0.953278,-0.491638,0.661041,-0.566772,-0.304199,-0.572083,-0.761688,0.908081,-0.398956,0.127014,-0.523621,-0.549683,-0.650848,-0.932922,-0.19986,0.299408,0.099426, +0.140869,0.984985,-0.020325,-0.999756,-0.002319,0.952667,0.280853,-0.11615,-0.971893,0.082581,0.220337,0.65921,0.705292,-0.260651,0.733063,-0.175537,0.657043,-0.555206,0.429504,-0.712189,0.400421,-0.89859,0.179352,0.750885,-0.19696,0.630341,0.785675,-0.569336,0.241821,-0.058899,-0.464111,0.883789, +0.129608,-0.94519,0.299622,-0.357819,0.907654,0.219238,-0.842133,-0.439117,-0.312927,-0.313477,0.84433,0.434479,-0.241211,0.053253,0.968994,0.063873,0.823273,0.563965,0.476288,0.862152,-0.172516,0.620941,-0.298126,0.724915,0.25238,-0.749359,-0.612122,-0.577545,0.386566,0.718994,-0.406342,-0.737976, +0.538696,0.04718,0.556305,0.82959,-0.802856,0.587463,0.101166,-0.707733,-0.705963,0.026428,0.374908,0.68457,0.625092,0.472137,0.208405,-0.856506,-0.703064,-0.581085,-0.409821,-0.417206,-0.736328,0.532623,-0.447876,-0.20285,-0.870728,0.086945,-0.990417,0.107086,0.183685,0.018341,-0.982788,0.560638, +-0.428864,0.708282,0.296722,-0.952576,-0.0672,0.135773,0.990265,0.030243,-0.068787,0.654724,0.752686,0.762604,-0.551758,0.337585,-0.819611,-0.407684,0.402466,-0.727844,-0.55072,-0.408539,-0.855774,-0.480011,0.19281,0.693176,-0.079285,0.716339,0.226013,0.650116,-0.725433,0.246704,0.953369,-0.173553, +-0.970398,-0.239227,-0.03244,0.136383,-0.394318,0.908752,0.813232,0.558167,0.164368,0.40451,0.549042,-0.731323,-0.380249,-0.566711,0.730865,0.022156,0.932739,0.359741,0.00824,0.996552,-0.082306,0.956635,-0.065338,-0.283722,-0.743561,0.008209,0.668579,-0.859589,-0.509674,0.035767,-0.852234,0.363678, +-0.375977,-0.201965,-0.970795,-0.12915,0.313477,0.947327,0.06546,-0.254028,-0.528259,0.81015,0.628052,0.601105,0.49411,-0.494385,0.868378,0.037933,0.275635,-0.086426,0.957336,-0.197937,0.468903,-0.860748,0.895599,0.399384,0.195801,0.560791,0.825012,-0.069214,0.304199,-0.849487,0.43103,0.096375, +0.93576,0.339111,-0.051422,0.408966,-0.911072,0.330444,0.942841,-0.042389,-0.452362,-0.786407,0.420563,0.134308,-0.933472,-0.332489,0.80191,-0.566711,-0.188934,-0.987946,-0.105988,0.112518,-0.24408,0.892242,-0.379791,-0.920502,0.229095,-0.316376,0.7789,0.325958,0.535706,-0.912872,0.185211,-0.36377, +-0.184784,0.565369,-0.803833,-0.018463,0.119537,0.992615,-0.259247,-0.935608,0.239532,-0.82373,-0.449127,-0.345947,-0.433105,0.659515,0.614349,-0.822754,0.378845,-0.423676,0.687195,-0.674835,-0.26889,-0.246582,-0.800842,0.545715,-0.729187,-0.207794,0.651978,0.653534,-0.610443,-0.447388,0.492584,-0.023346, +0.869934,0.609039,0.009094,-0.79306,0.962494,-0.271088,-0.00885,0.2659,-0.004913,0.963959,0.651245,0.553619,-0.518951,0.280548,-0.84314,0.458618,-0.175293,-0.983215,0.049805,0.035339,-0.979919,0.196045,-0.982941,0.164307,-0.082245,0.233734,-0.97226,-0.005005,-0.747253,-0.611328,0.260437,0.645599, +0.592773,0.481384,0.117706,-0.949524,-0.29068,-0.535004,-0.791901,-0.294312,-0.627167,-0.214447,0.748718,-0.047974,-0.813477,-0.57959,-0.175537,0.477264,-0.860992,0.738556,-0.414246,-0.53183,0.562561,-0.704071,0.433289,-0.754944,0.64801,-0.100586,0.114716,0.044525,-0.992371,0.966003,0.244873,-0.082764, +0.33783,0.715698,-0.611206,-0.944031,-0.326599,-0.045624}; + + + +#define DOT(a,b) (a[0] * b[0] + a[1] * b[1] + a[2] * b[2]) + +#define setup(i,b0,b1,r0,r1) \ + t = vec[i] + 10000.; \ + b0 = ((int)t) & 255; \ + b1 = (b0+1) & 255; \ + r0 = t - (int)t; \ + r1 = r0 - 1.; + + +float noise3_perlin(float vec[3]) +{ + int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11; + float rx0, rx1, ry0, ry1, rz0, rz1, *q, sx, sy, sz, a, b, c, d, t, u, v; + register int i, j; + + + setup(0, bx0,bx1, rx0,rx1); + setup(1, by0,by1, ry0,ry1); + setup(2, bz0,bz1, rz0,rz1); + + i = p[ bx0 ]; + j = p[ bx1 ]; + + b00 = p[ i + by0 ]; + b10 = p[ j + by0 ]; + b01 = p[ i + by1 ]; + b11 = p[ j + by1 ]; + +#define at(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] ) + +#define surve(t) ( t * t * (3. - 2. * t) ) + +#define lerp(t, a, b) ( a + t * (b - a) ) + + sx = surve(rx0); + sy = surve(ry0); + sz = surve(rz0); + + + q = g[ b00 + bz0 ] ; + u = at(rx0,ry0,rz0); + q = g[ b10 + bz0 ] ; + v = at(rx1,ry0,rz0); + a = lerp(sx, u, v); + + q = g[ b01 + bz0 ] ; + u = at(rx0,ry1,rz0); + q = g[ b11 + bz0 ] ; + v = at(rx1,ry1,rz0); + b = lerp(sx, u, v); + + c = lerp(sy, a, b); /* interpolate in y at lo x */ + + q = g[ b00 + bz1 ] ; + u = at(rx0,ry0,rz1); + q = g[ b10 + bz1 ] ; + v = at(rx1,ry0,rz1); + a = lerp(sx, u, v); + + q = g[ b01 + bz1 ] ; + u = at(rx0,ry1,rz1); + q = g[ b11 + bz1 ] ; + v = at(rx1,ry1,rz1); + b = lerp(sx, u, v); + + d = lerp(sy, a, b); /* interpolate in y at hi x */ + + return 1.5 * lerp(sz, c, d); /* interpolate in z */ +} + + +float turbulence_perlin(float *point, float lofreq, float hifreq) +{ + float freq, t, p[3]; + + p[0] = point[0] + 123.456; + p[1] = point[1]; + p[2] = point[2]; + + t = 0; + for (freq = lofreq ; freq < hifreq ; freq *= 2.) { + t += fabs(noise3_perlin(p)) / freq; + p[0] *= 2.; + p[1] *= 2.; + p[2] *= 2.; + } + return t - 0.3; /* readjust to make mean value = 0.0 */ +} + + + +/* *************** AANROEPEN ALS: *************** */ + +float BLI_hnoisep(float noisesize, float x, float y, float z) +{ + float vec[3]; + + vec[0]= x/noisesize; + vec[1]= y/noisesize; + vec[2]= z/noisesize; + + return noise3_perlin(vec); +} + +float turbulencep(float noisesize, float x, float y, float z, int nr) +{ + float vec[3]; + + vec[0]= x/noisesize; + vec[1]= y/noisesize; + vec[2]= z/noisesize; + nr++; + return turbulence_perlin(vec, 1.0, (float)(1< +#include +#include +#include +#include + +#include "MEM_guardedalloc.h" + +#include "BLI_vfontdata.h" +#include "BLI_blenlib.h" + +#include "DNA_packedFile_types.h" +#include "DNA_curve_types.h" + + /* ObjFnt types */ + +typedef struct chardesc { + short movex, movey; /* advance */ + short llx, lly; /* bounding box */ + short urx, ury; + short *data; /* char data */ + long 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 1000 +#define MAXCHARS 1000 +#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) + +/* some dirt for windows */ +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif + +static char oneline[LINELEN]; +static objfnt *fnt; + +static unsigned short int mr; + +static char *bindat; +static int datbytes; +static int firsted; +static short chardata[2000]; +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: uit de 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 de rest zit in lfm_s !!*/ + +/* START 5.2 */ + +static int chartoindex(objfnt *fnt, int c) +{ + if(ccharmin) + 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; imy_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 read = 0; + int c; + char * p; + + p = s; + while (n > 0){ + c = ((char *) pf->data)[pf->seek]; + pf->seek++; + if (pf->seek > pf->size){ + if (read == 0) return (0); + *p = 0; + return(s); + } + 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='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 (fakeposfakemax) { + 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; imy_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=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 xpos, ypos, noise; + + ypos = pop(); + xpos = pop(); + 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 --; /* voor de eerste keer */ + 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=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; + } + } + } + + /* i.p.v. the sidebearing[c1] moet misschen thesidebearing gebruikt worden */ + + 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=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], last[2]; + struct Nurb *nu; + struct BezTriple *bezt, *bez2; + float scale, dx, dy; + + if (!fnt || (fnt->type!=SP_TYPE)) { + return NULL; + } + + vfd= MEM_callocN(sizeof(*vfd), "VFontData"); + scale = 10.0/(float)fnt->scale; /* na IRIX 6.2, schaal klopte niet meer */ + + for (i = 0; i < MAX_VF_CHARS; i++) { + cd = getchardesc(fnt, i); + if (cd && cd->data && cd->datalen) { + vfd->width[i] = scale * cd->movex; + + _data = data = cd->data; + + do{ + /* eerst even tellen */ + _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 (last[0] == first[0] && last[1] == first[1]) meet = 1; + else meet = 0; + + /* is er meer dan 1 uniek punt ?*/ + + 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(&vfd->nurbsbase[i], nu); + nu->type= CU_BEZIER+CU_2D; + nu->pntsu = count; + nu->resolu= 8; + nu->flagu= 1; + nu->bezt = bezt; + stop = 0; + + /* punten inlezen */ + 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) { + /* kopieer handles */ + nu->bezt->vec[0][0] = bezt->vec[0][0]; + nu->bezt->vec[0][1] = bezt->vec[0][1]; + /* en vergeet laatste punt */ + 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; + } + + /* verboden handle combinaties */ + 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++; + } + + } + 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/rand.c b/source/blender/blenlib/intern/rand.c new file mode 100644 index 00000000000..bf29d57c2cf --- /dev/null +++ b/source/blender/blenlib/intern/rand.c @@ -0,0 +1,84 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + */ +#include "PIL_time.h" +#include "BLI_rand.h" + +#ifdef WIN32 +typedef unsigned __int64 r_uint64; +#else +typedef unsigned long long r_uint64; +#endif + +#define MULTIPLIER 0x5DEECE66D +#define ADDEND 0xB + +#define LOWSEED 0x330E + +static r_uint64 X= 0; + +void BLI_srand(unsigned int seed) { + X= (((r_uint64) seed)<<16) | LOWSEED; +} + +int BLI_rand(void) { + X= (MULTIPLIER*X + ADDEND)&0x0000FFFFFFFFFFFF; + return (int) (X>>17); +} + +double BLI_drand(void) { + return (double) BLI_rand()/0x80000000; +} + +float BLI_frand(void) { + return (float) BLI_rand()/0x80000000; +} + +void BLI_storerand(unsigned int loc_r[2]) { + loc_r[0]= (unsigned int) (X>>32); + loc_r[1]= (unsigned int) (X&0xFFFFFFFF); +} + +void BLI_restorerand(unsigned int loc[2]) { + X= ((r_uint64) loc[0])<<32; + X|= loc[1]; +} + +void BLI_fillrand(void *addr, int len) { + unsigned char *p= addr; + unsigned int save[2]; + + BLI_storerand(save); + + BLI_srand((unsigned int) (PIL_check_seconds_timer()*0x7FFFFFFF)); + while (len--) *p++= BLI_rand()&0xFF; + BLI_restorerand(save); +} diff --git a/source/blender/blenlib/intern/rct.c b/source/blender/blenlib/intern/rct.c new file mode 100644 index 00000000000..373edd1af5a --- /dev/null +++ b/source/blender/blenlib/intern/rct.c @@ -0,0 +1,115 @@ +/* + * + * rct.c + * + * april 95 + * + * $Id$ + * + * A minimalist lib for functions doing stuff with rectangle structs. + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + * + */ + +#include "DNA_vec_types.h" +#include "BLI_blenlib.h" + +int BLI_rcti_is_empty(rcti * rect) +{ + return ((rect->xmax<=rect->xmin) || + (rect->ymax<=rect->ymin)); +} + +int BLI_in_rcti(rcti * rect, int x, int y) +{ + + if(xxmin) return 0; + if(x>rect->xmax) return 0; + if(yymin) return 0; + if(y>rect->ymax) return 0; + return 1; +} + +int BLI_in_rctf(rctf *rect, float x, float y) +{ + + if(xxmin) return 0; + if(x>rect->xmax) return 0; + if(yymin) return 0; + if(y>rect->ymax) return 0; + return 1; +} + +void BLI_union_rctf(rctf *rct1, rctf *rct2) +{ + + if(rct1->xmin>rct2->xmin) rct1->xmin= rct2->xmin; + if(rct1->xmaxxmax) rct1->xmax= rct2->xmax; + if(rct1->ymin>rct2->ymin) rct1->ymin= rct2->ymin; + if(rct1->ymaxymax) rct1->ymax= rct2->ymax; +} + +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; +} + +int BLI_isect_rctf(rctf *src1, rctf *src2, rctf *dest) +{ + float xmin, xmax; + float ymin, ymax; + + xmin = (src1->xmin) > (src2->xmin) ? (src1->xmin) : (src2->xmin); + xmax = (src1->xmax) < (src2->xmax) ? (src1->xmax) : (src2->xmax); + ymin = (src1->ymin) > (src2->ymin) ? (src1->ymin) : (src2->ymin); + ymax = (src1->ymax) < (src2->ymax) ? (src1->ymax) : (src2->ymax); + + if(xmax>=xmin && ymax>=ymin) { + if(dest) { + dest->xmin = xmin; + dest->xmax = xmax; + dest->ymin = ymin; + dest->ymax = ymax; + } + return 1; + } + else { + if(dest) { + dest->xmin = 0; + dest->xmax = 0; + dest->ymin = 0; + dest->ymax = 0; + } + return 0; + } +} diff --git a/source/blender/blenlib/intern/scanfill.c b/source/blender/blenlib/intern/scanfill.c new file mode 100644 index 00000000000..a6a1771148f --- /dev/null +++ b/source/blender/blenlib/intern/scanfill.c @@ -0,0 +1,1234 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + * (uit traces) maart 95 + */ + +#include +#include +#include + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" + +#include "BLI_util.h" +#include "DNA_listBase.h" +#include "BLI_editVert.h" +#include "BLI_arithb.h" +#include "BLI_scanfill.h" +#include "BLI_callbacks.h" + +/* callbacks for errors and interrupts and some goo */ +static void (*BLI_localErrorCallBack)(char*) = NULL; +static int (*BLI_localInterruptCallBack)(void) = NULL; +static void *objectref = NULL; +static char *colourref = NULL; + + +void BLI_setScanFillObjectRef(void* ob) +{ + objectref = ob; +} + +void BLI_setScanFillColourRef(char* c) +{ + colourref = c; +} + +void BLI_setErrorCallBack(void (*f)(char*)) +{ + BLI_localErrorCallBack = f; +} + +void BLI_setInterruptCallBack(int (*f)(void)) +{ + BLI_localInterruptCallBack = f; +} + +/* just flush the error to /dev/null if the error handler is missing */ +void callLocalErrorCallBack(char* msg) +{ + if (BLI_localErrorCallBack) { + BLI_localErrorCallBack(msg); + } +} + +/* ignore if the interrupt wasn't set */ +int callLocalInterruptCallBack(void) +{ + if (BLI_localInterruptCallBack) { + return BLI_localInterruptCallBack(); + } else { + return 0; + } +} + + +/* local types */ +typedef struct PolyFill { + int edges,verts; + float min[3],max[3]; + short f,nr; +} PolyFill; + +typedef struct ScFillVert { + EditVert *v1; + EditEdge *first,*last; + short f,f1; +} ScFillVert; + + +/* local funcs */ +int vergscdata(const void *a1, const void *a2); +int vergpoly(const void *a1, const void *a2); +void *new_mem_element(int size); +void addfillvlak(EditVert *v1, EditVert *v2, EditVert *v3); +int boundinside(PolyFill *pf1, PolyFill *pf2); +int boundisect(PolyFill *pf2, PolyFill *pf1); +void mergepolysSimp(PolyFill *pf1, PolyFill *pf2) /* pf2 bij pf1 */; +EditEdge *existfilledge(EditVert *v1, EditVert *v2); +short addedgetoscanvert(ScFillVert *sc, EditEdge *eed); +short testedgeside(float *v1, float *v2, float *v3); +short testedgeside2(float *v1, float *v2, float *v3); +short boundinsideEV(EditEdge *eed, EditVert *eve) /* is eve binnen boundbox eed */; +void testvertexnearedge(void); +void scanfill(PolyFill *pf); +void fill_mesh(void); +ScFillVert *addedgetoscanlist(EditEdge *eed, int len); +void splitlist(ListBase *tempve, ListBase *temped, short nr); + +/* This one is also used in isect.c Keep it here until we know what to do with isect.c */ +#define COMPLIMIT 0.0003 + +ScFillVert *scdata; + +ListBase fillvertbase = {0,0}; +ListBase filledgebase = {0,0}; +ListBase fillvlakbase = {0,0}; + +short cox, coy; + +/* **** FUNKTIES VOOR QSORT *************************** */ + + +int vergscdata(const void *a1, const void *a2) +{ + const ScFillVert *x1=a1,*x2=a2; + + if( x1->v1->co[coy] < x2->v1->co[coy] ) return 1; + else if( x1->v1->co[coy] > x2->v1->co[coy]) return -1; + else if( x1->v1->co[cox] > x2->v1->co[cox] ) return 1; + else if( x1->v1->co[cox] < x2->v1->co[cox]) return -1; + + return 0; +} + +int vergpoly(const void *a1, const void *a2) +{ + const PolyFill *x1=a1, *x2=a2; + + if( x1->min[cox] > x2->min[cox] ) return 1; + else if( x1->min[cox] < x2->min[cox] ) return -1; + else if( x1->min[coy] > x2->min[coy] ) return 1; + else if( x1->min[coy] < x2->min[coy] ) return -1; + + return 0; +} + +/* ************* MEMORY MANAGEMENT ************* */ + +struct mem_elements { + struct mem_elements *next, *prev; + char *data; +}; + +void *new_mem_element(int size) +{ + /* Alleen als gedurende het werken duizenden elementen worden aangemaakt en + * nooit (tussendoor) vrijgegeven. Op eind is vrijgeven nodig (-1). + */ + int blocksize= 16384; + static int offs= 0; /* het huidige vrije adres */ + static struct mem_elements *cur= 0; + static ListBase lb= {0, 0}; + void *adr; + + if(size>10000 || size==0) { + printf("incorrect use of new_mem_element\n"); + } + else if(size== -1) { + cur= lb.first; + while(cur) { + MEM_freeN(cur->data); + cur= cur->next; + } + BLI_freelistN(&lb); + + return NULL; + } + + size= 4*( (size+3)/4 ); + + if(cur) { + if(size+offs < blocksize) { + adr= (void *) (cur->data+offs); + offs+= size; + return adr; + } + } + + cur= MEM_callocN( sizeof(struct mem_elements), "newmem"); + cur->data= MEM_callocN(blocksize, "newmem"); + BLI_addtail(&lb, cur); + + offs= size; + return cur->data; +} + +void BLI_end_edgefill(void) +{ + new_mem_element(-1); + + fillvertbase.first= fillvertbase.last= 0; + filledgebase.first= filledgebase.last= 0; + fillvlakbase.first= fillvlakbase.last= 0; +} + +/* **** FILL ROUTINES *************************** */ + +EditVert *BLI_addfillvert(float *vec) +{ + EditVert *eve; + + eve= new_mem_element(sizeof(EditVert)); + BLI_addtail(&fillvertbase, eve); + + if(vec) { + *(eve->co) = *(vec); + *(eve->co + 1) = *(vec + 1); + *(eve->co + 2) = *(vec + 2); + } +/* VECCOPY(eve->co, vec); */ + + return eve; +} + +EditEdge *BLI_addfilledge(EditVert *v1, EditVert *v2) +{ + EditEdge *newed; + + newed= new_mem_element(sizeof(EditEdge)); + BLI_addtail(&filledgebase, newed); + + newed->v1= v1; + newed->v2= v2; + + return newed; +} + +void addfillvlak(EditVert *v1, EditVert *v2, EditVert *v3) +{ + /* maakt geen edges aan */ + EditVlak *evl; + + evl= new_mem_element(sizeof(EditVlak)); + BLI_addtail(&fillvlakbase, evl); + + evl->v1= v1; + evl->v2= v2; + evl->v3= v3; + evl->f= 2; + /* G.obedit is Object*, actcol is char */ +/* if(G.obedit && G.obedit->actcol) evl->mat_nr= G.obedit->actcol-1; */ + if (objectref && colourref && *colourref) { + evl->mat_nr = *colourref - 1; + } else { + evl->mat_nr = 0; + } +} + + +int boundinside(PolyFill *pf1, PolyFill *pf2) +{ + /* is pf2 INSIDE pf1 ? met boundingbox */ + /* eerst testen of poly's bestaan */ + + if(pf1->edges==0 || pf2->edges==0) return 0; + + if(pf2->max[cox]max[cox]) + if(pf2->max[coy]max[coy]) + if(pf2->min[cox]>pf1->min[cox]) + if(pf2->min[coy]>pf1->min[coy]) return 1; + return 0; +} + +int boundisect(PolyFill *pf2, PolyFill *pf1) +{ + /* is pf2 aangeraakt door pf1 ? met boundingbox */ + /* eerst testen of poly's bestaan */ + + if(pf1->edges==0 || pf2->edges==0) return 0; + + if(pf2->max[cox] < pf1->min[cox] ) return 0; + if(pf2->max[coy] < pf1->min[coy] ) return 0; + + if(pf2->min[cox] > pf1->max[cox] ) return 0; + if(pf2->min[coy] > pf1->max[coy] ) return 0; + + /* samenvoegen */ + if(pf2->max[cox]max[cox]) pf2->max[cox]= pf1->max[cox]; + if(pf2->max[coy]max[coy]) pf2->max[coy]= pf1->max[coy]; + + if(pf2->min[cox]>pf1->min[cox]) pf2->min[cox]= pf1->min[cox]; + if(pf2->min[coy]>pf1->min[coy]) pf2->min[coy]= pf1->min[coy]; + + return 1; +} + + + + + +void mergepolysSimp(PolyFill *pf1, PolyFill *pf2) /* pf2 bij pf1 */ +/* PolyFill *pf1,*pf2; */ +{ + EditVert *eve; + EditEdge *eed; + + /* alle oude polynummers vervangen */ + eve= fillvertbase.first; + while(eve) { + if(eve->xs== pf2->nr) eve->xs= pf1->nr; + eve= eve->next; + } + eed= filledgebase.first; + while(eed) { + if(eed->f1== pf2->nr) eed->f1= pf1->nr; + eed= eed->next; + } + + pf1->verts+= pf2->verts; + pf1->edges+= pf2->edges; + pf2->verts= pf2->edges= 0; + pf1->f= (pf1->f | pf2->f); +} + + + +EditEdge *existfilledge(EditVert *v1, EditVert *v2) +/* EditVert *v1,*v2; */ +{ + EditEdge *eed; + + eed= filledgebase.first; + while(eed) { + if(eed->v1==v1 && eed->v2==v2) return eed; + if(eed->v2==v1 && eed->v1==v2) return eed; + eed= eed->next; + } + return 0; +} + + +short testedgeside(float *v1, float *v2, float *v3) /* is v3 rechts van v1-v2 ? Met uizondering: v3==v1 || v3==v2*/ +/* float *v1,*v2,*v3; */ +{ + float inp; + + inp= (v2[cox]-v1[cox])*(v1[coy]-v3[coy]) + +(v1[coy]-v2[coy])*(v1[cox]-v3[cox]); + + if(inp<0.0) return 0; + else if(inp==0) { + if(v1[cox]==v3[cox] && v1[coy]==v3[coy]) return 0; + if(v2[cox]==v3[cox] && v2[coy]==v3[coy]) return 0; + } + return 1; +} + +short testedgeside2(float *v1, float *v2, float *v3) /* is v3 rechts van v1-v2 ? niet doorsnijden! */ +/* float *v1,*v2,*v3; */ +{ + float inp; + + inp= (v2[cox]-v1[cox])*(v1[coy]-v3[coy]) + +(v1[coy]-v2[coy])*(v1[cox]-v3[cox]); + + if(inp<=0.0) return 0; + return 1; +} + +short addedgetoscanvert(ScFillVert *sc, EditEdge *eed) +/* ScFillVert *sc; */ +/* EditEdge *eed; */ +{ + /* zoek eerste edge die rechts van eed ligt en stop eed daarvoor */ + EditEdge *ed; + float fac,fac1,x,y; + + if(sc->first==0) { + sc->first= sc->last= eed; + eed->prev= eed->next=0; + return 1; + } + + x= eed->v1->co[cox]; + y= eed->v1->co[coy]; + + fac1= eed->v2->co[coy]-y; + if(fac1==0.0) { + fac1= 1.0e10*(eed->v2->co[cox]-x); + + } + else fac1= (x-eed->v2->co[cox])/fac1; + + ed= sc->first; + while(ed) { + + if(ed->v2==eed->v2) return 0; + + fac= ed->v2->co[coy]-y; + if(fac==0.0) { + fac= 1.0e10*(ed->v2->co[cox]-x); + + } + else fac= (x-ed->v2->co[cox])/fac; + if(fac>fac1) break; + + ed= ed->next; + } + if(ed) BLI_insertlinkbefore((ListBase *)&(sc->first), ed, eed); + else BLI_addtail((ListBase *)&(sc->first),eed); + + return 1; +} + + +ScFillVert *addedgetoscanlist(EditEdge *eed, int len) +/* EditEdge *eed; */ +/* int len; */ +{ + /* voegt edge op juiste plek in ScFillVert list */ + /* geeft sc terug als edge al bestaat */ + ScFillVert *sc,scsearch; + EditVert *eve; + + /* welke vert is linksboven */ + if(eed->v1->co[coy] == eed->v2->co[coy]) { + if(eed->v1->co[cox] > eed->v2->co[cox]) { + eve= eed->v1; + eed->v1= eed->v2; + eed->v2= eve; + } + } + else if(eed->v1->co[coy] < eed->v2->co[coy]) { + eve= eed->v1; + eed->v1= eed->v2; + eed->v2= eve; + } + /* zoek plek in lijst */ + scsearch.v1= eed->v1; + sc= (ScFillVert *)bsearch(&scsearch,scdata,len, + sizeof(ScFillVert), vergscdata); + + if(sc==0) printf("Error in search edge: %x\n",eed); + else if(addedgetoscanvert(sc,eed)==0) return sc; + + return 0; +} + +short boundinsideEV(EditEdge *eed, EditVert *eve) /* is eve binnen boundbox eed */ +/* EditEdge *eed; */ +/* EditVert *eve; */ +{ + float minx,maxx,miny,maxy; + + if(eed->v1->co[cox]v2->co[cox]) { + minx= eed->v1->co[cox]; + maxx= eed->v2->co[cox]; + } else { + minx= eed->v2->co[cox]; + maxx= eed->v1->co[cox]; + } + if(eve->co[cox]>=minx && eve->co[cox]<=maxx) { + if(eed->v1->co[coy]v2->co[coy]) { + miny= eed->v1->co[coy]; + maxy= eed->v2->co[coy]; + } else { + miny= eed->v2->co[coy]; + maxy= eed->v1->co[coy]; + } + if(eve->co[coy]>=miny && eve->co[coy]<=maxy) return 1; + } + return 0; +} + + +void testvertexnearedge(void) +{ + /* alleen de vertices met ->h==1 worden getest op + nabijheid van edge, zo ja invoegen */ + + EditVert *eve; + EditEdge *eed,*ed1; + float dist,vec1[2],vec2[2],vec3[2]; + + eve= fillvertbase.first; + while(eve) { + if(eve->h==1) { + vec3[0]= eve->co[cox]; + vec3[1]= eve->co[coy]; + /* de bewuste edge vinden waar eve aan zit */ + ed1= filledgebase.first; + while(ed1) { + if(ed1->v1==eve || ed1->v2==eve) break; + ed1= ed1->next; + } + if(ed1->v1==eve) { + ed1->v1= ed1->v2; + ed1->v2= eve; + } + eed= filledgebase.first; + while(eed) { + if(eve!=eed->v1 && eve!=eed->v2 && eve->xs==eed->f1) { + if(FloatCompare(eve->co,eed->v1->co, COMPLIMIT)) { + ed1->v2= eed->v1; + eed->v1->h++; + eve->h= 0; + break; + } + else if(FloatCompare(eve->co,eed->v2->co, COMPLIMIT)) { + ed1->v2= eed->v2; + eed->v2->h++; + eve->h= 0; + break; + } + else { + vec1[0]= eed->v1->co[cox]; + vec1[1]= eed->v1->co[coy]; + vec2[0]= eed->v2->co[cox]; + vec2[1]= eed->v2->co[coy]; + if(boundinsideEV(eed,eve)) { + dist= DistVL2Dfl(vec1,vec2,vec3); + if(distv1, eve); + + /* printf("fill: vertex near edge %x\n",eve); */ + ed1->f= ed1->h= 0; + ed1->f1= eed->f1; + eed->v1= eve; + eve->h= 3; + break; + } + } + } + } + eed= eed->next; + } + } + eve= eve->next; + } +} + +void splitlist(ListBase *tempve, ListBase *temped, short nr) +/* ListBase *tempve,*temped; */ +/* short nr; */ +{ + /* alles zit in de templist, alleen poly nr naar fillist schrijven */ + EditVert *eve,*nextve; + EditEdge *eed,*nexted; + + addlisttolist(tempve,&fillvertbase); + addlisttolist(temped,&filledgebase); + + eve= tempve->first; + while(eve) { + nextve= eve->next; + if(eve->xs==nr) { + BLI_remlink(tempve,eve); + BLI_addtail(&fillvertbase,eve); + } + eve= nextve; + } + eed= temped->first; + while(eed) { + nexted= eed->next; + if(eed->f1==nr) { + BLI_remlink(temped,eed); + BLI_addtail(&filledgebase,eed); + } + eed= nexted; + } +} + + +void scanfill(PolyFill *pf) +{ + ScFillVert *sc = NULL, *sc1; + EditVert *eve,*v1,*v2,*v3; + EditEdge *eed,*nexted,*ed1,*ed2,*ed3; + float miny = 0.0; + int a,b,verts, maxvlak, totvlak; + short nr, test, twoconnected=0; + + nr= pf->nr; + verts= pf->verts; + + /* PRINTS + eve= fillvertbase.first; + while(eve) { + printf("vert: %x co: %f %f\n",eve,eve->co[cox],eve->co[coy]); + eve= eve->next; + } + eed= filledgebase.first; + while(eed) { + printf("edge: %x verts: %x %x\n",eed,eed->v1,eed->v2); + eed= eed->next; + } */ + + /* STAP 0: alle nul lange edges eruit */ + eed= filledgebase.first; + while(eed) { + if(eed->v1->co[cox]==eed->v2->co[cox]) { + if(eed->v1->co[coy]==eed->v2->co[coy]) { + if(eed->v1->f==255 && eed->v2->f!=255) { + eed->v2->f= 255; + eed->v2->vn= eed->v1->vn; + } + else if(eed->v2->f==255 && eed->v1->f!=255) { + eed->v1->f= 255; + eed->v1->vn= eed->v2->vn; + } + else if(eed->v2->f==255 && eed->v1->f==255) { + eed->v1->vn= eed->v2->vn; + } + else { + eed->v2->f= 255; + eed->v2->vn= eed->v1; + } + } + } + eed= eed->next; + } + + /* STAP 1: maak ahv van FillVert en FillEdge lijsten een gesorteerde + ScFillVert lijst + */ + sc= scdata= (ScFillVert *)MEM_callocN(pf->verts*sizeof(ScFillVert),"Scanfill1"); + eve= fillvertbase.first; + verts= 0; + while(eve) { + if(eve->xs==nr) { + if(eve->f!= 255) { + verts++; + eve->f= 0; /* vlag later voor connectedges */ + sc->v1= eve; + sc++; + } + } + eve= eve->next; + } + + qsort(scdata, verts, sizeof(ScFillVert), vergscdata); + + sc= scdata; + eed= filledgebase.first; + while(eed) { + nexted= eed->next; + eed->f= 0; + BLI_remlink(&filledgebase,eed); + if(eed->v1->f==255) { + v1= eed->v1; + while(eed->v1->f==255 && eed->v1->vn!=v1) eed->v1= eed->v1->vn; + } + if(eed->v2->f==255) { + v2= eed->v2; + while(eed->v2->f==255 && eed->v2->vn!=v2) eed->v2= eed->v2->vn; + } + if(eed->v1!=eed->v2) addedgetoscanlist(eed,verts); + + eed= nexted; + } + /* + sc= scdata; + for(a=0;av1); + eed= sc->first; + while(eed) { + printf(" ed %x %x %x\n",eed,eed->v1,eed->v2); + eed= eed->next; + } + sc++; + }*/ + + + /* STAP 2: FILL LUS */ + + if(pf->f==0) twoconnected= 1; + + /* (tijdelijke) beveiliging: nooit veel meer vlakken dan vertices */ + totvlak= 0; + maxvlak= 2*verts; /* 2*verts: cirkel in driehoek, beide gevuld */ + + sc= scdata; + for(a=0;av1); */ + ed1= sc->first; + while(ed1) { /* connectflags zetten */ + nexted= ed1->next; + if(ed1->v1->h==1 || ed1->v2->h==1) { + BLI_remlink((ListBase *)&(sc->first),ed1); + BLI_addtail(&filledgebase,ed1); + if(ed1->v1->h>1) ed1->v1->h--; + if(ed1->v2->h>1) ed1->v2->h--; + } + else ed1->v2->f= 1; + + ed1= nexted; + } + while(sc->first) { /* zolang er edges zijn */ + ed1= sc->first; + ed2= ed1->next; + + if(callLocalInterruptCallBack()) break; + if(totvlak>maxvlak) { + /* printf("Fill error: endless loop. Escaped at vert %d, tot: %d.\n", a, verts); */ + a= verts; + break; + } + if(ed2==0) { + sc->first=sc->last= 0; + /* printf("maar 1 edge aan vert\n"); */ + BLI_addtail(&filledgebase,ed1); + ed1->v2->f= 0; + ed1->v1->h--; + ed1->v2->h--; + } else { + /* test rest vertices */ + v1= ed1->v2; + v2= ed1->v1; + v3= ed2->v2; + /* hieronder komt voor bij serie overlappende edges */ + if(v1==v2 || v2==v3) break; + /* printf("test verts %x %x %x\n",v1,v2,v3); */ + miny = ( (v1->co[coy])<(v3->co[coy]) ? (v1->co[coy]) : (v3->co[coy]) ); +/* miny= MIN2(v1->co[coy],v3->co[coy]); */ + sc1= sc+1; + test= 0; + + for(b=a+1;bv1->f==0) { + if(sc1->v1->co[coy] <= miny) break; + + if(testedgeside(v1->co,v2->co,sc1->v1->co)) + if(testedgeside(v2->co,v3->co,sc1->v1->co)) + if(testedgeside(v3->co,v1->co,sc1->v1->co)) { + /* punt in driehoek */ + + test= 1; + break; + } + } + sc1++; + } + if(test) { + /* nieuwe edge maken en overnieuw beginnen */ + /* printf("add new edge %x %x and start again\n",v2,sc1->v1); */ + + ed3= BLI_addfilledge(v2, sc1->v1); + BLI_remlink(&filledgebase, ed3); + BLI_insertlinkbefore((ListBase *)&(sc->first), ed2, ed3); + ed3->v2->f= 1; + ed3->f= 2; + ed3->v1->h++; + ed3->v2->h++; + } + else { + /* nieuwe driehoek */ + /* printf("add vlak %x %x %x\n",v1,v2,v3); */ + addfillvlak(v1, v2, v3); + totvlak++; + BLI_remlink((ListBase *)&(sc->first),ed1); + BLI_addtail(&filledgebase,ed1); + ed1->v2->f= 0; + ed1->v1->h--; + ed1->v2->h--; + /* ed2 mag ook weg als het een oude is */ + if(ed2->f==0 && twoconnected) { + BLI_remlink((ListBase *)&(sc->first),ed2); + BLI_addtail(&filledgebase,ed2); + ed2->v2->f= 0; + ed2->v1->h--; + ed2->v2->h--; + } + + /* nieuwe edge */ + ed3= BLI_addfilledge(v1, v3); + BLI_remlink(&filledgebase, ed3); + ed3->f= 2; + ed3->v1->h++; + ed3->v2->h++; + + /* printf("add new edge %x %x\n",v1,v3); */ + sc1= addedgetoscanlist(ed3, verts); + + if(sc1) { /* ed3 bestaat al: verwijderen*/ + /* printf("Edge bestaat al\n"); */ + ed3->v1->h--; + ed3->v2->h--; + + if(twoconnected) ed3= sc1->first; + else ed3= 0; + while(ed3) { + if( (ed3->v1==v1 && ed3->v2==v3) || (ed3->v1==v3 && ed3->v2==v1) ) { + BLI_remlink((ListBase *)&(sc1->first),ed3); + BLI_addtail(&filledgebase,ed3); + ed3->v1->h--; + ed3->v2->h--; + break; + } + ed3= ed3->next; + } + } + + } + } + /* test op loze edges */ + ed1= sc->first; + while(ed1) { + nexted= ed1->next; + if(ed1->v1->h<2 || ed1->v2->h<2) { + BLI_remlink((ListBase *)&(sc->first),ed1); + BLI_addtail(&filledgebase,ed1); + if(ed1->v1->h>1) ed1->v1->h--; + if(ed1->v2->h>1) ed1->v2->h--; + } + + ed1= nexted; + } + } + sc++; + } + + MEM_freeN(scdata); +} + + + +int BLI_edgefill(int mode) /* DE HOOFD FILL ROUTINE */ +{ + /* + - fill werkt met eigen lijsten, eerst aanmaken dus (geen vlakken) + - geef vertices in ->vn de oude pointer mee + - alleen xs en ys worden hier niet gebruikt: daar kan je iets in verstoppen + - edge flag ->f wordt 2 als het nieuwe edge betreft + - mode: & 1 is kruispunten testen, edges maken (NOG DOEN ) + */ + ListBase tempve, temped; + EditVert *eve; + EditEdge *eed,*nexted; + PolyFill *pflist,*pf; + float *minp, *maxp, *v1, *v2, norm[3], len; + short a,c,poly=0,ok=0,toggle=0; + + /* variabelen resetten*/ + eve= fillvertbase.first; + while(eve) { + eve->f= 0; + eve->xs= 0; + eve->h= 0; + eve= eve->next; + } + + /* eerst de vertices testen op aanwezigheid in edges */ + /* plus flaggen resetten */ + eed= filledgebase.first; + while(eed) { + eed->f= eed->f1= eed->h= 0; + eed->v1->f= 1; + eed->v2->f= 1; + + eed= eed->next; + } + + eve= fillvertbase.first; + while(eve) { + if(eve->f & 1) { + ok=1; + break; + } + eve= eve->next; + } + + if(ok==0) return 0; + + /* NEW NEW! projektie bepalen: met beste normaal */ + /* pak de eerste drie verschillende verts */ + + /* DIT STUK IS NOG STEEDS TAMELIJK ZWAK! */ + + eve= fillvertbase.last; + len= 0.0; + v1= eve->co; + v2= 0; + eve= fillvertbase.first; + while(eve) { + if(v2) { + if( FloatCompare(v2, eve->co, 0.0003)==0) { + len= CalcNormFloat(v1, v2, eve->co, norm); + if(len != 0.0) break; + } + } + else if(FloatCompare(v1, eve->co, 0.0003)==0) { + v2= eve->co; + } + eve= eve->next; + } + + if(len==0.0) return 0; /* geen fill mogelijk */ + + norm[0]= fabs(norm[0]); + norm[1]= fabs(norm[1]); + norm[2]= fabs(norm[2]); + + if(norm[2]>=norm[0] && norm[2]>=norm[1]) { + cox= 0; coy= 1; + } + else if(norm[1]>=norm[0] && norm[1]>=norm[2]) { + cox= 0; coy= 2; + } + else { + cox= 1; coy= 2; + } + + /* STAP 1: AANTAL POLY'S TELLEN */ + eve= fillvertbase.first; + while(eve) { + /* pak eerste vertex zonder polynummer */ + if(eve->xs==0) { + poly++; + /* nu een soort select connected */ + ok= 1; + eve->xs= poly; + + while(ok) { + + ok= 0; + toggle++; + if(toggle & 1) eed= filledgebase.first; + else eed= filledgebase.last; + + while(eed) { + if(eed->v1->xs==0 && eed->v2->xs==poly) { + eed->v1->xs= poly; + eed->f1= poly; + ok= 1; + } + else if(eed->v2->xs==0 && eed->v1->xs==poly) { + eed->v2->xs= poly; + eed->f1= poly; + ok= 1; + } + else if(eed->f1==0) { + if(eed->v1->xs==poly && eed->v2->xs==poly) { + eed->f1= poly; + ok= 1; + } + } + if(toggle & 1) eed= eed->next; + else eed= eed->prev; + } + } + } + eve= eve->next; + } + /* printf("aantal poly's: %d\n",poly); */ + + /* STAP 2: LOSSE EDGES EN SLIERTEN VERWIJDEREN */ + eed= filledgebase.first; + while(eed) { + if(eed->v1->h++ >250) break; + if(eed->v2->h++ >250) break; + eed= eed->next; + } + if(eed) { + /* anders kan hierna niet met zekerheid vertices worden gewist */ + callLocalErrorCallBack("No vertices with 250 edges allowed!"); + return 0; + } + + /* doet alleen vertices met ->h==1 */ + testvertexnearedge(); + + ok= 1; + while(ok) { + ok= 0; + toggle++; + if(toggle & 1) eed= filledgebase.first; + else eed= filledgebase.last; + while(eed) { + if(toggle & 1) nexted= eed->next; + else nexted= eed->prev; + if(eed->v1->h==1) { + eed->v2->h--; + BLI_remlink(&fillvertbase,eed->v1); + BLI_remlink(&filledgebase,eed); + ok= 1; + } + else if(eed->v2->h==1) { + eed->v1->h--; + BLI_remlink(&fillvertbase,eed->v2); + BLI_remlink(&filledgebase,eed); + ok= 1; + } + eed= nexted; + } + } + if(filledgebase.first==0) { + /* printf("All edges removed\n"); */ + return 0; + } + + + /* STAND VAN ZAKEN: + - eve->f :1= aanwezig in edges + - eve->xs :polynummer + - eve->h :aantal edges aan vertex + - eve->vn :bewaren! oorspronkelijke vertexnummer + + - eed->f : + - eed->f1 :polynummer +*/ + + + /* STAP 3: POLYFILL STRUCT MAKEN */ + pflist= (PolyFill *)MEM_callocN(poly*sizeof(PolyFill),"edgefill"); + pf= pflist; + for(a=1;a<=poly;a++) { + pf->nr= a; + pf->min[0]=pf->min[1]=pf->min[2]= 1.0e20; + pf->max[0]=pf->max[1]=pf->max[2]= -1.0e20; + pf++; + } + eed= filledgebase.first; + while(eed) { + pflist[eed->f1-1].edges++; + eed= eed->next; + } + + eve= fillvertbase.first; + while(eve) { + pflist[eve->xs-1].verts++; + minp= pflist[eve->xs-1].min; + maxp= pflist[eve->xs-1].max; + + minp[cox]= (minp[cox])<(eve->co[cox]) ? (minp[cox]) : (eve->co[cox]); + minp[coy]= (minp[coy])<(eve->co[coy]) ? (minp[coy]) : (eve->co[coy]); + maxp[cox]= (maxp[cox])>(eve->co[cox]) ? (maxp[cox]) : (eve->co[cox]); + maxp[coy]= (maxp[coy])>(eve->co[coy]) ? (maxp[coy]) : (eve->co[coy]); + if(eve->h>2) pflist[eve->xs-1].f= 1; + + eve= eve->next; + } + + /* STAP 4: GATEN OF BOUNDS VINDEN EN SAMENVOEGEN + * ( bounds alleen om grote hoeveelheden een beetje in stukjes te verdelen, + * de edgefill heeft van zichzelf een adequate autogat!!! + * LET OP: WERKT ALLEEN ALS POLY'S GESORTEERD ZIJN!!! */ + + if(poly>1) { + short *polycache, *pc; + + /* dus: eerst sorteren */ + qsort(pflist, poly, sizeof(PolyFill), vergpoly); + + /*pf= pflist; + for(a=1;a<=poly;a++) { + printf("poly:%d edges:%d verts:%d flag: %d\n",a,pf->edges,pf->verts,pf->f); + PRINT2(f, f, pf->min[0], pf->min[1]); + pf++; + }*/ + + polycache= pc= MEM_callocN(sizeof(short)*poly, "polycache"); + pf= pflist; + for(a=0; amax[cox] < (pflist+c)->min[cox]) break; */ + + } + while(pc!=polycache) { + pc--; + mergepolysSimp(pf, pflist+ *pc); + } + } + MEM_freeN(polycache); + } + + pf= pflist; + /* printf("na merge\n"); + for(a=1;a<=poly;a++) { + printf("poly:%d edges:%d verts:%d flag: %d\n",a,pf->edges,pf->verts,pf->f); + pf++; + } */ + + /* STAP 5: DRIEHOEKEN MAKEN */ + + tempve.first= fillvertbase.first; + tempve.last= fillvertbase.last; + temped.first= filledgebase.first; + temped.last= filledgebase.last; + fillvertbase.first=fillvertbase.last= 0; + filledgebase.first=filledgebase.last= 0; + + pf= pflist; + for(a=0;aedges>1) { + splitlist(&tempve,&temped,pf->nr); + scanfill(pf); + } + pf++; + } + addlisttolist(&fillvertbase,&tempve); + addlisttolist(&filledgebase,&temped); + + /* evl= fillvlakbase.first; + while(evl) { + printf("nieuw vlak %x %x %x\n",evl->v1,evl->v2,evl->v3); + evl= evl->next; + }*/ + + + /* VRIJGEVEN */ + + MEM_freeN(pflist); + return 1; + +} + +/* + MOVED TO EDITMESH.C since it's really bad to leave it here + +void fill_mesh(void) +{ + EditVert *eve,*v1; + EditEdge *eed,*e1,*nexted; + EditVlak *evl,*nextvl; + short ok; + + if(G.obedit==0 || (G.obedit->type!=OB_MESH)) return; + + waitcursor(1); + + / * alle selected vertices kopieeren * / + eve= G.edve.first; + while(eve) { + if(eve->f & 1) { + v1= addfillvert(eve->co); + eve->vn= v1; + v1->vn= eve; + v1->h= 0; + } + eve= eve->next; + } + / * alle selected edges kopieeren * / + eed= G.eded.first; + while(eed) { + if( (eed->v1->f & 1) && (eed->v2->f & 1) ) { + e1= addfilledge(eed->v1->vn, eed->v2->vn); + e1->v1->h++; + e1->v2->h++; + } + eed= eed->next; + } + / * van alle selected vlakken vertices en edges verwijderen om dubbels te voorkomen * / + / * alle edges tellen punten op, vlakken trekken af, + edges met vertices ->h<2 verwijderen * / + evl= G.edvl.first; + ok= 0; + while(evl) { + nextvl= evl->next; + if( vlakselectedAND(evl, 1) ) { + evl->v1->vn->h--; + evl->v2->vn->h--; + evl->v3->vn->h--; + if(evl->v4) evl->v4->vn->h--; + ok= 1; + + } + evl= nextvl; + } + if(ok) { / * er zijn vlakken geselecteerd * / + eed= filledgebase.first; + while(eed) { + nexted= eed->next; + if(eed->v1->h<2 || eed->v2->h<2) { + remlink(&filledgebase,eed); + } + eed= nexted; + } + } + + / * tijd=clock(); * / + + ok= edgefill(0); + + / * printf("time: %d\n",(clock()-tijd)/1000); * / + + if(ok) { + evl= fillvlakbase.first; + while(evl) { + addvlaklist(evl->v1->vn, evl->v2->vn, evl->v3->vn, 0, evl); + evl= evl->next; + } + } + / * else printf("fill error\n"); * / + + end_edgefill(); + + waitcursor(0); + + countall(); + allqueue(REDRAWVIEW3D, 0); +} + +MOVED TO editmesh.c !!!!! (you bastards!) + + */ diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c new file mode 100644 index 00000000000..1f86fcbf54b --- /dev/null +++ b/source/blender/blenlib/intern/storage.c @@ -0,0 +1,568 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + * Reorganised mar-01 nzc + * Some really low-level file thingies. + */ + +#include +#include +#include /* voorkomt dat je bij malloc type moet aangeven */ + +#ifdef WIN32 + +#include +#include "BLI_winstuff.h" +#include +#include +#include +#endif + +#ifndef WIN32 +#include +#endif + +#include +#include + +#if defined(__sgi) || defined(__sun__) +#include +#endif + +#ifdef __FreeBSD__ +#include +#include +#endif + +#if defined(linux) || defined(__CYGWIN32__) +#include +#endif + +#ifdef __BeOS +struct statfs { + int f_bsize; + int f_bfree; +}; +#endif + +#ifdef __APPLE__ +/* For statfs */ +#include +#include +#endif /* __APPLE__ */ + + +#include +#if !defined(__BeOS) && !defined(WIN32) +#include /* tape comando's */ +#endif +#include /* strcpy etc.. */ + +#ifndef WIN32 +#include +#include /* */ +#include +#endif + +/* MAART: #ifndef __FreeBSD__ */ +#if !defined(__FreeBSD__) && !defined(__APPLE__) +#include +#endif + +/* lib includes */ +#include "MEM_guardedalloc.h" + +#include "DNA_listBase.h" +#include "BLI_blenlib.h" +#include "BLI_storage.h" +#include "BLI_storage_types.h" + +#include "BLI_util.h" +#include "BLI_linklist.h" + +/* functions */ +void BLI_buildpwtable(struct passwd **pwtable); +void BLI_freepwtable(struct passwd *pwtable); +char *BLI_findpwtable(struct passwd *pwtable, unsigned short user); + +/* vars: */ +static int totnum,actnum; +static struct direntry *files; + +static struct ListBase dirbase_={ + 0,0}; +static struct ListBase *dirbase = &dirbase_; + + +char *BLI_getwdN(char *dir) +{ + char *pwd; + + if (dir) { + pwd = getenv("PWD"); + if (pwd){ + strcpy(dir, pwd); + return(dir); + } + /* 160 is FILE_MAXDIR in filesel.c */ + return( getcwd(dir, 160) ); + } + return(0); +} + + +int BLI_compare(struct direntry *entry1, struct direntry *entry2) +{ + /* type is gelijk aan stat.st_mode */ + + if (S_ISDIR(entry1->type)){ + if (S_ISDIR(entry2->type)==0) return (-1); + } else{ + if (S_ISDIR(entry2->type)) return (1); + } + if (S_ISREG(entry1->type)){ + if (S_ISREG(entry2->type)==0) return (-1); + } else{ + if (S_ISREG(entry2->type)) return (1); + } + if ((entry1->type & S_IFMT) < (entry2->type & S_IFMT)) return (-1); + if ((entry1->type & S_IFMT) > (entry2->type & S_IFMT)) return (1); + return (strcasecmp(entry1->relname,entry2->relname)); +} + + +double BLI_diskfree(char *dir) +{ +#ifdef WIN32 + DWORD sectorspc, bytesps, freec, clusters; + char tmp[4]; + + tmp[0]='\\'; tmp[1]=0; /* Just a failsafe */ + if (dir[0]=='/' || dir[0]=='\\') { + tmp[0]='\\'; + tmp[1]=0; + } else if (dir[1]==':') { + tmp[0]=dir[0]; + tmp[1]=':'; + tmp[2]='\\'; + tmp[3]=0; + } + + GetDiskFreeSpace(tmp,§orspc, &bytesps, &freec, &clusters); + + return (double) (freec*bytesps*sectorspc); +#else + struct statfs disk; + char name[100],*slash; + + + strcpy(name,dir); + + if(strlen(name)){ + slash = strrchr(name,'/'); + if (slash) slash[1] = 0; + } else strcpy(name,"/"); + +#if defined __FreeBSD__ || defined linux + if (statfs(name, &disk)) return(-1); +#endif +#ifdef __BeOS + return -1; +#endif +#if defined __sgi || defined __sun__ + + if (statfs(name, &disk, sizeof(struct statfs), 0)){ + /* printf("diskfree: Couldn't get information about %s.\n",dir); */ + return(-1); + } +#endif + + return ( ((double) disk.f_bsize) * ((double) disk.f_bfree)); +#endif +} + +static int hide_dot= 0; + +void BLI_hide_dot_files(int set) +{ + if(set) hide_dot= 1; + else hide_dot= 0; +} + +void BLI_builddir(char *dirname, char *relname) +{ + struct dirent *fname; + struct dirlink *dlink; + int rellen, newnum = 0, seen_ = 0, seen__ = 0; + char buf[256]; + DIR *dir; + + strcpy(buf,relname); + rellen=strlen(relname); + + if (rellen){ + buf[rellen]='/'; + rellen++; + } + + if (chdir(dirname) == -1){ + perror(dirname); + return; + } + + if (dir = (DIR *)opendir(".")){ + while ((fname = (struct dirent*) readdir(dir)) != NULL) { + + if(hide_dot && fname->d_name[0]=='.' && fname->d_name[1]!='.' && fname->d_name[1]!=0); + else { + + dlink = (struct dirlink *)malloc(sizeof(struct dirlink)); + if (dlink){ + strcpy(buf+rellen,fname->d_name); + + dlink->name = 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++; + } + } + } + + if (newnum){ +#ifndef WIN32 + if (seen_ == 0) { /* Cachefs PATCH */ + dlink = (struct dirlink *)malloc(sizeof(struct dirlink)); + strcpy(buf+rellen,"./."); + dlink->name = strdup(buf); + BLI_addhead(dirbase,dlink); + newnum++; + } + if (seen__ == 0) { /* MAC PATCH */ + dlink = (struct dirlink *)malloc(sizeof(struct dirlink)); + strcpy(buf+rellen,"./.."); + dlink->name = 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)); + + if (files){ + dlink = (struct dirlink *) dirbase->first; + while(dlink){ + memset(&files[actnum], 0 , sizeof(struct direntry)); + files[actnum].relname = dlink->name; + stat(dlink->name,&files[actnum].s); + files[actnum].type=files[actnum].s.st_mode; + files[actnum].flags = 0; + totnum++; + actnum++; + dlink = dlink->next; + } + } else{ + printf("Couldn't get memory for dir\n"); + exit(1); + } + + BLI_freelist(dirbase); + if (files) qsort(files, actnum, sizeof(struct direntry), (int (*)(const void *,const void*))BLI_compare); + } else { + printf("%s empty directory\n",dirname); + } + + closedir(dir); + } else { + printf("%s non-existant directory\n",dirname); + } +} + +#ifndef WIN32 +void BLI_buildpwtable(struct passwd **pwtable) +{ + int count=0,slen; + struct passwd *pw,*pwtab; + + do{ + pw=getpwent(); + if (pw){ + count++; + } + }while(pw); + endpwent(); + + pwtab = (struct passwd *)calloc(count+1,sizeof(struct passwd)); + count=0; + do{ + pw=getpwent(); + if (pw){ + pwtab[count] = *pw; + slen = strlen(pw->pw_name); + pwtab[count].pw_name = malloc(slen+1); + strcpy(pwtab[count].pw_name,pw->pw_name); + count ++; + } + }while(pw); + pwtab[count].pw_name = 0; + endpwent(); + + *(pwtable) = pwtab; +} + +void BLI_freepwtable(struct passwd *pwtable) +{ + int count=0; + + do{ + if (pwtable[count].pw_name) free(pwtable[count].pw_name); + else break; + count++; + }while (1); + + free(pwtable); +} + + +char *BLI_findpwtable(struct passwd *pwtable, ushort user) +{ + static char string[32]; + + while (pwtable->pw_name){ + if (pwtable->pw_uid == user){ + return (pwtable->pw_name); + } + pwtable++; + } + sprintf(string, "%d", user); + return (string); +} +#endif + + +void BLI_adddirstrings() +{ + char datum[100]; + char buf[250]; + char size[250]; + static char * types[8] = {"---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx"}; + int num, mode; + int num1, num2, num3, num4, st_size; +#ifndef WIN32 + struct passwd *pwtable; +#endif + struct direntry * file; + struct tm *tm; + +#ifndef WIN32 + BLI_buildpwtable(&pwtable); +#endif + + file = &files[0]; + + for(num=0;nummode1, types[0]); + strcpy(file->mode2, types[0]); + strcpy(file->mode3, types[0]); +#else + mode = file->s.st_mode; + + strcpy(file->mode1, types[(mode & 0700) >> 6]); + strcpy(file->mode2, types[(mode & 0070) >> 3]); + strcpy(file->mode3, types[(mode & 0007)]); + + if (((mode & S_ISGID) == S_ISGID) && (file->mode2[2]=='-'))file->mode2[2]='l'; + + if (mode & (S_ISUID | S_ISGID)){ + if (file->mode1[2]=='x') file->mode1[2]='s'; + else file->mode1[2]='S'; + + if (file->mode2[2]=='x')file->mode2[2]='s'; + } + + if (mode & S_ISVTX){ + if (file->mode3[2] == 'x') file->mode3[2] = 't'; + else file->mode3[2] = 'T'; + } +#endif + +#ifdef WIN32 + strcpy(files[num].owner,"user"); +#else + strcpy(files[num].owner, BLI_findpwtable(pwtable,files[num].s.st_uid)); +#endif + + tm= localtime(&files[num].s.st_mtime); + strftime(files[num].time, 8, "%H:%M", tm); + strftime(files[num].date, 16, "%d-%b-%y", tm); + + st_size= (int)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; + + if(num4) sprintf(files[num].size, "%3d %03d %03d %03d", num4, num3, num2, num1); + else if(num3) sprintf(files[num].size, "%7d %03d %03d", num3, num2, num1); + else if(num2) sprintf(files[num].size, "%11d %03d", num2, num1); + else if(num1) sprintf(files[num].size, "%15d", num1); + else sprintf(files[num].size, ""); + + strftime(datum, 32, "%d-%b-%y %R", tm); + + if (st_size < 1000) { + sprintf(size, "%10d", st_size); + } else if (st_size < 1000 * 1000) { + sprintf(size, "%6d %03d", st_size / 1000, st_size % 1000); + } else if (st_size < 100 * 1000 * 1000) { + sprintf(size, "%2d %03d %03d", st_size / (1000 * 1000), (st_size / 1000) % 1000, st_size % 1000); + } else { + sprintf(size, "> %4.1f M", st_size / (1024.0 * 1024.0)); + sprintf(size, "%10d", 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); + + files[num].string=malloc(strlen(buf)+1); + if (files[num].string){ + strcpy(files[num].string,buf); + } + + file++; + } +#ifndef WIN32 + BLI_freepwtable(pwtable); +#endif +} + +unsigned int BLI_getdir(char *dirname, struct direntry **filelist) +{ + // reset global variables + // memory stored in files is free()'d in + // filesel.c:freefilelist() + + actnum = totnum = 0; + files = 0; + + BLI_builddir(dirname,""); + BLI_adddirstrings(); + + if (files) { + *(filelist) = files; + } else { + // keep blender happy. Blender stores this in a variable + // where 0 has special meaning..... + *(filelist) = files = malloc(sizeof(struct direntry)); + } + + return(actnum); +} + + +int BLI_filesize(int file) +{ + struct stat buf; + + if (file <= 0) return (-1); + fstat(file, &buf); + return (buf.st_size); +} + + + +int BLI_exist(char *name) +{ + struct stat st; + + if (stat(name,&st)) return(0); + return(st.st_mode); +} + +LinkNode *BLI_read_file_as_lines(char *name) +{ + FILE *fp= fopen(name, "r"); + LinkNode *lines= NULL; + char *buf; + int size; + + if (!fp) return NULL; + + fseek(fp, 0, SEEK_END); + size= ftell(fp); + fseek(fp, 0, SEEK_SET); + + buf= malloc(size); + if (buf) { + int i, last= 0; + + /* + * size = because on win32 reading + * all the bytes in the file will return + * less bytes because of crnl changes. + */ + size= fread(buf, 1, size, fp); + for (i=0; i<=size; i++) { + if (i==size || buf[i]=='\n') { + char *line= BLI_strdupn(&buf[last], i-last); + + BLI_linklist_prepend(&lines, line); + last= i+1; + } + } + + free(buf); + } + + fclose(fp); + + BLI_linklist_reverse(&lines); + return lines; +} + +void BLI_free_file_lines(LinkNode *lines) +{ + BLI_linklist_free(lines, (void(*)(void*)) MEM_freeN); +} diff --git a/source/blender/blenlib/intern/time.c b/source/blender/blenlib/intern/time.c new file mode 100644 index 00000000000..832a6c8b2e9 --- /dev/null +++ b/source/blender/blenlib/intern/time.c @@ -0,0 +1,101 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + */ +#include "PIL_time.h" + +#ifdef WIN32 + +#include + +double PIL_check_seconds_timer(void) +{ + static int hasperfcounter= -1; /* -1==unknown */ + static double perffreq; + + if (hasperfcounter==-1) { + __int64 ifreq; + hasperfcounter= QueryPerformanceFrequency((LARGE_INTEGER*) &ifreq); + perffreq= (double) ifreq; + } + + if (hasperfcounter) { + __int64 count; + + QueryPerformanceCounter((LARGE_INTEGER*) &count); + + return count/perffreq; + } else { + static double accum= 0.0; + static int ltick= 0; + int ntick= GetTickCount(); + + if (ntick +#include + +double PIL_check_seconds_timer(void) +{ + struct timeval tv; + struct timezone tz; + + gettimeofday(&tv, &tz); + + return ((double) tv.tv_sec + tv.tv_usec/1000000.0); +} + +void PIL_sleep_ms(int ms) +{ + if (ms>=1000) { + sleep(ms/1000); + ms= (ms%1000); + } + + usleep(ms*1000); +} + +#endif diff --git a/source/blender/blenlib/intern/util.c b/source/blender/blenlib/intern/util.c new file mode 100644 index 00000000000..f3a2d4f3970 --- /dev/null +++ b/source/blender/blenlib/intern/util.c @@ -0,0 +1,828 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + * Diverse string, file, list operations. + */ + +#include +#include +#include +#include +#include + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "DNA_listBase.h" +#include "BLI_storage.h" +#include "BLI_storage_types.h" + +#include "BLI_util.h" + +#ifndef WIN32 +#include +#else +#include +#endif + +#ifdef WIN32 +#include "BLI_winstuff.h" +#endif + + +#ifndef WIN32 +#include +#endif + +/* local */ + +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 { + ((struct Link *)list1->last)->next= list2->first; + ((struct Link *)list2->first)->prev= list1->last; + list1->last= list2->last; + } + list2->first= list2->last= 0; +} + +int BLI_stringdec(char *string, char *kop, char *staart, unsigned short *numlen) +{ + unsigned short len, len2, nums = 0, nume = 0; + short i, found = 0; + + len2 = len = strlen( string); + + if (len > 6) { + if (strncasecmp(string + len - 6, ".blend", 6) == 0) len -= 6; + else if (strncasecmp(string + len - 6, ".trace", 6) == 0) len -= 6; + } + + if (len == len2) { + if (len > 4) { + /* .jf0 en .jf1 voor jstreams afvangen */ + if (strncasecmp(string + len - 4, ".jf", 3) == 0) len -= 4; + else if (strncasecmp(string + len - 4, ".tga", 4) == 0) len -= 4; + else if (strncasecmp(string + len - 4, ".jpg", 4) == 0) len -= 4; + else if (strncasecmp(string + len - 4, ".png", 4) == 0) len -= 4; + else if (strncasecmp(string + len - 4, ".txt", 4) == 0) len -= 4; + else if (strncasecmp(string + len - 4, ".cyc", 4) == 0) len -= 4; + else if (strncasecmp(string + len - 4, ".enh", 4) == 0) len -= 4; + else if (strncasecmp(string + len - 4, ".rgb", 4) == 0) len -= 4; + else if (strncasecmp(string + len - 4, ".psx", 4) == 0) len -= 4; + else if (strncasecmp(string + len - 4, ".ble", 4) == 0) len -= 4; + } + } + + for (i = len - 1; i >= 0; i--){ + if (string[i] == '/') break; + if (isdigit(string[i])) { + if (found){ + nums = i; + } + else{ + nume = i; + nums = i; + found = 1; + } + } + else{ + if (found) break; + } + } + if (found){ + if (staart) strcpy(staart,&string[nume+1]); + if (kop) { + strcpy(kop,string); + kop[nums]=0; + } + if (numlen) *numlen = nume-nums+1; + return ((int)atoi(&(string[nums]))); + } + if (staart) strcpy(staart, string + len); + if (kop) { + strncpy(kop, string, len); + kop[len] = 0; + } + if (numlen) *numlen=0; + return 0; +} + + +void BLI_stringenc(char *string, char *kop, char *staart, unsigned short numlen, int pic) +{ + char numstr[10]=""; + unsigned short len,i; + + strcpy(string,kop); + + if (pic>0 || numlen==4) { + len= sprintf(numstr,"%d",pic); + + for(i=len;i 99 of van 10 naar 9 */ + if (add < 0 && digits < 4 && digits > 0) { + int i, exp; + exp = 1; + for (i = digits; i > 1; i--) exp *= 10; + if (pic >= exp && (pic + add) < exp) digits--; + } + + pic += add; + + if(digits==4 && pic<0) pic= 0; + BLI_stringenc(name, head, tail, digits, pic); +} + + +void BLI_addhead(ListBase *listbase, void *vlink) +{ + struct Link *link= vlink; + + if (link == 0) return; + if (listbase == 0) return; + + link->next = listbase->first; + link->prev = 0; + + if (listbase->first) ((struct Link *)listbase->first)->prev = link; + if (listbase->last == 0) listbase->last = link; + listbase->first = link; +} + + +void BLI_addtail(ListBase *listbase, void *vlink) +{ + struct Link *link= vlink; + + if (link == 0) return; + if (listbase == 0) return; + + link->next = 0; + link->prev = listbase->last; + + if (listbase->last) ((struct Link *)listbase->last)->next = link; + if (listbase->first == 0) listbase->first = link; + listbase->last = link; +} + + +void BLI_remlink(ListBase *listbase, void *vlink) +{ + struct Link *link= vlink; + + if (link == 0) return; + if (listbase == 0) 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) +{ + struct Link *link= vlink; + + if (link == 0) return; + if (listbase == 0) return; + + BLI_remlink(listbase,link); + MEM_freeN(link); +} + + +void BLI_insertlink(ListBase *listbase, void *vprevlink, void *vnewlink) +{ + struct Link *prevlink= vprevlink, *newlink= vnewlink; + + /* newlink komt na prevlink */ + + if (newlink == 0) return; + if (listbase == 0) return; + + if(listbase->first==0) { /* lege lijst */ + listbase->first= newlink; + listbase->last= newlink; + return; + } + if (prevlink== 0) { /* inserten voor eerste element */ + newlink->next= listbase->first; + newlink->prev= 0; + newlink->next->prev= newlink; + listbase->first= newlink; + return; + } + + if (listbase->last== prevlink) /* aan einde lijst */ + listbase->last = newlink; + + newlink->next= prevlink->next; + prevlink->next= newlink; + if(newlink->next) newlink->next->prev= newlink; + newlink->prev= prevlink; +} + +void BLI_insertlinkbefore(ListBase *listbase, void *vnextlink, void *vnewlink) +{ + struct Link *nextlink= vnextlink, *newlink= vnewlink; + + /* newlink komt voor nextlink */ + + if (newlink == 0) return; + if (listbase == 0) return; + + if(listbase->first==0) { /* lege lijst */ + listbase->first= newlink; + listbase->last= newlink; + return; + } + if (nextlink== 0) { /* inserten aan einde lijst */ + newlink->prev= listbase->last; + newlink->next= 0; + ((struct Link *)listbase->last)->next= newlink; + listbase->last= newlink; + return; + } + + if (listbase->first== nextlink) /* aan begin lijst */ + 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) +{ + struct Link *link,*next; + + if (listbase == 0) return; + link= listbase->first; + while(link) { + next= link->next; + free(link); + link= next; + } + listbase->first=0; + listbase->last=0; +} + +void BLI_freelistN(ListBase *listbase) +{ + struct Link *link,*next; + + if (listbase == 0) return; + link= listbase->first; + while(link) { + next= link->next; + MEM_freeN(link); + link= next; + } + listbase->first=0; + listbase->last=0; +} + + +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); +} + + +char *BLI_strdupn(char *str, int len) { + char *n= MEM_mallocN(len+1, "strdup"); + memcpy(n, str, len); + n[len]= '\0'; + + return n; +} +char *BLI_strdup(char *str) { + return BLI_strdupn(str, strlen(str)); +} + +char *BLI_strncpy(char *dst, 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_streq(char *a, char *b) { + return (strcmp(a, b)==0); +} +int BLI_strcaseeq(char *a, char *b) { + return (strcasecmp(a, b)==0); +} + +void BLI_makestringcode(char *fromfile, char *str) +{ + char *slash, len, temp[512]; + + strcpy(temp, fromfile); + + /* Find the last slash */ + slash = (strrchr(temp, '/')>strrchr(temp, '\\')) + ? strrchr(temp, '/') : strrchr(temp, '\\'); + if(slash) { + *(slash+1)= 0; + len= strlen(temp); + if(len) { + if(strncmp(str, temp, len)==0) { + temp[0]= '/'; + temp[1]= '/'; + strcpy(temp+2, str+len); + strcpy(str, temp); + } + } + } +} + +int BLI_convertstringcode(char *path, char *basepath, int framenum) +{ + int len, wasrelative= (strncmp(path, "//", 2)==0); + + if (path[0] == '/' && path[1] == '/') { + char *filepart= BLI_strdup(path+2); /* skip code */ + char *lslash= BLI_last_slash(basepath); + + if (lslash) { + int baselen= (int) (lslash-basepath) + 1; + + memcpy(path, basepath, baselen); + strcpy(path+baselen, filepart); + } else { + strcpy(path, filepart); + } + + MEM_freeN(filepart); + } + + len= strlen(path); + if(len && path[len-1]=='#') { + sprintf(path+len-1, "%04d", framenum); + } + + return wasrelative; +} + +void BLI_splitdirstring(char *di,char *fi) +{ + char *lslash= BLI_last_slash(di); + + if (lslash) { + strcpy(fi, lslash+1); + *(lslash+1)=0; + } else { + strcpy(fi, di); + di[0]= 0; + } +} + +char *BLI_gethome(void) { + + #ifdef __BeOS + return "/boot/home/"; /* BeOS 4.5: doubleclick at icon doesnt give home env */ + + #elif !defined(WIN32) + return getenv("HOME"); + + #else /* Windows */ + char * ret; + static char dir[512]; + + ret = getenv("HOME"); + if(ret) { + if (BLI_exists(ret)) return ret; + } + + // add user profile support for WIN 2K / NT + ret = getenv("USERPROFILE"); + if (ret) { + if (BLI_exists(ret)) { /* from fop, also below... */ + sprintf(dir, "%s/Application Data/Not a Number/Blender", ret); + BLI_recurdir_fileops(dir); + if (BLI_exists(dir)) { + return(dir); + } else { + return(ret); + } + } + } + + ret = getenv("WINDOWS"); + if (ret) { + if(BLI_exists(ret)) return ret; + } + + ret = getenv("WINDIR"); + if (ret) { + if(BLI_exists(ret)) return ret; + } + + return "C:\\Temp"; + #endif +} + +static void char_switch(char *string, char from, char to) +{ + while (*string != 0) { + if (*string == from) *string = to; + string++; + } +} + +void BLI_make_exist(char *dir) +{ + int a; + + #ifdef WIN32 + char_switch(dir, '/', '\\'); + #else + char_switch(dir, '\\', '/'); + #endif + + a = strlen(dir); + +#ifdef WIN32 + while(BLI_exists(dir) == 0){ + a --; + while(dir[a] != '\\'){ + a--; + if (a <= 0) break; + } + if (a >= 0) dir[a+1] = 0; + else { + strcpy(dir,"\\"); + break; + } + } +#else + while(BLI_exist(dir) == 0){ + a --; + while(dir[a] != '/'){ + a--; + if (a <= 0) break; + } + if (a >= 0) dir[a+1] = 0; + else { + strcpy(dir,"/"); + break; + } + } +#endif +} + +void BLI_make_file_string(char *relabase, char *string, char *dir, char *file) +{ + + if (!string || !dir || !file) return; /* We don't want any NULLs */ + + string[0]= 0; /* ton */ + + /* Resolve relative references */ + if (relabase && dir[0] == '/' && dir[1] == '/') { + char *lslash; + + /* Get the file name, chop everything past the last slash (ie. the filename) */ + strcpy(string, relabase); + + lslash= (strrchr(string, '/')>strrchr(string, '\\'))?strrchr(string, '/'):strrchr(string, '\\'); + + if(lslash) *(lslash+1)= 0; + + dir+=2; /* Skip over the relative reference */ + } + + strcat(string, dir); + + /* Make sure string ends in one (and only one) slash */ + if (string[strlen(string)-1] != '/' && string[strlen(string)-1] != '\\') + strcat(string, "/"); + + while (*file && (*file == '/' || *file == '\\')) /* Trim slashes from the front of file */ + file++; + + strcat (string, file); + + /* Push all slashes to the system preferred direction */ + #ifdef WIN32 + char_switch(string, '/', '\\'); + #else + char_switch(string, '\\', '/'); + #endif +} + +int BLI_testextensie(char *str, char *ext) +{ + short a, b; + int retval; + + a= strlen(str); + b= strlen(ext); + + if(a==0 || b==0 || b>=a) { + retval = 0; + } else if (strcasecmp(ext, str + a - b)) { + retval = 0; + } else { + retval = 1; + } + + return (retval); +} + +void BLI_split_dirfile(char *string, char *dir, char *file) +{ + int a; + + dir[0]= 0; + file[0]= 0; + +#ifdef WIN32 + if (strlen(string)) { + if (string[0] == '/' || string[0] == '\\') { + strcpy(dir, string); + } else if (string[1] == ':' && string[2] == '\\') { + strcpy(dir, string); + } else { + BLI_getwdN(dir); + strcat(dir,"/"); + strcat(dir,string); + strcpy(string,dir); + } + + BLI_make_exist(dir); + + if (S_ISDIR(BLI_exist(dir))) { + strcpy(file,string + strlen(dir)); + + if (strrchr(file,'\\')) strcpy(file,strrchr(file,'\\')+1); + + if (a = strlen(dir)) { + if (dir[a-1] != '\\') strcat(dir,"\\"); + } + } + else { + a = strlen(dir) - 1; + while(a>0 && dir[a] != '\\') a--; + dir[a + 1] = 0; + strcpy(file, string + strlen(dir)); + } + + } + else { + strcpy(dir, "\\"); + file[0]=0; + } +#else + if (strlen(string)) { + if (string[0] == '/') { + strcpy(dir, string); + } else if (string[1] == ':' && string[2] == '\\') { + string+=2; + strcpy(dir, string); + } else { + BLI_getwdN(dir); + strcat(dir,"/"); + strcat(dir,string); + strcpy(string,dir); + } + + BLI_make_exist(dir); + + if (S_ISDIR(BLI_exist(dir))) { + strcpy(file,string + strlen(dir)); + + if (strrchr(file,'/')) strcpy(file,strrchr(file,'/')+1); + + if ( (a = strlen(dir)) ) { + if (dir[a-1] != '/') strcat(dir,"/"); + } + } + else { + a = strlen(dir) - 1; + while(dir[a] != '/') a--; + dir[a + 1] = 0; + strcpy(file, string + strlen(dir)); + } + } + else { + BLI_getwdN(dir); + strcat(dir, "/"); + file[0] = 0; + } +#endif +} + +// copies from BKE_utildefines +#ifndef FILE_MAXDIR +#define FILE_MAXDIR 160 +#endif + +#ifndef FILE_MAXFILE +#define FILE_MAXFILE 80 +#endif + +static int add_win32_extension(char *name) +{ + int retval = 0; + int type; + + type = BLI_exist(name); + if ((type == 0) || S_ISDIR(type)) { +#ifdef _WIN32 + char filename[FILE_MAXDIR+FILE_MAXFILE]; + char ext[FILE_MAXDIR+FILE_MAXFILE]; + char *extensions = getenv("PATHEXT"); + if (extensions) { + char *temp; + do { + strcpy(filename, name); + temp = strstr(extensions, ";"); + if (temp) { + strncpy(ext, extensions, temp - extensions); + ext[temp - extensions] = 0; + extensions = temp + 1; + strcat(filename, ext); + } else { + strcat(filename, extensions); + } + + type = BLI_exist(filename); + if (type && (! S_ISDIR(type))) { + retval = 1; + strcpy(name, filename); + break; + } + } while (temp); + } +#endif + } else { + retval = 1; + } + + return (retval); +} + +void BLI_where_am_i(char *fullname, char *name) +{ + char filename[FILE_MAXDIR+FILE_MAXFILE]; + char *path, *temp; + int len; +#ifdef _WIN32 + char *seperator = ";"; + char *slash = "\\"; +#else + char *seperator = ":"; + char *slash = "/"; +#endif + + if (name && fullname && strlen(name)) { + strcpy(fullname, 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); + add_win32_extension(fullname); + } else if (BLI_last_slash(name)) { + // full path + strcpy(fullname, name); + add_win32_extension(fullname); + } else { + // search for binary in $PATH + path = getenv("PATH"); + if (path) { + do { + temp = strstr(path, seperator); + if (temp) { + strncpy(filename, path, temp - path); + filename[temp - path] = 0; + path = temp + 1; + } else { + strncpy(filename, path, sizeof(filename)); + } + len = strlen(filename); + if (len && filename[len - 1] != slash[0]) { + strcat(filename, slash); + } + strcat(filename, name); + if (add_win32_extension(filename)) { + strcpy(fullname, filename); + break; + } + } while (temp); + } + } +#ifndef NDEBUG + if (strcmp(name, fullname)) { + printf("guessing '%s' == '%s'\n", name, fullname); + } +#endif + +#ifdef _WIN32 + // in windows change long filename to short filename because + // win2k doesn't know how to parse a commandline with lots of + // spaces and double-quotes. There's another solution to this + // with spawnv(P_WAIT, bprogname, argv) instead of system() but + // that's even uglier + GetShortPathName(fullname, fullname, FILE_MAXDIR+FILE_MAXFILE); +#ifndef NDEBUG + printf("Shortname = '%s'\n", fullname); +#endif +#endif + } +} + diff --git a/source/blender/blenlib/intern/vectorops.c b/source/blender/blenlib/intern/vectorops.c new file mode 100644 index 00000000000..9314e7fca3e --- /dev/null +++ b/source/blender/blenlib/intern/vectorops.c @@ -0,0 +1,165 @@ +/* + * + * Some vector operations. + * + * Always use + * - vector with x components : float x[3], int x[3], etc + * + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + */ + +/* ------------------------------------------------------------------------- */ +/* General format: op(a, b, c): a = b op c */ +/* Copying is done cp */ +/* ------------------------------------------------------------------------- */ + +#include "MTC_vectorops.h" +#include + +void MTC_diff3Int(int v1[3], int v2[3], int v3[3]) +{ + v1[0] = v2[0] - v3[0]; + v1[1] = v2[1] - v3[1]; + v1[2] = v2[2] - v3[2]; +} + +/* ------------------------------------------------------------------------- */ +void MTC_diff3Float(float v1[3], float v2[3], float v3[3]) +{ + v1[0] = v2[0] - v3[0]; + v1[1] = v2[1] - v3[1]; + v1[2] = v2[2] - v3[2]; +} + +/* ------------------------------------------------------------------------- */ + +void MTC_cross3Int(int v1[3], int v2[3], int v3[3]) +{ + v1[0] = v2[1]*v3[2] - v2[2]*v3[1]; + v1[1] = v2[2]*v3[0] - v2[0]*v3[2]; + v1[2] = v2[0]*v3[1] - v2[1]*v3[0]; +} + +/* ------------------------------------------------------------------------- */ + +void MTC_cross3Float(float v1[3], float v2[3], float v3[3]) +{ + v1[0] = v2[1]*v3[2] - v2[2]*v3[1]; + v1[1] = v2[2]*v3[0] - v2[0]*v3[2]; + v1[2] = v2[0]*v3[1] - v2[1]*v3[0]; +} +/* ------------------------------------------------------------------------- */ + +void MTC_cross3Double(double v1[3], double v2[3], double v3[3]) +{ + v1[0] = v2[1]*v3[2] - v2[2]*v3[1]; + v1[1] = v2[2]*v3[0] - v2[0]*v3[2]; + v1[2] = v2[0]*v3[1] - v2[1]*v3[0]; +} + +/* ------------------------------------------------------------------------- */ + +int MTC_dot3Int(int v1[3], int v2[3]) +{ + return (v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]); +} + +/* ------------------------------------------------------------------------- */ + +float MTC_dot3Float(float v1[3], float v2[3]) +{ + return (v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2]); +} + +/* ------------------------------------------------------------------------- */ + +void MTC_cp3Float(float v1[3], float v2[3]) +{ + v2[0] = v1[0]; + v2[1] = v1[1]; + v2[2] = v1[2]; +} + +/* ------------------------------------------------------------------------- */ + +void MTC_cp3FloatInv(float v1[3], float v2[3]) +{ + v2[0] = -v1[0]; + v2[1] = -v1[1]; + v2[2] = -v1[2]; +} + +/* ------------------------------------------------------------------------- */ + +void MTC_swapInt(int *i1, int *i2) +{ + int swap; + swap = *i1; + *i1 = *i2; + *i2 = swap; +} + +/* ------------------------------------------------------------------------- */ + +void MTC_diff3DFF(double v1[3], float v2[3], float v3[3]) +{ + v1[0] = v2[0] - v3[0]; + v1[1] = v2[1] - v3[1]; + v1[2] = v2[2] - v3[2]; +} + +/* ------------------------------------------------------------------------- */ +float MTC_normalise3DF(float n[3]) +{ + float d; + + d= n[0]*n[0]+n[1]*n[1]+n[2]*n[2]; + /* FLT_EPSILON is too large! A larger value causes normalise errors in */ + /* a scaled down utah teapot */ + if(d>0.0000000000001) { + + /* d= sqrt(d); This _should_ be sqrt, but internally it's a double*/ + /* anyway. This is safe. */ + d = sqrt(d); + + n[0]/=d; + n[1]/=d; + n[2]/=d; + } else { + n[0]=n[1]=n[2]= 0.0; + d= 0.0; + } + return d; +} + +/* ------------------------------------------------------------------------- */ + +/* eof */ diff --git a/source/blender/blenlib/intern/winstuff.c b/source/blender/blenlib/intern/winstuff.c new file mode 100644 index 00000000000..91062297cda --- /dev/null +++ b/source/blender/blenlib/intern/winstuff.c @@ -0,0 +1,193 @@ +/** + * $Id$ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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/BL DUAL LICENSE BLOCK ***** + * Windows-posix compatibility layer, windows-specific functions. + */ + +#ifdef WIN32 + +#include +#include + +#include "MEM_guardedalloc.h" + +#include "BLI_blenlib.h" +#include "BLI_util.h" +#include "BLI_winstuff.h" + + +void RegisterBlendExtension(char * str) { + LONG lresult; + HKEY hkey = 0; + DWORD dwd = 0; + char buffer[128]; + + lresult = RegCreateKeyEx(HKEY_CLASSES_ROOT, "blendfile\\shell\\open\\command", 0, + "", REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwd); + + if (lresult == ERROR_SUCCESS) { + sprintf(buffer, "\"%s\" \"%%1\"", str); + lresult = RegSetValueEx(hkey, NULL, 0, REG_SZ, buffer, strlen(buffer) + 1); + RegCloseKey(hkey); + } + + lresult = RegCreateKeyEx(HKEY_CLASSES_ROOT, "blendfile\\DefaultIcon", 0, + "", REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwd); + + if (lresult == ERROR_SUCCESS) { + sprintf(buffer, "\"%s\",1", str); + lresult = RegSetValueEx(hkey, NULL, 0, REG_SZ, buffer, strlen(buffer) + 1); + RegCloseKey(hkey); + } + + lresult = RegCreateKeyEx(HKEY_CLASSES_ROOT, ".blend", 0, + "", REG_OPTION_VOLATILE, KEY_ALL_ACCESS, NULL, &hkey, &dwd); + + if (lresult == ERROR_SUCCESS) { + sprintf(buffer, "%s", "blendfile"); + lresult = RegSetValueEx(hkey, NULL, 0, REG_SZ, buffer, strlen(buffer) + 1); + RegCloseKey(hkey); + } +} + +static void strlower (char *str) { + while (*str) { + *str= tolower(*str); + str++; + } +} + +static void strnlower (char *str, int n) { + while (n>0 && *str) { + *str= tolower(*str); + str++; + n--; + } +} + +int strcasecmp (char *s1, char *s2) { + char *st1, *st2; + int r; + + st1= MEM_mallocN(strlen(s1)+1, "temp string"); + strcpy(st1, s1); + + st2= MEM_mallocN(strlen(s2)+1, "temp string"); + strcpy(st2, s2); + + strlower(st1); + strlower(st2); + r= strcmp (st1, st2); + + MEM_freeN(st1); + MEM_freeN(st2); + + return r; +} + +int strncasecmp (char *s1, char *s2, int n) { + char *st1, *st2; + int r; + + st1= MEM_mallocN(n, "temp string"); + memcpy(st1, s1, n); + + st2= MEM_mallocN(n, "temp string"); + memcpy(st2, s2, n); + + strnlower(st1, n); + strnlower(st2, n); + + r= strncmp (st1, st2, n); + + MEM_freeN(st1); + MEM_freeN(st2); + + return r; +} + +DIR *opendir (const char *path) { + if (GetFileAttributes(path) & FILE_ATTRIBUTE_DIRECTORY) { + DIR *newd= MEM_mallocN(sizeof(DIR), "opendir"); + + newd->handle = INVALID_HANDLE_VALUE; + sprintf(newd->path, "%s/*.*",path); + + newd->direntry.d_ino= 0; + newd->direntry.d_off= 0; + newd->direntry.d_reclen= 0; + newd->direntry.d_name= NULL; + + return newd; + } else { + return NULL; + } +} + +struct dirent *readdir(DIR *dp) { + if (dp->direntry.d_name) { + MEM_freeN(dp->direntry.d_name); + dp->direntry.d_name= NULL; + } + + if (dp->handle==INVALID_HANDLE_VALUE) { + dp->handle= FindFirstFile(dp->path, &(dp->data)); + if (dp->handle==INVALID_HANDLE_VALUE) + return NULL; + + dp->direntry.d_name= BLI_strdup(dp->data.cFileName); + + return &dp->direntry; + } else if (FindNextFile (dp->handle, &(dp->data))) { + dp->direntry.d_name= BLI_strdup(dp->data.cFileName); + + return &dp->direntry; + } else { + return NULL; + } +} + +int closedir (DIR *dp) { + if (dp->direntry.d_name) MEM_freeN(dp->direntry.d_name); + if (dp->handle!=INVALID_HANDLE_VALUE) FindClose(dp->handle); + + MEM_freeN(dp); + + return 0; +} + +#else + +void BLI_WINSTUFF_C_IS_EMPTY_FOR_UNIX(void) +{ + /*intentionally empty*/ +} + +#endif -- cgit v1.2.3