~ubuntu-branches/ubuntu/quantal/aqsis/quantal

« back to all changes in this revision

Viewing changes to renderer/render/filters.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Fabrice Coutadeur
  • Date: 2009-08-06 04:53:26 UTC
  • mfrom: (1.2.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20090806045326-z6xeaaao62idxcc6
Tags: 1.6.0-0ubuntu1
* New upstream release
* debian/control:
  - changed name of lib package to libaqsis1 instead of aqsis-libsc2a
  - changed name of dev package to libaqsis-dev instead of aqsis-libs-dev
  - Added aqsis-data package
  - Revised summary text according to that specified by the RISpec (Pixar)
* Moved examples installation from aqsis.install to aqsis-data.install
* debian/rules: 
  - added content to binary-indep target
* debian/rules: added explicit name of mime file to force dh_installmime
  to generate postinst and prerm scripts

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Aqsis
2
 
// Copyright 1997 - 2001, Paul C. Gregory
3
 
//
4
 
// Contact: pgregory@aqsis.org
5
 
//
6
 
// This library is free software; you can redistribute it and/or
7
 
// modify it under the terms of the GNU General Public
8
 
// License as published by the Free Software Foundation; either
9
 
// version 2 of the License, or (at your option) any later version.
10
 
//
11
 
// This library is distributed in the hope that it will be useful,
12
 
// but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
 
// General Public License for more details.
15
 
//
16
 
// You should have received a copy of the GNU General Public
17
 
// License along with this library; if not, write to the Free Software
18
 
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19
 
 
20
 
 
21
 
/** \file
22
 
                \brief Implement the filters of the RenderMan API functions.
23
 
                \author Paul C. Gregory (pgregory@aqsis.org)
24
 
*/
25
 
 
26
 
 
27
 
#include        <stdarg.h>
28
 
#include        <math.h>
29
 
#include        <list>
30
 
 
31
 
#include        "aqsis.h"
32
 
#include        "ri.h"
33
 
 
34
 
START_NAMESPACE( Aqsis )
35
 
 
36
 
// Mitchell Filter Declarations
37
 
class MitchellFilter {
38
 
public:
39
 
   // MitchellFilter Public Methods
40
 
   MitchellFilter(TqFloat b, TqFloat c, TqFloat xw, TqFloat yw)
41
 
   {
42
 
      B = b;
43
 
      C = c;
44
 
      invXWidth = 1.0f/xw;
45
 
      invYWidth = 1.0f/yw;
46
 
   }
47
 
   TqFloat Evaluate(TqFloat x, TqFloat y) const {
48
 
      return Evaluate(x * invXWidth) * Evaluate(y * invYWidth);
49
 
   }
50
 
   TqFloat Evaluate(TqFloat x) const {
51
 
      x = fabsf(2.f * x);
52
 
      if (x > 1.f)
53
 
         return ((-B - 6*C) * x*x*x + (6*B + 30*C) * x*x +
54
 
         (-12*B - 48*C) * x + (8*B + 24*C)) * (1.f/6.f);
55
 
      else
56
 
         return ((12 - 9*B - 6*C) * x*x*x +
57
 
         (-18 + 12*B + 6*C) * x*x +
58
 
         (6 - 2*B)) * (1.f/6.f);
59
 
   }
60
 
private:
61
 
   TqFloat B, C;
62
 
   TqFloat invXWidth, invYWidth;
63
 
};
64
 
 
65
 
END_NAMESPACE( Aqsis )
66
 
 
67
 
//----------------------------------------------------------------------
68
 
// RiGaussianFilter
69
 
// Gaussian filter used as a possible value passed to RiPixelFilter.
70
 
//
71
 
extern "C" 
72
 
 RtFloat        RiGaussianFilter( RtFloat x, RtFloat y, RtFloat xwidth, RtFloat ywidth )
73
 
{
74
 
        /*
75
 
         *  d = distance from origin
76
 
         *  w = filterwidth ([COOK84a] article used 1.5)
77
 
         *      For here use sqrt( (xwidth/2)*(xwidth/2) + (ywidth/2)*(ywidth/2) ).
78
 
         *      Simplifying:
79
 
         *
80
 
         *          w = sqrt( (xwidth*xwidth)/2 + (ywidth*ywidth)/2 )
81
 
         *          w = sqrt( (xwidth*xwidth + ywidth*ywidth)/2 )
82
 
         *        w*w = (xwidth*xwidth + ywidth*ywidth)/2
83
 
         *
84
 
         *  if (d < filterwidth) then 0
85
 
         *  else  exp(-d*d) - exp(-w*w)
86
 
         *
87
 
         */
88
 
        //RtFloat d,d2,w,w2;
89
 
        //
90
 
        ///* d = sqrt(x*x+y*y), d*d = (x*x+y*y)  */
91
 
        //d2 = (x*x+y*y);
92
 
        //d = sqrt(d2);
93
 
        //
94
 
        //w2 = 0.5*(xwidth*xwidth + ywidth*ywidth);
95
 
        //w = sqrt(w2);
96
 
        //
97
 
        //if(d>w)
98
 
        //      return(0.0);
99
 
        //else
100
 
        //      return(exp(-d2) - exp(-w2));
101
 
 
102
 
        // The above version falls faster than the one used by the 3.2 spec
103
 
        //   PRMan and RenderDotC.  Since all three match exactly, might as
104
 
        //   well change to the code below:
105
 
        x *= 2.0 / xwidth;
106
 
        y *= 2.0 / ywidth;
107
 
 
108
 
        return exp( -2.0 * ( x * x + y * y ) );
109
 
}
110
 
 
111
 
 
112
 
//----------------------------------------------------------------------
113
 
// RiMitchellFilter
114
 
// Mitchell filter used as a possible value passed to RiPixelFIlter.
115
 
//
116
 
extern "C" 
117
 
RtFloat RiMitchellFilter( RtFloat x, RtFloat y, RtFloat xwidth, RtFloat ywidth )
118
 
{
119
 
        Aqsis::MitchellFilter mc(1/3.0f, 1/3.0f, xwidth, ywidth);
120
 
 
121
 
        return mc.Evaluate(x, y);
122
 
}
123
 
 
124
 
//----------------------------------------------------------------------
125
 
// RiBoxFilter
126
 
// Box filter used as a possible value passed to RiPixelFIlter.
127
 
//
128
 
extern "C" 
129
 
RtFloat RiBoxFilter( RtFloat x, RtFloat y, RtFloat xwidth, RtFloat ywidth )
130
 
{
131
 
        /* [UPST89] -- (RC p. 178) says that x and y will be in the
132
 
         *    following intervals:
133
 
         *           -xwidth/2 <= x <= xwidth/2
134
 
         *           -ywidth/2 <= y <= ywidth/2
135
 
         *    These constraints on x and y really simplifies the
136
 
         *       the following code to just return (1.0).
137
 
         *
138
 
         */
139
 
        return MIN( ( fabs( x ) <= xwidth / 2.0 ? 1.0 : 0.0 ),
140
 
                    ( fabs( y ) <= ywidth / 2.0 ? 1.0 : 0.0 ) );
141
 
}
142
 
 
143
 
 
144
 
//----------------------------------------------------------------------
145
 
// RiTriangleFilter
146
 
// Triangle filter used as a possible value passed to RiPixelFilter
147
 
//
148
 
extern "C" 
149
 
RtFloat RiTriangleFilter( RtFloat x, RtFloat y, RtFloat xwidth, RtFloat ywidth )
150
 
{
151
 
        RtFloat hxw = xwidth / 2.0;
152
 
        RtFloat hyw = ywidth / 2.0;
153
 
        RtFloat absx = fabs( x );
154
 
        RtFloat absy = fabs( y );
155
 
 
156
 
        /* This function can be simplified as well by not worrying about
157
 
         *    returning zero if the sample is beyond the filter window.
158
 
         */
159
 
        return MIN( ( absx <= hxw ? ( hxw - absx ) / hxw : 0.0 ),
160
 
                    ( absy <= hyw ? ( hyw - absy ) / hyw : 0.0 ) );
161
 
}
162
 
 
163
 
 
164
 
//----------------------------------------------------------------------
165
 
// RiCatmullRomFilter
166
 
// Catmull Rom filter used as a possible value passed to RiPixelFilter.
167
 
//
168
 
extern "C" 
169
 
RtFloat RiCatmullRomFilter( RtFloat x, RtFloat y, RtFloat xwidth, RtFloat ywidth )
170
 
{
171
 
        /*
172
 
         * From page 223 of [MITC88]
173
 
         *
174
 
         * if abs(d) < 1
175
 
         *    f(d) = 1/6*(  (12-9*B-9*C)*abs(d*d*d)
176
 
         *                + (-18 + 12*B + 6*C)*d*d + (6-2*B) )
177
 
         *
178
 
         * if 1 <= abs(d) < 2
179
 
         *    f(d) = 1/6*(  (-B-6*C)*abs(d*d*d)
180
 
         *                + (6*B + 30*C)*d*d
181
 
         *                + (-12*B - 48*C)*d
182
 
         *                + (8*B + 24*C) )
183
 
         *
184
 
         * otherwise  f(d)=0
185
 
         *
186
 
         * -------------------------------------------------------------
187
 
         *  When B = 0.0 and C = 0.5 the filter is a Catmull-Rom cubic spline.
188
 
         *
189
 
         * if abs(d) < 1
190
 
         *    f(d) = 1/6*[  (12-3)*abs(d*d*d) + (-18 + 3)*d*d + (6) ]
191
 
         *
192
 
         * if 1 <= abs(d) < 2
193
 
         *    f(d) = 1/6*[  (-3)*abs(d*d*d) + (15)*d*d + (-24)*d + (12) ]
194
 
         *
195
 
         * otherwise  f(d)=0
196
 
         * -------------------------------------------------------------
197
 
         * Simplifying:
198
 
         *
199
 
         * if abs(d) < 1
200
 
         *    f(d) = (3/2)*abs(d*d*d) - (5/2)*d*d + 1
201
 
         *
202
 
         * if 1 <= abs(d) <2
203
 
         *    f(d) = (-0.5)*abs(d*d*d) + (5/2)*d*d - 4*abs(d) + 2
204
 
         *
205
 
         * otherwise  f(d)=0
206
 
         *
207
 
         */
208
 
        /*    RtFloat d, d2;
209
 
 
210
 
            d2 = x * x + y * y; // d*d
211
 
            d = sqrt( d2 ); // distance from origin
212
 
 
213
 
            if ( d < 1 )
214
 
                return ( 1.5 * d * d2 - 2.5 * d2 + 1.0 );
215
 
            else if ( d < 2 )
216
 
                return ( -d * d2 * 0.5 + 2.5 * d2 - 4.0 * d + 2.0 );
217
 
            else
218
 
                return 0.0;*/
219
 
 
220
 
        /* RI SPec 3.2 */
221
 
        RtFloat r2 = (x*x+y*y);
222
 
        RtFloat r = sqrt(r2);
223
 
        return (r>=2.0)?0.0:
224
 
               (r<1.0)?(3.0*r*r2-5.0*r2+2.0):(-r*r2+5.0*r2-8.0*r+4.0);
225
 
}
226
 
 
227
 
 
228
 
//----------------------------------------------------------------------
229
 
// RiSincFilter
230
 
// Sinc filter used as a possible value passed to RiPixelFilter.
231
 
//
232
 
extern "C" 
233
 
RtFloat RiSincFilter( RtFloat x, RtFloat y, RtFloat xwidth, RtFloat ywidth )
234
 
{
235
 
        //RtFloat d;
236
 
        //
237
 
        //d = sqrt(x*x+y*y);
238
 
        //
239
 
        //if(d!=0)
240
 
        //      return(sin(RI_PI*d)/(RI_PI*d));
241
 
        //else
242
 
        //      return(1.0);
243
 
 
244
 
        // The above is an un-windowed sinc, below is a windowed sinc
245
 
        //   function similar in shape to what PRMan 3.9 uses.
246
 
        // tburge 5-28-01
247
 
 
248
 
        /* Modified version of the RI Spec 3.2 sinc filter to be
249
 
         *   windowed with a positive lobe of a cosine which is half
250
 
         *   of a cosine period.
251
 
         */
252
 
 
253
 
        /* Uses a -PI to PI cosine window. */
254
 
        if ( x != 0.0 )
255
 
        {
256
 
                x *= RI_PI;
257
 
                x = cos( 0.5 * x / xwidth ) * sin( x ) / x;
258
 
        }
259
 
        else
260
 
        {
261
 
                x = 1.0;
262
 
        }
263
 
        if ( y != 0.0 )
264
 
        {
265
 
                y *= RI_PI;
266
 
                y = cos( 0.5 * y / ywidth ) * sin( y ) / y;
267
 
        }
268
 
        else
269
 
        {
270
 
                y = 1.0;
271
 
        }
272
 
 
273
 
        /* This is a square separable filter and is the 2D Fourier
274
 
         * transform of a rectangular box outlining a lowpass bandwidth
275
 
        * filter in the frequency domain.
276
 
        */
277
 
        return x*y;
278
 
}
279
 
 
280
 
 
281
 
//----------------------------------------------------------------------
282
 
// RiDiskFilter -- this is in Pixar's ri.h
283
 
// Cylindrical filter used as a possible value passed to RiPixelFilter
284
 
//
285
 
extern "C" 
286
 
RtFloat RiDiskFilter( RtFloat x, RtFloat y, RtFloat xwidth, RtFloat ywidth )
287
 
{
288
 
        double d, xx, yy;
289
 
 
290
 
        xx = x * x;
291
 
        yy = y * y;
292
 
        xwidth *= 0.5;
293
 
        ywidth *= 0.5;
294
 
 
295
 
        d = ( xx ) / ( xwidth * xwidth ) + ( yy ) / ( ywidth * ywidth );
296
 
        if ( d < 1.0 )
297
 
        {
298
 
                return 1.0;
299
 
        }
300
 
        else
301
 
        {
302
 
                return 0.0;
303
 
        }
304
 
}
305
 
 
306
 
 
307
 
//----------------------------------------------------------------------
308
 
// RiBesselFilter -- this is in Pixar's ri.h
309
 
// Besselj0 filter used as a possible value passed to RiPixelFilter
310
 
//
311
 
extern "C" 
312
 
RtFloat RiBesselFilter( RtFloat x, RtFloat y, RtFloat xwidth, RtFloat ywidth )
313
 
{
314
 
 
315
 
        double d, w, xx, yy;
316
 
 
317
 
        xx = x * x;
318
 
        yy = y * y;
319
 
 
320
 
        xwidth *= 0.5;
321
 
        ywidth *= 0.5;
322
 
 
323
 
        w = ( xx ) / ( xwidth * xwidth ) + ( yy ) / ( ywidth * ywidth );
324
 
        if ( w < 1.0 )
325
 
        {
326
 
                d = sqrt( xx + yy );
327
 
                if ( d != 0.0 )
328
 
                {
329
 
                        /* Half cosine window. */
330
 
                        w = cos( 0.5 * RI_PI * sqrt( w ) );
331
 
                        return w * 2*j1( RI_PI * d ) / d;
332
 
                }
333
 
                else
334
 
                {
335
 
                        return RI_PI;
336
 
                }
337
 
        }
338
 
        else
339
 
        {
340
 
                return 0.0;
341
 
        }
342
 
}
343
 
 
344
 
//---------------------------------------------------------------------
345
 
 
346
 
 
347
 
 
348