~siretart/ubuntu/utopic/blender/libav10

« back to all changes in this revision

Viewing changes to extern/eltopo/common/util.h

  • Committer: Package Import Robot
  • Author(s): Matteo F. Vescovi
  • Date: 2012-07-23 08:54:18 UTC
  • mfrom: (14.2.16 sid)
  • mto: (14.2.19 sid)
  • mto: This revision was merged to the branch mainline in revision 42.
  • Revision ID: package-import@ubuntu.com-20120723085418-9foz30v6afaf5ffs
Tags: 2.63a-2
* debian/: Cycles support added (Closes: #658075)
  For now, this top feature has been enabled only
  on [any-amd64 any-i386] architectures because
  of OpenImageIO failing on all others
* debian/: scripts installation path changed
  from /usr/lib to /usr/share:
  + debian/patches/: patchset re-worked for path changing
  + debian/control: "Breaks" field added on yafaray-exporter

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifndef UTIL_H
 
2
#define UTIL_H
 
3
 
 
4
#include <algorithm>
 
5
#include <array3.h>
 
6
#include <climits>
 
7
#include <cmath>
 
8
#include <iostream>
 
9
#include <vector>
 
10
 
 
11
#ifndef M_PI
 
12
const double M_PI = 3.1415926535897932384626433832795;
 
13
#endif
 
14
 
 
15
#ifdef WIN32
 
16
#undef min
 
17
#undef max
 
18
#endif
 
19
 
 
20
using std::min;
 
21
using std::max;
 
22
using std::swap;
 
23
 
 
24
template<class T>
 
25
inline T sqr(const T& x)
 
26
{ return x*x; }
 
27
 
 
28
template<class T>
 
29
inline T cube(const T& x)
 
30
{ return x*x*x; }
 
31
 
 
32
template<class T>
 
33
inline T min(T a1, T a2, T a3)
 
34
{ return min(a1, min(a2, a3)); }
 
35
 
 
36
template<class T>
 
37
inline T min(T a1, T a2, T a3, T a4)
 
38
{ return min(min(a1, a2), min(a3, a4)); }
 
39
 
 
40
template<class T>
 
41
inline T min(T a1, T a2, T a3, T a4, T a5)
 
42
{ return min(min(a1, a2), min(a3, a4), a5); }
 
43
 
 
44
template<class T>
 
45
inline T min(T a1, T a2, T a3, T a4, T a5, T a6)
 
46
{ return min(min(a1, a2), min(a3, a4), min(a5, a6)); }
 
47
 
 
48
template<class T>
 
49
inline T max(T a1, T a2, T a3)
 
50
{ return max(a1, max(a2, a3)); }
 
51
 
 
52
template<class T>
 
53
inline T max(T a1, T a2, T a3, T a4)
 
54
{ return max(max(a1, a2), max(a3, a4)); }
 
55
 
 
56
template<class T>
 
57
inline T max(T a1, T a2, T a3, T a4, T a5)
 
58
{ return max(max(a1, a2), max(a3, a4),  a5); }
 
59
 
 
60
template<class T>
 
61
inline T max(T a1, T a2, T a3, T a4, T a5, T a6)
 
62
{ return max(max(a1, a2), max(a3, a4),  max(a5, a6)); }
 
63
 
 
64
template<class T>
 
65
inline void minmax(T a1, T a2, T& amin, T& amax)
 
66
{
 
67
    if(a1<a2){
 
68
        amin=a1;
 
69
        amax=a2;
 
70
    }else{
 
71
        amin=a2;
 
72
        amax=a1;
 
73
    }
 
74
}
 
75
 
 
76
template<class T>
 
77
inline void minmax(T a1, T a2, T a3, T& amin, T& amax)
 
78
{
 
79
    if(a1<a2){
 
80
        if(a1<a3){
 
81
            amin=a1;
 
82
            if(a2<a3) amax=a3;
 
83
            else amax=a2;
 
84
        }else{
 
85
            amin=a3;
 
86
            if(a1<a2) amax=a2;
 
87
            else amax=a1;
 
88
        }
 
89
    }else{
 
90
        if(a2<a3){
 
91
            amin=a2;
 
92
            if(a1<a3) amax=a3;
 
93
            else amax=a1;
 
94
        }else{
 
95
            amin=a3;
 
96
            amax=a1;
 
97
        }
 
98
    }
 
99
}
 
100
 
 
101
template<class T>
 
102
inline void minmax(T a1, T a2, T a3, T a4, T& amin, T& amax)
 
103
{
 
104
    if(a1<a2){
 
105
        if(a3<a4){
 
106
            amin=min(a1,a3);
 
107
            amax=max(a2,a4);
 
108
        }else{
 
109
            amin=min(a1,a4);
 
110
            amax=max(a2,a3);
 
111
        }
 
112
    }else{
 
113
        if(a3<a4){
 
114
            amin=min(a2,a3);
 
115
            amax=max(a1,a4);
 
116
        }else{
 
117
            amin=min(a2,a4);
 
118
            amax=max(a1,a3);
 
119
        }
 
120
    }
 
121
}
 
122
 
 
123
template<class T>
 
124
inline void minmax(T a1, T a2, T a3, T a4, T a5, T& amin, T& amax)
 
125
{
 
126
    //@@@ the logic could be shortcircuited a lot!
 
127
    amin=min(a1,a2,a3,a4,a5);
 
128
    amax=max(a1,a2,a3,a4,a5);
 
129
}
 
130
 
 
131
template<class T>
 
132
inline void minmax(T a1, T a2, T a3, T a4, T a5, T a6, T& amin, T& amax)
 
133
{
 
134
    //@@@ the logic could be shortcircuited a lot!
 
135
    amin=min(a1,a2,a3,a4,a5,a6);
 
136
    amax=max(a1,a2,a3,a4,a5,a6);
 
137
}
 
138
 
 
139
template<class T>
 
140
inline void update_minmax(T a1, T& amin, T& amax)
 
141
{
 
142
    if(a1<amin) amin=a1;
 
143
    else if(a1>amax) amax=a1;
 
144
}
 
145
 
 
146
template<class T>
 
147
inline void sort(T &a, T &b, T &c)
 
148
{
 
149
    T temp;
 
150
    if(a<b){
 
151
        if(a<c){
 
152
            if(c<b){ // a<c<b
 
153
                temp=c;c=b;b=temp;
 
154
            } // else: a<b<c
 
155
        }else{ // c<a<b
 
156
            temp=c;c=b;b=a;a=temp;
 
157
        }
 
158
    }else{
 
159
        if(b<c){
 
160
            if(a<c){ //b<a<c
 
161
                temp=b;b=a;a=temp;
 
162
            }else{ // b<c<a
 
163
                temp=b;b=c;c=a;a=temp;
 
164
            }
 
165
        }else{ // c<b<a
 
166
            temp=c;c=a;a=temp;
 
167
        }
 
168
    }
 
169
}
 
170
 
 
171
template<class T>
 
172
inline T clamp(T a, T lower, T upper)
 
173
{
 
174
    if(a<lower) return lower;
 
175
    else if(a>upper) return upper;
 
176
    else return a;
 
177
}
 
178
 
 
179
// only makes sense with T=float or double
 
180
template<class T>
 
181
inline T smooth_step(T r)
 
182
{
 
183
    if(r<0) return 0;
 
184
    else if(r>1) return 1;
 
185
    return r*r*r*(10+r*(-15+r*6));
 
186
}
 
187
 
 
188
// only makes sense with T=float or double
 
189
template<class T>
 
190
inline T smooth_step(T r, T r_lower, T r_upper, T value_lower, T value_upper)
 
191
{ return value_lower + smooth_step((r-r_lower)/(r_upper-r_lower)) * (value_upper-value_lower); }
 
192
 
 
193
// only makes sense with T=float or double
 
194
template<class T>
 
195
inline T ramp(T r)
 
196
{ return smooth_step((r+1)/2)*2-1; }
 
197
 
 
198
#ifdef WIN32
 
199
inline int lround(double x)
 
200
{
 
201
    if(x>0)
 
202
        return (x-floor(x)<0.5) ? (int)floor(x) : (int)ceil(x);
 
203
    else
 
204
        return (x-floor(x)<=0.5) ? (int)floor(x) : (int)ceil(x);
 
205
}
 
206
 
 
207
inline double remainder(double x, double y)
 
208
{
 
209
    return x-std::floor(x/y+0.5)*y;
 
210
}
 
211
#endif
 
212
 
 
213
inline unsigned int round_up_to_power_of_two(unsigned int n)
 
214
{
 
215
    int exponent=0;
 
216
    --n;
 
217
    while(n){
 
218
        ++exponent;
 
219
        n>>=1;
 
220
    }
 
221
    return 1<<exponent;
 
222
}
 
223
 
 
224
inline unsigned int round_down_to_power_of_two(unsigned int n)
 
225
{
 
226
    int exponent=0;
 
227
    while(n>1){
 
228
        ++exponent;
 
229
        n>>=1;
 
230
    }
 
231
    return 1<<exponent;
 
232
}
 
233
 
 
234
// Transforms even the sequence 0,1,2,3,... into reasonably good random numbers 
 
235
// Challenge: improve on this in speed and "randomness"!
 
236
// This seems to pass several statistical tests, and is a bijective map (of 32-bit unsigned ints)
 
237
 
 
238
inline unsigned int randhash(unsigned int seed)
 
239
{
 
240
    unsigned int i=(seed^12345391u)*2654435769u;
 
241
    i^=(i<<6)^(i>>26);
 
242
    i*=2654435769u;
 
243
    i+=(i<<5)^(i>>12);
 
244
    return i;
 
245
}
 
246
 
 
247
// the inverse of randhash
 
248
inline unsigned int unhash(unsigned int h)
 
249
{
 
250
    h*=340573321u;
 
251
    h^=(h>>16);
 
252
    h*=340573321u;
 
253
    h^=(h>>16);
 
254
    h*=340573321u;
 
255
    h^=0xA3C59AC3u;
 
256
    return h;
 
257
}
 
258
 
 
259
// returns repeatable stateless pseudo-random number in [0,1]
 
260
inline double randhashd(unsigned int seed)
 
261
{ return randhash(seed)/(double)UINT_MAX; }
 
262
inline float randhashf(unsigned int seed)
 
263
{ return randhash(seed)/(float)UINT_MAX; }
 
264
 
 
265
// returns repeatable stateless pseudo-random number in [a,b]
 
266
inline double randhashd(unsigned int seed, double a, double b)
 
267
{ return (b-a)*randhash(seed)/(double)UINT_MAX + a; }
 
268
inline float randhashf(unsigned int seed, float a, float b)
 
269
{ return ( (b-a)*randhash(seed)/(float)UINT_MAX + a); }
 
270
 
 
271
inline int intlog2(int x)
 
272
{
 
273
    int exp=-1;
 
274
    while(x){
 
275
        x>>=1;
 
276
        ++exp;
 
277
    }
 
278
    return exp;
 
279
}
 
280
 
 
281
template<class T>
 
282
inline void get_barycentric(T x, ssize_t& i, T& f, ssize_t i_low, ssize_t i_high)
 
283
{
 
284
    T s=std::floor(x);
 
285
    i=(int)s;
 
286
    if(i<i_low){
 
287
        i=i_low;
 
288
        f=0;
 
289
    }else if(i>i_high-2){
 
290
        i=i_high-2;
 
291
        f=1;
 
292
    }else
 
293
        f=(T)(x-s);
 
294
}
 
295
 
 
296
template<class S, class T>
 
297
inline S lerp(const S& value0, const S& value1, T f)
 
298
{ return (1-f)*value0 + f*value1; }
 
299
 
 
300
template<class S, class T>
 
301
inline S bilerp(const S& v00, const S& v10, 
 
302
                const S& v01, const S& v11, 
 
303
                T fx, T fy)
 
304
 
305
    return lerp(lerp(v00, v10, fx),
 
306
                lerp(v01, v11, fx), 
 
307
                fy);
 
308
}
 
309
 
 
310
template<class S, class T>
 
311
inline S trilerp(const S& v000, const S& v100,
 
312
                 const S& v010, const S& v110,
 
313
                 const S& v001, const S& v101,  
 
314
                 const S& v011, const S& v111,
 
315
                 T fx, T fy, T fz) 
 
316
{
 
317
    return lerp(bilerp(v000, v100, v010, v110, fx, fy),
 
318
                bilerp(v001, v101, v011, v111, fx, fy),
 
319
                fz);
 
320
}
 
321
 
 
322
template<class S, class T>
 
323
inline S quadlerp(const S& v0000, const S& v1000,
 
324
                  const S& v0100, const S& v1100,
 
325
                  const S& v0010, const S& v1010,  
 
326
                  const S& v0110, const S& v1110,
 
327
                  const S& v0001, const S& v1001,
 
328
                  const S& v0101, const S& v1101,
 
329
                  const S& v0011, const S& v1011,  
 
330
                  const S& v0111, const S& v1111,
 
331
                  T fx, T fy, T fz, T ft) 
 
332
{
 
333
    return lerp(trilerp(v0000, v1000, v0100, v1100, v0010, v1010, v0110, v1110, fx, fy, fz),
 
334
                trilerp(v0001, v1001, v0101, v1101, v0011, v1011, v0111, v1111, fx, fy, fz),
 
335
                ft);
 
336
}
 
337
 
 
338
// f should be between 0 and 1, with f=0.5 corresponding to balanced weighting between w0 and w2
 
339
template<class T>
 
340
inline void quadratic_bspline_weights(T f, T& w0, T& w1, T& w2)
 
341
{
 
342
    w0=T(0.5)*sqr(f-1);
 
343
    w1=T(0.75)-sqr(f-T(0.5));;
 
344
    w2=T(0.5)*sqr(f);
 
345
}
 
346
 
 
347
// f should be between 0 and 1
 
348
template<class T>
 
349
inline void cubic_interp_weights(T f, T& wneg1, T& w0, T& w1, T& w2)
 
350
{
 
351
    T f2(f*f), f3(f2*f);
 
352
    wneg1=-T(1./3)*f+T(1./2)*f2-T(1./6)*f3;
 
353
    w0=1-f2+T(1./2)*(f3-f);
 
354
    w1=f+T(1./2)*(f2-f3);
 
355
    w2=T(1./6)*(f3-f);
 
356
}
 
357
 
 
358
template<class S, class T>
 
359
inline S cubic_interp(const S& value_neg1, const S& value0, const S& value1, const S& value2, T f)
 
360
{
 
361
    T wneg1, w0, w1, w2;
 
362
    cubic_interp_weights(f, wneg1, w0, w1, w2);
 
363
    return wneg1*value_neg1 + w0*value0 + w1*value1 + w2*value2;
 
364
}
 
365
 
 
366
template<class S, class T>
 
367
inline S bicubic_interp(const S& v00, const S& v10, const S& v20, const S& v30,
 
368
                        const S& v01, const S& v11, const S& v21, const S& v31,
 
369
                        const S& v02, const S& v12, const S& v22, const S& v32, 
 
370
                        const S& v03, const S& v13, const S& v23, const S& v33, 
 
371
                        T fx, T fy )
 
372
{
 
373
    return cubic_interp( cubic_interp( v00, v10, v20, v30, fx ),
 
374
                        cubic_interp( v01, v11, v21, v31, fx ),
 
375
                        cubic_interp( v02, v12, v22, v32, fx ),
 
376
                        cubic_interp( v03, v13, v23, v33, fx ),
 
377
                        fy );   
 
378
}
 
379
 
 
380
template<class S, class T>
 
381
inline S tricubic_interp( const Array3<S, Array1<S> >& v, ssize_t i, ssize_t j, ssize_t k, T fx, T fy, T fz )
 
382
{
 
383
    return cubic_interp( bicubic_interp( v(i+0,j+0,k+0), v(i+1,j+0,k+0), v(i+2,j+0,k+0), v(i+3,j+0,k+0), 
 
384
                                        v(i+0,j+1,k+0), v(i+1,j+1,k+0), v(i+2,j+1,k+0), v(i+3,j+1,k+0), 
 
385
                                        v(i+0,j+2,k+0), v(i+1,j+2,k+0), v(i+2,j+2,k+0), v(i+3,j+2,k+0), 
 
386
                                        v(i+0,j+3,k+0), v(i+1,j+3,k+0), v(i+2,j+3,k+0), v(i+3,j+3,k+0), fx, fy ),
 
387
                        bicubic_interp( v(i+0,j+0,k+1), v(i+1,j+0,k+1), v(i+2,j+0,k+1), v(i+3,j+0,k+1), 
 
388
                                       v(i+0,j+1,k+1), v(i+1,j+1,k+1), v(i+2,j+1,k+1), v(i+3,j+1,k+1), 
 
389
                                       v(i+0,j+2,k+1), v(i+1,j+2,k+1), v(i+2,j+2,k+1), v(i+3,j+2,k+1), 
 
390
                                       v(i+0,j+3,k+1), v(i+1,j+3,k+1), v(i+2,j+3,k+1), v(i+3,j+3,k+1), fx, fy ),
 
391
                        bicubic_interp( v(i+0,j+0,k+2), v(i+1,j+0,k+2), v(i+2,j+0,k+2), v(i+3,j+0,k+2), 
 
392
                                       v(i+0,j+1,k+2), v(i+1,j+1,k+2), v(i+2,j+1,k+2), v(i+3,j+1,k+2), 
 
393
                                       v(i+0,j+2,k+2), v(i+1,j+2,k+2), v(i+2,j+2,k+2), v(i+3,j+2,k+2), 
 
394
                                       v(i+0,j+3,k+2), v(i+1,j+3,k+2), v(i+2,j+3,k+2), v(i+3,j+3,k+2), fx, fy ),
 
395
                        bicubic_interp( v(i+0,j+0,k+3), v(i+1,j+0,k+3), v(i+2,j+0,k+3), v(i+3,j+0,k+3), 
 
396
                                       v(i+0,j+1,k+3), v(i+1,j+1,k+3), v(i+2,j+1,k+3), v(i+3,j+1,k+3), 
 
397
                                       v(i+0,j+2,k+3), v(i+1,j+2,k+3), v(i+2,j+2,k+3), v(i+3,j+2,k+3), 
 
398
                                       v(i+0,j+3,k+3), v(i+1,j+3,k+3), v(i+2,j+3,k+3), v(i+3,j+3,k+3), fx, fy ),                       
 
399
                        fz );
 
400
}
 
401
 
 
402
 
 
403
 
 
404
template<class T>
 
405
void zero(std::vector<T>& v)
 
406
{ for(int i=(int)v.size()-1; i>=0; --i) v[i]=0; }
 
407
 
 
408
template<class T>
 
409
T abs_max(const std::vector<T>& v)
 
410
{
 
411
    T m=0;
 
412
    for(int i=(int)v.size()-1; i>=0; --i){
 
413
        if(std::fabs(v[i])>m)
 
414
            m=std::fabs(v[i]);
 
415
    }
 
416
    return m;
 
417
}
 
418
 
 
419
template<class T>
 
420
bool contains(const std::vector<T>& a, T e)
 
421
{
 
422
    for(unsigned int i=0; i<a.size(); ++i)
 
423
        if(a[i]==e) return true;
 
424
    return false;
 
425
}
 
426
 
 
427
template<class T>
 
428
void add_unique(std::vector<T>& a, T e)
 
429
{
 
430
    for(unsigned int i=0; i<a.size(); ++i)
 
431
        if(a[i]==e) return;
 
432
    a.push_back(e);
 
433
}
 
434
 
 
435
template<class T>
 
436
void insert(std::vector<T>& a, unsigned int index, T e)
 
437
{
 
438
    a.push_back(a.back());
 
439
    for(unsigned int i=(unsigned int)a.size()-1; i>index; --i)
 
440
        a[i]=a[i-1];
 
441
    a[index]=e;
 
442
}
 
443
 
 
444
template<class T>
 
445
void erase(std::vector<T>& a, unsigned int index)
 
446
{
 
447
    for(unsigned int i=index; i<a.size()-1; ++i)
 
448
        a[i]=a[i+1];
 
449
    a.pop_back();
 
450
}
 
451
 
 
452
template<class T>
 
453
void erase_swap(std::vector<T>& a, unsigned int index)
 
454
{
 
455
    for(unsigned int i=index; i<a.size()-1; ++i)
 
456
        swap(a[i], a[i+1]);
 
457
    a.pop_back();
 
458
}
 
459
 
 
460
template<class T>
 
461
void erase_unordered(std::vector<T>& a, unsigned int index)
 
462
{
 
463
    a[index]=a.back();
 
464
    a.pop_back();
 
465
}
 
466
 
 
467
template<class T>
 
468
void erase_unordered_swap(std::vector<T>& a, unsigned int index)
 
469
{
 
470
    swap(a[index], a.back());
 
471
    a.pop_back();
 
472
}
 
473
 
 
474
template<class T>
 
475
void find_and_erase_unordered(std::vector<T>& a, const T& doomed_element)
 
476
{
 
477
    for(unsigned int i=0; i<a.size(); ++i)
 
478
        if(a[i]==doomed_element){
 
479
            erase_unordered(a, i);
 
480
            return;
 
481
        }
 
482
}
 
483
 
 
484
template<class T>
 
485
void replace_once(std::vector<T>& a, const T& old_element, const T& new_element)
 
486
{
 
487
    for(unsigned int i=0; i<a.size(); ++i)
 
488
        if(a[i]==old_element){
 
489
            a[i]=new_element;
 
490
            return;
 
491
        }
 
492
}
 
493
 
 
494
template<class T>
 
495
void write_matlab(std::ostream& output, const std::vector<T>& a, const char *variable_name, bool column_vector=true, int significant_digits=18)
 
496
{
 
497
    output<<variable_name<<"=[";
 
498
    std::streamsize old_precision=output.precision();
 
499
    output.precision(significant_digits);
 
500
    for(unsigned int i=0; i<a.size(); ++i){
 
501
        output<<a[i]<<" ";
 
502
    }
 
503
    output<<"]";
 
504
    if(column_vector)
 
505
        output<<"'";
 
506
    output<<";"<<std::endl;
 
507
    output.precision(old_precision);
 
508
}
 
509
 
 
510
#endif