diff options
author | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-12-07 22:22:48 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@pandora.be> | 2009-12-07 22:22:48 +0300 |
commit | 82ddfbf99fc0776a7fe439b81cf71bab87ceaaf9 (patch) | |
tree | fb1eda53eeeab12b093f5178693923b606708b05 /source/blender/blenlib | |
parent | 4ca2581b77112c488938f0a2dc226042e0390b71 (diff) | |
parent | fc69c54c4ce810e6236eaa45017130f27ba3f1e2 (diff) |
Sculpt Branch:
svn merge https://svn.blender.org/svnroot/bf-blender/trunk/blender -r24889:25180
Diffstat (limited to 'source/blender/blenlib')
-rw-r--r-- | source/blender/blenlib/BLI_math_base.h | 2 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_math_color.h | 22 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_math_geom.h | 6 | ||||
-rw-r--r-- | source/blender/blenlib/BLI_util.h | 2 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_base.c | 60 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_color.c | 61 | ||||
-rw-r--r-- | source/blender/blenlib/intern/math_geom.c | 158 | ||||
-rw-r--r-- | source/blender/blenlib/intern/util.c | 2 |
8 files changed, 305 insertions, 8 deletions
diff --git a/source/blender/blenlib/BLI_math_base.h b/source/blender/blenlib/BLI_math_base.h index 4e845ae35d9..af301386920 100644 --- a/source/blender/blenlib/BLI_math_base.h +++ b/source/blender/blenlib/BLI_math_base.h @@ -148,6 +148,8 @@ float power_of_2(float f); float shell_angle_to_dist(float angle); +double double_round(double x, int ndigits); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenlib/BLI_math_color.h b/source/blender/blenlib/BLI_math_color.h index b2d14f3ecbd..7444e01c3a6 100644 --- a/source/blender/blenlib/BLI_math_color.h +++ b/source/blender/blenlib/BLI_math_color.h @@ -32,10 +32,16 @@ extern "C" { #endif -#define BLI_CS_SMPTE 0 -#define BLI_CS_REC709 1 -#define BLI_CS_CIE 2 +/* primaries */ +#define BLI_XYZ_SMPTE 0 +#define BLI_XYZ_REC709_SRGB 1 +#define BLI_XYZ_CIE 2 +/* built-in profiles */ +#define BLI_PR_NONE 0 +#define BLI_PR_SRGB 1 +#define BLI_PR_REC709 2 + /******************* Conversion to RGB ********************/ void hsv_to_rgb(float h, float s, float v, float *r, float *g, float *b); @@ -53,6 +59,16 @@ void rgb_to_hsv(float r, float g, float b, float *lh, float *ls, float *lv); unsigned int rgb_to_cpack(float r, float g, float b); unsigned int hsv_to_cpack(float h, float s, float v); +/***************** Profile Transformations ********************/ + +void gamma_correct(float *c, float gamma); +float rec709_to_linearrgb(float c); +float linearrgb_to_rec709(float c); +float srgb_to_linearrgb(float c); +float linearrgb_to_srgb(float c); +void srgb_to_linearrgb_v3_v3(float *col_to, float *col_from); +void linearrgb_to_srgb_v3_v3(float *col_to, float *col_from); + /************************** Other *************************/ int constrain_rgb(float *r, float *g, float *b); diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h index d54be9d5e03..c50d9caade0 100644 --- a/source/blender/blenlib/BLI_math_geom.h +++ b/source/blender/blenlib/BLI_math_geom.h @@ -148,6 +148,12 @@ void sum_or_add_vertex_tangent(void *arena, VertexTangent **vtang, void tangent_from_uv(float *uv1, float *uv2, float *uv3, float *co1, float *co2, float *co3, float *n, float *tang); +/********************************* vector clouds******************************/ + + +void vcloud_estimate_transform(int list_size, float (*pos)[3], float *weight,float (*rpos)[3], float *rweight, + float lloc[3],float rloc[3],float lrot[3][3],float lscale[3][3]); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenlib/BLI_util.h b/source/blender/blenlib/BLI_util.h index 7642b71eea0..ca483903d46 100644 --- a/source/blender/blenlib/BLI_util.h +++ b/source/blender/blenlib/BLI_util.h @@ -61,7 +61,7 @@ void BLI_split_dirfile_basic(const char *string, char *dir, char *file); void BLI_join_dirfile(char *string, const char *dir, const char *file); void BLI_getlastdir(const char* dir, char *last, int maxlen); int BLI_testextensie(const char *str, const char *ext); -void BLI_uniquename(struct ListBase *list, void *vlink, char defname[], char delim, short name_offs, short len); +void BLI_uniquename(struct ListBase *list, void *vlink, const char defname[], char delim, short name_offs, short len); void BLI_newname(char * name, int add); int BLI_stringdec(char *string, char *kop, char *start, unsigned short *numlen); void BLI_stringenc(char *string, char *kop, char *start, unsigned short numlen, int pic); diff --git a/source/blender/blenlib/intern/math_base.c b/source/blender/blenlib/intern/math_base.c index f3fe09c088f..c5d0a1090b3 100644 --- a/source/blender/blenlib/intern/math_base.c +++ b/source/blender/blenlib/intern/math_base.c @@ -109,3 +109,63 @@ float power_of_2(float val) return (float)pow(2, ceil(log(val) / log(2))); } + +/* WARNING: MSVC compiling hack for double_round() */ +#if (WIN32 || WIN64) && !(FREE_WINDOWS) + +/* from python 3.1 pymath.c */ +double copysign(double x, double y) +{ + /* use atan2 to distinguish -0. from 0. */ + if (y > 0. || (y == 0. && atan2(y, -1.) > 0.)) { + return fabs(x); + } else { + return -fabs(x); + } +} + +/* from python 3.1 pymath.c */ +double round(double x) +{ + double absx, y; + absx = fabs(x); + y = floor(absx); + if (absx - y >= 0.5) + y += 1.0; + return copysign(y, x); +} + +#endif + + +/* from python 3.1 floatobject.c + * ndigits must be between 0 and 21 */ +double double_round(double x, int ndigits) { + double pow1, pow2, y, z; + if (ndigits >= 0) { + pow1 = pow(10.0, (double)ndigits); + pow2 = 1.0; + y = (x*pow1)*pow2; + /* if y overflows, then rounded value is exactly x */ + if (!finite(y)) + return x; + } + else { + pow1 = pow(10.0, (double)-ndigits); + pow2 = 1.0; /* unused; silences a gcc compiler warning */ + y = x / pow1; + } + + z = round(y); + if (fabs(y-z) == 0.5) + /* halfway between two integers; use round-half-even */ + z = 2.0*round(y/2.0); + + if (ndigits >= 0) + z = (z / pow2) / pow1; + else + z *= pow1; + + /* if computation resulted in overflow, raise OverflowError */ + return z; +} diff --git a/source/blender/blenlib/intern/math_color.c b/source/blender/blenlib/intern/math_color.c index 7ae380a1dde..6dbd9c1381f 100644 --- a/source/blender/blenlib/intern/math_color.c +++ b/source/blender/blenlib/intern/math_color.c @@ -208,17 +208,17 @@ void rgb_to_hsv(float r, float g, float b, float *lh, float *ls, float *lv) void xyz_to_rgb(float xc, float yc, float zc, float *r, float *g, float *b, int colorspace) { switch (colorspace) { - case BLI_CS_SMPTE: + case BLI_XYZ_SMPTE: *r = (3.50570f * xc) + (-1.73964f * yc) + (-0.544011f * zc); *g = (-1.06906f * xc) + (1.97781f * yc) + (0.0351720f * zc); *b = (0.0563117f * xc) + (-0.196994f * yc) + (1.05005f * zc); break; - case BLI_CS_REC709: + case BLI_XYZ_REC709_SRGB: *r = (3.240476f * xc) + (-1.537150f * yc) + (-0.498535f * zc); *g = (-0.969256f * xc) + (1.875992f * yc) + (0.041556f * zc); *b = (0.055648f * xc) + (-0.204043f * yc) + (1.057311f * zc); break; - case BLI_CS_CIE: + case BLI_XYZ_CIE: *r = (2.28783848734076f * xc) + (-0.833367677835217f * yc) + (-0.454470795871421f * zc); *g = (-0.511651380743862f * xc) + (1.42275837632178f * yc) + (0.0888930017552939f * zc); *b = (0.00572040983140966f * xc) + (-0.0159068485104036f * yc) + (1.0101864083734f * zc); @@ -274,6 +274,61 @@ void cpack_to_rgb(unsigned int col, float *r, float *g, float *b) *b /= 255.0f; } +/* ********************************* color transforms ********************************* */ + + +void gamma_correct(float *c, float gamma) +{ + *c = powf((*c), gamma); +} + +float rec709_to_linearrgb(float c) +{ + if (c < 0.081f) + return (c < 0.0f)? 0.0f: c * (1.0f/4.5f); + else + return powf((c + 0.099f)*(1.0f/1.099f), (1.0f/0.45f)); +} + +float linearrgb_to_rec709(float c) +{ + if (c < 0.018f) + return (c < 0.0f)? 0.0f: c * 4.5f; + else + return 1.099f * powf(c, 0.45f) - 0.099f; +} + +float srgb_to_linearrgb(float c) +{ + if (c < 0.04045f) + return (c < 0.0f)? 0.0f: c * (1.0f/12.92f); + else + return powf((c + 0.055f)*(1.0f/1.055f), 2.4f); +} + +float linearrgb_to_srgb(float c) +{ + if (c < 0.0031308f) + return (c < 0.0f)? 0.0f: c * 12.92f; + else + return 1.055f * powf(c, 1.0f/2.4f) - 0.055f; +} + +void srgb_to_linearrgb_v3_v3(float *col_to, float *col_from) +{ + col_to[0] = srgb_to_linearrgb(col_from[0]); + col_to[1] = srgb_to_linearrgb(col_from[1]); + col_to[2] = srgb_to_linearrgb(col_from[2]); +} + +void linearrgb_to_srgb_v3_v3(float *col_to, float *col_from) +{ + col_to[0] = linearrgb_to_srgb(col_from[0]); + col_to[1] = linearrgb_to_srgb(col_from[1]); + col_to[2] = linearrgb_to_srgb(col_from[2]); +} + + void minmax_rgb(short c[]) { if(c[0]>255) c[0]=255; diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 0b3ab2f0afc..efa5876e1b0 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -1597,3 +1597,161 @@ void tangent_from_uv(float *uv1, float *uv2, float *uv3, float *co1, float *co2, negate_v3(tang); } +/********************************************************/ + +/* vector clouds */ +/* void vcloud_estimate_transform(int list_size, float (*pos)[3], float *weight,float (*rpos)[3], float *rweight, + float lloc[3],float rloc[3],float lrot[3][3],float lscale[3][3]) + +input +( +int list_size +4 lists as pointer to array[list_size] +1. current pos array of 'new' positions +2. current weight array of 'new'weights (may be NULL pointer if you have no weights ) +3. reference rpos array of 'old' positions +4. reference rweight array of 'old'weights (may be NULL pointer if you have no weights ) +) +output +( +float lloc[3] center of mass pos +float rloc[3] center of mass rpos +float lrot[3][3] rotation matrix +float lscale[3][3] scale matrix +pointers may be NULL if not needed +) + +*/ +/* can't believe there is none in math utils */ +float _det_m3(float m2[3][3]) +{ + float det = 0.f; + if (m2){ + det= m2[0][0]* (m2[1][1]*m2[2][2] - m2[1][2]*m2[2][1]) + -m2[1][0]* (m2[0][1]*m2[2][2] - m2[0][2]*m2[2][1]) + +m2[2][0]* (m2[0][1]*m2[1][2] - m2[0][2]*m2[1][1]); + } + return det; +} + + +void vcloud_estimate_transform(int list_size, float (*pos)[3], float *weight,float (*rpos)[3], float *rweight, + float lloc[3],float rloc[3],float lrot[3][3],float lscale[3][3]) +{ + float accu_com[3]= {0.0f,0.0f,0.0f}, accu_rcom[3]= {0.0f,0.0f,0.0f}; + float accu_weight = 0.0f,accu_rweight = 0.0f,eps = 0.000001f; + + int a; + /* first set up a nice default response */ + if (lloc) zero_v3(lloc); + if (rloc) zero_v3(rloc); + if (lrot) unit_m3(lrot); + if (lscale) unit_m3(lscale); + /* do com for both clouds */ + if (pos && rpos && (list_size > 0)) /* paranoya check */ + { + /* do com for both clouds */ + for(a=0; a<list_size; a++){ + if (weight){ + float v[3]; + copy_v3_v3(v,pos[a]); + mul_v3_fl(v,weight[a]); + add_v3_v3v3(accu_com,accu_com,v); + accu_weight +=weight[a]; + } + else add_v3_v3v3(accu_com,accu_com,pos[a]); + + if (rweight){ + float v[3]; + copy_v3_v3(v,rpos[a]); + mul_v3_fl(v,rweight[a]); + add_v3_v3v3(accu_rcom,accu_rcom,v); + accu_rweight +=rweight[a]; + } + else add_v3_v3v3(accu_rcom,accu_rcom,rpos[a]); + + } + if (!weight || !rweight){ + accu_weight = accu_rweight = list_size; + } + + mul_v3_fl(accu_com,1.0f/accu_weight); + mul_v3_fl(accu_rcom,1.0f/accu_rweight); + if (lloc) copy_v3_v3(lloc,accu_com); + if (rloc) copy_v3_v3(rloc,accu_rcom); + if (lrot || lscale){ /* caller does not want rot nor scale, strange but legal */ + /*so now do some reverse engeneering and see if we can split rotation from scale ->Polardecompose*/ + /* build 'projection' matrix */ + float m[3][3],mr[3][3],q[3][3],qi[3][3]; + float va[3],vb[3],stunt[3]; + float odet,ndet; + int i=0,imax=15; + zero_m3(m); + zero_m3(mr); + + /* build 'projection' matrix */ + for(a=0; a<list_size; a++){ + sub_v3_v3v3(va,rpos[a],accu_rcom); + /* mul_v3_fl(va,bp->mass); mass needs renormalzation here ?? */ + sub_v3_v3v3(vb,pos[a],accu_com); + /* mul_v3_fl(va,rp->mass); */ + m[0][0] += va[0] * vb[0]; + m[0][1] += va[0] * vb[1]; + m[0][2] += va[0] * vb[2]; + + m[1][0] += va[1] * vb[0]; + m[1][1] += va[1] * vb[1]; + m[1][2] += va[1] * vb[2]; + + m[2][0] += va[2] * vb[0]; + m[2][1] += va[2] * vb[1]; + m[2][2] += va[2] * vb[2]; + + /* building the referenc matrix on the fly + needed to scale properly later*/ + + mr[0][0] += va[0] * va[0]; + mr[0][1] += va[0] * va[1]; + mr[0][2] += va[0] * va[2]; + + mr[1][0] += va[1] * va[0]; + mr[1][1] += va[1] * va[1]; + mr[1][2] += va[1] * va[2]; + + mr[2][0] += va[2] * va[0]; + mr[2][1] += va[2] * va[1]; + mr[2][2] += va[2] * va[2]; + } + copy_m3_m3(q,m); + stunt[0] = q[0][0]; stunt[1] = q[1][1]; stunt[2] = q[2][2]; + /* renormalizing for numeric stability */ + mul_m3_fl(q,1.f/len_v3(stunt)); + + /* this is pretty much Polardecompose 'inline' the algo based on Higham's thesis */ + /* without the far case ... but seems to work here pretty neat */ + odet = 0.f; + ndet = _det_m3(q); + while((odet-ndet)*(odet-ndet) > eps && i<imax){ + invert_m3_m3(qi,q); + transpose_m3(qi); + add_m3_m3m3(q,q,qi); + mul_m3_fl(q,0.5f); + odet =ndet; + ndet =_det_m3(q); + i++; + } + + if (i){ + float scale[3][3]; + float irot[3][3]; + if(lrot) copy_m3_m3(lrot,q); + invert_m3_m3(irot,q); + invert_m3_m3(qi,mr); + mul_m3_m3m3(q,m,qi); + mul_m3_m3m3(scale,irot,q); + if(lscale) copy_m3_m3(lscale,scale); + + } + } + } +} diff --git a/source/blender/blenlib/intern/util.c b/source/blender/blenlib/intern/util.c index 39afced92bc..5ff4dfe4e96 100644 --- a/source/blender/blenlib/intern/util.c +++ b/source/blender/blenlib/intern/util.c @@ -223,7 +223,7 @@ void BLI_newname(char *name, int add) * defname: the name that should be used by default if none is specified already * delim: the character which acts as a delimeter between parts of the name */ -void BLI_uniquename(ListBase *list, void *vlink, char defname[], char delim, short name_offs, short len) +void BLI_uniquename(ListBase *list, void *vlink, const char defname[], char delim, short name_offs, short len) { Link *link; char tempname[128]; |