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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Luc Peurière <jlp@nerim.net>2008-03-14 02:54:02 +0300
committerJean-Luc Peurière <jlp@nerim.net>2008-03-14 02:54:02 +0300
commita68a7f42b02ad0260220d94f36ab61c772db071a (patch)
tree620b763cd24fbfc1259f00ccb005217914af0c6f /source/blender/blenlib
parent526d0bec4722900a86d81ff0f5d71504b2b4ad8c (diff)
parent15215493bf9d1d08e650109e6eb6189fc76e289e (diff)
resolved conflict state with HEAD r14096
blenderbuttons still bad not let this compile
Diffstat (limited to 'source/blender/blenlib')
-rw-r--r--source/blender/blenlib/BLI_arithb.h1034
-rw-r--r--source/blender/blenlib/BLI_blenlib.h61
-rw-r--r--source/blender/blenlib/BLI_boxpack2d.h5
-rw-r--r--source/blender/blenlib/BLI_bpath.h60
-rw-r--r--source/blender/blenlib/BLI_editVert.h14
-rw-r--r--source/blender/blenlib/BLI_fnmatch.h69
-rw-r--r--source/blender/blenlib/BLI_kdtree.h63
-rw-r--r--source/blender/blenlib/BLI_rand.h3
-rw-r--r--source/blender/blenlib/BLI_storage_types.h3
-rw-r--r--source/blender/blenlib/BLI_threads.h1
-rw-r--r--source/blender/blenlib/CMakeLists.txt7
-rw-r--r--source/blender/blenlib/SConscript1
-rw-r--r--source/blender/blenlib/intern/BLI_ghash.c18
-rw-r--r--source/blender/blenlib/intern/BLI_kdtree.c341
-rw-r--r--source/blender/blenlib/intern/BLI_storage.h5
-rw-r--r--source/blender/blenlib/intern/Makefile7
-rw-r--r--source/blender/blenlib/intern/arithb.c1163
-rw-r--r--source/blender/blenlib/intern/bpath.c556
-rw-r--r--source/blender/blenlib/intern/fileops.c69
-rw-r--r--source/blender/blenlib/intern/fnmatch.c250
-rw-r--r--source/blender/blenlib/intern/psfont.c2
-rw-r--r--source/blender/blenlib/intern/rand.c8
-rw-r--r--source/blender/blenlib/intern/storage.c61
-rw-r--r--source/blender/blenlib/intern/threads.c73
-rw-r--r--source/blender/blenlib/intern/util.c495
25 files changed, 3286 insertions, 1083 deletions
diff --git a/source/blender/blenlib/BLI_arithb.h b/source/blender/blenlib/BLI_arithb.h
index cebeff5c3e1..99e30bc91c0 100644
--- a/source/blender/blenlib/BLI_arithb.h
+++ b/source/blender/blenlib/BLI_arithb.h
@@ -54,6 +54,13 @@ extern "C" {
#define M_SQRT1_2 0.70710678118654752440
#endif
+#ifdef WIN32
+ #ifndef FREE_WINDOWS
+ #define isnan(n) _isnan(n)
+ #define finite _finite
+ #endif
+#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},\
@@ -64,577 +71,216 @@ extern "C" {
{ 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]); */
+void CalcCent3f(float *cent, float *v1, float *v2, float *v3);
+void CalcCent4f(float *cent, float *v1, float *v2, float *v3, float *v4);
-/* M1 = M3*M2 */
-/* void Mat3MulMat3(float m1[][3], float m2[][3], float m3[][3]); */
-/*void Mat3MulMat3(float *m1, float *m3, float *m2); */
+void Crossf(float *c, float *a, float *b);
+void Projf(float *c, float *v1, float *v2);
-/* m1 = m2 * m3, ignore the elements on the 4th row/column of m3 */
-/*void Mat3IsMat3MulMat4(float m1[][3], float m2[][3], float m3[][4]); */
+float Inpf(float *v1, float *v2);
+float Inp2f(float *v1, float *v2);
-/* m1 to m2 */
-/* void Mat4CpyMat4(float m1[][4], float m2[][4]); */
-/* void Mat4CpyMat4(float *m1, float *m2); */
+float Normalize(float *n);
+float Normalize2(float *n);
+float Sqrt3f(float f);
+double Sqrt3d(double d);
-/* 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); */
+float saacos(float fac);
+float saasin(float fac);
+float sasqrt(float fac);
-/* void Mat3Inv(float m1[][3], float m2[][3]); */
-/* void Mat4One(float m[][4]); */
-/* void Mat3One(float m[][3]); */
+int FloatCompare(float *v1, float *v2, float limit);
+float FloatLerpf(float target, float origin, float fac);
+float CalcNormFloat(float *v1, float *v2, float *v3, float *n);
+float CalcNormFloat4(float *v1, float *v2, float *v3, float *v4, float *n);
- void
-CalcCent3f(
- float *cent, float *v1, float *v2, float *v3
-);
-
- void
-CalcCent4f(
- float *cent, float *v1,
- float *v2, float *v3,
- float *v4
-);
+void CalcNormLong(int *v1, int *v2, int *v3, float *n);
+/* CalcNormShort: is ook uitprodukt - (translates as 'is also out/cross product') */
+void CalcNormShort(short *v1, short *v2, short *v3, float *n);
- void
-Crossf(
- float *c, float *a, float *b
-);
-
- void
-Projf(
- float *c, float *v1, float *v2
-);
/**
- * Euler conversion routines
+ * @section Euler conversion routines
*/
- void
-EulToMat3(
- float *eul,
- float mat[][3]
-);
- void
-EulToMat4(
- float* eul,
- float mat[][4]
-);
+void EulToMat3(float *eul, float mat[][3]);
+void EulToMat4(float *eul, float mat[][4]);
- void
-Mat3ToEul(
- float tmat[][3],
- float *eul
-);
+void Mat3ToEul(float tmat[][3], float *eul);
+void Mat4ToEul(float tmat[][4],float *eul);
- void
-Mat4ToEul(
- float tmat[][4],
- float *eul
-);
+void EulToQuat(float *eul, float *quat);
void compatible_eul(float *eul, float *oldrot);
void Mat3ToCompatibleEul(float mat[][3], float *eul, float *oldrot);
+
/**
* @section Quaternion arithmetic routines
*/
- void
-QuatToEul(
- float *quat,
- float *eul
-);
- void
-QuatOne(
- float *
-);
- void
-QuatMul(
- float *,
- float *,
- float *
-);
- void
-QuatMulVecf(
- float *q,
- float *v
-);
- void
-NormalQuat(
- float *
-);
- void
-VecRotToQuat(
- float *vec,
- float phi,
- float *quat
-);
- void
-QuatSub(
- float *q,
- float *q1,
- float *q2
-);
- void
-QuatConj(
- float *q
-);
- void
-QuatInv(
- float *q
-);
- void
-QuatMulf(
- float *q,
- float f
-);
- float
-QuatDot(
- float *q1,
- float *q2
-);
- void
-printquat(
- char *str,
- float q[4]
-);
+void QuatToEul(float *quat, float *eul);
+void QuatOne(float *);
+void QuatMul(float *, float *, float *);
+void QuatMulVecf(float *q, float *v);
+void QuatMulf(float *q, float f);
+void QuatMulFac(float *q, float fac);
+void NormalQuat(float *);
+void VecRotToQuat(float *vec, float phi, float *quat);
+
+void QuatSub(float *q, float *q1, float *q2);
+void QuatConj(float *q);
+void QuatInv(float *q);
+float QuatDot(float *q1, float *q2);
+void QuatCopy(float *q1, float *q2);
+
+void printquat(char *str, float q[4]);
void QuatInterpol(float *result, float *quat1, float *quat2, float t);
void QuatAdd(float *result, float *quat1, float *quat2, float t);
/**
- * @section matrix multiplication can copying routines
+ * @section matrix multiplication and 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],
- float mat[][4]
-);
- void
-Mat4InvertSimp(
- float inverse[][4],
- float mat[][4]
-);
- void
-Mat4Inv(
- float *m1,
- float *m2
-);
- void
-Mat4InvGG(
- float out[][4],
- float in[][4]
-);
- void
-Mat3CpyMat4(
- float m1[][3],
- float m2[][4]
-);
+void Mat3MulFloat(float *m, float f);
+void Mat4MulFloat(float *m, float f);
+void Mat4MulFloat3(float *m, float f);
- void
-Mat3Inv(
- float m1[][3],
- float m2[][3]
-);
+void Mat3Transp(float mat[][3]);
+void Mat4Transp(float mat[][4]);
- void
-Mat4CpyMat3(
- float m1[][4],
- float m2[][3]
-);
+int Mat4Invert(float inverse[][4], float mat[][4]);
+void Mat4InvertSimp(float inverse[][4], float mat[][4]);
+void Mat4Inv(float *m1, float *m2);
+void Mat4InvGG(float out[][4], float in[][4]);
+void Mat3Inv(float m1[][3], float m2[][3]);
- float
-Det2x2(
- float a,float b,float c,float d
-);
+void Mat3CpyMat4(float m1[][3],float m2[][4]);
+void Mat4CpyMat3(float m1[][4], float m2[][3]);
- float
-Det3x3(
+void Mat4BlendMat4(float out[][4], float dst[][4], float src[][4], float srcweight);
+
+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(
- float m[][4]
-);
+float Det4x4(float m[][4]);
- void
-Mat4Adj(
- float out[][4],
- float in[][4]
-);
- void
-Mat3Adj(
- float m1[][3],
- float m[][3]
-);
- void
-Mat4MulMat4(
- float m1[][4],
- float m2[][4],
- float m3[][4]
-);
- void
-subMat4MulMat4(
- float *m1,
- float *m2,
- float *m3
-);
+void Mat3Adj(float m1[][3], float m[][3]);
+void Mat4Adj(float out[][4], float in[][4]);
+
+void Mat4MulMat4(float m1[][4], float m2[][4], float m3[][4]);
+void subMat4MulMat4(float *m1, float *m2, float *m3);
#ifndef TEST_ACTIVE
- void
-Mat3MulMat3(
- float m1[][3],
- float m3[][3],
- float m2[][3]
-);
+void Mat3MulMat3(float m1[][3], float m3[][3], float m2[][3]);
#else
- void
-Mat3MulMat3(
- float *m1,
- float *m3,
- float *m2
-);
+void Mat3MulMat3(float *m1, float *m3, float *m2);
#endif
- void
-Mat4MulMat34(
- float (*m1)[4],
- float (*m3)[3],
- float (*m2)[4]
-);
- void
-Mat4CpyMat4(
- float m1[][4],
- float m2[][4]
-);
- void
-Mat4SwapMat4(
- float *m1,
- float *m2
-);
- void
-Mat3CpyMat3(
- float m1[][3],
- float m2[][3]
-);
- void
-Mat3MulSerie(
- float answ[][3],
+void Mat4MulMat34(float (*m1)[4], float (*m3)[3], float (*m2)[4]);
+void Mat4CpyMat4(float m1[][4], float m2[][4]);
+void Mat4SwapMat4(float *m1, float *m2);
+void Mat3CpyMat3(float m1[][3], float m2[][3]);
+
+void Mat3MulSerie(float answ[][3],
float m1[][3], float m2[][3], float m3[][3],
float m4[][3], float m5[][3], float m6[][3],
float m7[][3], float m8[][3]
);
- void
-Mat4MulSerie(
- float answ[][4],
- float m1[][4],
+
+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]
);
- void
-Mat4Clr(
- float *m
-);
- void
-Mat3Clr(
- float *m
-);
- void
-Mat3One(
- float m[][3]
-);
- void
-Mat4MulVec3Project(
- float mat[][4],
- float *vec
-);
- void
-Mat4MulVec(
- float mat[][4],
- int *vec
-);
- void
-VecMat4MulVecfl(
- float *in,
- float mat[][4],
- float *vec
-);
- void
-Mat4MulMat43(
- float (*m1)[4],
- float (*m3)[4],
- float (*m2)[3]
-);
-
- void
-Mat3IsMat3MulMat4(
- float m1[][3],
- float m2[][3],
- float m3[][4]
-);
- void
-Mat4One(
- float m[][4]
-);
- void
-Mat4Mul3Vecfl(
- float mat[][4],
- float *vec
-);
- void
-Mat4MulVec4fl(
- float mat[][4],
- float *vec
-);
- void
-Mat3MulVec(
- float mat[][3],
- int *vec
-);
- void
-Mat4MulVecfl(
- float mat[][4],
- float *vec
-);
- void
-Mat4ToQuat(
- float m[][4],
- float *q
-);
- void
-VecUpMat3old(
- float *vec,
- float mat[][3],
- short axis
-);
- int
-FloatCompare(
- float *v1,
- float *v2,
- float limit
-);
- float
-FloatLerpf(
- float target,
- float origin,
- float fac
-);
- float
-Normalize(
- float *n
-);
- float
-CalcNormFloat(
- float *v1,
- float *v2,
- float *v3,
- float *n
-);
-
- float
-CalcNormFloat4(
- float *v1,
- float *v2,
- float *v3,
- float *v4,
- float *n
-);
- float
-VecLenf(
- float *v1,
- float *v2
-);
- float
-VecLength(
- float *v
-);
- void
-VecMulf(
- float *v1,
- float f
-);
- int
-VecLenCompare(
- float *v1,
- float *v2,
- float limit
-);
- int
-VecCompare(
- float *v1,
- float *v2,
- float limit
-);
- int
-VecEqual(
- float *v1,
- float *v2
-);
- float
-Sqrt3f(
- float f
-);
- double
-Sqrt3d(
- double d
-);
+
+void Mat4Clr(float *m);
+void Mat3Clr(float *m);
+
+void Mat3One(float m[][3]);
+void Mat4One(float m[][4]);
+
+void Mat3Ortho(float mat[][3]);
+void Mat4Ortho(float mat[][4]);
+
+void VecMat4MulVecfl(float *in, float mat[][4], float *vec);
+void Mat4MulMat43(float (*m1)[4], float (*m3)[4], float (*m2)[3]);
+void Mat3IsMat3MulMat4(float m1[][3], float m2[][3], float m3[][4]);
+
+void Mat4MulVec(float mat[][4],int *vec);
+void Mat4MulVecfl(float mat[][4], float *vec);
+void Mat4Mul3Vecfl(float mat[][4], float *vec);
+void Mat4MulVec3Project(float mat[][4],float *vec);
+void Mat4MulVec4fl(float mat[][4], float *vec);
+void Mat3MulVec(float mat[][3],int *vec);
+void Mat3MulVecfl(float mat[][3], float *vec);
+void Mat3MulVecd(float mat[][3], double *vec);
+void Mat3TransMulVecfl(float mat[][3], float *vec);
+
+void Mat3AddMat3(float m1[][3], float m2[][3], float m3[][3]);
+void Mat4AddMat4(float m1[][4], float m2[][4], float m3[][4]);
+
+void VecUpMat3old(float *vec, float mat[][3], short axis);
+void VecUpMat3(float *vec, float mat[][3], short axis);
+void VecRotToMat3(float *vec, float phi, float mat[][3]);
+void VecRotToMat4(float *vec, float phi, float mat[][4]);
+
+void VecCopyf(float *v1, float *v2);
+int VecLen(int *v1, int *v2);
+float VecLenf(float *v1, float *v2);
+float VecLength(float *v);
+void VecMulf(float *v1, float f);
+
+int VecLenCompare(float *v1, float *v2, float limit);
+int VecCompare(float *v1, float *v2, float limit);
+int VecEqual(float *v1, float *v2);
+
+void printvecf(char *str,float v[3]);
+void printvec4f(char *str, float v[4]);
+
+void VecAddf(float *v, float *v1, float *v2);
+void VecSubf(float *v, float *v1, float *v2);
+void VecLerpf(float *target, float *a, float *b, float t);
+void VecMidf(float *v, float *v1, float *v2);
+
+void VecOrthoBasisf(float *v, float *v1, float *v2);
+
+float Vec2Lenf(float *v1, float *v2);
+float Vec2Length(float *v);
+void Vec2Mulf(float *v1, float f);
+void Vec2Addf(float *v, float *v1, float *v2);
+void Vec2Subf(float *v, float *v1, float *v2);
+void Vec2Copyf(float *v1, float *v2);
+
+void vectoquat(float *vec, short axis, short upflag, float *q);
+
+float VecAngle2(float *v1, float *v2);
+float VecAngle3(float *v1, float *v2, float *v3);
+float NormalizedVecAngle2(float *v1, float *v2);
+
+float VecAngle3_2D(float *v1, float *v2, float *v3);
+float NormalizedVecAngle2_2D(float *v1, float *v2);
+
+void euler_rot(float *beul, float ang, char axis);
+
- void
-euler_rot(
- float *beul,
- float ang,
- char axis
-);
- float
-saacos(
- float fac
-);
- float
-saasin(
- float fac
-);
- float
-sasqrt(
- float fac
-);
- void
-printvecf(
- char *str,
- float v[3]
-);
- void
-printvec4f(
- char *str,
- float v[4]
-);
- float
-Inpf(
- float *v1,
- float *v2
-);
- void
-VecSubf(
- float *v,
- float *v1,
- float *v2
-);
- void
-VecAddf(
- float *v,
- float *v1,
- float *v2
-);
- void
-VecLerpf(
- float *target,
- float *a,
- float *b,
- float t
-);
- void
-VecUpMat3(
- float *vec,
- float mat[][3],
- short axis
-);
- float
-DistVL2Dfl(
- float *v1,
- float *v2,
- float *v3
-);
- float
-PdistVL2Dfl(
- float *v1,
- float *v2,
- float *v3
-);
- float
-AreaF2Dfl(
- float *v1,
- float *v2,
- float *v3
-);
- float
-AreaQ3Dfl(
- float *v1,
- float *v2,
- float *v3,
- float *v4
-);
- float
-AreaT3Dfl(
- float *v1,
- float *v2,
- float *v3
-);
- float
-AreaPoly3Dfl(
- int nr,
- float *verts,
- float *normal
-);
- void
-VecRotToMat3(
- float *vec,
- float phi,
- float mat[][3]
-);
+float DistVL2Dfl(float *v1, float *v2, float *v3);
+float PdistVL2Dfl(float *v1, float *v2, float *v3);
+float PdistVL3Dfl(float *v1, float *v2, float *v3);
+void PclosestVL3Dfl(float *closest, float *v1, float *v2, float *v3);
+float AreaF2Dfl(float *v1, float *v2, float *v3);
+float AreaQ3Dfl(float *v1, float *v2, float *v3, float *v4);
+float AreaT3Dfl(float *v1, float *v2, float *v3);
+float AreaPoly3Dfl(int nr, float *verts, float *normal);
/* intersect Line-Line
return:
@@ -646,313 +292,113 @@ VecRotToMat3(
extern short IsectLL2Df(float *v1, float *v2, float *v3, float *v4);
extern short IsectLL2Ds(short *v1, short *v2, short *v3, short *v4);
-/* interpolation weights of point in a triangle or quad, v4 may be NULL */
- void
-InterpWeightsQ3Dfl(
- float *v1, float *v2, float *v3, float *v4,
- float *co,
- float *w
-);
-
- float *
-vectoquat(
- float *vec,
- short axis,
- short upflag
-);
+/*point in tri, 0 no intersection, 1 intersect */
+int IsectPT2Df(float pt[2], float v1[2], float v2[2], float v3[2]);
+/* point in quad, 0 no intersection, 1 intersect */
+int IsectPQ2Df(float pt[2], float v1[2], float v2[2], float v3[2], float v4[2]);
- float
-VecAngle3(
- float *v1,
- float *v2,
- float *v3
-);
-
- float
-VecAngle2(
- float *v1,
- float *v2
-);
- float
-NormalizedVecAngle2(
- float *v1,
- float *v2
-);
+/* interpolation weights of point in a triangle or quad, v4 may be NULL */
+void InterpWeightsQ3Dfl(float *v1, float *v2, float *v3, float *v4, float *co, float *w);
+/* interpolation weights of point in a polygon with >= 3 vertices */
+void MeanValueWeights(float v[][3], int n, float *co, float *w);
- void
-i_lookat(
+void i_lookat(
float vx, float vy,
float vz, float px,
float py, float pz,
float twist, float mat[][4]
);
- void
-i_window(
+
+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 hsv_to_rgb(float h, float s, float v, float *r, float *g, float *b);
+void hex_to_rgb(char *hexcol, float *r, float *g, float *b);
+void rgb_to_yuv(float r, float g, float b, float *ly, float *lu, float *lv);
+void yuv_to_rgb(float y, float u, float v, float *lr, float *lg, float *lb);
+void ycc_to_rgb(float y, float cb, float cr, float *lr, float *lg, float *lb);
+void rgb_to_ycc(float r, float g, float b, float *ly, float *lcb, float *lcr);
+void rgb_to_hsv(float r, float g, float b, float *lh, float *ls, float *lv);
+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 MinMaxRGB(short c[]);
- void
-hex_to_rgb(
- char *hexcol,
- float *r,
- float *g,
- float *b
-);
- void
-rgb_to_yuv(
- float r, float g, float b,
- float *ly, float *lu, float *lv
-);
- void
-yuv_to_rgb(
- float y, float u, float v,
- float *lr, float *lg, float *lb
-);
+void VecStar(float mat[][3],float *vec);
- void
-ycc_to_rgb(
- float y, float cb, float cr,
- float *lr, float *lg, float *lb
-);
+short EenheidsMat(float mat[][3]);
- void
-rgb_to_ycc(
- float r, float g, float b,
- float *ly, float *lcb, float *lcr
-);
- void
-rgb_to_hsv(
- float r, float g, float b,
- float *lh, float *ls, float *lv
-);
- 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 QuatToMat3(float *q, float m[][3]);
+void QuatToMat4(float *q, float m[][4]);
- void
-EulToQuat(
- float *eul,
- float *quat
-);
+void Mat3ToQuat_is_ok(float wmat[][3], float *q);
- void
-Mat3MulVecfl(
- float mat[][3],
- float *vec
-);
- void
-Mat3MulVecd(
- float mat[][3],
- double *vec
-);
- void
-Mat3TransMulVecfl(
- float mat[][3],
- float *vec
-);
- void
-VecStar(
- float mat[][3],
- float *vec
-);
- short
-EenheidsMat(
- float mat[][3]
-);
- void
-printmatrix3(
- char *str, float m[][3]
-);
- void
-QuatToMat3(
- float *q,
- float m[][3]
-);
- void
-QuatToMat4(
- float *q,
- float m[][4]
-);
- void
-Mat3ToQuat_is_ok(
- 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,
- float *v2
-);
- int
-VecLen(
- int *v1,
- int *v2
-);
- void
-CalcNormShort(
- short *v1,
- short *v2,
- short *v3,
- float *n
-) /* is ook uitprodukt */;
-
- void
-CalcNormLong(
- int* v1,
- int*v2,
- int*v3,
- float *n
-);
- void
-MinMax3(
- float *min,
- float *max,
- float *vec
-);
+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 i_translate(float Tx, float Ty, float Tz, float mat[][4]);
+void i_multmatrix(float icand[][4], float Vm[][4]);
+void i_rotate(float angle, char axis, float mat[][4]);
+
+
+
+
+
+void MinMax3(float *min, float *max, float *vec);
+void SizeToMat3(float *size, float mat[][3]);
+void SizeToMat4(float *size, float mat[][4]);
+
+float Mat3ToScalef(float mat[][3]);
+float Mat4ToScalef(float mat[][4]);
+
+void printmatrix3(char *str, float m[][3]);
+void printmatrix4(char *str, float m[][4]);
- void
-SizeToMat3(
- float *size,
- float mat[][3]
-);
- void
-printmatrix4(
- char *str,
- float m[][4]
-);
/* uit Sig.Proc.85 pag 253 */
- void
-Mat3ToQuat(
- float wmat[][3],
- float *q
-);
- void
-i_translate(
- float Tx,
- float Ty,
- float Tz,
- float mat[][4]
-);
- void
-i_multmatrix(
- float icand[][4],
- float Vm[][4]
-);
- void
-i_rotate(
- float angle,
- char axis,
- float mat[][4]
-);
- void
-VecMidf(
- float *v, float *v1, float *v2
-);
- void
-Mat3ToSize(
- float mat[][3], float *size
-);
- void
-Mat4ToSize(
- float mat[][4], float *size
-);
- void
-triatoquat(
- float *v1,
- float *v2,
- float *v3, float *quat
-);
- void
-MinMaxRGB(
- short c[]
-);
- float
-Vec2Lenf(
- float *v1,
- float *v2
-);
- void
-Vec2Mulf(
- float *v1,
- float f
-);
- void
-Vec2Addf(
- float *v,
- float *v1,
- float *v2
-);
- void
-Vec2Subf(
- float *v,
- float *v1,
- float *v2
-);
- void
-Vec2Copyf(
- float *v1,
- float *v2
-);
- float
-Inp2f(
- float *v1,
- float *v2
-);
- float
-Normalize2(
- float *n
-);
+void Mat3ToQuat(float wmat[][3], float *q);
+void Mat4ToQuat(float m[][4], float *q);
+
+void Mat3ToSize(float mat[][3], float *size);
+void Mat4ToSize(float mat[][4], float *size);
+
+void triatoquat(float *v1, float *v2, float *v3, float *quat);
void LocEulSizeToMat4(float mat[][4], float loc[3], float eul[3], float size[3]);
void LocQuatSizeToMat4(float mat[][4], float loc[3], float quat[4], float size[3]);
void tubemap(float x, float y, float z, float *u, float *v);
void spheremap(float x, float y, float z, float *u, float *v);
-
-int LineIntersectsTriangle(float p1[3], float p2[3], float v0[3], float v1[3], float v2[3], float *lambda);
+
+int LineIntersectsTriangle(float p1[3], float p2[3], float v0[3], float v1[3], float v2[3], float *lambda, float *uv);
+int SweepingSphereIntersectsTriangleUV(float p1[3], float p2[3], float radius, float v0[3], float v1[3], float v2[3], float *lambda, float *ipoint);
+int AxialLineIntersectsTriangle(int axis, float co1[3], float co2[3], float v0[3], float v1[3], float v2[3], float *lambda);
+int AabbIntersectAabb(float min1[3], float max1[3], float min2[3], float max2[3]);
+void VecfCubicInterpol(float *x1, float *v1, float *x2, float *v2, float t, float *x, float *v);
+void PointInQuad2DUV(float v0[2], float v1[2], float v2[2], float v3[2], float pt[2], float *uv);
+void PointInFace2DUV(int isquad, float v0[2], float v1[2], float v2[2], float v3[2], float pt[2], float *uv);
int point_in_tri_prism(float p[3], float v1[3], float v2[3], float v3[3]);
+
+float lambda_cp_line_ex(float p[3], float l1[3], float l2[3], float cp[3]);
+
+typedef struct DualQuat {
+ float quat[4];
+ float trans[4];
+
+ float scale[4][4];
+ float scale_weight;
+} DualQuat;
+
+void Mat4ToDQuat(float basemat[][4], float mat[][4], DualQuat *dq);
+void DQuatToMat4(DualQuat *dq, float mat[][4]);
+void DQuatAddWeighted(DualQuat *dqsum, DualQuat *dq, float weight);
+void DQuatNormalize(DualQuat *dq, float totweight);
+void DQuatMulVecfl(DualQuat *dq, float *co, float mat[][3]);
+void DQuatCpyDQuat(DualQuat *dq1, DualQuat *dq2);
#ifdef __cplusplus
}
diff --git a/source/blender/blenlib/BLI_blenlib.h b/source/blender/blenlib/BLI_blenlib.h
index 75a0e7b49a1..7d401cf2fc3 100644
--- a/source/blender/blenlib/BLI_blenlib.h
+++ b/source/blender/blenlib/BLI_blenlib.h
@@ -70,7 +70,6 @@
#include "DNA_listBase.h"
#include <stdlib.h>
-
extern ListBase fillfacebase;
extern ListBase fillvertbase;
/**
@@ -79,6 +78,8 @@ extern ListBase fillvertbase;
extern ListBase filledgebase;
extern int totblock;
+extern char btempdir[]; /* creator.c temp dir used instead of U.tempdir, set with BLI_where_is_temp( btempdir, 1 ); */
+
struct chardesc;
struct direntry;
struct rctf;
@@ -97,20 +98,24 @@ char *BLI_gethome(void);
void BLI_make_file_string(const char *relabase, char *string, const char *dir, const char *file);
void BLI_make_exist(char *dir);
void BLI_make_existing_file(char *name);
-void BLI_split_dirfile(const char *string, char *dir, char *file);
+void BLI_split_dirfile(char *string, char *dir, char *file);
void BLI_join_dirfile(char *string, const char *dir, const char *file);
int BLI_testextensie(const char *str, const char *ext);
void addlisttolist(ListBase *list1, ListBase *list2);
void BLI_insertlink(struct ListBase *listbase, void *vprevlink, void *vnewlink);
-void * BLI_findlink(struct ListBase *listbase, int number);
+void *BLI_findlink(struct ListBase *listbase, int number);
+int BLI_findindex(struct ListBase *listbase, void *vlink);
void BLI_freelistN(struct ListBase *listbase);
void BLI_addtail(struct ListBase *listbase, void *vlink);
void BLI_remlink(struct ListBase *listbase, void *vlink);
+void BLI_uniquename(struct ListBase *list, void *vlink, char defname[], short name_offs, short len);
void BLI_newname(char * name, int add);
-int BLI_stringdec(char *string, char *kop, char *staart, unsigned short *numlen);
-void BLI_stringenc(char *string, char *kop, char *staart, unsigned short numlen, int pic);
+int BLI_stringdec(char *string, char *kop, char *start, unsigned short *numlen);
+void BLI_stringenc(char *string, char *kop, char *start, unsigned short numlen, int pic);
void BLI_addhead(struct ListBase *listbase, void *vlink);
void BLI_insertlinkbefore(struct ListBase *listbase, void *vnextlink, void *vnewlink);
+void BLI_insertlinkafter(struct ListBase *listbase, void *vprevlink, void *vnewlink);
+void BLI_sortlist(struct ListBase *listbase, int (*cmp)(void *, void *));
void BLI_freelist(struct ListBase *listbase);
int BLI_countlist(struct ListBase *listbase);
void BLI_freelinkN(ListBase *listbase, void *vlink);
@@ -132,7 +137,8 @@ void BLI_dlist_reinit(struct DynamicList *dlist);
* converts it to a regular full path.
* Also removes garbage from directory paths, like /../ or double slashes etc
*/
-void BLI_cleanup_dir(const char *relabase, char *dir);
+void BLI_cleanup_file(const char *relabase, char *dir);
+void BLI_cleanup_dir(const char *relabase, char *dir); /* same as above but adds a trailing slash */
/**
* Blender's path code replacement function.
@@ -173,7 +179,7 @@ void BLI_clean(char *path);
* @param str The string to be duplicated
* @retval Returns the duplicated string
*/
-char* BLI_strdup(char *str);
+char *BLI_strdup(const char *str);
/**
* Duplicates the first @a len bytes of cstring @a str
@@ -184,7 +190,7 @@ char* BLI_strdup(char *str);
* @param len The number of bytes to duplicate
* @retval Returns the duplicated string
*/
-char* BLI_strdupn(char *str, int len);
+char *BLI_strdupn(const char *str, int len);
/**
* Like strncpy but ensures dst is always
@@ -196,7 +202,7 @@ char* BLI_strdupn(char *str, int len);
* the size of dst)
* @retval Returns dst
*/
-char* BLI_strncpy(char *dst, const char *src, int maxncpy);
+char *BLI_strncpy(char *dst, const char *src, int maxncpy);
/*
* Replacement for snprintf
@@ -217,6 +223,11 @@ int BLI_streq(char *a, char *b);
*/
int BLI_strcaseeq(char *a, char *b);
+/* in util.c */
+#ifdef WITH_ICONV
+void BLI_string_to_utf8(char *original, char *utf_8, char *code);
+#endif
+
/**
* Read a file as ASCII lines. An empty list is
* returned if the file cannot be opened or read.
@@ -245,10 +256,21 @@ void BLI_free_file_lines(struct LinkNode *lines);
* @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);
+void BLI_where_am_i(char *fullname, const char *name);
char *get_install_dir(void);
/**
+ * Gets the temp directory when blender first runs.
+ * If the default path is not found, use try $TEMP
+ *
+ * Also make sure the temp dir has a trailing slash
+ *
+ * @param fullname The full path to the temp directory
+ */
+void BLI_where_is_temp(char *fullname, int usertemp);
+
+
+ /**
* determines the full path to the application bundle on OS X
*
* @return path to application bundle
@@ -258,15 +280,16 @@ char* BLI_getbundle(void);
#endif
#ifdef WIN32
-int BLI_getInstallationDir( char * str );
+int BLI_getInstallationDir(char *str);
#endif
/* BLI_storage.h */
int BLI_filesize(int file);
+int BLI_filepathsize(const char *path);
double BLI_diskfree(char *dir);
-char * BLI_getwdN(char * dir);
+char *BLI_getwdN(char *dir);
void BLI_hide_dot_files(int set);
-unsigned int BLI_getdir(char *dirname, struct direntry **filelist);
+unsigned int BLI_getdir(char *dirname, struct direntry **filelist);
/**
* @attention Do not confuse with BLI_exists
@@ -288,8 +311,10 @@ int BLI_rename(char *from, char *to);
int BLI_gzip(char *from, char *to);
int BLI_delete(char *file, int dir, int recursive);
int BLI_move(char *file, char *to);
-int BLI_touch(char *file);
-char *BLI_last_slash(char *string);
+int BLI_touch(const char *file);
+char *BLI_last_slash(const char *string);
+void BLI_add_slash(char *string);
+void BLI_del_slash(char *string);
/* BLI_rct.c */
/**
@@ -299,12 +324,12 @@ char *BLI_last_slash(char *string);
*
* @return True if @a rect is empty.
*/
-int BLI_rcti_is_empty(struct rcti * rect);
+int BLI_rcti_is_empty(struct rcti *rect);
void BLI_init_rctf(struct rctf *rect, float xmin, float xmax, float ymin, float ymax);
void BLI_init_rcti(struct rcti *rect, int xmin, int xmax, int ymin, int ymax);
void BLI_translate_rctf(struct rctf *rect, float x, float y);
void BLI_translate_rcti(struct rcti *rect, int x, int y);
-int BLI_in_rcti(struct rcti * rect, int x, int y);
+int BLI_in_rcti(struct rcti *rect, int x, int y);
int BLI_in_rctf(struct rctf *rect, float x, float y);
int BLI_isect_rctf(struct rctf *src1, struct rctf *src2, struct rctf *dest);
int BLI_isect_rcti(struct rcti *src1, struct rcti *src2, struct rcti *dest);
@@ -361,7 +386,7 @@ void BLI_setInterruptCallBack(int (*f)(void));
char *BLI_strcasestr(const char *s, const char *find);
int BLI_strcasecmp(const char *s1, const char *s2);
int BLI_strncasecmp(const char *s1, const char *s2, int n);
-void BLI_timestr(double time, char *str);
+void BLI_timestr(double _time, char *str); /* time var is global */
/**
* Trick to address 32 GB with an int (only for malloced pointers)
diff --git a/source/blender/blenlib/BLI_boxpack2d.h b/source/blender/blenlib/BLI_boxpack2d.h
index b5cf9cd81e9..50b864df5f8 100644
--- a/source/blender/blenlib/BLI_boxpack2d.h
+++ b/source/blender/blenlib/BLI_boxpack2d.h
@@ -28,10 +28,7 @@
* Contributor(s): Campbell Barton
*
* ***** 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 :) )
- * */
+ */
/* Box Packer */
diff --git a/source/blender/blenlib/BLI_bpath.h b/source/blender/blenlib/BLI_bpath.h
new file mode 100644
index 00000000000..e932c39eb06
--- /dev/null
+++ b/source/blender/blenlib/BLI_bpath.h
@@ -0,0 +1,60 @@
+/**
+ *
+ * ***** 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): Campbell Barton
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+/* Based on ghash, difference is ghash is not a fixed size,
+ * so for BPath we dont need to malloc */
+
+struct BPathIterator {
+ char* path;
+ char* lib;
+ char* name;
+ void* data;
+ int len;
+ int type;
+};
+
+void BLI_bpathIterator_init (struct BPathIterator *bpi);
+char* BLI_bpathIterator_getPath (struct BPathIterator *bpi);
+char* BLI_bpathIterator_getLib (struct BPathIterator *bpi);
+char* BLI_bpathIterator_getName (struct BPathIterator *bpi);
+int BLI_bpathIterator_getType (struct BPathIterator *bpi);
+int BLI_bpathIterator_getPathMaxLen(struct BPathIterator *bpi);
+void BLI_bpathIterator_step (struct BPathIterator *bpi);
+int BLI_bpathIterator_isDone (struct BPathIterator *bpi);
+void BLI_bpathIterator_copyPathExpanded( struct BPathIterator *bpi, char *path_expanded);
+
+/* high level funcs */
+
+/* creates a text file with missing files if there are any */
+void checkMissingFiles(char *txtname );
+void makeFilesRelative(char *txtname, int *tot, int *changed, int *failed, int *linked);
+void makeFilesAbsolute(char *txtname, int *tot, int *changed, int *failed, int *linked);
+void findMissingFiles(char *str);
diff --git a/source/blender/blenlib/BLI_editVert.h b/source/blender/blenlib/BLI_editVert.h
index a763ad53f1f..f9b73d521c9 100644
--- a/source/blender/blenlib/BLI_editVert.h
+++ b/source/blender/blenlib/BLI_editVert.h
@@ -55,9 +55,9 @@ typedef struct EditVert
struct EditVert *v;
struct EditEdge *e;
struct EditFace *f;
- float *fp;
void *p;
long l;
+ float fp;
} tmp;
float no[3]; /*vertex normal */
float co[3]; /*vertex location */
@@ -67,6 +67,7 @@ typedef struct EditVert
h for hidden. if (!eve->h) {...
f1 and f2 can be used for temp data, clear them first*/
unsigned char f, h, f1, f2;
+ float bweight;
short fast; /* only 0 or 1, for editmesh_fastmalloc, do not store temp data here! */
int hash;
int keyindex; /* original index #, for restoring key information */
@@ -103,9 +104,11 @@ typedef struct EditEdge
short f1, f2; /* short, f1 is (ab)used in subdiv */
unsigned char f, h, dir, seam, sharp;
float crease;
+ float bweight;
short fast; /* only 0 or 1, for editmesh_fastmalloc */
short fgoni; /* index for fgon, for search */
HashEdge hash;
+ void *data; /*custom edge data*/
} EditEdge;
/* note; changing this also might affect the undo copy in editmesh.c */
@@ -163,6 +166,13 @@ typedef struct EditMesh
/* DerivedMesh caches... note that derived cage can be equivalent
* to derived final, care should be taken on release.
*/
+
+ /* used for keeping track of the last clicked on face - so the space image
+ * when using the last selected face - (EditSelection) the space image flickered too much
+ *
+ * never access this directly, use EM_set_actFace and EM_get_actFace */
+ EditFace *act_face;
+
struct DerivedMesh *derivedCage, *derivedFinal;
/* the custom data layer mask that was last used to calculate
* derivedCage and derivedFinal
@@ -171,7 +181,7 @@ typedef struct EditMesh
struct RetopoPaintData *retopo_paint_data;
- CustomData vdata, fdata;
+ CustomData vdata, edata, fdata;
#ifdef WITH_VERSE
void *vnode;
diff --git a/source/blender/blenlib/BLI_fnmatch.h b/source/blender/blenlib/BLI_fnmatch.h
new file mode 100644
index 00000000000..af1dcf523bf
--- /dev/null
+++ b/source/blender/blenlib/BLI_fnmatch.h
@@ -0,0 +1,69 @@
+/* Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
+
+NOTE: The canonical source of this file is maintained with the GNU C Library.
+Bugs can be reported to bug-glibc@prep.ai.mit.edu.
+
+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, or (at your option) any
+later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software Foundation,
+Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifndef _FNMATCH_H
+
+#define _FNMATCH_H 1
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined (__cplusplus) || (defined (__STDC__) && __STDC__)
+#undef __P
+#define __P(protos) protos
+#else /* Not C++ or ANSI C. */
+#undef __P
+#define __P(protos) ()
+/* We can get away without defining `const' here only because in this file
+ it is used only inside the prototype for `fnmatch', which is elided in
+ non-ANSI C where `const' is problematical. */
+#endif /* C++ or ANSI C. */
+
+
+/* We #undef these before defining them because some losing systems
+ (HP-UX A.08.07 for example) define these in <unistd.h>. */
+#undef FNM_PATHNAME
+#undef FNM_NOESCAPE
+#undef FNM_PERIOD
+
+/* Bits set in the FLAGS argument to `fnmatch'. */
+#define FNM_PATHNAME (1 << 0) /* No wildcard can ever match `/'. */
+#define FNM_NOESCAPE (1 << 1) /* Backslashes don't quote special chars. */
+#define FNM_PERIOD (1 << 2) /* Leading `.' is matched only explicitly. */
+
+#if !defined (_POSIX_C_SOURCE) || _POSIX_C_SOURCE < 2 || defined (_GNU_SOURCE)
+#define FNM_FILE_NAME FNM_PATHNAME /* Preferred GNU name. */
+#define FNM_LEADING_DIR (1 << 3) /* Ignore `/...' after a match. */
+#define FNM_CASEFOLD (1 << 4) /* Compare without regard to case. */
+#endif
+
+/* Value returned by `fnmatch' if STRING does not match PATTERN. */
+#define FNM_NOMATCH 1
+
+/* Match STRING against the filename pattern PATTERN,
+ returning zero if it matches, FNM_NOMATCH if not. */
+extern int fnmatch __P ((const char *__pattern, const char *__string,
+ int __flags));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* fnmatch.h */
diff --git a/source/blender/blenlib/BLI_kdtree.h b/source/blender/blenlib/BLI_kdtree.h
new file mode 100644
index 00000000000..d32e85c150c
--- /dev/null
+++ b/source/blender/blenlib/BLI_kdtree.h
@@ -0,0 +1,63 @@
+/**
+ * A kd-tree for nearest neighbour search.
+ *
+ * $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: none of this file.
+ *
+ * Contributor(s): Janne Karhu
+ * Brecht Van Lommel
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef BLI_KDTREE_H
+#define BLI_KDTREE_H
+
+struct KDTree;
+typedef struct KDTree KDTree;
+
+typedef struct KDTreeNearest {
+ int index;
+ float dist;
+ float co[3];
+} KDTreeNearest;
+
+/* Creates or free a kdtree */
+KDTree* BLI_kdtree_new(int maxsize);
+void BLI_kdtree_free(KDTree *tree);
+
+/* Construction: first insert points, then call balance. Normal is optional. */
+void BLI_kdtree_insert(KDTree *tree, int index, float *co, float *nor);
+void BLI_kdtree_balance(KDTree *tree);
+
+/* Find nearest returns index, and -1 if no node is found.
+ * Find n nearest returns number of points found, with results in nearest.
+ * Normal is optional. */
+int BLI_kdtree_find_nearest(KDTree *tree, float *co, float *nor, KDTreeNearest *nearest);
+int BLI_kdtree_find_n_nearest(KDTree *tree, int n, float *co, float *nor, KDTreeNearest *nearest);
+
+#endif
+
diff --git a/source/blender/blenlib/BLI_rand.h b/source/blender/blenlib/BLI_rand.h
index da2ecb79651..638f36b7414 100644
--- a/source/blender/blenlib/BLI_rand.h
+++ b/source/blender/blenlib/BLI_rand.h
@@ -52,6 +52,9 @@ double rng_getDouble (struct RNG* rng);
float rng_getFloat (struct RNG* rng);
void rng_shuffleArray(struct RNG *rng, void *data, int elemSize, int numElems);
+ /** Note that skipping is as slow as generating n numbers! */
+void rng_skip (struct RNG *rng, int n);
+
/** Seed the random number generator */
void BLI_srand (unsigned int seed);
diff --git a/source/blender/blenlib/BLI_storage_types.h b/source/blender/blenlib/BLI_storage_types.h
index 825a8bc9cbd..ebce33852a1 100644
--- a/source/blender/blenlib/BLI_storage_types.h
+++ b/source/blender/blenlib/BLI_storage_types.h
@@ -52,6 +52,8 @@ struct header{
typedef unsigned int mode_t;
#endif
+struct ImBuf;
+
struct direntry{
char *string;
mode_t type;
@@ -68,6 +70,7 @@ struct direntry{
char extra[16];
void *poin;
int nr;
+ struct ImBuf *image;
};
struct dirlink
diff --git a/source/blender/blenlib/BLI_threads.h b/source/blender/blenlib/BLI_threads.h
index 60ecce3f9d8..39162b8bd91 100644
--- a/source/blender/blenlib/BLI_threads.h
+++ b/source/blender/blenlib/BLI_threads.h
@@ -50,5 +50,6 @@ void BLI_end_threads (struct ListBase *threadbase);
void BLI_lock_thread (int type);
void BLI_unlock_thread (int type);
+int BLI_system_thread_count( void ); /* gets the number of threads the system can make use of */
#endif
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index 4812cad033d..ac2f3235646 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -36,6 +36,13 @@ SET(INC
${ZLIB_INC}
)
+IF(CMAKE_SYSTEM_NAME MATCHES "Linux")
+SET(INC
+ ${INC}
+ ${BINRELOC_INC}
+)
+ENDIF(CMAKE_SYSTEM_NAME MATCHES "Linux")
+
IF(WITH_VERSE)
ADD_DEFINITIONS(-DWITH_VERSE)
SET(INC ${INC} ${VERSE_INC})
diff --git a/source/blender/blenlib/SConscript b/source/blender/blenlib/SConscript
index e11934d968e..649d3cb5659 100644
--- a/source/blender/blenlib/SConscript
+++ b/source/blender/blenlib/SConscript
@@ -19,6 +19,7 @@ if env['WITH_BF_VERSE']:
if env['OURPLATFORM'] == 'linux2':
cflags='-pthread'
+ incs += ' ../../../extern/binreloc/include'
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw'):
incs += ' ' + env['BF_PTHREADS_INC']
diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c
index 5846bbda40e..6af377edfba 100644
--- a/source/blender/blenlib/intern/BLI_ghash.c
+++ b/source/blender/blenlib/intern/BLI_ghash.c
@@ -117,14 +117,16 @@ void BLI_ghash_insert(GHash *gh, void *key, void *val) {
}
}
-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;
-
+void* BLI_ghash_lookup(GHash *gh, void *key)
+{
+ if(gh) {
+ 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;
}
diff --git a/source/blender/blenlib/intern/BLI_kdtree.c b/source/blender/blenlib/intern/BLI_kdtree.c
new file mode 100644
index 00000000000..80e92cb8809
--- /dev/null
+++ b/source/blender/blenlib/intern/BLI_kdtree.c
@@ -0,0 +1,341 @@
+/**
+ * $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: none of this file.
+ *
+ * Contributor(s): Janne Karhu
+ * Brecht Van Lommel
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_arithb.h"
+#include "BLI_kdtree.h"
+
+#define SWAP(type, a, b) { type sw_ap; sw_ap=(a); (a)=(b); (b)=sw_ap; }
+
+typedef struct KDTreeNode {
+ struct KDTreeNode *left, *right;
+ float co[3], nor[3];
+ int index;
+ short d;
+} KDTreeNode;
+
+struct KDTree {
+ KDTreeNode *nodes;
+ int totnode;
+ KDTreeNode *root;
+};
+
+KDTree *BLI_kdtree_new(int maxsize)
+{
+ KDTree *tree;
+
+ tree= MEM_callocN(sizeof(KDTree), "KDTree");
+ tree->nodes= MEM_callocN(sizeof(KDTreeNode)*maxsize, "KDTreeNode");
+ tree->totnode= 0;
+
+ return tree;
+}
+
+void BLI_kdtree_free(KDTree *tree)
+{
+ if(tree) {
+ MEM_freeN(tree->nodes);
+ MEM_freeN(tree);
+ }
+}
+
+void BLI_kdtree_insert(KDTree *tree, int index, float *co, float *nor)
+{
+ KDTreeNode *node= &tree->nodes[tree->totnode++];
+
+ node->index= index;
+ VecCopyf(node->co, co);
+ if(nor) VecCopyf(node->nor, nor);
+}
+
+static KDTreeNode *kdtree_balance(KDTreeNode *nodes, int totnode, int axis)
+{
+ KDTreeNode *node;
+ float co;
+ int left, right, median, i, j;
+
+ if(totnode <= 0)
+ return NULL;
+ else if(totnode == 1)
+ return nodes;
+
+ /* quicksort style sorting around median */
+ left= 0;
+ right= totnode-1;
+ median= totnode/2;
+
+ while(right > left) {
+ co= nodes[right].co[axis];
+ i= left-1;
+ j= right;
+
+ while(1) {
+ while(nodes[++i].co[axis] < co);
+ while(nodes[--j].co[axis] > co && j>left);
+
+ if(i >= j) break;
+ SWAP(KDTreeNode, nodes[i], nodes[j]);
+ }
+
+ SWAP(KDTreeNode, nodes[i], nodes[right]);
+ if(i >= median)
+ right= i-1;
+ if(i <= median)
+ left= i+1;
+ }
+
+ /* set node and sort subnodes */
+ node= &nodes[median];
+ node->d= axis;
+ node->left= kdtree_balance(nodes, median, (axis+1)%3);
+ node->right= kdtree_balance(nodes+median+1, (totnode-(median+1)), (axis+1)%3);
+
+ return node;
+}
+
+void BLI_kdtree_balance(KDTree *tree)
+{
+ tree->root= kdtree_balance(tree->nodes, tree->totnode, 0);
+}
+
+static float squared_distance(float *v1, float *v2, float *n1, float *n2)
+{
+ float d[3], dist;
+
+ d[0]= v2[0]-v1[0];
+ d[1]= v2[1]-v1[1];
+ d[2]= v2[2]-v1[2];
+
+ dist= d[0]*d[0] + d[1]*d[1] + d[2]*d[2];
+
+ if(n1 && n2 && n1[0]*n2[0] + n1[1]*n2[1] + n1[2]*n2[2] < 0.0f)
+ dist *= 10.0f;
+
+ return dist;
+}
+
+int BLI_kdtree_find_nearest(KDTree *tree, float *co, float *nor, KDTreeNearest *nearest)
+{
+ KDTreeNode *root, *node, *min_node;
+ KDTreeNode **stack, *defaultstack[100];
+ float min_dist, cur_dist;
+ int totstack, cur=0;
+
+ if(!tree->root)
+ return -1;
+
+ stack= defaultstack;
+ totstack= 100;
+
+ root= tree->root;
+ min_node= root;
+ min_dist= squared_distance(root->co,co,root->nor,nor);
+
+ if(co[root->d] < root->co[root->d]) {
+ if(root->right)
+ stack[cur++]=root->right;
+ if(root->left)
+ stack[cur++]=root->left;
+ }
+ else {
+ if(root->left)
+ stack[cur++]=root->left;
+ if(root->right)
+ stack[cur++]=root->right;
+ }
+
+ while(cur--){
+ node=stack[cur];
+
+ cur_dist = node->co[node->d] - co[node->d];
+
+ if(cur_dist<0.0){
+ cur_dist= -cur_dist*cur_dist;
+
+ if(-cur_dist<min_dist){
+ cur_dist=squared_distance(node->co,co,node->nor,nor);
+ if(cur_dist<min_dist){
+ min_dist=cur_dist;
+ min_node=node;
+ }
+ if(node->left)
+ stack[cur++]=node->left;
+ }
+ if(node->right)
+ stack[cur++]=node->right;
+ }
+ else{
+ cur_dist= cur_dist*cur_dist;
+
+ if(cur_dist<min_dist){
+ cur_dist=squared_distance(node->co,co,node->nor,nor);
+ if(cur_dist<min_dist){
+ min_dist=cur_dist;
+ min_node=node;
+ }
+ if(node->right)
+ stack[cur++]=node->right;
+ }
+ if(node->left)
+ stack[cur++]=node->left;
+ }
+ if(cur+3 > totstack){
+ KDTreeNode **temp=MEM_callocN((totstack+100)*sizeof(KDTreeNode*), "psys_treestack");
+ memcpy(temp,stack,totstack*sizeof(KDTreeNode*));
+ if(stack != defaultstack)
+ MEM_freeN(stack);
+ stack=temp;
+ totstack+=100;
+ }
+ }
+
+ if(nearest) {
+ nearest->index= min_node->index;
+ nearest->dist= sqrt(min_dist);
+ VecCopyf(nearest->co, min_node->co);
+ }
+
+ if(stack != defaultstack)
+ MEM_freeN(stack);
+
+ return min_node->index;
+}
+
+static void add_nearest(KDTreeNearest *ptn, int *found, int n, int index, float dist, float *co)
+{
+ int i;
+
+ if(*found<n) (*found)++;
+
+ for(i=*found-1; i>0; i--) {
+ if(dist >= ptn[i-1].dist)
+ break;
+ else
+ ptn[i]= ptn[i-1];
+ }
+
+ ptn[i].index= index;
+ ptn[i].dist= dist;
+ VecCopyf(ptn[i].co, co);
+}
+
+/* finds the nearest n entries in tree to specified coordinates */
+int BLI_kdtree_find_n_nearest(KDTree *tree, int n, float *co, float *nor, KDTreeNearest *nearest)
+{
+ KDTreeNode *root, *node=0;
+ KDTreeNode **stack, *defaultstack[100];
+ float cur_dist;
+ int i, totstack, cur=0, found=0;
+
+ if(!tree->root)
+ return 0;
+
+ stack= defaultstack;
+ totstack= 100;
+
+ root= tree->root;
+
+ cur_dist= squared_distance(root->co,co,root->nor,nor);
+ add_nearest(nearest,&found,n,root->index,cur_dist,root->co);
+
+ if(co[root->d] < root->co[root->d]) {
+ if(root->right)
+ stack[cur++]=root->right;
+ if(root->left)
+ stack[cur++]=root->left;
+ }
+ else {
+ if(root->left)
+ stack[cur++]=root->left;
+ if(root->right)
+ stack[cur++]=root->right;
+ }
+
+ while(cur--){
+ node=stack[cur];
+
+ cur_dist = node->co[node->d] - co[node->d];
+
+ if(cur_dist<0.0){
+ cur_dist= -cur_dist*cur_dist;
+
+ if(found<n || -cur_dist<nearest[found-1].dist){
+ cur_dist=squared_distance(node->co,co,node->nor,nor);
+
+ if(found<n || cur_dist<nearest[found-1].dist)
+ add_nearest(nearest,&found,n,node->index,cur_dist,node->co);
+
+ if(node->left)
+ stack[cur++]=node->left;
+ }
+ if(node->right)
+ stack[cur++]=node->right;
+ }
+ else{
+ cur_dist= cur_dist*cur_dist;
+
+ if(found<n || cur_dist<nearest[found-1].dist){
+ cur_dist=squared_distance(node->co,co,node->nor,nor);
+ if(found<n || cur_dist<nearest[found-1].dist)
+ add_nearest(nearest,&found,n,node->index,cur_dist,node->co);
+
+ if(node->right)
+ stack[cur++]=node->right;
+ }
+ if(node->left)
+ stack[cur++]=node->left;
+ }
+ if(cur+3 > totstack){
+ KDTreeNode **temp=MEM_callocN((totstack+100)*sizeof(KDTreeNode*), "psys_treestack");
+ memcpy(temp,stack,totstack*sizeof(KDTreeNode*));
+ if(stack != defaultstack)
+ MEM_freeN(stack);
+ stack=temp;
+ totstack+=100;
+ }
+ }
+
+ for(i=0; i<found; i++)
+ nearest[i].dist= sqrt(nearest[i].dist);
+
+ if(stack != defaultstack)
+ MEM_freeN(stack);
+
+ return found;
+}
+
diff --git a/source/blender/blenlib/intern/BLI_storage.h b/source/blender/blenlib/intern/BLI_storage.h
index 5e9c377c410..9cbdfa327cd 100644
--- a/source/blender/blenlib/intern/BLI_storage.h
+++ b/source/blender/blenlib/intern/BLI_storage.h
@@ -31,6 +31,11 @@
#ifndef BLI_STORAGE_H
#define BLI_STORAGE_H
+#ifndef WIN32
+#define _LARGEFILE_SOURCE 1
+#define _FILE_OFFSET_BITS 64
+#endif
+
#include "BLI_storage_types.h"
void BLI_adddirstrings(void);
diff --git a/source/blender/blenlib/intern/Makefile b/source/blender/blenlib/intern/Makefile
index 0c3f4a486be..9f40710209d 100644
--- a/source/blender/blenlib/intern/Makefile
+++ b/source/blender/blenlib/intern/Makefile
@@ -36,10 +36,6 @@ 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_CPP_WARNINGS)
# path to SDNA types
@@ -63,3 +59,6 @@ endif
ifeq ($(WITH_FREETYPE2), true)
CPPFLAGS += -DWITH_FREETYPE2
endif
+ifeq ($(OS),linux)
+ CPPFLAGS += -I$(OCGDIR)/extern/binreloc/include
+endif \ No newline at end of file
diff --git a/source/blender/blenlib/intern/arithb.c b/source/blender/blenlib/intern/arithb.c
index 182607740a5..cd7de83b9c0 100644
--- a/source/blender/blenlib/intern/arithb.c
+++ b/source/blender/blenlib/intern/arithb.c
@@ -760,7 +760,28 @@ void Mat4MulSerie(float answ[][4], float m1[][4],
}
}
+void Mat4BlendMat4(float out[][4], float dst[][4], float src[][4], float srcweight)
+{
+ float squat[4], dquat[4], fquat[4];
+ float ssize[3], dsize[3], fsize[4];
+ float sloc[3], dloc[3], floc[3];
+
+ Mat4ToQuat(dst, dquat);
+ Mat4ToSize(dst, dsize);
+ VecCopyf(dloc, dst[3]);
+
+ Mat4ToQuat(src, squat);
+ Mat4ToSize(src, ssize);
+ VecCopyf(sloc, src[3]);
+
+ /* do blending */
+ VecLerpf(floc, dloc, sloc, srcweight);
+ QuatInterpol(fquat, dquat, squat, srcweight);
+ VecLerpf(fsize, dsize, ssize, srcweight);
+ /* compose new matrix */
+ LocQuatSizeToMat4(out, floc, fquat, fsize);
+}
void Mat4Clr(float *m)
{
@@ -915,7 +936,7 @@ void Mat4MulFloat(float *m, float f)
{
int i;
- for(i=0;i<12;i++) m[i]*=f; /* count to 12: without vector component */
+ for(i=0;i<16;i++) m[i]*=f; /* count to 12: without vector component */
}
@@ -931,6 +952,24 @@ void Mat4MulFloat3(float *m, float f) /* only scale component */
}
}
+void Mat3AddMat3(float m1[][3], float m2[][3], float m3[][3])
+{
+ int i, j;
+
+ for(i=0;i<3;i++)
+ for(j=0;j<3;j++)
+ m1[i][j]= m2[i][j] + m3[i][j];
+}
+
+void Mat4AddMat4(float m1[][4], float m2[][4], float m3[][4])
+{
+ int i, j;
+
+ for(i=0;i<4;i++)
+ for(j=0;j<4;j++)
+ m1[i][j]= m2[i][j] + m3[i][j];
+}
+
void VecStar(float mat[][3], float *vec)
{
@@ -1070,6 +1109,7 @@ void QuatInv(float *q)
QuatMulf(q, 1.0f/f);
}
+/* simple mult */
void QuatMulf(float *q, float f)
{
q[0] *= f;
@@ -1085,6 +1125,20 @@ void QuatSub(float *q, float *q1, float *q2)
q2[0]= -q2[0];
}
+/* angular mult factor */
+void QuatMulFac(float *q, float fac)
+{
+ float angle= fac*saacos(q[0]); /* quat[0]= cos(0.5*angle), but now the 0.5 and 2.0 rule out */
+
+ float co= (float)cos(angle);
+ float si= (float)sin(angle);
+ q[0]= co;
+ Normalize(q+1);
+ q[1]*= si;
+ q[2]*= si;
+ q[3]*= si;
+
+}
void QuatToMat3( float *q, float m[][3])
{
@@ -1157,7 +1211,7 @@ void QuatToMat4( float *q, float m[][4])
m[3][3]= 1.0f;
}
-void Mat3ToQuat( float wmat[][3], float *q) /* from Sig.Proc.85 pag 253 */
+void Mat3ToQuat(float wmat[][3], float *q)
{
double tr, s;
float mat[3][3];
@@ -1171,34 +1225,38 @@ void Mat3ToQuat( float wmat[][3], float *q) /* from Sig.Proc.85 pag 253 */
if(tr>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);
+ s= 1.0/(4.0*s);
+ 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));
+ if(mat[0][0] > mat[1][1] && mat[0][0] > mat[2][2]) {
+ s= 2.0*sqrtf(1.0 + mat[0][0] - mat[1][1] - mat[2][2]);
+ q[1]= (float)(0.25*s);
+
+ s= 1.0/s;
+ q[0]= (float)((mat[2][1] - mat[1][2])*s);
+ q[2]= (float)((mat[1][0] + mat[0][1])*s);
+ q[3]= (float)((mat[2][0] + mat[0][2])*s);
+ }
+ else if(mat[1][1] > mat[2][2]) {
+ s= 2.0*sqrtf(1.0 + mat[1][1] - mat[0][0] - mat[2][2]);
+ q[2]= (float)(0.25*s);
+
+ s= 1.0/s;
+ q[0]= (float)((mat[2][0] - mat[0][2])*s);
+ q[1]= (float)((mat[1][0] + mat[0][1])*s);
+ q[3]= (float)((mat[2][1] + mat[1][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;
- }
+ s= 2.0*sqrtf(1.0 + mat[2][2] - mat[0][0] - mat[1][1]);
+ q[3]= (float)(0.25*s);
+
+ s= 1.0/s;
+ q[0]= (float)((mat[1][0] - mat[0][1])*s);
+ q[1]= (float)((mat[2][0] + mat[0][2])*s);
+ q[2]= (float)((mat[2][1] + mat[1][2])*s);
}
}
NormalQuat(q);
@@ -1279,9 +1337,8 @@ void NormalQuat(float *q)
}
}
-float *vectoquat( float *vec, short axis, short upflag)
+void vectoquat(float *vec, short axis, short upflag, float *q)
{
- static float q1[4];
float q2[4], nor[3], *fp, mat[3][3], angle, si, co, x2, y2, z2, len1;
/* first rotate to axis */
@@ -1293,11 +1350,11 @@ float *vectoquat( float *vec, short axis, short upflag)
x2= -vec[0] ; y2= -vec[1] ; z2= -vec[2];
}
- q1[0]=1.0;
- q1[1]=q1[2]=q1[3]= 0.0;
+ q[0]=1.0;
+ q[1]=q[2]=q[3]= 0.0;
len1= (float)sqrt(x2*x2+y2*y2+z2*z2);
- if(len1 == 0.0) return(q1);
+ if(len1 == 0.0) return;
/* nasty! I need a good routine for this...
* problem is a rotation of an Y axis to the negative Y-axis for example.
@@ -1308,9 +1365,8 @@ float *vectoquat( float *vec, short axis, short upflag)
nor[1]= -z2;
nor[2]= y2;
- if( fabs(y2)+fabs(z2)<0.0001 ) {
+ if(fabs(y2)+fabs(z2)<0.0001)
nor[1]= 1.0;
- }
co= x2;
}
@@ -1319,9 +1375,8 @@ float *vectoquat( float *vec, short axis, short upflag)
nor[1]= 0.0;
nor[2]= -x2;
- if( fabs(x2)+fabs(z2)<0.0001 ) {
+ if(fabs(x2)+fabs(z2)<0.0001)
nor[2]= 1.0;
- }
co= y2;
}
@@ -1330,9 +1385,8 @@ float *vectoquat( float *vec, short axis, short upflag)
nor[1]= x2;
nor[2]= 0.0;
- if( fabs(x2)+fabs(y2)<0.0001 ) {
+ if(fabs(x2)+fabs(y2)<0.0001)
nor[0]= 1.0;
- }
co= z2;
}
@@ -1342,13 +1396,13 @@ float *vectoquat( float *vec, short axis, short upflag)
angle= 0.5f*saacos(co);
si= (float)sin(angle);
- q1[0]= (float)cos(angle);
- q1[1]= nor[0]*si;
- q1[2]= nor[1]*si;
- q1[3]= nor[2]*si;
+ q[0]= (float)cos(angle);
+ q[1]= nor[0]*si;
+ q[2]= nor[1]*si;
+ q[3]= nor[2]*si;
if(axis!=upflag) {
- QuatToMat3(q1, mat);
+ QuatToMat3(q, mat);
fp= mat[2];
if(axis==0) {
@@ -1371,10 +1425,8 @@ float *vectoquat( float *vec, short axis, short upflag)
q2[2]= y2*si;
q2[3]= z2*si;
- QuatMul(q1,q2,q1);
+ QuatMul(q,q2,q);
}
-
- return(q1);
}
void VecUpMat3old( float *vec, float mat[][3], short axis)
@@ -1558,6 +1610,225 @@ void QuatAdd(float *result, float *quat1, float *quat2, float t)
result[3]= quat1[3] + t*quat2[3];
}
+void QuatCopy(float *q1, float *q2)
+{
+ q1[0]= q2[0];
+ q1[1]= q2[1];
+ q1[2]= q2[2];
+ q1[3]= q2[3];
+}
+
+/* **************** DUAL QUATERNIONS ************** */
+
+/*
+ Conversion routines between (regular quaternion, translation) and
+ dual quaternion.
+
+ Version 1.0.0, February 7th, 2007
+
+ Copyright (C) 2006-2007 University of Dublin, Trinity College, All Rights
+ Reserved
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the author(s) be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
+
+ Author: Ladislav Kavan, kavanl@cs.tcd.ie
+
+ Changes for Blender:
+ - renaming, style changes and optimizations
+ - added support for scaling
+*/
+
+void Mat4ToDQuat(float basemat[][4], float mat[][4], DualQuat *dq)
+{
+ float *t, *q, dscale[3], scale[3], basequat[4];
+ float baseRS[4][4], baseinv[4][4], baseR[4][4], baseRinv[4][4];
+ float R[4][4], S[4][4];
+
+ /* split scaling and rotation, there is probably a faster way to do
+ this, it's done like this now to correctly get negative scaling */
+ Mat4MulMat4(baseRS, basemat, mat);
+ Mat4ToSize(baseRS, scale);
+
+ VecCopyf(dscale, scale);
+ dscale[0] -= 1.0f; dscale[1] -= 1.0f; dscale[2] -= 1.0f;
+
+ if((Det4x4(mat) < 0.0f) || VecLength(dscale) > 1e-4) {
+ /* extract R and S */
+ Mat4ToQuat(baseRS, basequat);
+ QuatToMat4(basequat, baseR);
+ VecCopyf(baseR[3], baseRS[3]);
+
+ Mat4Invert(baseinv, basemat);
+ Mat4MulMat4(R, baseinv, baseR);
+
+ Mat4Invert(baseRinv, baseR);
+ Mat4MulMat4(S, baseRS, baseRinv);
+
+ /* set scaling part */
+ Mat4MulSerie(dq->scale, basemat, S, baseinv, 0, 0, 0, 0, 0);
+ dq->scale_weight= 1.0f;
+ }
+ else {
+ /* matrix does not contain scaling */
+ Mat4CpyMat4(R, mat);
+ dq->scale_weight= 0.0f;
+ }
+
+ /* non-dual part */
+ Mat4ToQuat(R, dq->quat);
+
+ /* dual part */
+ t= R[3];
+ q= dq->quat;
+ dq->trans[0]= -0.5f*( t[0]*q[1] + t[1]*q[2] + t[2]*q[3]);
+ dq->trans[1]= 0.5f*( t[0]*q[0] + t[1]*q[3] - t[2]*q[2]);
+ dq->trans[2]= 0.5f*(-t[0]*q[3] + t[1]*q[0] + t[2]*q[1]);
+ dq->trans[3]= 0.5f*( t[0]*q[2] - t[1]*q[1] + t[2]*q[0]);
+}
+
+void DQuatToMat4(DualQuat *dq, float mat[][4])
+{
+ float len, *t, q0[4];
+
+ /* regular quaternion */
+ QuatCopy(q0, dq->quat);
+
+ /* normalize */
+ len= sqrt(QuatDot(q0, q0));
+ if(len != 0.0f)
+ QuatMulf(q0, 1.0f/len);
+
+ /* rotation */
+ QuatToMat4(q0, mat);
+
+ /* translation */
+ t= dq->trans;
+ mat[3][0]= 2.0*(-t[0]*q0[1] + t[1]*q0[0] - t[2]*q0[3] + t[3]*q0[2]);
+ mat[3][1]= 2.0*(-t[0]*q0[2] + t[1]*q0[3] + t[2]*q0[0] - t[3]*q0[1]);
+ mat[3][2]= 2.0*(-t[0]*q0[3] - t[1]*q0[2] + t[2]*q0[1] + t[3]*q0[0]);
+
+ /* note: this does not handle scaling */
+}
+
+void DQuatAddWeighted(DualQuat *dqsum, DualQuat *dq, float weight)
+{
+ /* make sure we interpolate quats in the right direction */
+ if (QuatDot(dq->quat, dqsum->quat) < 0)
+ weight = -weight;
+
+ /* interpolate rotation and translation */
+ dqsum->quat[0] += weight*dq->quat[0];
+ dqsum->quat[1] += weight*dq->quat[1];
+ dqsum->quat[2] += weight*dq->quat[2];
+ dqsum->quat[3] += weight*dq->quat[3];
+
+ dqsum->trans[0] += weight*dq->trans[0];
+ dqsum->trans[1] += weight*dq->trans[1];
+ dqsum->trans[2] += weight*dq->trans[2];
+ dqsum->trans[3] += weight*dq->trans[3];
+
+ /* interpolate scale - but only if needed */
+ if (dq->scale_weight) {
+ float wmat[4][4];
+
+ Mat4CpyMat4(wmat, dq->scale);
+ Mat4MulFloat((float*)wmat, weight);
+ Mat4AddMat4(dqsum->scale, dqsum->scale, wmat);
+ dqsum->scale_weight += weight;
+ }
+}
+
+void DQuatNormalize(DualQuat *dq, float totweight)
+{
+ float scale= 1.0f/totweight;
+
+ QuatMulf(dq->quat, scale);
+ QuatMulf(dq->trans, scale);
+
+ if(dq->scale_weight) {
+ float addweight= totweight - dq->scale_weight;
+
+ if(addweight) {
+ dq->scale[0][0] += addweight;
+ dq->scale[1][1] += addweight;
+ dq->scale[2][2] += addweight;
+ dq->scale[3][3] += addweight;
+ }
+
+ Mat4MulFloat((float*)dq->scale, scale);
+ dq->scale_weight= 1.0f;
+ }
+}
+
+void DQuatMulVecfl(DualQuat *dq, float *co, float mat[][3])
+{
+ float M[3][3], t[3], scalemat[3][3], len2;
+ float w= dq->quat[0], x= dq->quat[1], y= dq->quat[2], z= dq->quat[3];
+ float t0= dq->trans[0], t1= dq->trans[1], t2= dq->trans[2], t3= dq->trans[3];
+
+ /* rotation matrix */
+ M[0][0]= w*w + x*x - y*y - z*z;
+ M[1][0]= 2*(x*y - w*z);
+ M[2][0]= 2*(x*z + w*y);
+
+ M[0][1]= 2*(x*y + w*z);
+ M[1][1]= w*w + y*y - x*x - z*z;
+ M[2][1]= 2*(y*z - w*x);
+
+ M[0][2]= 2*(x*z - w*y);
+ M[1][2]= 2*(y*z + w*x);
+ M[2][2]= w*w + z*z - x*x - y*y;
+
+ len2= QuatDot(dq->quat, dq->quat);
+ if(len2 > 0.0f)
+ len2= 1.0f/len2;
+
+ /* translation */
+ t[0]= 2*(-t0*x + w*t1 - t2*z + y*t3);
+ t[1]= 2*(-t0*y + t1*z - x*t3 + w*t2);
+ t[2]= 2*(-t0*z + x*t2 + w*t3 - t1*y);
+
+ /* apply scaling */
+ if(dq->scale_weight)
+ Mat4MulVecfl(dq->scale, co);
+
+ /* apply rotation and translation */
+ Mat3MulVecfl(M, co);
+ co[0]= (co[0] + t[0])*len2;
+ co[1]= (co[1] + t[1])*len2;
+ co[2]= (co[2] + t[2])*len2;
+
+ /* compute crazyspace correction mat */
+ if(mat) {
+ if(dq->scale_weight) {
+ Mat3CpyMat4(scalemat, dq->scale);
+ Mat3MulMat3(mat, M, scalemat);
+ }
+ else
+ Mat3CpyMat3(mat, M);
+ Mat3MulFloat((float*)mat, len2);
+ }
+}
+
+void DQuatCpyDQuat(DualQuat *dq1, DualQuat *dq2)
+{
+ memcpy(dq1, dq2, sizeof(DualQuat));
+}
+
/* **************** VIEW / PROJECTION ******************************** */
@@ -1767,7 +2038,6 @@ void Mat4Ortho(float mat[][4])
void VecCopyf(float *v1, float *v2)
{
-
v1[0]= v2[0];
v1[1]= v2[1];
v1[2]= v2[2];
@@ -1836,6 +2106,30 @@ void VecMulf(float *v1, float f)
v1[2]*= f;
}
+void VecOrthoBasisf(float *v, float *v1, float *v2)
+{
+ if (v[0] == 0.0f && v[1] == 0.0f)
+ {
+ // degenerate case
+ v1[0] = 0.0f; v1[1] = 1.0f; v1[2] = 0.0f;
+ if (v[2] > 0.0f) {
+ v2[0] = 1.0f; v2[1] = v2[2] = 0.0f;
+ }
+ else {
+ v2[0] = -1.0f; v2[1] = v2[2] = 0.0f;
+ }
+ }
+ else
+ {
+ float f = 1.0f/sqrt(v[0]*v[0] + v[1]*v[1]);
+ v1[0] = v[1]*f;
+ v1[1] = -v[0]*f;
+ v1[2] = 0.0f;
+
+ Crossf(v2, v, v1);
+ }
+}
+
int VecLenCompare(float *v1, float *v2, float limit)
{
float x,y,z;
@@ -2125,6 +2419,98 @@ short IsectLL2Df(float *v1, float *v2, float *v3, float *v4)
return 0;
}
+/*
+-1: colliniar
+ 1: intersection
+
+*/
+short IsectLLPt2Df(float x0,float y0,float x1,float y1,
+ float x2,float y2,float x3,float y3, float *xi,float *yi)
+
+{
+ /*
+ this function computes the intersection of the sent lines
+ and returns the intersection point, note that the function assumes
+ the lines intersect. the function can handle vertical as well
+ as horizontal lines. note the function isn't very clever, it simply
+ applies the math, but we don't need speed since this is a
+ pre-processing step
+ */
+ float c1,c2, // constants of linear equations
+ det_inv, // the inverse of the determinant of the coefficient
+ m1,m2; // the slopes of each line
+ /*
+ compute slopes, note the cludge for infinity, however, this will
+ be close enough
+ */
+ if ( fabs( x1-x0 ) > 0.000001 )
+ m1 = ( y1-y0 ) / ( x1-x0 );
+ else
+ return -1; /*m1 = ( float ) 1e+10;*/ // close enough to infinity
+
+ if ( fabs( x3-x2 ) > 0.000001 )
+ m2 = ( y3-y2 ) / ( x3-x2 );
+ else
+ return -1; /*m2 = ( float ) 1e+10;*/ // close enough to infinity
+
+ if (fabs(m1-m2) < 0.000001)
+ return -1; /* paralelle lines */
+
+// compute constants
+
+ c1 = ( y0-m1*x0 );
+ c2 = ( y2-m2*x2 );
+
+// compute the inverse of the determinate
+
+ det_inv = 1.0f / ( -m1 + m2 );
+
+// use Kramers rule to compute xi and yi
+
+ *xi= ( ( -c2 + c1 ) *det_inv );
+ *yi= ( ( m2*c1 - m1*c2 ) *det_inv );
+
+ return 1;
+} // end Intersect_Lines
+
+#define SIDE_OF_LINE(pa,pb,pp) ((pa[0]-pp[0])*(pb[1]-pp[1]))-((pb[0]-pp[0])*(pa[1]-pp[1]))
+#define ISECT_EPSILON 1e-6
+
+/* point in tri */
+int IsectPT2Df(float pt[2], float v1[2], float v2[2], float v3[2])
+{
+ if ((SIDE_OF_LINE(v1,v2,pt)>=-ISECT_EPSILON) &&
+ (SIDE_OF_LINE(v2,v3,pt)>=-ISECT_EPSILON) &&
+ (SIDE_OF_LINE(v3,v1,pt)>=-ISECT_EPSILON))
+ return 1;
+ else {
+ return 0;
+ }
+}
+/* point in quad - only convex quads */
+int IsectPQ2Df(float pt[2], float v1[2], float v2[2], float v3[2], float v4[2])
+{
+ if ((SIDE_OF_LINE(v1,v2,pt)>=-ISECT_EPSILON) &&
+ (SIDE_OF_LINE(v2,v3,pt)>=-ISECT_EPSILON) &&
+ (SIDE_OF_LINE(v3,v4,pt)>=-ISECT_EPSILON) &&
+ (SIDE_OF_LINE(v4,v1,pt)>=-ISECT_EPSILON))
+ return 1;
+ else
+ return 0;
+}
+
+
+
+ /* copied from Geometry.c - todo - move to arithb.c or some other generic place we can reuse */
+#define SIDE_OF_LINE(pa,pb,pp) ((pa[0]-pp[0])*(pb[1]-pp[1]))-((pb[0]-pp[0])*(pa[1]-pp[1]))
+#define POINT_IN_TRI(p0,p1,p2,p3) ((SIDE_OF_LINE(p1,p2,p0)>=0) && (SIDE_OF_LINE(p2,p3,p0)>=0) && (SIDE_OF_LINE(p3,p1,p0)>=0))
+
+/**
+ *
+ * @param min
+ * @param max
+ * @param vec
+ */
void MinMax3(float *min, float *max, float *vec)
{
if(min[0]>vec[0]) min[0]= vec[0];
@@ -2225,7 +2611,53 @@ void InterpWeightsQ3Dfl(float *v1, float *v2, float *v3, float *v4, float *co, f
else
BarycentricWeights(v1, v2, v3, co, n, w);
}
-}
+}
+
+/* Mean value weights - smooth interpolation weights for polygons with
+ * more than 3 vertices */
+static float MeanValueHalfTan(float *v1, float *v2, float *v3)
+{
+ float d2[3], d3[3], cross[3], area, dot, len;
+
+ VecSubf(d2, v2, v1);
+ VecSubf(d3, v3, v1);
+ Crossf(cross, d2, d3);
+
+ area= VecLength(cross);
+ dot= Inpf(d2, d3);
+ len= VecLength(d2)*VecLength(d3);
+
+ if(area == 0.0f)
+ return 0.0f;
+ else
+ return (len - dot)/area;
+}
+
+void MeanValueWeights(float v[][3], int n, float *co, float *w)
+{
+ float totweight, t1, t2, len, *vmid, *vprev, *vnext;
+ int i;
+
+ totweight= 0.0f;
+
+ for(i=0; i<n; i++) {
+ vmid= v[i];
+ vprev= (i == 0)? v[n-1]: v[i-1];
+ vnext= (i == n-1)? v[0]: v[i+1];
+
+ t1= MeanValueHalfTan(co, vprev, vmid);
+ t2= MeanValueHalfTan(co, vmid, vnext);
+
+ len= VecLenf(co, vmid);
+ w[i]= (t1+t2)/len;
+ totweight += w[i];
+ }
+
+ if(totweight != 0.0f)
+ for(i=0; i<n; i++)
+ w[i] /= totweight;
+}
+
/* ************ EULER *************** */
@@ -2391,6 +2823,15 @@ void VecRotToMat3( float *vec, float phi, float mat[][3])
}
+void VecRotToMat4( float *vec, float phi, float mat[][4])
+{
+ float tmat[3][3];
+
+ VecRotToMat3(vec, phi, tmat);
+ Mat4One(mat);
+ Mat4CpyMat3(mat, tmat);
+}
+
void VecRotToQuat( float *vec, float phi, float *quat)
{
/* rotation of phi radials around vec */
@@ -2399,7 +2840,7 @@ void VecRotToQuat( float *vec, float phi, float *quat)
quat[1]= vec[0];
quat[2]= vec[1];
quat[3]= vec[2];
-
+
if( Normalize(quat+1) == 0.0) {
QuatOne(quat);
}
@@ -2427,6 +2868,22 @@ float VecAngle3(float *v1, float *v2, float *v3)
return NormalizedVecAngle2(vec1, vec2) * 180.0/M_PI;
}
+float VecAngle3_2D(float *v1, float *v2, float *v3)
+{
+ float vec1[2], vec2[2];
+
+ vec1[0] = v2[0]-v1[0];
+ vec1[1] = v2[1]-v1[1];
+
+ vec2[0] = v2[0]-v3[0];
+ vec2[1] = v2[1]-v3[1];
+
+ Normalize2(vec1);
+ Normalize2(vec2);
+
+ return NormalizedVecAngle2_2D(vec1, vec2) * 180.0/M_PI;
+}
+
/* Return the shortest angle in degrees between the 2 vectors */
float VecAngle2(float *v1, float *v2)
{
@@ -2456,6 +2913,21 @@ float NormalizedVecAngle2(float *v1, float *v2)
return 2.0f*saasin(VecLenf(v2, v1)/2.0);
}
+float NormalizedVecAngle2_2D(float *v1, float *v2)
+{
+ /* this is the same as acos(Inpf(v1, v2)), but more accurate */
+ if (Inp2f(v1, v2) < 0.0f) {
+ float vec[2];
+
+ vec[0]= -v2[0];
+ vec[1]= -v2[1];
+
+ return (float)M_PI - 2.0f*saasin(Vec2Lenf(vec, v1)/2.0f);
+ }
+ else
+ return 2.0f*saasin(Vec2Lenf(v2, v1)/2.0);
+}
+
void euler_rot(float *beul, float ang, char axis)
{
float eul[3], mat1[3][3], mat2[3][3], totmat[3][3];
@@ -2577,32 +3049,48 @@ void SizeToMat3( float *size, float mat[][3])
mat[2][0]= 0.0;
}
-void Mat3ToSize( float mat[][3], float *size)
+void SizeToMat4( float *size, float mat[][4])
{
- float vec[3];
-
- VecCopyf(vec, mat[0]);
- size[0]= Normalize(vec);
- VecCopyf(vec, mat[1]);
- size[1]= Normalize(vec);
- VecCopyf(vec, mat[2]);
- size[2]= Normalize(vec);
+ float tmat[3][3];
+
+ SizeToMat3(size, tmat);
+ Mat4One(mat);
+ Mat4CpyMat3(mat, tmat);
+}
+void Mat3ToSize( float mat[][3], float *size)
+{
+ size[0]= VecLength(mat[0]);
+ size[1]= VecLength(mat[1]);
+ size[2]= VecLength(mat[2]);
}
void Mat4ToSize( float mat[][4], float *size)
{
- float vec[3];
-
+ size[0]= VecLength(mat[0]);
+ size[1]= VecLength(mat[1]);
+ size[2]= VecLength(mat[2]);
+}
+
+/* this gets the average scale of a matrix, only use when your scaling
+ * data that has no idea of scale axis, examples are bone-envelope-radius
+ * and curve radius */
+float Mat3ToScalef(float mat[][3])
+{
+ /* unit length vector */
+ float unit_vec[3] = {0.577350269189626, 0.577350269189626, 0.577350269189626};
+ Mat3MulVecfl(mat, unit_vec);
+ return VecLength(unit_vec);
+}
- VecCopyf(vec, mat[0]);
- size[0]= Normalize(vec);
- VecCopyf(vec, mat[1]);
- size[1]= Normalize(vec);
- VecCopyf(vec, mat[2]);
- size[2]= Normalize(vec);
+float Mat4ToScalef(float mat[][4])
+{
+ float tmat[3][3];
+ Mat3CpyMat4(tmat, mat);
+ return Mat3ToScalef(tmat);
}
+
/* ************* SPECIALS ******************* */
void triatoquat( float *v1, float *v2, float *v3, float *quat)
@@ -2668,6 +3156,11 @@ float Vec2Lenf(float *v1, float *v2)
return (float)sqrt(x*x+y*y);
}
+float Vec2Length(float *v)
+{
+ return (float)sqrt(v[0]*v[0] + v[1]*v[1]);
+}
+
void Vec2Mulf(float *v1, float f)
{
v1[0]*= f;
@@ -2947,6 +3440,8 @@ void tubemap(float x, float y, float z, float *u, float *v)
len= sqrt(x*x+y*y);
if(len>0) {
*u = (1.0 - (atan2(x/len,y/len) / M_PI)) / 2.0;
+ } else {
+ *v = *u = 0.0f; /* to avoid un-initialized variables */
}
}
@@ -2964,6 +3459,8 @@ void spheremap(float x, float y, float z, float *u, float *v)
z/=len;
*v = 1.0- saacos(z)/M_PI;
+ } else {
+ *v = *u = 0.0f; /* to avoid un-initialized variables */
}
}
@@ -3134,7 +3631,7 @@ void mul_v3_v3m4(float *v1, float *v2, float mat[][4])
test if the line starting at p1 ending at p2 intersects the triangle v0..v2
return non zero if it does
*/
-int LineIntersectsTriangle(float p1[3], float p2[3], float v0[3], float v1[3], float v2[3], float *lambda)
+int LineIntersectsTriangle(float p1[3], float p2[3], float v0[3], float v1[3], float v2[3], float *lambda, float *uv)
{
float p[3], s[3], d[3], e1[3], e2[3], q[3];
@@ -3160,15 +3657,318 @@ int LineIntersectsTriangle(float p1[3], float p2[3], float v0[3], float v1[3], f
v = f * Inpf(d, q);
if ((v < 0.0)||((u + v) > 1.0)) return 0;
+
+ if(uv) {
+ uv[0]= u;
+ uv[1]= v;
+ }
return 1;
}
+/* Adapted from the paper by Kasper Fauerby */
+/* "Improved Collision detection and Response" */
+int SweepingSphereIntersectsTriangleUV(float p1[3], float p2[3], float radius, float v0[3], float v1[3], float v2[3], float *lambda, float *ipoint)
+{
+ float e1[3], e2[3], e3[3], point[3], vel[3], /*dist[3],*/ nor[3], temp[3], bv[3];
+ float a, b, c, d, e, x, y, z, t, t0, t1, radius2=radius*radius;
+ float elen2,edotv,edotbv,nordotv,vel2;
+ int embedded_in_plane=0, found_by_sweep=0;
-/*
-find closest point to p on line through l1,l2
-and return lambda, where (0 <= lambda <= 1) when cp is in the line segement l1,l2
-*/
+ VecSubf(e1,v1,v0);
+ VecSubf(e2,v2,v0);
+ VecSubf(vel,p2,p1);
+
+/*---test plane of tri---*/
+ Crossf(nor,e1,e2);
+ Normalize(nor);
+ /* flip normal */
+ if(Inpf(nor,vel)>0.0f) VecMulf(nor,-1.0f);
+
+ a=Inpf(p1,nor)-Inpf(v0,nor);
+
+ nordotv=Inpf(nor,vel);
+
+ if ((nordotv > -0.000001) && (nordotv < 0.000001)) {
+ if(fabs(a)>=1.0f)
+ return 0;
+ else{
+ embedded_in_plane=1;
+ t0=0.0f;
+ t1=1.0f;
+ }
+ }
+ else{
+ t0=(radius-a)/nordotv;
+ t1=(-radius-a)/nordotv;
+ /* make t0<t1 */
+ if(t0>t1){b=t1; t1=t0; t0=b;}
+
+ if(t0>1.0f || t1<0.0f) return 0;
+
+ /* clamp to [0,1] */
+ t0=(t0<0.0f)?0.0f:((t0>1.0f)?1.0:t0);
+ t1=(t1<0.0f)?0.0f:((t1>1.0f)?1.0:t1);
+ }
+
+/*---test inside of tri---*/
+ if(embedded_in_plane==0){
+ /* plane intersection point */
+ VecCopyf(point,vel);
+ VecMulf(point,t0);
+ VecAddf(point,point,p1);
+ VecCopyf(temp,nor);
+ VecMulf(temp,radius);
+ VecSubf(point,point,temp);
+
+ /* is the point in the tri? */
+ a=Inpf(e1,e1);
+ b=Inpf(e1,e2);
+ c=Inpf(e2,e2);
+
+ VecSubf(temp,point,v0);
+ d=Inpf(temp,e1);
+ e=Inpf(temp,e2);
+
+ x=d*c-e*b;
+ y=e*a-d*b;
+ z=x+y-(a*c-b*b);
+
+ if(( ((unsigned int)z)& ~(((unsigned int)x)|((unsigned int)y)) ) & 0x80000000){
+ *lambda=t0;
+ VecCopyf(ipoint,point);
+ return 1;
+ }
+ }
+
+ *lambda=1.0f;
+/*---test points---*/
+ a=vel2=Inpf(vel,vel);
+
+ /*v0*/
+ VecSubf(temp,p1,v0);
+ b=2.0f*Inpf(vel,temp);
+ c=Inpf(temp,temp)-radius2;
+ d=b*b-4*a*c;
+
+ if(d>=0.0f){
+ if(d==0.0f)
+ t=-b/2*a;
+ else{
+ z=sqrt(d);
+ x=(-b-z)*0.5/a;
+ y=(-b+z)*0.5/a;
+ t=x<y?x:y;
+ }
+
+ if(t>0.0 && t < *lambda){
+ *lambda=t;
+ VecCopyf(ipoint,v0);
+ found_by_sweep=1;
+ }
+ }
+
+ /*v1*/
+ VecSubf(temp,p1,v1);
+ b=2.0f*Inpf(vel,temp);
+ c=Inpf(temp,temp)-radius2;
+ d=b*b-4*a*c;
+
+ if(d>=0.0f){
+ if(d==0.0f)
+ t=-b/2*a;
+ else{
+ z=sqrt(d);
+ x=(-b-z)*0.5/a;
+ y=(-b+z)*0.5/a;
+ t=x<y?x:y;
+ }
+
+ if(t>0.0 && t < *lambda){
+ *lambda=t;
+ VecCopyf(ipoint,v1);
+ found_by_sweep=1;
+ }
+ }
+ /*v2*/
+ VecSubf(temp,p1,v2);
+ b=2.0f*Inpf(vel,temp);
+ c=Inpf(temp,temp)-radius2;
+ d=b*b-4*a*c;
+
+ if(d>=0.0f){
+ if(d==0.0f)
+ t=-b/2*a;
+ else{
+ z=sqrt(d);
+ x=(-b-z)*0.5/a;
+ y=(-b+z)*0.5/a;
+ t=x<y?x:y;
+ }
+
+ if(t>0.0 && t < *lambda){
+ *lambda=t;
+ VecCopyf(ipoint,v2);
+ found_by_sweep=1;
+ }
+ }
+
+/*---test edges---*/
+ /*e1*/
+ VecSubf(bv,v0,p1);
+ elen2 = Inpf(e1,e1);
+ edotv = Inpf(e1,vel);
+ edotbv = Inpf(e1,bv);
+
+ a=elen2*(-Inpf(vel,vel))+edotv*edotv;
+ b=2.0f*(elen2*Inpf(vel,bv)-edotv*edotbv);
+ c=elen2*(radius2-Inpf(bv,bv))+edotbv*edotbv;
+ d=b*b-4*a*c;
+ if(d>=0.0f){
+ if(d==0.0f)
+ t=-b/2*a;
+ else{
+ z=sqrt(d);
+ x=(-b-z)*0.5/a;
+ y=(-b+z)*0.5/a;
+ t=x<y?x:y;
+ }
+
+ e=(edotv*t-edotbv)/elen2;
+
+ if((e>=0.0f) && (e<=1.0f)){
+ if(t>0.0 && t < *lambda){
+ *lambda=t;
+ VecCopyf(ipoint,e1);
+ VecMulf(ipoint,e);
+ VecAddf(ipoint,ipoint,v0);
+ found_by_sweep=1;
+ }
+ }
+ }
+
+ /*e2*/
+ /*bv is same*/
+ elen2 = Inpf(e2,e2);
+ edotv = Inpf(e2,vel);
+ edotbv = Inpf(e2,bv);
+
+ a=elen2*(-Inpf(vel,vel))+edotv*edotv;
+ b=2.0f*(elen2*Inpf(vel,bv)-edotv*edotbv);
+ c=elen2*(radius2-Inpf(bv,bv))+edotbv*edotbv;
+ d=b*b-4*a*c;
+ if(d>=0.0f){
+ if(d==0.0f)
+ t=-b/2*a;
+ else{
+ z=sqrt(d);
+ x=(-b-z)*0.5/a;
+ y=(-b+z)*0.5/a;
+ t=x<y?x:y;
+ }
+
+ e=(edotv*t-edotbv)/elen2;
+
+ if((e>=0.0f) && (e<=1.0f)){
+ if(t>0.0 && t < *lambda){
+ *lambda=t;
+ VecCopyf(ipoint,e2);
+ VecMulf(ipoint,e);
+ VecAddf(ipoint,ipoint,v0);
+ found_by_sweep=1;
+ }
+ }
+ }
+
+ /*e3*/
+ VecSubf(e3,v2,v1);
+ VecSubf(bv,v1,p1);
+ elen2 = Inpf(e3,e3);
+ edotv = Inpf(e3,vel);
+ edotbv = Inpf(e3,bv);
+
+ a=elen2*(-Inpf(vel,vel))+edotv*edotv;
+ b=2.0f*(elen2*Inpf(vel,bv)-edotv*edotbv);
+ c=elen2*(radius2-Inpf(bv,bv))+edotbv*edotbv;
+ d=b*b-4*a*c;
+ if(d>=0.0f){
+ if(d==0.0f)
+ t=-b/2*a;
+ else{
+ z=sqrt(d);
+ x=(-b-z)*0.5/a;
+ y=(-b+z)*0.5/a;
+ t=x<y?x:y;
+ }
+
+ e=(edotv*t-edotbv)/elen2;
+
+ if((e>=0.0f) && (e<=1.0f)){
+ if(t>0.0 && t < *lambda){
+ *lambda=t;
+ VecCopyf(ipoint,e3);
+ VecMulf(ipoint,e);
+ VecAddf(ipoint,ipoint,v1);
+ found_by_sweep=1;
+ }
+ }
+ }
+
+ return found_by_sweep;
+}
+int AxialLineIntersectsTriangle(int axis, float p1[3], float p2[3], float v0[3], float v1[3], float v2[3], float *lambda)
+{
+ float p[3], e1[3], e2[3];
+ float u, v, f;
+ int a0=axis, a1=(axis+1)%3, a2=(axis+2)%3;
+
+ //return LineIntersectsTriangle(p1,p2,v0,v1,v2,lambda);
+
+ ///* first a simple bounding box test */
+ //if(MIN3(v0[a1],v1[a1],v2[a1]) > p1[a1]) return 0;
+ //if(MIN3(v0[a2],v1[a2],v2[a2]) > p1[a2]) return 0;
+ //if(MAX3(v0[a1],v1[a1],v2[a1]) < p1[a1]) return 0;
+ //if(MAX3(v0[a2],v1[a2],v2[a2]) < p1[a2]) return 0;
+
+ ///* then a full intersection test */
+
+ VecSubf(e1,v1,v0);
+ VecSubf(e2,v2,v0);
+ VecSubf(p,v0,p1);
+
+ f= (e2[a1]*e1[a2]-e2[a2]*e1[a1]);
+ if ((f > -0.000001) && (f < 0.000001)) return 0;
+
+ v= (p[a2]*e1[a1]-p[a1]*e1[a2])/f;
+ if ((v < 0.0)||(v > 1.0)) return 0;
+
+ f= e1[a1];
+ if((f > -0.000001) && (f < 0.000001)){
+ f= e1[a2];
+ if((f > -0.000001) && (f < 0.000001)) return 0;
+ u= (-p[a2]-v*e2[a2])/f;
+ }
+ else
+ u= (-p[a1]-v*e2[a1])/f;
+
+ if ((u < 0.0)||((u + v) > 1.0)) return 0;
+
+ *lambda = (p[a0]+u*e1[a0]+v*e2[a0])/(p2[a0]-p1[a0]);
+
+ if ((*lambda < 0.0)||(*lambda > 1.0)) return 0;
+
+ return 1;
+}
+
+int AabbIntersectAabb(float min1[3], float max1[3], float min2[3], float max2[3])
+{
+ return (min1[0]<max2[0] && min1[1]<max2[1] && min1[2]<max2[2] &&
+ min2[0]<max1[0] && min2[1]<max1[1] && min2[2]<max1[2]);
+}
+
+/* find closest point to p on line through l1,l2 and return lambda,
+ * where (0 <= lambda <= 1) when cp is in the line segement l1,l2
+ */
float lambda_cp_line_ex(float p[3], float l1[3], float l2[3], float cp[3])
{
float h[3],u[3],lambda;
@@ -3180,6 +3980,7 @@ float lambda_cp_line_ex(float p[3], float l1[3], float l2[3], float cp[3])
cp[2] = l1[2] + u[2] * lambda;
return lambda;
}
+
/* little sister we only need to know lambda */
float lambda_cp_line(float p[3], float l1[3], float l2[3])
{
@@ -3189,7 +3990,156 @@ float lambda_cp_line(float p[3], float l1[3], float l2[3])
return(Inpf(u,h)/Inpf(u,u));
}
+/* Similar to LineIntersectsTriangleUV, except it operates on a quad and in 2d, assumes point is in quad */
+void PointInQuad2DUV(float v0[2], float v1[2], float v2[2], float v3[2], float pt[2], float *uv)
+{
+ float x0,y0, x1,y1, wtot, v2d[2], w1, w2;
+
+ /* used for paralelle lines */
+ float pt3d[3], l1[3], l2[3], pt_on_line[3];
+
+ /* compute 2 edges of the quad intersection point */
+ if (IsectLLPt2Df(v0[0],v0[1],v1[0],v1[1], v2[0],v2[1],v3[0],v3[1], &x0,&y0) == 1) {
+ /* the intersection point between the quad-edge intersection and the point in the quad we want the uv's for */
+ /* should never be paralle !! */
+ /*printf("\tnot paralelle 1\n");*/
+ IsectLLPt2Df(pt[0],pt[1],x0,y0, v0[0],v0[1],v3[0],v3[1], &x1,&y1);
+
+ /* Get the weights from the new intersection point, to each edge */
+ v2d[0] = x1-v0[0];
+ v2d[1] = y1-v0[1];
+ w1 = Vec2Length(v2d);
+
+ v2d[0] = x1-v3[0]; /* some but for the other vert */
+ v2d[1] = y1-v3[1];
+ w2 = Vec2Length(v2d);
+ wtot = w1+w2;
+ /*w1 = w1/wtot;*/
+ /*w2 = w2/wtot;*/
+ uv[0] = w1/wtot;
+ } else {
+ /* lines are paralelle, lambda_cp_line_ex is 3d grrr */
+ /*printf("\tparalelle1\n");*/
+ pt3d[0] = pt[0];
+ pt3d[1] = pt[1];
+ pt3d[2] = l1[2] = l2[2] = 0.0f;
+
+ l1[0] = v0[0]; l1[1] = v0[1];
+ l2[0] = v1[0]; l2[1] = v1[1];
+ lambda_cp_line_ex(pt3d, l1, l2, pt_on_line);
+ v2d[0] = pt[0]-pt_on_line[0]; /* same, for the other vert */
+ v2d[1] = pt[1]-pt_on_line[1];
+ w1 = Vec2Length(v2d);
+
+ l1[0] = v2[0]; l1[1] = v2[1];
+ l2[0] = v3[0]; l2[1] = v3[1];
+ lambda_cp_line_ex(pt3d, l1, l2, pt_on_line);
+ v2d[0] = pt[0]-pt_on_line[0]; /* same, for the other vert */
+ v2d[1] = pt[1]-pt_on_line[1];
+ w2 = Vec2Length(v2d);
+ wtot = w1+w2;
+ uv[0] = w1/wtot;
+ }
+
+ /* Same as above to calc the uv[1] value, alternate calculation */
+
+ if (IsectLLPt2Df(v0[0],v0[1],v3[0],v3[1], v1[0],v1[1],v2[0],v2[1], &x0,&y0) == 1) { /* was v0,v1 v2,v3 now v0,v3 v1,v2*/
+ /* never paralle if above was not */
+ /*printf("\tnot paralelle2\n");*/
+ IsectLLPt2Df(pt[0],pt[1],x0,y0, v0[0],v0[1],v1[0],v1[1], &x1,&y1);/* was v0,v3 now v0,v1*/
+
+ v2d[0] = x1-v0[0];
+ v2d[1] = y1-v0[1];
+ w1 = Vec2Length(v2d);
+
+ v2d[0] = x1-v1[0];
+ v2d[1] = y1-v1[1];
+ w2 = Vec2Length(v2d);
+ wtot = w1+w2;
+ uv[1] = w1/wtot;
+ } else {
+ /* lines are paralelle, lambda_cp_line_ex is 3d grrr */
+ /*printf("\tparalelle2\n");*/
+ pt3d[0] = pt[0];
+ pt3d[1] = pt[1];
+ pt3d[2] = l1[2] = l2[2] = 0.0f;
+
+
+ l1[0] = v0[0]; l1[1] = v0[1];
+ l2[0] = v3[0]; l2[1] = v3[1];
+ lambda_cp_line_ex(pt3d, l1, l2, pt_on_line);
+ v2d[0] = pt[0]-pt_on_line[0]; /* some but for the other vert */
+ v2d[1] = pt[1]-pt_on_line[1];
+ w1 = Vec2Length(v2d);
+
+ l1[0] = v1[0]; l1[1] = v1[1];
+ l2[0] = v2[0]; l2[1] = v2[1];
+ lambda_cp_line_ex(pt3d, l1, l2, pt_on_line);
+ v2d[0] = pt[0]-pt_on_line[0]; /* some but for the other vert */
+ v2d[1] = pt[1]-pt_on_line[1];
+ w2 = Vec2Length(v2d);
+ wtot = w1+w2;
+ uv[1] = w1/wtot;
+ }
+ /* may need to flip UV's here */
+}
+
+/* same as above but does tri's and quads, tri's are a bit of a hack */
+void PointInFace2DUV(int isquad, float v0[2], float v1[2], float v2[2], float v3[2], float pt[2], float *uv)
+{
+ if (isquad) {
+ PointInQuad2DUV(v0, v1, v2, v3, pt, uv);
+ }
+ else {
+ /* not for quads, use for our abuse of LineIntersectsTriangleUV */
+ float p1_3d[3], p2_3d[3], v0_3d[3], v1_3d[3], v2_3d[3], lambda;
+
+ p1_3d[0] = p2_3d[0] = uv[0];
+ p1_3d[1] = p2_3d[1] = uv[1];
+ p1_3d[2] = 1.0f;
+ p2_3d[2] = -1.0f;
+ v0_3d[2] = v1_3d[2] = v2_3d[2] = 0.0;
+
+ /* generate a new fuv, (this is possibly a non optimal solution,
+ * since we only need 2d calculation but use 3d func's)
+ *
+ * this method makes an imaginary triangle in 2d space using the UV's from the derived mesh face
+ * Then find new uv coords using the fuv and this face with LineIntersectsTriangleUV.
+ * This means the new values will be correct in relation to the derived meshes face.
+ */
+ Vec2Copyf(v0_3d, v0);
+ Vec2Copyf(v1_3d, v1);
+ Vec2Copyf(v2_3d, v2);
+
+ /* Doing this in 3D is not nice */
+ LineIntersectsTriangle(p1_3d, p2_3d, v0_3d, v1_3d, v2_3d, &lambda, uv);
+ }
+}
+
+/* (x1,v1)(t1=0)------(x2,v2)(t2=1), 0<t<1 --> (x,v)(t) */
+void VecfCubicInterpol(float *x1, float *v1, float *x2, float *v2, float t, float *x, float *v)
+{
+ float a[3],b[3];
+ float t2= t*t;
+ float t3= t2*t;
+ /* cubic interpolation */
+ a[0]= v1[0] + v2[0] + 2*(x1[0] - x2[0]);
+ a[1]= v1[1] + v2[1] + 2*(x1[1] - x2[1]);
+ a[2]= v1[2] + v2[2] + 2*(x1[2] - x2[2]);
+
+ b[0]= -2*v1[0] - v2[0] - 3*(x1[0] - x2[0]);
+ b[1]= -2*v1[1] - v2[1] - 3*(x1[1] - x2[1]);
+ b[2]= -2*v1[2] - v2[2] - 3*(x1[2] - x2[2]);
+
+ x[0]= a[0]*t3 + b[0]*t2 + v1[0]*t + x1[0];
+ x[1]= a[1]*t3 + b[1]*t2 + v1[1]*t + x1[1];
+ x[2]= a[2]*t3 + b[2]*t2 + v1[2]*t + x1[2];
+
+ v[0]= 3*a[0]*t2 + 2*b[0]*t + v1[0];
+ v[1]= 3*a[1]*t2 + 2*b[1]*t + v1[1];
+ v[2]= 3*a[2]*t2 + 2*b[2]*t + v1[2];
+}
int point_in_slice(float p[3], float v1[3], float l1[3], float l2[3])
{
@@ -3246,46 +4196,75 @@ int point_in_tri_prism(float p[3], float v1[3], float v2[3], float v3[3])
return 1;
}
+/* point closest to v1 on line v2-v3 in 3D */
+void PclosestVL3Dfl(float *closest, float *v1, float *v2, float *v3)
+{
+ float lambda, cp[3];
+
+ lambda= lambda_cp_line_ex(v1, v2, v3, cp);
+
+ if(lambda <= 0.0f)
+ VecCopyf(closest, v2);
+ else if(lambda >= 1.0f)
+ VecCopyf(closest, v3);
+ else
+ VecCopyf(closest, cp);
+}
+
+/* distance v1 to line-piece v2-v3 in 3D */
+float PdistVL3Dfl(float *v1, float *v2, float *v3)
+{
+ float closest[3];
+
+ PclosestVL3Dfl(closest, v1, v2, v3);
+
+ return VecLenf(closest, v1);
+}
+
/********************************************************/
/* make a 4x4 matrix out of 3 transform components */
+/* matrices are made in the order: scale * rot * loc */
void LocEulSizeToMat4(float mat[][4], float loc[3], float eul[3], float size[3])
{
- float tmat[3][3];
+ float rmat[3][3], smat[3][3], tmat[3][3];
- /* make base matrix */
- EulToMat3(eul, tmat);
-
- /* make new matrix */
+ /* initialise new matrix */
Mat4One(mat);
- mat[0][0] = tmat[0][0] * size[0];
- mat[0][1] = tmat[0][1] * size[1];
- mat[0][2] = tmat[0][2] * size[2];
-
- mat[1][0] = tmat[1][0] * size[0];
- mat[1][1] = tmat[1][1] * size[1];
- mat[1][2] = tmat[1][2] * size[2];
+ /* make rotation + scaling part */
+ EulToMat3(eul, rmat);
+ SizeToMat3(size, smat);
+ Mat3MulMat3(tmat, rmat, smat);
- mat[2][0] = tmat[2][0] * size[0];
- mat[2][1] = tmat[2][1] * size[1];
- mat[2][2] = tmat[2][2] * size[2];
+ /* copy rot/scale part to output matrix*/
+ Mat4CpyMat3(mat, tmat);
+ /* copy location to matrix */
mat[3][0] = loc[0];
mat[3][1] = loc[1];
mat[3][2] = loc[2];
}
/* make a 4x4 matrix out of 3 transform components */
+/* matrices are made in the order: scale * rot * loc */
void LocQuatSizeToMat4(float mat[][4], float loc[3], float quat[4], float size[3])
{
- float eul[3];
+ float rmat[3][3], smat[3][3], tmat[3][3];
- /* convert quaternion component to euler
- * NOTE: not as good as using quat directly. Todo for later.
- */
- QuatToEul(quat, eul);
+ /* initialise new matrix */
+ Mat4One(mat);
- /* make into matrix using exisiting code */
- LocEulSizeToMat4(mat, loc, eul, size);
+ /* make rotation + scaling part */
+ QuatToMat3(quat, rmat);
+ SizeToMat3(size, smat);
+ Mat3MulMat3(tmat, rmat, smat);
+
+ /* copy rot/scale part to output matrix*/
+ Mat4CpyMat3(mat, tmat);
+
+ /* copy location to matrix */
+ mat[3][0] = loc[0];
+ mat[3][1] = loc[1];
+ mat[3][2] = loc[2];
}
diff --git a/source/blender/blenlib/intern/bpath.c b/source/blender/blenlib/intern/bpath.c
new file mode 100644
index 00000000000..219ca424df8
--- /dev/null
+++ b/source/blender/blenlib/intern/bpath.c
@@ -0,0 +1,556 @@
+/**
+ *
+ * ***** 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): Campbell barton
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "BLI_bpath.h"
+#include "BKE_global.h"
+#include "DNA_ID.h" /* Library */
+#include "DNA_vfont_types.h"
+#include "DNA_image_types.h"
+#include "DNA_sound_types.h"
+#include "DNA_scene_types.h" /* to get the current frame */
+#include <stdlib.h>
+#include <string.h>
+
+#include "BKE_main.h" /* so we can access G.main->*.first */
+#include "BKE_image.h" /* so we can check the image's type */
+
+#include "blendef.h"
+#include "BKE_utildefines.h"
+
+/* for writing to a textblock */
+#include "BKE_text.h"
+#include "BLI_blenlib.h"
+#include "DNA_text_types.h"
+
+/* path/file handeling stuff */
+#ifndef WIN32
+ #include <dirent.h>
+ #include <unistd.h>
+#else
+ #include "BLI_winstuff.h"
+ #include <io.h>
+#endif
+
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+
+#define FILE_MAX 240
+
+
+/* TODO - BPATH_PLUGIN, BPATH_SEQ */
+enum BPathTypes {
+ BPATH_IMAGE = 0,
+ BPATH_SOUND,
+ BPATH_FONT,
+ BPATH_LIB,
+
+ BPATH_DONE
+};
+
+
+void BLI_bpathIterator_init( struct BPathIterator *bpi ) {
+ bpi->type = BPATH_IMAGE;
+ bpi->data = NULL;
+ BLI_bpathIterator_step(bpi);
+}
+
+char* BLI_bpathIterator_getPath( struct BPathIterator *bpi) {
+ return bpi->path;
+}
+void BLI_bpathIterator_copyPathExpanded( struct BPathIterator *bpi, char *path_expanded) {
+ char *filepath, *libpath;
+
+ filepath = BLI_bpathIterator_getPath(bpi);
+ libpath = BLI_bpathIterator_getLib(bpi);
+
+ BLI_strncpy(path_expanded, filepath, FILE_MAXDIR*2);
+
+ if (libpath) { /* check the files location relative to its library path */
+ BLI_convertstringcode(path_expanded, libpath, G.scene->r.cfra);
+ } else { /* local data, use the blend files path */
+ BLI_convertstringcode(path_expanded, G.sce, G.scene->r.cfra);
+ }
+}
+char* BLI_bpathIterator_getLib( struct BPathIterator *bpi) {
+ return bpi->lib;
+}
+char* BLI_bpathIterator_getName( struct BPathIterator *bpi) {
+ return bpi->name;
+}
+int BLI_bpathIterator_getType( struct BPathIterator *bpi) {
+ return bpi->type;
+}
+int BLI_bpathIterator_getPathMaxLen( struct BPathIterator *bpi) {
+ return bpi->len;
+}
+
+/* gets the first or the next image that has a path - not a viewer node or generated image */
+static struct Image *ima_getpath__internal(struct Image *ima, int step_next) {
+ if (ima==NULL)
+ return NULL;
+
+ if (step_next)
+ ima = ima->id.next;
+
+ while (ima) {
+ if (ima->packedfile==NULL && ELEM3(ima->source, IMA_SRC_FILE, IMA_SRC_MOVIE, IMA_SRC_SEQUENCE))
+ break;
+ /* image is not a image with a path, skip it */
+ ima = ima->id.next;
+ }
+ return ima;
+}
+
+static struct VFont *vf_getpath__internal(struct VFont *vf, int step_next) {
+ if (vf==NULL)
+ return NULL;
+
+ if (step_next)
+ vf = vf->id.next;
+
+ while (vf) {
+ if (vf->packedfile==NULL && BLI_streq(vf->name, "<builtin>")==0) {
+ break;
+ }
+
+ /* font with no path, skip it */
+ vf = vf->id.next;
+ }
+ return vf;
+}
+
+static struct bSound *snd_getpath__internal(struct bSound *snd, int step_next) {
+ if (snd==NULL)
+ return NULL;
+
+ if (step_next)
+ snd = snd->id.next;
+
+ while (snd) {
+ if (snd->packedfile==NULL) {
+ break;
+ }
+
+ /* font with no path, skip it */
+ snd = snd->id.next;
+ }
+ return snd;
+}
+
+void BLI_bpathIterator_step( struct BPathIterator *bpi) {
+ while (bpi->type != BPATH_DONE) {
+
+ if ((bpi->type) == BPATH_IMAGE) {
+ /*if (bpi->data) bpi->data = ((ID *)bpi->data)->next;*/
+ if (bpi->data) bpi->data = ima_getpath__internal( (Image *)bpi->data, 1 ); /* must skip images that have no path */
+ else bpi->data = ima_getpath__internal(G.main->image.first, 0);
+
+ if (bpi->data) {
+ /* get the path info from this datatype */
+ Image *ima = (Image *)bpi->data;
+
+ bpi->lib = ima->id.lib ? ima->id.lib->filename : NULL;
+ bpi->path = ima->name;
+ bpi->name = ima->id.name+2;
+ bpi->len = sizeof(ima->name);
+
+ /* we are done, advancing to the next item, this type worked fine */
+ break;
+
+ } else {
+ bpi->type+=1; /* advance to the next type */
+ }
+
+
+ } else if ((bpi->type) == BPATH_SOUND) {
+ if (bpi->data) bpi->data = snd_getpath__internal( (bSound *)bpi->data, 1 ); /* must skip images that have no path */
+ else bpi->data = snd_getpath__internal(G.main->sound.first, 0);
+
+ if (bpi->data) {
+ /* get the path info from this datatype */
+ bSound *snd = (bSound *)bpi->data;
+
+ bpi->lib = snd->id.lib ? snd->id.lib->filename : NULL;
+ bpi->path = snd->sample->name;
+ bpi->name = snd->id.name+2;
+ bpi->len = sizeof(snd->sample->name);
+
+ /* we are done, advancing to the next item, this type worked fine */
+ break;
+ } else {
+ bpi->type+=1; /* advance to the next type */
+ }
+
+
+ } else if ((bpi->type) == BPATH_FONT) {
+
+ if (bpi->data) bpi->data = vf_getpath__internal( (VFont *)bpi->data, 1 );
+ else bpi->data = vf_getpath__internal( G.main->vfont.first, 0 );
+
+ if (bpi->data) {
+ /* get the path info from this datatype */
+ VFont *vf = (VFont *)bpi->data;
+
+ bpi->lib = vf->id.lib ? vf->id.lib->filename : NULL;
+ bpi->path = vf->name;
+ bpi->name = vf->id.name+2;
+ bpi->len = sizeof(vf->name);
+
+ /* we are done, advancing to the next item, this type worked fine */
+ break;
+ } else {
+ bpi->type+=1; /* advance to the next type */
+ }
+
+
+ } else if ((bpi->type) == BPATH_LIB) {
+
+ if (bpi->data) bpi->data = ((ID *)bpi->data)->next;
+ else bpi->data = G.main->library.first;
+
+ if (bpi->data) {
+ /* get the path info from this datatype */
+ Library *lib = (Library *)bpi->data;
+
+ bpi->lib = NULL;
+ bpi->path = lib->name;
+ bpi->name = NULL;
+ bpi->len = sizeof(lib->name);
+
+ /* we are done, advancing to the next item, this type worked fine */
+ break;
+ } else {
+ bpi->type+=1; /* advance to the next type */
+ }
+ }
+ }
+}
+
+int BLI_bpathIterator_isDone( struct BPathIterator *bpi) {
+ return bpi->type==BPATH_DONE;
+}
+
+/* include the path argument */
+static void bpathToText(Text *btxt, struct BPathIterator *bpi)
+{
+ char *name;
+ char path_expanded[FILE_MAXDIR*2];
+
+ switch(BLI_bpathIterator_getType(bpi)) {
+ case BPATH_IMAGE:
+ txt_insert_buf( btxt, "Image \"" );
+ break;
+ case BPATH_SOUND:
+ txt_insert_buf( btxt, "Sound \"" );
+ break;
+ case BPATH_FONT:
+ txt_insert_buf( btxt, "Font \"" );
+ break;
+ case BPATH_LIB:
+ txt_insert_buf( btxt, "Library \"" );
+ break;
+ default:
+ txt_insert_buf( btxt, "Unknown \"" );
+ break;
+ }
+
+ name = BLI_bpathIterator_getName(bpi);
+
+ if (name) {
+ txt_insert_buf( btxt, name );
+ }
+ txt_insert_buf( btxt, "\" " );
+
+ BLI_bpathIterator_copyPathExpanded(bpi, path_expanded);
+
+ txt_insert_buf( btxt, path_expanded );
+ txt_insert_buf( btxt, "\n" );
+ txt_move_eof( btxt, 0 );
+}
+
+/* high level function */
+void checkMissingFiles( char *txtname ) {
+ Text *btxt = NULL;
+ struct BPathIterator bpi;
+
+ /* be sure there is low chance of the path being too short */
+ char filepath_expanded[FILE_MAXDIR*2];
+ char *filepath, *libpath;
+ int files_missing = 0;
+
+ BLI_bpathIterator_init(&bpi);
+ while (!BLI_bpathIterator_isDone(&bpi)) {
+ filepath = BLI_bpathIterator_getPath(&bpi);
+ libpath = BLI_bpathIterator_getLib(&bpi);
+
+ BLI_bpathIterator_copyPathExpanded( &bpi, filepath_expanded );
+
+ if (!BLI_exists(filepath_expanded)) {
+ if (!btxt) {
+ btxt = add_empty_text( "missing_files.log" );
+ if (txtname) {
+ BLI_strncpy(txtname, btxt->id.name+2, 24);
+ }
+ }
+ bpathToText(btxt, &bpi);
+ files_missing = 1;
+ }
+ BLI_bpathIterator_step(&bpi);
+ }
+}
+
+/* dont log any errors at the moment, should probably do this */
+void makeFilesRelative(char *txtname, int *tot, int *changed, int *failed, int *linked) {
+ struct BPathIterator bpi;
+ char *filepath, *libpath;
+
+ /* be sure there is low chance of the path being too short */
+ char filepath_relative[(FILE_MAXDIR * 2) + FILE_MAXFILE];
+
+ Text *btxt = NULL;
+
+ *tot = *changed = *failed = *linked = 0;
+
+ BLI_bpathIterator_init(&bpi);
+ while (!BLI_bpathIterator_isDone(&bpi)) {
+ filepath = BLI_bpathIterator_getPath(&bpi);
+ libpath = BLI_bpathIterator_getLib(&bpi);
+
+ if(strncmp(filepath, "//", 2)) {
+ if (libpath) { /* cant make relative if we are library - TODO, LOG THIS */
+ (*linked)++;
+ } else { /* local data, use the blend files path */
+ BLI_strncpy(filepath_relative, filepath, sizeof(filepath_relative));
+ /* Important BLI_cleanup_dir runs before the path is made relative
+ * because it wont work for paths that start with "//../" */
+ BLI_cleanup_file(G.sce, filepath_relative); /* fix any /foo/../foo/ */
+ BLI_makestringcode(G.sce, filepath_relative);
+ /* be safe and check the length */
+ if (BLI_bpathIterator_getPathMaxLen(&bpi) <= strlen(filepath_relative)) {
+ if (!btxt) {
+ btxt = add_empty_text( "missing_no_rel.log" );
+ if (txtname) {
+ BLI_strncpy(txtname, btxt->id.name+2, 24);
+ }
+ }
+ bpathToText(btxt, &bpi);
+ (*failed)++;
+ } else {
+ if(strncmp(filepath_relative, "//", 2)==0) {
+ strcpy(filepath, filepath_relative);
+ (*changed)++;
+ } else {
+ if (!btxt) {
+ btxt = add_empty_text( "missing_no_rel.log" );
+ if (txtname) {
+ BLI_strncpy(txtname, btxt->id.name+2, 24);
+ }
+ }
+ bpathToText(btxt, &bpi);
+ (*failed)++;
+ }
+ }
+ }
+ }
+ BLI_bpathIterator_step(&bpi);
+ (*tot)++;
+ }
+}
+
+/* dont log any errors at the moment, should probably do this -
+ * Verry similar to makeFilesRelative - keep in sync! */
+void makeFilesAbsolute(char *txtname, int *tot, int *changed, int *failed, int *linked) {
+ struct BPathIterator bpi;
+ char *filepath, *libpath;
+
+ /* be sure there is low chance of the path being too short */
+ char filepath_absolute[(FILE_MAXDIR * 2) + FILE_MAXFILE];
+
+ Text *btxt = NULL;
+
+ *tot = *changed = *failed = *linked = 0;
+
+ BLI_bpathIterator_init(&bpi);
+ while (!BLI_bpathIterator_isDone(&bpi)) {
+ filepath = BLI_bpathIterator_getPath(&bpi);
+ libpath = BLI_bpathIterator_getLib(&bpi);
+
+ if(strncmp(filepath, "//", 2)==0) {
+ if (libpath) { /* cant make absolute if we are library - TODO, LOG THIS */
+ (*linked)++;
+ } else { /* get the expanded path and check it is relative or too long */
+ BLI_bpathIterator_copyPathExpanded( &bpi, filepath_absolute );
+ BLI_cleanup_file(G.sce, filepath_absolute); /* fix any /foo/../foo/ */
+ /* to be safe, check the length */
+ if (BLI_bpathIterator_getPathMaxLen(&bpi) <= strlen(filepath_absolute)) {
+ if (!btxt) {
+ btxt = add_empty_text( "missing_no_abs.log" );
+ if (txtname) {
+ BLI_strncpy(txtname, btxt->id.name+2, 24);
+ }
+ }
+ bpathToText(btxt, &bpi);
+ (*failed)++;
+ } else {
+ if(strncmp(filepath_absolute, "//", 2)) {
+ strcpy(filepath, filepath_absolute);
+ (*changed)++;
+ } else {
+ if (!btxt) {
+ btxt = add_empty_text( "missing_no_abs.log" );
+ if (txtname) {
+ BLI_strncpy(txtname, btxt->id.name+2, 24);
+ }
+ }
+ bpathToText(btxt, &bpi);
+ (*failed)++;
+ }
+ }
+ }
+ }
+ BLI_bpathIterator_step(&bpi);
+ (*tot)++;
+ }
+}
+
+
+/* find this file recursively, use the biggest file so thumbnails dont get used by mistake
+ - dir: subdir to search
+ - filename: set this filename
+ - filesize: filesize for the file
+*/
+#define MAX_RECUR 16
+static int findFileRecursive(char *filename_new, const char *dirname, const char *filename, int *filesize, int *recur_depth)
+{
+ /* file searching stuff */
+ DIR *dir;
+ struct dirent *de;
+ struct stat status;
+ char path[FILE_MAX];
+ int size;
+
+ dir = opendir(dirname);
+
+ if (dir==0)
+ return 0;
+
+ if (*filesize == -1)
+ *filesize = 0; /* dir opened fine */
+
+ while ((de = readdir(dir)) != NULL) {
+
+ if (strncmp(".", de->d_name, 2)==0 || strncmp("..", de->d_name, 3)==0)
+ continue;
+
+ BLI_join_dirfile(path, dirname, de->d_name);
+
+ if (stat(path, &status) != 0)
+ continue; /* cant stat, dont bother with this file, could print debug info here */
+
+ if (S_ISREG(status.st_mode)) { /* is file */
+ if (strncmp(filename, de->d_name, FILE_MAX)==0) { /* name matches */
+ /* open the file to read its size */
+ size = BLI_filepathsize(path);
+ if ((size > 0) && (size > *filesize)) { /* find the biggest file */
+ *filesize = size;
+ BLI_strncpy(filename_new, path, FILE_MAX);
+ }
+ }
+ } else if (S_ISDIR(status.st_mode)) { /* is subdir */
+ if (*recur_depth <= MAX_RECUR) {
+ (*recur_depth)++;
+ findFileRecursive(filename_new, path, filename, filesize, recur_depth);
+ (*recur_depth)--;
+ }
+ }
+ }
+ closedir(dir);
+ return 1;
+}
+
+/* high level function - call from fileselector */
+void findMissingFiles(char *str) {
+ struct BPathIterator bpi;
+
+ /* be sure there is low chance of the path being too short */
+ char filepath_expanded[FILE_MAXDIR*2];
+ char *filepath, *libpath;
+ int filesize, recur_depth;
+
+ char dirname[FILE_MAX], filename[FILE_MAX], filename_new[FILE_MAX], dummyname[FILE_MAX];
+
+ BLI_split_dirfile(str, dirname, dummyname);
+
+ BLI_bpathIterator_init(&bpi);
+
+ while (!BLI_bpathIterator_isDone(&bpi)) {
+ filepath = BLI_bpathIterator_getPath(&bpi);
+ libpath = BLI_bpathIterator_getLib(&bpi);
+
+ if (libpath==NULL) {
+
+ BLI_bpathIterator_copyPathExpanded( &bpi, filepath_expanded );
+
+ if (!BLI_exists(filepath_expanded)) {
+ /* can the dir be opened? */
+ filesize = -1;
+ recur_depth = 0;
+ BLI_split_dirfile(filepath, dummyname, filename); /* the file to find */
+
+ findFileRecursive(filename_new, dirname, filename, &filesize, &recur_depth);
+ if (filesize == -1) { /* could not open dir */
+ printf("Could not open dir \"%s\"\n", dirname);
+ return;
+ }
+
+ if (filesize > 0) {
+
+ if (BLI_bpathIterator_getPathMaxLen( &bpi ) < strlen(filename_new)) {
+ printf("cannot set path \"%s\" too long!", filename_new);
+ } else {
+ /* copy the found path into the old one */
+ if (G.relbase_valid)
+ BLI_makestringcode(G.sce, filename_new);
+
+ strcpy( BLI_bpathIterator_getPath( &bpi ), filename_new );
+ }
+ }
+ }
+ }
+ BLI_bpathIterator_step(&bpi);
+ }
+}
diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c
index fcea30982bd..e5b11412aa1 100644
--- a/source/blender/blenlib/intern/fileops.c
+++ b/source/blender/blenlib/intern/fileops.c
@@ -79,7 +79,7 @@ char *first_slash(char *string) {
else return fbslash;
}
-char *BLI_last_slash(char *string) {
+char *BLI_last_slash(const char *string) {
char *lfslash, *lbslash;
lfslash= strrchr(string, '/');
@@ -92,6 +92,39 @@ char *BLI_last_slash(char *string) {
else return lfslash;
}
+/* adds a slash if there isnt one there alredy */
+void BLI_add_slash(char *string) {
+ int len = strlen(string);
+#ifdef WIN32
+ if (string[len-1]!='\\') {
+ string[len] = '\\';
+ string[len+1] = '\0';
+ }
+#else
+ if (string[len-1]!='/') {
+ string[len] = '/';
+ string[len+1] = '\0';
+ }
+#endif
+}
+
+/* removes a slash if there is one */
+void BLI_del_slash(char *string) {
+ int len = strlen(string);
+ while (len) {
+#ifdef WIN32
+ if (string[len-1]=='\\') {
+#else
+ if (string[len-1]=='/') {
+#endif
+ string[len-1] = '\0';
+ len--;
+ } else {
+ break;
+ }
+ }
+}
+
/* gzip the file in from and write it to "to".
return -1 if zlib fails, -2 if the originating file does not exist
note: will remove the "from" file
@@ -140,6 +173,23 @@ int BLI_is_writable(char *filename)
}
}
+int BLI_touch(const char *file)
+{
+ FILE *f = fopen(file,"r+b");
+ if (f != NULL) {
+ char c = getc(f);
+ rewind(f);
+ putc(c,f);
+ } else {
+ f = fopen(file,"wb");
+ }
+ if (f) {
+ fclose(f);
+ return 1;
+ }
+ return 0;
+}
+
#ifdef WIN32
static char str[MAXPATHLEN+12];
@@ -161,12 +211,6 @@ int BLI_delete(char *file, int dir, int recursive) {
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;
@@ -296,17 +340,6 @@ int BLI_delete(char *file, int dir, int recursive)
return -1;
}
-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);
diff --git a/source/blender/blenlib/intern/fnmatch.c b/source/blender/blenlib/intern/fnmatch.c
new file mode 100644
index 00000000000..54114ad3448
--- /dev/null
+++ b/source/blender/blenlib/intern/fnmatch.c
@@ -0,0 +1,250 @@
+/* Copyright (C) 1991, 1992, 1993, 1996, 1997 Free Software Foundation, Inc.
+
+ 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, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software Foundation,
+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
+#ifdef WIN32
+
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+/* Enable GNU extensions in fnmatch.h. */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE 1
+#endif
+
+#include <errno.h>
+#include <BLI_fnmatch.h>
+#include <ctype.h>
+
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+ actually compiling the library itself. This code is part of the GNU C
+ Library, but also included in many other GNU distributions. Compiling
+ and linking in this code is a waste when using the GNU C library
+ (especially if it is a shared library). Rather than having every GNU
+ program understand `configure --with-gnu-libc' and omit the object files,
+ it is simpler to just do this in the source for each such file. */
+
+#if defined _LIBC || !defined __GNU_LIBRARY__
+
+
+# if defined STDC_HEADERS || !defined isascii
+# define ISASCII(c) 1
+# else
+# define ISASCII(c) isascii(c)
+# endif
+
+# define ISUPPER(c) (ISASCII (c) && isupper (c))
+
+
+# ifndef errno
+extern int errno;
+# endif
+
+/* Match STRING against the filename pattern PATTERN, returning zero if
+ it matches, nonzero if not. */
+int
+fnmatch (const char *pattern, const char *string, int flags)
+{
+ register const char *p = pattern, *n = string;
+ register char c;
+
+/* Note that this evaluates C many times. */
+# define FOLD(c) ((flags & FNM_CASEFOLD) && ISUPPER (c) ? tolower (c) : (c))
+
+ while ((c = *p++) != '\0')
+ {
+ c = FOLD (c);
+
+ switch (c)
+ {
+ case '?':
+ if (*n == '\0')
+ return FNM_NOMATCH;
+ else if ((flags & FNM_FILE_NAME) && *n == '/')
+ return FNM_NOMATCH;
+ else if ((flags & FNM_PERIOD) && *n == '.' &&
+ (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+ return FNM_NOMATCH;
+ break;
+
+ case '\\':
+ if (!(flags & FNM_NOESCAPE))
+ {
+ c = *p++;
+ if (c == '\0')
+ /* Trailing \ loses. */
+ return FNM_NOMATCH;
+ c = FOLD (c);
+ }
+ if (FOLD (*n) != c)
+ return FNM_NOMATCH;
+ break;
+
+ case '*':
+ if ((flags & FNM_PERIOD) && *n == '.' &&
+ (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+ return FNM_NOMATCH;
+
+ for (c = *p++; c == '?' || c == '*'; c = *p++)
+ {
+ if ((flags & FNM_FILE_NAME) && *n == '/')
+ /* A slash does not match a wildcard under FNM_FILE_NAME. */
+ return FNM_NOMATCH;
+ else if (c == '?')
+ {
+ /* A ? needs to match one character. */
+ if (*n == '\0')
+ /* There isn't another character; no match. */
+ return FNM_NOMATCH;
+ else
+ /* One character of the string is consumed in matching
+ this ? wildcard, so *??? won't match if there are
+ less than three characters. */
+ ++n;
+ }
+ }
+
+ if (c == '\0')
+ return 0;
+
+ {
+ char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
+ c1 = FOLD (c1);
+ for (--p; *n != '\0'; ++n)
+ if ((c == '[' || FOLD (*n) == c1) &&
+ fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
+ return 0;
+ return FNM_NOMATCH;
+ }
+
+ case '[':
+ {
+ /* Nonzero if the sense of the character class is inverted. */
+ register int not;
+
+ if (*n == '\0')
+ return FNM_NOMATCH;
+
+ if ((flags & FNM_PERIOD) && *n == '.' &&
+ (n == string || ((flags & FNM_FILE_NAME) && n[-1] == '/')))
+ return FNM_NOMATCH;
+
+ not = (*p == '!' || *p == '^');
+ if (not)
+ ++p;
+
+ c = *p++;
+ for (;;)
+ {
+ register char cstart = c, cend = c;
+
+ if (!(flags & FNM_NOESCAPE) && c == '\\')
+ {
+ if (*p == '\0')
+ return FNM_NOMATCH;
+ cstart = cend = *p++;
+ }
+
+ cstart = cend = FOLD (cstart);
+
+ if (c == '\0')
+ /* [ (unterminated) loses. */
+ return FNM_NOMATCH;
+
+ c = *p++;
+ c = FOLD (c);
+
+ if ((flags & FNM_FILE_NAME) && c == '/')
+ /* [/] can never match. */
+ return FNM_NOMATCH;
+
+ if (c == '-' && *p != ']')
+ {
+ cend = *p++;
+ if (!(flags & FNM_NOESCAPE) && cend == '\\')
+ cend = *p++;
+ if (cend == '\0')
+ return FNM_NOMATCH;
+ cend = FOLD (cend);
+
+ c = *p++;
+ }
+
+ if (FOLD (*n) >= cstart && FOLD (*n) <= cend)
+ goto matched;
+
+ if (c == ']')
+ break;
+ }
+ if (!not)
+ return FNM_NOMATCH;
+ break;
+
+ matched:;
+ /* Skip the rest of the [...] that already matched. */
+ while (c != ']')
+ {
+ if (c == '\0')
+ /* [... (unterminated) loses. */
+ return FNM_NOMATCH;
+
+ c = *p++;
+ if (!(flags & FNM_NOESCAPE) && c == '\\')
+ {
+ if (*p == '\0')
+ return FNM_NOMATCH;
+ /* XXX 1003.2d11 is unclear if this is right. */
+ ++p;
+ }
+ }
+ if (not)
+ return FNM_NOMATCH;
+ }
+ break;
+
+ default:
+ if (c != FOLD (*n))
+ return FNM_NOMATCH;
+ }
+
+ ++n;
+ }
+
+ if (*n == '\0')
+ return 0;
+
+ if ((flags & FNM_LEADING_DIR) && *n == '/')
+ /* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
+ return 0;
+
+ return FNM_NOMATCH;
+
+# undef FOLD
+}
+
+#endif /* _LIBC or not __GNU_LIBRARY__. */
+
+#else
+
+static void BLI_FNMATCH_C_IS_EMPTY_FOR_UNIX(void)
+{
+ /*intentionally empty*/
+}
+
+#endif /* WIN32 */
+
+
diff --git a/source/blender/blenlib/intern/psfont.c b/source/blender/blenlib/intern/psfont.c
index 941bf4204a8..1fcb6653dc9 100644
--- a/source/blender/blenlib/intern/psfont.c
+++ b/source/blender/blenlib/intern/psfont.c
@@ -1949,7 +1949,7 @@ static VFontData *objfnt_to_vfontdata(objfnt *fnt)
chardesc *cd;
short *_data, *data;
int a, i, count, stop, ready, meet;
- short first[2], last[2];
+ short first[2]={0,0}, last[2]={0,0};
struct Nurb *nu;
struct BezTriple *bezt, *bez2;
float scale, dx, dy;
diff --git a/source/blender/blenlib/intern/rand.c b/source/blender/blenlib/intern/rand.c
index df01288aab8..71df0ede037 100644
--- a/source/blender/blenlib/intern/rand.c
+++ b/source/blender/blenlib/intern/rand.c
@@ -116,6 +116,14 @@ void rng_shuffleArray(RNG *rng, void *data, int elemSize, int numElems)
free(temp);
}
+void rng_skip(RNG *rng, int n)
+{
+ int i;
+
+ for(i=0; i<n; i++)
+ rng_getInt(rng);
+}
+
/***/
static RNG theBLI_rng = {0};
diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c
index a6b91bf489d..9d70d85939e 100644
--- a/source/blender/blenlib/intern/storage.c
+++ b/source/blender/blenlib/intern/storage.c
@@ -50,7 +50,9 @@
#include <time.h>
#include <sys/stat.h>
-#if !defined(linux) && (defined(__sgi) || defined(__sun__) || defined(__sun) || defined(__sparc) || defined(__sparc__))
+#if defined (__sun__) || defined (__sun)
+#include <sys/statvfs.h> /* Other modern unix os's should probably use this also */
+#elif !defined(linux) && (defined(__sgi) || defined(__sparc) || defined(__sparc__))
#include <sys/statfs.h>
#endif
@@ -179,13 +181,21 @@ double BLI_diskfree(char *dir)
return (double) (freec*bytesps*sectorspc);
#else
- struct statfs disk;
- char name[100],*slash;
-
+#if defined (__sun__) || defined (__sun)
+ struct statvfs disk;
+#else
+ struct statfs disk;
+#endif
+ char name[FILE_MAXDIR],*slash;
+ int len = strlen(dir);
+
+ if (len >= FILE_MAXDIR) /* path too long */
+ return -1;
+
strcpy(name,dir);
- if(strlen(name)){
+ if(len){
slash = strrchr(name,'/');
if (slash) slash[1] = 0;
} else strcpy(name,"/");
@@ -196,12 +206,12 @@ double BLI_diskfree(char *dir)
#ifdef __BeOS
return -1;
#endif
-#if !defined(linux) && (defined (__sgi) || defined (__sun__) || defined (__sun) || defined(__sparc) || defined(__sparc__))
- if (statfs(name, &disk, sizeof(struct statfs), 0)){
- /* printf("diskfree: Couldn't get information about %s.\n",dir); */
- return(-1);
- }
+#if defined (__sun__) || defined (__sun)
+ if (statvfs(name, &disk)) return(-1);
+#elif !defined(linux) && (defined (__sgi) || defined(__sparc) || defined(__sparc__))
+ /* WARNING - This may not be supported by geeneric unix os's - Campbell */
+ if (statfs(name, &disk, sizeof(struct statfs), 0)) return(-1);
#endif
return ( ((double) disk.f_bsize) * ((double) disk.f_bfree));
@@ -326,11 +336,11 @@ void BLI_adddirstrings()
char size[250];
static char * types[8] = {"---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx"};
int num, mode;
- int num1, num2, num3, num4;
+ off_t num1, num2, num3, num4, num5;
#ifdef WIN32
__int64 st_size;
#else
- long long st_size;
+ off_t st_size;
#endif
struct direntry * file;
@@ -392,7 +402,7 @@ void BLI_adddirstrings()
* will buy us some time until files get bigger than 4GB or until
* everyone starts using __USE_FILE_OFFSET64 or equivalent.
*/
- st_size= (unsigned int)files[num].s.st_size;
+ st_size= (off_t)files[num].s.st_size;
num1= st_size % 1000;
num2= st_size/1000;
@@ -401,11 +411,15 @@ void BLI_adddirstrings()
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);
+ num5= st_size/(1000000000000LL);
+ num5= num5 % 1000;
+
+ if(num5)
+ sprintf(files[num].size, "%1d %03d %03d %03d K", (int)num5, (int)num4, (int)num3, (int)num2);
+ else if(num4) sprintf(files[num].size, "%3d %03d %03d %03d", (int)num4, (int)num3, (int)num2, (int)num1);
+ else if(num3) sprintf(files[num].size, "%7d %03d %03d", (int)num3, (int)num2, (int)num1);
+ else if(num2) sprintf(files[num].size, "%11d %03d", (int)num2, (int)num1);
+ else if(num1) sprintf(files[num].size, "%15d", (int)num1);
else sprintf(files[num].size, "0");
strftime(datum, 32, "%d-%b-%y %H:%M", tm);
@@ -469,6 +483,17 @@ int BLI_filesize(int file)
return (buf.st_size);
}
+int BLI_filepathsize(const char *path)
+{
+ int size, file = open(path, O_BINARY|O_RDONLY);
+
+ if (file <= 0)
+ return -1;
+
+ size = BLI_filesize(file);
+ close(file);
+ return size;
+}
int BLI_exist(char *name)
diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c
index cb10185386a..f4a44b3a0db 100644
--- a/source/blender/blenlib/intern/threads.c
+++ b/source/blender/blenlib/intern/threads.c
@@ -38,6 +38,15 @@
#include "BLI_blenlib.h"
#include "BLI_threads.h"
+/* for checking system threads - BLI_system_thread_count */
+#ifdef WIN32
+#include "Windows.h"
+#elif defined(__APPLE__)
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#else
+#include <unistd.h>
+#endif
/* ********** basic thread control API ************
@@ -109,22 +118,26 @@ static void BLI_unlock_malloc_thread(void)
pthread_mutex_unlock(&_malloc_lock);
}
+/* tot = 0 only initializes malloc mutex in a safe way (see sequence.c)
+ problem otherwise: scene render will kill of the mutex!
+*/
+
void BLI_init_threads(ListBase *threadbase, void *(*do_thread)(void *), int tot)
{
int a;
- if(threadbase==NULL)
- return;
- threadbase->first= threadbase->last= NULL;
+ if(threadbase != NULL && tot > 0) {
+ threadbase->first= threadbase->last= NULL;
- if(tot>RE_MAX_THREAD) tot= RE_MAX_THREAD;
- else if(tot<1) tot= 1;
+ if(tot>RE_MAX_THREAD) tot= RE_MAX_THREAD;
+ else if(tot<1) tot= 1;
- for(a=0; a<tot; a++) {
- ThreadSlot *tslot= MEM_callocN(sizeof(ThreadSlot), "threadslot");
- BLI_addtail(threadbase, tslot);
- tslot->do_thread= do_thread;
- tslot->avail= 1;
+ for(a=0; a<tot; a++) {
+ ThreadSlot *tslot= MEM_callocN(sizeof(ThreadSlot), "threadslot");
+ BLI_addtail(threadbase, tslot);
+ tslot->do_thread= do_thread;
+ tslot->avail= 1;
+ }
}
MEM_set_lock_callback(BLI_lock_malloc_thread, BLI_unlock_malloc_thread);
@@ -190,12 +203,14 @@ void BLI_end_threads(ListBase *threadbase)
{
ThreadSlot *tslot;
- for(tslot= threadbase->first; tslot; tslot= tslot->next) {
- if(tslot->avail==0) {
- pthread_join(tslot->pthread, NULL);
+ if (threadbase) {
+ for(tslot= threadbase->first; tslot; tslot= tslot->next) {
+ if(tslot->avail==0) {
+ pthread_join(tslot->pthread, NULL);
+ }
}
+ BLI_freelistN(threadbase);
}
- BLI_freelistN(threadbase);
thread_levels--;
if(thread_levels==0)
@@ -218,4 +233,34 @@ void BLI_unlock_thread(int type)
pthread_mutex_unlock(&_custom1_lock);
}
+/* how many threads are native on this system? */
+int BLI_system_thread_count( void )
+{
+ int t;
+#ifdef WIN32
+ SYSTEM_INFO info;
+ GetSystemInfo(&info);
+ t = (int) info.dwNumberOfProcessors;
+#else
+# ifdef __APPLE__
+ int mib[2];
+ size_t len;
+
+ mib[0] = CTL_HW;
+ mib[1] = HW_NCPU;
+ len = sizeof(t);
+ sysctl(mib, 2, &t, &len, NULL, 0);
+# else
+ t = (int)sysconf(_SC_NPROCESSORS_ONLN);
+# endif
+#endif
+
+ if (t>RE_MAX_THREAD)
+ return RE_MAX_THREAD;
+ if (t<1)
+ return 1;
+
+ return t;
+}
+
/* eof */
diff --git a/source/blender/blenlib/intern/util.c b/source/blender/blenlib/intern/util.c
index cfce8e3dafa..51691499ba8 100644
--- a/source/blender/blenlib/intern/util.c
+++ b/source/blender/blenlib/intern/util.c
@@ -44,8 +44,10 @@
#include "MEM_guardedalloc.h"
-#include "BLI_blenlib.h"
#include "DNA_listBase.h"
+#include "DNA_userdef_types.h"
+
+#include "BLI_blenlib.h"
#include "BLI_storage.h"
#include "BLI_storage_types.h"
#include "BLI_dynamiclist.h"
@@ -84,37 +86,39 @@
#include <CoreFoundation/CoreFoundation.h>
#endif
+#ifdef __linux__
+#include "binreloc.h"
+#endif
+
/* local */
static int add_win32_extension(char *name);
/* implementation */
-/* Ripped this from blender.c
- */
+/* Ripped this from blender.c */
void addlisttolist(ListBase *list1, ListBase *list2)
{
+ if (list2->first==0) return;
- if(list2->first==0) return;
-
- if(list1->first==0) {
+ 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;
+ ((Link *)list1->last)->next= list2->first;
+ ((Link *)list2->first)->prev= list1->last;
list1->last= list2->last;
}
list2->first= list2->last= 0;
}
-int BLI_stringdec(char *string, char *kop, char *staart, unsigned short *numlen)
+int BLI_stringdec(char *string, char *kop, char *start, unsigned short *numlen)
{
unsigned short len, len2, nums = 0, nume = 0;
short i, found = 0;
- len2 = len = strlen( string);
+ len2 = len = strlen(string);
if (len > 6) {
if (BLI_strncasecmp(string + len - 6, ".blend", 6) == 0) len -= 6;
@@ -125,7 +129,6 @@ int BLI_stringdec(char *string, char *kop, char *staart, unsigned short *numlen)
if (BLI_strncasecmp(string + len - 9, ".blend.gz", 9) == 0) len -= 9;
}
-
if (len == len2) {
if (len > 4) {
/* handle .jf0 en .jf1 for jstreams */
@@ -143,7 +146,7 @@ int BLI_stringdec(char *string, char *kop, char *staart, unsigned short *numlen)
}
}
- for (i = len - 1; i >= 0; i--){
+ for (i = len - 1; i >= 0; i--) {
if (string[i] == '/') break;
if (isdigit(string[i])) {
if (found){
@@ -155,12 +158,12 @@ int BLI_stringdec(char *string, char *kop, char *staart, unsigned short *numlen)
found = 1;
}
}
- else{
+ else {
if (found) break;
}
}
if (found){
- if (staart) strcpy(staart,&string[nume+1]);
+ if (start) strcpy(start,&string[nume+1]);
if (kop) {
strcpy(kop,string);
kop[nums]=0;
@@ -168,7 +171,7 @@ int BLI_stringdec(char *string, char *kop, char *staart, unsigned short *numlen)
if (numlen) *numlen = nume-nums+1;
return ((int)atoi(&(string[nums])));
}
- if (staart) strcpy(staart, string + len);
+ if (start) strcpy(start, string + len);
if (kop) {
strncpy(kop, string, len);
kop[len] = 0;
@@ -178,7 +181,7 @@ 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_stringenc(char *string, char *kop, char *start, unsigned short numlen, int pic)
{
char numstr[10]="";
unsigned short len,i;
@@ -187,17 +190,17 @@ void BLI_stringenc(char *string, char *kop, char *staart, unsigned short numlen,
if (pic>0 || numlen==4) {
len= sprintf(numstr,"%d",pic);
-
+
for(i=len;i<numlen;i++){
strcat(string,"0");
}
strcat(string,numstr);
}
- strcat(string,staart);
+ strcat(string, start);
}
-void BLI_newname(char * name, int add)
+void BLI_newname(char *name, int add)
{
char head[128], tail[128];
int pic;
@@ -215,38 +218,111 @@ void BLI_newname(char * name, int add)
pic += add;
- if(digits==4 && pic<0) pic= 0;
+ if (digits==4 && pic<0) pic= 0;
BLI_stringenc(name, head, tail, digits, pic);
}
+/* little helper macro for BLI_uniquename */
+#ifndef GIVE_STRADDR
+ #define GIVE_STRADDR(data, offset) ( ((char *)data) + offset )
+#endif
+
+/* Generic function to set a unique name. It is only designed to be used in situations
+ * where the name is part of the struct, and also that the name is at most 128 chars long.
+ *
+ * For places where this is used, see constraint.c for example...
+ *
+ * name_offs: should be calculated using offsetof(structname, membername) macro from stddef.h
+ * len: maximum length of string (to prevent overflows, etc.)
+ * defname: the name that should be used by default if none is specified already
+ */
+void BLI_uniquename(ListBase *list, void *vlink, char defname[], short name_offs, short len)
+{
+ Link *link;
+ char tempname[128];
+ int number = 1, exists = 0;
+ char *dot;
+
+ /* Make sure length can be handled */
+ if ((len < 0) || (len > 128))
+ return;
+
+ /* See if we are given an empty string */
+ if (ELEM(NULL, vlink, defname))
+ return;
+
+ if (GIVE_STRADDR(vlink, name_offs) == '\0') {
+ /* give it default name first */
+ BLI_strncpy(GIVE_STRADDR(vlink, name_offs), defname, len);
+ }
+
+ /* See if we even need to do this */
+ if (list == NULL)
+ return;
+
+ for (link = list->first; link; link= link->next) {
+ if (link != vlink) {
+ if (!strcmp(GIVE_STRADDR(link, name_offs), GIVE_STRADDR(vlink, name_offs))) {
+ exists = 1;
+ break;
+ }
+ }
+ }
+ if (exists == 0)
+ return;
+
+ /* Strip off the suffix */
+ dot = strchr(GIVE_STRADDR(vlink, name_offs), '.');
+ if (dot)
+ *dot=0;
+
+ for (number = 1; number <= 999; number++) {
+ BLI_snprintf(tempname, 128, "%s.%03d", GIVE_STRADDR(vlink, name_offs), number);
+
+ exists = 0;
+ for (link= list->first; link; link= link->next) {
+ if (vlink != link) {
+ if (!strcmp(GIVE_STRADDR(link, name_offs), tempname)) {
+ exists = 1;
+ break;
+ }
+ }
+ }
+ if (exists == 0) {
+ BLI_strncpy(GIVE_STRADDR(vlink, name_offs), tempname, len);
+ return;
+ }
+ }
+}
+
void BLI_addhead(ListBase *listbase, void *vlink)
{
- struct Link *link= vlink;
+ Link *link= vlink;
- if (link == 0) return;
- if (listbase == 0) return;
+ if (link == NULL) return;
+ if (listbase == NULL) return;
link->next = listbase->first;
- link->prev = 0;
+ link->prev = NULL;
- if (listbase->first) ((struct Link *)listbase->first)->prev = link;
- if (listbase->last == 0) listbase->last = link;
+ if (listbase->first) ((Link *)listbase->first)->prev = link;
+ if (listbase->last == NULL) listbase->last = link;
listbase->first = link;
}
void BLI_addtail(ListBase *listbase, void *vlink)
{
- struct Link *link= vlink;
+ Link *link= vlink;
- if (link == 0) return;
- if (listbase == 0) return;
+ if (link == NULL) return;
+ if (listbase == NULL) return;
- link->next = 0;
+ link->next = NULL;
link->prev = listbase->last;
- if (listbase->last) ((struct Link *)listbase->last)->next = link;
+ if (listbase->last) ((Link *)listbase->last)->next = link;
if (listbase->first == 0) listbase->first = link;
listbase->last = link;
}
@@ -254,10 +330,10 @@ void BLI_addtail(ListBase *listbase, void *vlink)
void BLI_remlink(ListBase *listbase, void *vlink)
{
- struct Link *link= vlink;
+ Link *link= vlink;
- if (link == 0) return;
- if (listbase == 0) return;
+ if (link == NULL) return;
+ if (listbase == NULL) return;
if (link->next) link->next->prev = link->prev;
if (link->prev) link->prev->next = link->next;
@@ -269,10 +345,10 @@ void BLI_remlink(ListBase *listbase, void *vlink)
void BLI_freelinkN(ListBase *listbase, void *vlink)
{
- struct Link *link= vlink;
+ Link *link= vlink;
- if (link == 0) return;
- if (listbase == 0) return;
+ if (link == NULL) return;
+ if (listbase == NULL) return;
BLI_remlink(listbase,link);
MEM_freeN(link);
@@ -281,19 +357,23 @@ void BLI_freelinkN(ListBase *listbase, void *vlink)
void BLI_insertlink(ListBase *listbase, void *vprevlink, void *vnewlink)
{
- struct Link *prevlink= vprevlink, *newlink= vnewlink;
+ Link *prevlink= vprevlink;
+ Link *newlink= vnewlink;
/* newlink comes after prevlink */
-
- if (newlink == 0) return;
- if (listbase == 0) return;
-
- if(listbase->first==0) { /* empty list */
+ if (newlink == NULL) return;
+ if (listbase == NULL) return;
+
+ /* empty list */
+ if (listbase->first == NULL) {
+
listbase->first= newlink;
listbase->last= newlink;
return;
}
- if (prevlink== 0) { /* insert before first element */
+
+ /* insert before first element */
+ if (prevlink == NULL) {
newlink->next= listbase->first;
newlink->prev= 0;
newlink->next->prev= newlink;
@@ -301,96 +381,170 @@ void BLI_insertlink(ListBase *listbase, void *vprevlink, void *vnewlink)
return;
}
- if (listbase->last== prevlink) /* at end of list */
+ /* at end of list */
+ if (listbase->last== prevlink)
listbase->last = newlink;
newlink->next= prevlink->next;
prevlink->next= newlink;
- if(newlink->next) newlink->next->prev= newlink;
+ if (newlink->next) newlink->next->prev= newlink;
newlink->prev= prevlink;
}
-void BLI_insertlinkbefore(ListBase *listbase, void *vnextlink, void *vnewlink)
+/* This uses insertion sort, so NOT ok for large list */
+void BLI_sortlist(ListBase *listbase, int (*cmp)(void *, void *))
+{
+ Link *current = NULL;
+ Link *previous = NULL;
+ Link *next = NULL;
+
+ if (cmp == NULL) return;
+ if (listbase == NULL) return;
+
+ if (listbase->first != listbase->last)
+ {
+ for( previous = listbase->first, current = previous->next; current; current = next )
+ {
+ next = current->next;
+ previous = current->prev;
+
+ BLI_remlink(listbase, current);
+
+ while(previous && cmp(previous, current) == 1)
+ {
+ previous = previous->prev;
+ }
+
+ BLI_insertlinkafter(listbase, previous, current);
+ }
+ }
+}
+
+void BLI_insertlinkafter(ListBase *listbase, void *vprevlink, void *vnewlink)
{
- struct Link *nextlink= vnextlink, *newlink= vnewlink;
+ Link *prevlink= vprevlink;
+ Link *newlink= vnewlink;
/* newlink before nextlink */
+ if (newlink == NULL) return;
+ if (listbase == NULL) return;
- if (newlink == 0) return;
- if (listbase == 0) return;
+ /* empty list */
+ if (listbase->first == NULL) {
+ listbase->first= newlink;
+ listbase->last= newlink;
+ return;
+ }
+
+ /* insert at head of list */
+ if (prevlink == NULL) {
+ newlink->prev = NULL;
+ newlink->next = listbase->first;
+ ((Link *)listbase->first)->prev = newlink;
+ listbase->first = newlink;
+ return;
+ }
+
+ /* at end of list */
+ if (listbase->last == prevlink)
+ listbase->last = newlink;
+
+ newlink->next = prevlink->next;
+ newlink->prev = prevlink;
+ prevlink->next = newlink;
+ if (newlink->next) newlink->next->prev = newlink;
+}
- if(listbase->first==0) { /* empty list */
+void BLI_insertlinkbefore(ListBase *listbase, void *vnextlink, void *vnewlink)
+{
+ Link *nextlink= vnextlink;
+ Link *newlink= vnewlink;
+
+ /* newlink before nextlink */
+ if (newlink == NULL) return;
+ if (listbase == NULL) return;
+
+ /* empty list */
+ if (listbase->first == NULL) {
listbase->first= newlink;
listbase->last= newlink;
return;
}
- if (nextlink== 0) { /* insert at end of list */
+
+ /* insert at end of list */
+ if (nextlink == NULL) {
newlink->prev= listbase->last;
newlink->next= 0;
- ((struct Link *)listbase->last)->next= newlink;
+ ((Link *)listbase->last)->next= newlink;
listbase->last= newlink;
return;
}
- if (listbase->first== nextlink) /* at beginning of list */
+ /* at beginning of list */
+ if (listbase->first== nextlink)
listbase->first = newlink;
newlink->next= nextlink;
newlink->prev= nextlink->prev;
nextlink->prev= newlink;
- if(newlink->prev) newlink->prev->next= newlink;
+ if (newlink->prev) newlink->prev->next= newlink;
}
void BLI_freelist(ListBase *listbase)
{
- struct Link *link,*next;
+ Link *link, *next;
- if (listbase == 0) return;
+ if (listbase == NULL)
+ return;
+
link= listbase->first;
- while(link) {
+ while (link) {
next= link->next;
free(link);
link= next;
}
- listbase->first=0;
- listbase->last=0;
+
+ listbase->first= NULL;
+ listbase->last= NULL;
}
void BLI_freelistN(ListBase *listbase)
{
- struct Link *link,*next;
+ Link *link, *next;
- if (listbase == 0) return;
+ if (listbase == NULL) return;
+
link= listbase->first;
- while(link) {
+ while (link) {
next= link->next;
MEM_freeN(link);
link= next;
}
- listbase->first=0;
- listbase->last=0;
+
+ listbase->first= NULL;
+ listbase->last= NULL;
}
int BLI_countlist(ListBase *listbase)
{
- Link * link;
+ Link *link;
int count = 0;
- if (listbase){
+ if (listbase) {
link = listbase->first;
- while(link) {
+ while (link) {
count++;
link= link->next;
}
}
- return(count);
+ return count;
}
-void * BLI_findlink(ListBase *listbase, int number)
+void *BLI_findlink(ListBase *listbase, int number)
{
- Link * link = NULL;
+ Link *link = NULL;
if (number >= 0) {
link = listbase->first;
@@ -400,7 +554,27 @@ void * BLI_findlink(ListBase *listbase, int number)
}
}
- return (link);
+ return link;
+}
+
+int BLI_findindex(ListBase *listbase, void *vlink)
+{
+ Link *link= NULL;
+ int number= 0;
+
+ if (listbase == NULL) return -1;
+ if (vlink == NULL) return -1;
+
+ link= listbase->first;
+ while (link) {
+ if (link == vlink)
+ return number;
+
+ number++;
+ link= link->next;
+ }
+
+ return -1;
}
/*=====================================================================================*/
@@ -626,14 +800,14 @@ void BLI_dlist_reinit(DynamicList *dlist)
/*=====================================================================================*/
-char *BLI_strdupn(char *str, int len) {
+char *BLI_strdupn(const char *str, int len) {
char *n= MEM_mallocN(len+1, "strdup");
memcpy(n, str, len);
n[len]= '\0';
return n;
}
-char *BLI_strdup(char *str) {
+char *BLI_strdup(const char *str) {
return BLI_strdupn(str, strlen(str));
}
@@ -682,6 +856,16 @@ int BLI_strcaseeq(char *a, char *b) {
void BLI_cleanup_dir(const char *relabase, char *dir)
{
+ BLI_cleanup_file(relabase, dir);
+#ifdef WIN32
+ strcat(dir, "\\");
+#else
+ strcat(dir, "/");
+#endif
+}
+
+void BLI_cleanup_file(const char *relabase, char *dir)
+{
short a;
char *start, *eind;
@@ -719,9 +903,7 @@ void BLI_cleanup_dir(const char *relabase, char *dir)
dir[a] = 0;
}
}
-
- strcat(dir, "\\");
-#else
+#else
if(dir[0]=='.') { /* happens, for example in FILE_MAIN */
dir[0]= '/';
dir[1]= 0;
@@ -755,8 +937,6 @@ void BLI_cleanup_dir(const char *relabase, char *dir)
if (a<=0) break;
}
}
-
- strcat(dir, "/");
#endif
}
@@ -922,6 +1102,7 @@ int BLI_convertstringcode(char *path, const char *basepath, int framenum)
return wasrelative;
}
+/* copy di to fi, filename only */
void BLI_splitdirstring(char *di, char *fi)
{
char *lslash= BLI_last_slash(di);
@@ -1167,35 +1348,37 @@ int BLI_testextensie(const char *str, const char *ext)
}
-
-void BLI_split_dirfile(const char *string, char *dir, char *file)
+/* warning, can modify 'string' */
+void BLI_split_dirfile(char *string, char *dir, char *file)
{
int a;
#ifdef WIN32
int sl;
short is_relative = 0;
+ char path[FILE_MAX];
#endif
dir[0]= 0;
file[0]= 0;
#ifdef WIN32
- BLI_char_switch(string, '/', '\\'); /* make sure we have a valid path format */
- sl = strlen(string);
+ BLI_strncpy(path, string, FILE_MAX);
+ BLI_char_switch(path, '/', '\\'); /* make sure we have a valid path format */
+ sl = strlen(path);
if (sl) {
int len;
- if (string[0] == '/' || string[0] == '\\') {
- BLI_strncpy(dir, string, FILE_MAXDIR);
- if (sl > 1 && string[0] == '\\' && string[1] == '\\') is_relative = 1;
- } else if (sl > 2 && string[1] == ':' && string[2] == '\\') {
- BLI_strncpy(dir, string, FILE_MAXDIR);
+ if (path[0] == '/' || path[0] == '\\') {
+ BLI_strncpy(dir, path, FILE_MAXDIR);
+ if (sl > 1 && path[0] == '\\' && path[1] == '\\') is_relative = 1;
+ } else if (sl > 2 && path[1] == ':' && path[2] == '\\') {
+ BLI_strncpy(dir, path, FILE_MAXDIR);
} else {
BLI_getwdN(dir);
strcat(dir,"\\");
- strcat(dir,string);
- BLI_strncpy(string,dir,FILE_MAXDIR+FILE_MAXFILE);
+ strcat(dir,path);
+ BLI_strncpy(path,dir,FILE_MAXDIR+FILE_MAXFILE);
}
-
+
// BLI_exist doesn't recognize a slashed dirname as a dir
// check if a trailing slash exists, and remove it. Do not do this
// when we are already at root. -jesterKing
@@ -1203,7 +1386,7 @@ void BLI_split_dirfile(const char *string, char *dir, char *file)
if(a>=4 && dir[a-1]=='\\') dir[a-1] = 0;
if (is_relative) {
- printf("WARNING: BLI_split_dirfile needs absolute dir");
+ printf("WARNING: BLI_split_dirfile needs absolute dir\n");
}
else {
BLI_make_exist(dir);
@@ -1214,18 +1397,18 @@ void BLI_split_dirfile(const char *string, char *dir, char *file)
/* copy from end of string into file, to ensure filename itself isn't truncated
if string is too long. (aphex) */
- len = FILE_MAXFILE - strlen(string);
+ len = FILE_MAXFILE - strlen(path);
if (len < 0)
- BLI_strncpy(file,string + abs(len),FILE_MAXFILE);
+ BLI_strncpy(file,path + abs(len),FILE_MAXFILE);
else
- BLI_strncpy(file,string,FILE_MAXFILE);
+ BLI_strncpy(file,path,FILE_MAXFILE);
- if (strrchr(string,'\\')){
- BLI_strncpy(file,strrchr(string,'\\')+1,FILE_MAXFILE);
+ if (strrchr(path,'\\')) {
+ BLI_strncpy(file,strrchr(path,'\\')+1,FILE_MAXFILE);
}
-
- if (a = strlen(dir)) {
+
+ if ( (a = strlen(dir)) ) {
if (dir[a-1] != '\\') strcat(dir,"\\");
}
}
@@ -1233,7 +1416,7 @@ void BLI_split_dirfile(const char *string, char *dir, char *file)
a = strlen(dir) - 1;
while(a>0 && dir[a] != '\\') a--;
dir[a + 1] = 0;
- BLI_strncpy(file, string + strlen(dir),FILE_MAXFILE);
+ BLI_strncpy(file, path + strlen(dir),FILE_MAXFILE);
}
}
@@ -1288,12 +1471,20 @@ void BLI_join_dirfile(char *string, const char *dir, const char *file)
int sl_dir = strlen(dir);
BLI_strncpy(string, dir, FILE_MAX);
if (sl_dir > FILE_MAX-1) sl_dir = FILE_MAX-1;
+
+ /* only add seperator if needed */
#ifdef WIN32
- string[sl_dir] = '\\';
+ if (string[sl_dir-1] != '\\') {
+ string[sl_dir] = '\\';
+ sl_dir++;
+ }
#else
- string[sl_dir] = '/';
+ if (string[sl_dir-1] != '/') {
+ string[sl_dir] = '/';
+ sl_dir++;
+ }
#endif
- sl_dir++;
+
if (sl_dir <FILE_MAX) {
BLI_strncpy(string + sl_dir, file, FILE_MAX-sl_dir);
}
@@ -1340,10 +1531,10 @@ static int add_win32_extension(char *name)
return (retval);
}
-void BLI_where_am_i(char *fullname, char *name)
+void BLI_where_am_i(char *fullname, const char *name)
{
char filename[FILE_MAXDIR+FILE_MAXFILE];
- char *path, *temp;
+ char *path = NULL, *temp;
int len;
#ifdef _WIN32
char *seperator = ";";
@@ -1353,6 +1544,17 @@ void BLI_where_am_i(char *fullname, char *name)
char *slash = "/";
#endif
+
+#ifdef __linux__
+ /* linux uses binreloc since argv[0] is not relyable, call br_init( NULL ) first */
+ path = br_find_exe( NULL );
+ if (path) {
+ strcpy(fullname, path);
+ return;
+ }
+#endif
+
+ /* unix and non linux */
if (name && fullname && strlen(name)) {
strcpy(fullname, name);
if (name[0] == '.') {
@@ -1413,6 +1615,47 @@ void BLI_where_am_i(char *fullname, char *name)
}
}
+void BLI_where_is_temp(char *fullname, int usertemp)
+{
+ fullname[0] = '\0';
+
+ if (usertemp && BLI_exists(U.tempdir)) {
+ strcpy(fullname, U.tempdir);
+ }
+
+
+#ifdef WIN32
+ if (fullname[0] == '\0') {
+ char *tmp = getenv("TEMP"); /* Windows */
+ if (tmp && BLI_exists(tmp)) {
+ strcpy(fullname, tmp);
+ }
+ }
+#else
+ /* Other OS's - Try TMP and TMPDIR */
+ if (fullname[0] == '\0') {
+ char *tmp = getenv("TMP");
+ if (tmp && BLI_exists(tmp)) {
+ strcpy(fullname, tmp);
+ }
+ }
+
+ if (fullname[0] == '\0') {
+ char *tmp = getenv("TMPDIR");
+ if (tmp && BLI_exists(tmp)) {
+ strcpy(fullname, tmp);
+ }
+ }
+#endif
+
+ if (fullname[0] == '\0') {
+ strcpy(fullname, "/tmp/");
+ } else {
+ /* add a trailing slash if needed */
+ BLI_add_slash(fullname);
+ }
+}
+
/*
* returns absolute path to the app bundle
* only useful on OS X
@@ -1491,13 +1734,45 @@ int BLI_strncasecmp(const char *s1, const char *s2, int n) {
return 0;
}
-void BLI_timestr(double time, char *str)
+
+#ifdef WITH_ICONV
+#include "iconv.h"
+#include "localcharset.h"
+
+void BLI_string_to_utf8(char *original, char *utf_8, char *code)
+{
+ size_t inbytesleft=strlen(original);
+ size_t outbytesleft=512;
+ size_t rv=0;
+ iconv_t cd;
+
+ if (NULL == code) {
+ code = locale_charset();
+ }
+ cd=iconv_open("UTF-8", code);
+
+ if (cd == (iconv_t)(-1)) {
+ printf("iconv_open Error");
+ *utf_8='\0';
+ return ;
+ }
+ rv=iconv(cd, &original, &inbytesleft, &utf_8, &outbytesleft);
+ if (rv == (size_t) -1) {
+ printf("iconv Error\n");
+ return ;
+ }
+ *utf_8 = '\0';
+ iconv_close(cd);
+}
+#endif // WITH_ICONV
+
+void BLI_timestr(double _time, char *str)
{
/* format 00:00:00.00 (hr:min:sec) string has to be 12 long */
- int hr= ((int) time) / (60*60);
- int min= ( ((int) time) / 60 ) % 60;
- int sec= ((int) (time)) % 60;
- int hun= ((int) (time * 100.0)) % 100;
+ int hr= ( (int) _time) / (60*60);
+ int min= (((int) _time) / 60 ) % 60;
+ int sec= ( (int) (_time)) % 60;
+ int hun= ( (int) (_time * 100.0)) % 100;
if (hr) {
sprintf(str, "%.2d:%.2d:%.2d.%.2d",hr,min,sec,hun);