49 virtual void release() {
delete this; }
50 virtual void eval(
float* result,
int firstchan,
int nchannels,
51 int faceid,
float u,
float v,
52 float ,
float ,
float ,
float ,
55 if (!_tx || nchannels <= 0)
return;
56 if (faceid < 0 || faceid >= _tx->numFaces())
return;
57 const FaceInfo& f = _tx->getFaceInfo(faceid);
58 int resu = f.
res.
u(), resv = f.
res.
v();
61 _tx->getPixel(faceid, ui, vi, result, firstchan, nchannels);
74 virtual void release() {
delete this; }
75 virtual void eval(
float* result,
int firstchan,
int nchannels,
76 int faceid,
float u,
float v,
77 float ,
float ,
float ,
float ,
80 if (!_tx || nchannels <= 0)
return;
81 if (faceid < 0 || faceid >= _tx->numFaces())
return;
82 const FaceInfo& f = _tx->getFaceInfo(faceid);
85 float ut = u * (float)res, vt = v * (
float)res;
86 int ui =
PtexUtils::clamp(
int(ut), 0, resm1);
87 int vi =
PtexUtils::clamp(
int(vt), 0, resm1);
88 float uf = ut - (
float)ui, vf = vt - (
float)vi;
90 if (uf + vf <= 1.0f) {
92 _tx->getPixel(faceid, ui, vi, result, firstchan, nchannels);
96 _tx->getPixel(faceid, resm1-vi, resm1-ui, result, firstchan, nchannels);
119 typedef float KernelFn(
float x,
const float* c);
138 return x < 1.0f ? (2.0f*x-3.0f)*x*x+1.0f : 0.0f;
141 void buildKernelAxis(int8_t& k_ureslog2,
int& k_u,
int& k_uw,
float* ku,
142 float u,
float uw,
int f_ureslog2)
151 int resu = 1 << k_ureslog2;
152 float uwlo = 1.0f/(float)resu;
155 float lerp2 = _options.lerp ? (uw-uwlo)/uwlo : 0;
156 float lerp1 = 1.0f-lerp2;
162 float upix = u * 4.0f - 0.5f;
163 int u1 = int(ceilf(upix - 2)), u2 = int(ceilf(upix + 2));
168 float x1 = (float)u1-upix;
169 for (
int i = 0; i < k_uw; i+=2) {
170 float xa = x1 + (float)i, xb = xa + 1.0f, xc = (xa+xb)*0.25f;
173 float s = 1.0f/(uw + .75f);
174 float ka = _k(xa, _c), kb = _k(xb, _c), kc = blur(xc*s);
175 ku[i] = ka * lerp1 + kc * lerp2;
176 ku[i+1] = kb * lerp1 + kc * lerp2;
182 float upix = u * 2.0f - 0.5f;
183 k_u = int(floorf(u - .5f))*2;
185 float x1 = (float)k_u-upix;
186 for (
int i = 0; i < k_uw; i+=2) {
187 float xa = x1 + (float)i, xb = xa + 1.0f, xc = (xa+xb)*0.5f;
190 float s = 1.0f/(uw*1.5f + .5f);
191 float ka = blur(xa*s), kb = blur(xb*s), kc = blur(xc*s);
192 ku[i] = ka * lerp1 + kc * lerp2;
193 ku[i+1] = kb * lerp1 + kc * lerp2;
201 float upix = u - .5f;
203 float ui = floorf(upix);
205 ku[0] = blur(upix-ui);
212 float upix = u * (float)resu - 0.5f;
213 float uwpix = uw * (float)resu;
217 float dupix = 2.0f*uwpix;
218 int u1 = int(ceilf(upix - dupix)), u2 = int(ceilf(upix + dupix));
229 float step = 1.0f/uwpix, x1 = ((float)u1-upix)*(float)step;
230 for (
int i = 0; i < k_uw; i+=2) {
231 float xa = x1 + (float)i*step, xb = xa + step, xc = (xa+xb)*0.5f;
232 float ka = _k(xa, _c), kb = _k(xb, _c), kc = _k(xc, _c);
233 ku[i] = ka * lerp1 + kc * lerp2;
234 ku[i+1] = kb * lerp1 + kc * lerp2;
241 float x1 = ((float)u1-upix)/uwpix, step = 1.0f/uwpix;
242 for (
int i = 0; i < k_uw; i++) ku[i] = _k(x1 + (
float)i*step, _c);
252 class PtexBicubicFilter :
public PtexWidth4Filter
256 : PtexWidth4Filter(tx, opts, kernelFn, _coeffs)
267 float B = 1.0f - sharpness;
268 _coeffs[0] = 1.5f - B;
269 _coeffs[1] = 1.5f * B - 2.5f;
270 _coeffs[2] = 1.0f - float(1.0/3.0) * B;
271 _coeffs[3] = float(1.0/3.0) * B - 0.5f;
272 _coeffs[4] = 2.5f - 1.5f * B;
273 _coeffs[5] = 2.0f * B - 4.0f;
274 _coeffs[6] = 2.0f - float(2.0/3.0) * B;
278 static float kernelFn(
float x,
const float* c)
281 if (x < 1.0f)
return (c[0]*x + c[1])*x*x + c[2];
282 else if (x < 2.0f)
return ((c[3]*x + c[4])*x + c[5])*x + c[6];
292 class PtexGaussianFilter :
public PtexWidth4Filter
296 : PtexWidth4Filter(tx, opts, kernelFn) {}
299 static float kernelFn(
float x,
const float*)
301 return (
float)exp(-2.0f*x*x);
332 Res res(ureslog2, vreslog2);
336 u = u * (float)k.
res.
u();
337 v = v * (float)k.
res.
v();
338 uw *= (float)k.
res.
u();
339 vw *= (float)k.
res.
v();
343 float u1 = u - 0.5f*uw, u2 = u + 0.5f*uw;
344 float v1 = v - 0.5f*vw, v2 = v + 0.5f*vw;
345 float u1floor = floorf(u1), u2ceil = ceilf(u2);
346 float v1floor = floorf(v1), v2ceil = ceilf(v2);
349 k.
uw = int(u2ceil)-k.
u;
350 k.
vw = int(v2ceil)-k.
v;
353 computeWeights(k.
ku, k.
uw, 1.0f-(u1-u1floor), 1.0f-(u2ceil-u2));
354 computeWeights(k.
kv, k.
vw, 1.0f-(v1-v1floor), 1.0f-(v2ceil-v2));
358 void computeWeights(
float* kernel,
int size,
float f1,
float f2)
360 assert(size >= 1 && size <= 3);
363 kernel[0] = f1 + f2 - 1.0f;
367 for (
int i = 1; i < size-1; i++) kernel[i] = 1.0f;
395 Res res(ureslog2, vreslog2);
399 float upix = u * (float)k.
res.
u() - 0.5f;
400 float vpix = v * (float)k.
res.
v() - 0.5f;
402 float ufloor = floorf(upix);
403 float vfloor = floorf(vpix);
410 float ufrac = upix-ufloor, vfrac = vpix-vfloor;
411 k.
ku[0] = 1.0f - ufrac;
413 k.
kv[0] = 1.0f - vfrac;
426 case f_point:
return new PtexPointFilter(tex);
427 case f_bilinear:
return new PtexBilinearFilter(tex, opts);
429 case f_box:
return new PtexBoxFilter(tex, opts);
430 case f_gaussian:
return new PtexGaussianFilter(tex, opts);
432 case f_bspline:
return new PtexBicubicFilter(tex, opts, 0.f);
433 case f_catmullrom:
return new PtexBicubicFilter(tex, opts, 1.f);
434 case f_mitchell:
return new PtexBicubicFilter(tex, opts, 2.f/3.f);
440 case f_point:
return new PtexPointFilterTri(tex);
Common data structures and enums used throughout the API.
static PtexFilter * getFilter(PtexTexture *tx, const Options &opts)
Pixel resolution of a given texture.
int v() const
V resolution in texels.
int8_t vlog2
log base 2 of v resolution, in texels
virtual Ptex::MeshType meshType()=0
Type of mesh for which texture data is defined.
int u() const
U resolution in texels.
int8_t vlog2
log base 2 of v resolution, in texels
static T clamp(T x, T lo, T hi)
int8_t ulog2
log base 2 of u resolution, in texels
if(WIN32) add_definitions(/DPTEX_EXPORTS) endif(WIN32) set(SRCS PtexCache.cpp PtexFilters.cpp PtexHalf.cpp PtexReader.cpp PtexSeparableFilter.cpp PtexSeparableKernel.cpp PtexTriangleFilter.cpp PtexTriangleKernel.cpp PtexUtils.cpp PtexWriter.cpp) add_library(Ptex_static STATIC $
Information about a face, as stored in the Ptex file header.
static int calcResFromWidth(float w)
Mitchell (equivalent to bi-cubic w/ sharpness=2/3)
Point-sampled (no filtering)
FilterType filter
Filter type.
int u() const
U resolution in texels.
Catmull-Rom (equivalent to bi-cubic w/ sharpness=1)
BSpline (equivalent to bi-cubic w/ sharpness=0)
int8_t ulog2
log base 2 of u resolution, in texels
float sharpness
Filter sharpness, 0..1 (for general bi-cubic filter only).
Interface for reading data from a ptex file.
int v() const
V resolution in texels.
Res res
Resolution of face.
Public API classes for reading, writing, caching, and filtering Ptex files.
General bi-cubic filter (uses sharpness option)
Interface for filtered sampling of ptex data files.