PtexFilters.cpp
Go to the documentation of this file.
/*
PTEX SOFTWARE
Copyright 2014 Disney Enterprises, Inc. All rights reserved
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
* The names "Disney", "Walt Disney Pictures", "Walt Disney Animation
Studios" or the names of its contributors may NOT be used to
endorse or promote products derived from this software without
specific prior written permission from Walt Disney Pictures.
Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED.
IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
*/
#include "PtexPlatform.h"
#include "Ptexture.h"
#include "PtexSeparableFilter.h"
#include "PtexSeparableKernel.h"
#include "PtexTriangleFilter.h"
PTEX_NAMESPACE_BEGIN
class PtexPointFilter : public PtexFilter
{
public:
PtexPointFilter(PtexTexture* tx) : _tx(tx) {}
virtual void release() { delete this; }
virtual void eval(float* result, int firstchan, int nchannels,
int faceid, float u, float v,
float /*uw1*/, float /*vw1*/, float /*uw2*/, float /*vw2*/,
float /*width*/, float /*blur*/)
{
if (!_tx || nchannels <= 0) return;
if (faceid < 0 || faceid >= _tx->numFaces()) return;
const FaceInfo& f = _tx->getFaceInfo(faceid);
int resu = f.res.u(), resv = f.res.v();
int ui = PtexUtils::clamp(int(u*(float)resu), 0, resu-1);
int vi = PtexUtils::clamp(int(v*(float)resv), 0, resv-1);
_tx->getPixel(faceid, ui, vi, result, firstchan, nchannels);
}
private:
PtexTexture* _tx;
};
class PtexPointFilterTri : public PtexFilter
{
public:
PtexPointFilterTri(PtexTexture* tx) : _tx(tx) {}
virtual void release() { delete this; }
virtual void eval(float* result, int firstchan, int nchannels,
int faceid, float u, float v,
float /*uw1*/, float /*vw1*/, float /*uw2*/, float /*vw2*/,
float /*width*/, float /*blur*/)
{
if (!_tx || nchannels <= 0) return;
if (faceid < 0 || faceid >= _tx->numFaces()) return;
const FaceInfo& f = _tx->getFaceInfo(faceid);
int res = f.res.u();
int resm1 = res - 1;
float ut = u * (float)res, vt = v * (float)res;
int ui = PtexUtils::clamp(int(ut), 0, resm1);
int vi = PtexUtils::clamp(int(vt), 0, resm1);
float uf = ut - (float)ui, vf = vt - (float)vi;
if (uf + vf <= 1.0f) {
// "even" triangles are stored in lower-left half-texture
_tx->getPixel(faceid, ui, vi, result, firstchan, nchannels);
}
else {
// "odd" triangles are stored in upper-right half-texture
_tx->getPixel(faceid, resm1-vi, resm1-ui, result, firstchan, nchannels);
}
}
private:
PtexTexture* _tx;
};
class PtexWidth4Filter : public PtexSeparableFilter
{
public:
typedef float KernelFn(float x, const float* c);
PtexWidth4Filter(PtexTexture* tx, const PtexFilter::Options& opts, KernelFn k, const float* c = 0)
: PtexSeparableFilter(tx, opts), _k(k), _c(c) {}
virtual void buildKernel(PtexSeparableKernel& k, float u, float v, float uw, float vw,
Res faceRes)
{
buildKernelAxis(k.res.ulog2, k.u, k.uw, k.ku, u, uw, faceRes.ulog2);
buildKernelAxis(k.res.vlog2, k.v, k.vw, k.kv, v, vw, faceRes.vlog2);
}
private:
float blur(float x)
{
// 2-unit (x in -1..1) cubic hermite kernel
// this produces a blur roughly 1.5 times that of the 4-unit b-spline kernel
x = PtexUtils::abs(x);
return x < 1.0f ? (2.0f*x-3.0f)*x*x+1.0f : 0.0f;
}
void buildKernelAxis(int8_t& k_ureslog2, int& k_u, int& k_uw, float* ku,
float u, float uw, int f_ureslog2)
{
// build 1 axis (note: "u" labels may repesent either u or v axis)
// clamp filter width to no smaller than a texel
uw = PtexUtils::max(uw, PtexUtils::reciprocalPow2(f_ureslog2));
// compute desired texture res based on filter width
k_ureslog2 = (int8_t)PtexUtils::calcResFromWidth(uw);
int resu = 1 << k_ureslog2;
float uwlo = 1.0f/(float)resu; // smallest filter width for this res
// compute lerp weights (amount to blend towards next-lower res)
float lerp2 = _options.lerp ? (uw-uwlo)/uwlo : 0;
float lerp1 = 1.0f-lerp2;
// adjust for large filter widths
if (uw >= .25f) {
if (uw < .5f) {
k_ureslog2 = 2;
float upix = u * 4.0f - 0.5f;
int u1 = int(PtexUtils::ceil(upix - 2)), u2 = int(PtexUtils::ceil(upix + 2));
u1 = u1 & ~1; // round down to even pair
u2 = (u2 + 1) & ~1; // round up to even pair
k_u = u1;
k_uw = u2-u1;
float x1 = (float)u1-upix;
for (int i = 0; i < k_uw; i+=2) {
float xa = x1 + (float)i, xb = xa + 1.0f, xc = (xa+xb)*0.25f;
// spread the filter gradually to approach the next-lower-res width
// at uw = .5, s = 1.0; at uw = 1, s = 0.8
float s = 1.0f/(uw + .75f);
float ka = _k(xa, _c), kb = _k(xb, _c), kc = blur(xc*s);
ku[i] = ka * lerp1 + kc * lerp2;
ku[i+1] = kb * lerp1 + kc * lerp2;
}
return;
}
else if (uw < 1) {
k_ureslog2 = 1;
float upix = u * 2.0f - 0.5f;
k_u = int(PtexUtils::floor(u - .5f))*2;
k_uw = 4;
float x1 = (float)k_u-upix;
for (int i = 0; i < k_uw; i+=2) {
float xa = x1 + (float)i, xb = xa + 1.0f, xc = (xa+xb)*0.5f;
// spread the filter gradually to approach the next-lower-res width
// at uw = .5, s = .8; at uw = 1, s = 0.5
float s = 1.0f/(uw*1.5f + .5f);
float ka = blur(xa*s), kb = blur(xb*s), kc = blur(xc*s);
ku[i] = ka * lerp1 + kc * lerp2;
ku[i+1] = kb * lerp1 + kc * lerp2;
}
return;
}
else {
// use res 0 (1 texel per face) w/ no lerping
// (future: use face-blended values for filter > 2)
k_ureslog2 = 0;
float upix = u - .5f;
k_uw = 2;
float ui = PtexUtils::floor(upix);
k_u = int(ui);
ku[0] = blur(upix-ui);
ku[1] = 1-ku[0];
return;
}
}
// convert from normalized coords to pixel coords
float upix = u * (float)resu - 0.5f;
float uwpix = uw * (float)resu;
// find integer pixel extent: [u,v] +/- [2*uw,2*vw]
// (kernel width is 4 times filter width)
float dupix = 2.0f*uwpix;
int u1 = int(PtexUtils::ceil(upix - dupix)), u2 = int(PtexUtils::ceil(upix + dupix));
if (lerp2) {
// lerp kernel weights towards next-lower res
// extend kernel width to cover even pairs
u1 = u1 & ~1;
u2 = (u2 + 1) & ~1;
k_u = u1;
k_uw = u2-u1;
// compute kernel weights
float step = 1.0f/uwpix, x1 = ((float)u1-upix)*(float)step;
for (int i = 0; i < k_uw; i+=2) {
float xa = x1 + (float)i*step, xb = xa + step, xc = (xa+xb)*0.5f;
float ka = _k(xa, _c), kb = _k(xb, _c), kc = _k(xc, _c);
ku[i] = ka * lerp1 + kc * lerp2;
ku[i+1] = kb * lerp1 + kc * lerp2;
}
}
else {
k_u = u1;
k_uw = u2-u1;
// compute kernel weights
float x1 = ((float)u1-upix)/uwpix, step = 1.0f/uwpix;
for (int i = 0; i < k_uw; i++) ku[i] = _k(x1 + (float)i*step, _c);
}
}
KernelFn* _k; // kernel function
const float* _c; // kernel coefficients (if any)
};
class PtexBicubicFilter : public PtexWidth4Filter
{
public:
PtexBicubicFilter(PtexTexture* tx, const PtexFilter::Options& opts, float sharpness)
: PtexWidth4Filter(tx, opts, kernelFn, _coeffs)
{
// compute Cubic filter coefficients:
// abs(x) < 1:
// 1/6 * ((12 - 9*B - 6*C)*x^3 + (-18 + 12*B + 6*C)*x^2 + (6 - 2*B))
// == c[0]*x^3 + c[1]*x^2 + c[2]
// abs(x) < 2:
// 1/6 * ((-B - 6*C)*x^3 + (6*B + 30*C)*x^2 + (-12*B - 48*C)*x + (8*B + 24*C))
// == c[3]*x^3 + c[4]*x^2 + c[5]*x + c[6]
// else: 0
float B = 1.0f - sharpness; // choose C = (1-B)/2
_coeffs[0] = 1.5f - B;
_coeffs[1] = 1.5f * B - 2.5f;
_coeffs[2] = 1.0f - float(1.0/3.0) * B;
_coeffs[3] = float(1.0/3.0) * B - 0.5f;
_coeffs[4] = 2.5f - 1.5f * B;
_coeffs[5] = 2.0f * B - 4.0f;
_coeffs[6] = 2.0f - float(2.0/3.0) * B;
}
private:
static float kernelFn(float x, const float* c)
{
x = PtexUtils::abs(x);
if (x < 1.0f) return (c[0]*x + c[1])*x*x + c[2];
else if (x < 2.0f) return ((c[3]*x + c[4])*x + c[5])*x + c[6];
else return 0.0f;
}
float _coeffs[7]; // filter coefficients for current sharpness
};
class PtexGaussianFilter : public PtexWidth4Filter
{
public:
PtexGaussianFilter(PtexTexture* tx, const PtexFilter::Options& opts)
: PtexWidth4Filter(tx, opts, kernelFn) {}
private:
static float kernelFn(float x, const float*)
{
return (float)exp(-2.0f*x*x);
}
};
class PtexBoxFilter : public PtexSeparableFilter
{
public:
PtexBoxFilter(PtexTexture* tx, const PtexFilter::Options& opts)
: PtexSeparableFilter(tx, opts) {}
protected:
virtual void buildKernel(PtexSeparableKernel& k, float u, float v, float uw, float vw,
Res faceRes)
{
// clamp filter width to no larger than 1.0
uw = PtexUtils::min(uw, 1.0f);
vw = PtexUtils::min(vw, 1.0f);
// clamp filter width to no smaller than a texel
uw = PtexUtils::max(uw, PtexUtils::reciprocalPow2(faceRes.ulog2));
vw = PtexUtils::max(vw, PtexUtils::reciprocalPow2(faceRes.vlog2));
// compute desired texture res based on filter width
uint8_t ureslog2 = (uint8_t)PtexUtils::calcResFromWidth(uw);
uint8_t vreslog2 = (uint8_t)PtexUtils::calcResFromWidth(vw);
Res res(ureslog2, vreslog2);
k.res = res;
// convert from normalized coords to pixel coords
u = u * (float)k.res.u();
v = v * (float)k.res.v();
uw *= (float)k.res.u();
vw *= (float)k.res.v();
// find integer pixel extent: [u,v] +/- [uw/2,vw/2]
// (box is 1 unit wide for a 1 unit filter period)
float u1 = u - 0.5f*uw, u2 = u + 0.5f*uw;
float v1 = v - 0.5f*vw, v2 = v + 0.5f*vw;
float u1floor = PtexUtils::floor(u1), u2ceil = PtexUtils::ceil(u2);
float v1floor = PtexUtils::floor(v1), v2ceil = PtexUtils::ceil(v2);
k.u = int(u1floor);
k.v = int(v1floor);
k.uw = int(u2ceil)-k.u;
k.vw = int(v2ceil)-k.v;
// compute kernel weights along u and v directions
computeWeights(k.ku, k.uw, 1.0f-(u1-u1floor), 1.0f-(u2ceil-u2));
computeWeights(k.kv, k.vw, 1.0f-(v1-v1floor), 1.0f-(v2ceil-v2));
}
private:
void computeWeights(float* kernel, int size, float f1, float f2)
{
assert(size >= 1 && size <= 3);
if (size == 1) {
kernel[0] = f1 + f2 - 1.0f;
}
else {
kernel[0] = f1;
for (int i = 1; i < size-1; i++) kernel[i] = 1.0f;
kernel[size-1] = f2;
}
}
};
class PtexBilinearFilter : public PtexSeparableFilter
{
public:
PtexBilinearFilter(PtexTexture* tx, const PtexFilter::Options& opts)
: PtexSeparableFilter(tx, opts) {}
protected:
virtual void buildKernel(PtexSeparableKernel& k, float u, float v, float uw, float vw,
Res faceRes)
{
// clamp filter width to no larger than 1.0
uw = PtexUtils::min(uw, 1.0f);
vw = PtexUtils::min(vw, 1.0f);
// clamp filter width to no smaller than a texel
uw = PtexUtils::max(uw, PtexUtils::reciprocalPow2(faceRes.ulog2));
vw = PtexUtils::max(vw, PtexUtils::reciprocalPow2(faceRes.vlog2));
uint8_t ureslog2 = (uint8_t)PtexUtils::calcResFromWidth(uw);
uint8_t vreslog2 = (uint8_t)PtexUtils::calcResFromWidth(vw);
Res res(ureslog2, vreslog2);
k.res = res;
// convert from normalized coords to pixel coords
float upix = u * (float)k.res.u() - 0.5f;
float vpix = v * (float)k.res.v() - 0.5f;
float ufloor = PtexUtils::floor(upix);
float vfloor = PtexUtils::floor(vpix);
k.u = int(ufloor);
k.v = int(vfloor);
k.uw = 2;
k.vw = 2;
// compute kernel weights
float ufrac = upix-ufloor, vfrac = vpix-vfloor;
k.ku[0] = 1.0f - ufrac;
k.ku[1] = ufrac;
k.kv[0] = 1.0f - vfrac;
k.kv[1] = vfrac;
}
};
PtexFilter* PtexFilter::getFilter(PtexTexture* tex, const PtexFilter::Options& opts)
{
switch (tex->meshType()) {
case Ptex::mt_quad:
switch (opts.filter) {
case f_point: return new PtexPointFilter(tex);
case f_bilinear: return new PtexBilinearFilter(tex, opts);
default:
case f_box: return new PtexBoxFilter(tex, opts);
case f_gaussian: return new PtexGaussianFilter(tex, opts);
case f_bicubic: return new PtexBicubicFilter(tex, opts, opts.sharpness);
case f_bspline: return new PtexBicubicFilter(tex, opts, 0.f);
case f_catmullrom: return new PtexBicubicFilter(tex, opts, 1.f);
case f_mitchell: return new PtexBicubicFilter(tex, opts, 2.f/3.f);
}
break;
case Ptex::mt_triangle:
switch (opts.filter) {
case f_point: return new PtexPointFilterTri(tex);
default: return new PtexTriangleFilter(tex, opts);
}
break;
}
return 0;
}
PTEX_NAMESPACE_END
PtexPlatform.h
Platform-specific classes, functions, and includes.
PtexSeparableFilter.h
PtexSeparableKernel.h
PtexTriangleFilter.h
PTEX_NAMESPACE_END
#define PTEX_NAMESPACE_END
Definition PtexVersion.h:62
Ptexture.h
Public API classes for reading, writing, caching, and filtering Ptex files.
PtexBicubicFilter
Separable bicubic filter.
Definition PtexFilters.cpp:253
PtexBicubicFilter::kernelFn
static float kernelFn(float x, const float *c)
Definition PtexFilters.cpp:278
PtexBicubicFilter::PtexBicubicFilter
PtexBicubicFilter(PtexTexture *tx, const PtexFilter::Options &opts, float sharpness)
Definition PtexFilters.cpp:255
PtexBicubicFilter::_coeffs
float _coeffs[7]
Definition PtexFilters.cpp:286
PtexBilinearFilter
Bilinear filter (for rectangular textures)
Definition PtexFilters.cpp:376
PtexBilinearFilter::PtexBilinearFilter
PtexBilinearFilter(PtexTexture *tx, const PtexFilter::Options &opts)
Definition PtexFilters.cpp:378
PtexBilinearFilter::buildKernel
virtual void buildKernel(PtexSeparableKernel &k, float u, float v, float uw, float vw, Res faceRes)
Definition PtexFilters.cpp:382
PtexBoxFilter
Rectangular box filter.
Definition PtexFilters.cpp:312
PtexBoxFilter::PtexBoxFilter
PtexBoxFilter(PtexTexture *tx, const PtexFilter::Options &opts)
Definition PtexFilters.cpp:314
PtexBoxFilter::computeWeights
void computeWeights(float *kernel, int size, float f1, float f2)
Definition PtexFilters.cpp:358
PtexBoxFilter::buildKernel
virtual void buildKernel(PtexSeparableKernel &k, float u, float v, float uw, float vw, Res faceRes)
Definition PtexFilters.cpp:318
PtexFilter
Interface for filtered sampling of ptex data files.
Definition Ptexture.h:937
PtexFilter::getFilter
static PtexFilter * getFilter(PtexTexture *tx, const Options &opts)
Definition PtexFilters.cpp:419
PtexFilter::f_bicubic
@ f_bicubic
General bi-cubic filter (uses sharpness option)
Definition Ptexture.h:949
PtexFilter::f_bspline
@ f_bspline
BSpline (equivalent to bi-cubic w/ sharpness=0)
Definition Ptexture.h:950
PtexFilter::f_bilinear
@ f_bilinear
Bi-linear interpolation.
Definition Ptexture.h:946
PtexFilter::f_catmullrom
@ f_catmullrom
Catmull-Rom (equivalent to bi-cubic w/ sharpness=1)
Definition Ptexture.h:951
PtexFilter::f_mitchell
@ f_mitchell
Mitchell (equivalent to bi-cubic w/ sharpness=2/3)
Definition Ptexture.h:952
PtexFilter::f_box
@ f_box
Box filter.
Definition Ptexture.h:947
PtexFilter::f_gaussian
@ f_gaussian
Gaussian filter.
Definition Ptexture.h:948
PtexFilter::f_point
@ f_point
Point-sampled (no filtering)
Definition Ptexture.h:945
PtexGaussianFilter
Separable gaussian filter.
Definition PtexFilters.cpp:293
PtexGaussianFilter::PtexGaussianFilter
PtexGaussianFilter(PtexTexture *tx, const PtexFilter::Options &opts)
Definition PtexFilters.cpp:295
PtexGaussianFilter::kernelFn
static float kernelFn(float x, const float *)
Definition PtexFilters.cpp:299
PtexPointFilterTri
Point-sampling filter for triangular textures.
Definition PtexFilters.cpp:71
PtexPointFilterTri::_tx
PtexTexture * _tx
Definition PtexFilters.cpp:101
PtexPointFilterTri::eval
virtual void eval(float *result, int firstchan, int nchannels, int faceid, float u, float v, float, float, float, float, float, float)
Apply filter to a ptex data file.
Definition PtexFilters.cpp:75
PtexPointFilterTri::release
virtual void release()
Release resources held by this pointer (pointer becomes invalid).
Definition PtexFilters.cpp:74
PtexPointFilterTri::PtexPointFilterTri
PtexPointFilterTri(PtexTexture *tx)
Definition PtexFilters.cpp:73
PtexPointFilter
Point-sampling filter for rectangular textures.
Definition PtexFilters.cpp:46
PtexPointFilter::eval
virtual void eval(float *result, int firstchan, int nchannels, int faceid, float u, float v, float, float, float, float, float, float)
Apply filter to a ptex data file.
Definition PtexFilters.cpp:50
PtexPointFilter::_tx
PtexTexture * _tx
Definition PtexFilters.cpp:65
PtexPointFilter::PtexPointFilter
PtexPointFilter(PtexTexture *tx)
Definition PtexFilters.cpp:48
PtexPointFilter::release
virtual void release()
Release resources held by this pointer (pointer becomes invalid).
Definition PtexFilters.cpp:49
PtexSeparableFilter
Definition PtexSeparableFilter.h:46
PtexSeparableFilter::_options
Options _options
Definition PtexSeparableFilter.h:79
PtexSeparableKernel
Definition PtexSeparableKernel.h:48
PtexSeparableKernel::u
int u
Definition PtexSeparableKernel.h:51
PtexSeparableKernel::kv
float * kv
Definition PtexSeparableKernel.h:54
PtexSeparableKernel::res
Res res
Definition PtexSeparableKernel.h:50
PtexSeparableKernel::vw
int vw
Definition PtexSeparableKernel.h:52
PtexSeparableKernel::v
int v
Definition PtexSeparableKernel.h:51
PtexSeparableKernel::ku
float * ku
Definition PtexSeparableKernel.h:53
PtexSeparableKernel::uw
int uw
Definition PtexSeparableKernel.h:52
PtexTexture
Interface for reading data from a ptex file.
Definition Ptexture.h:457
PtexTexture::meshType
virtual Ptex::MeshType meshType()=0
Type of mesh for which texture data is defined.
PtexTexture::numFaces
virtual int numFaces()=0
Number of faces stored in file.
PtexTexture::getPixel
virtual void getPixel(int faceid, int u, int v, float *result, int firstchan, int nchannels)=0
Access a single texel from the highest resolution texture .
PtexTexture::getFaceInfo
virtual const Ptex::FaceInfo & getFaceInfo(int faceid)=0
Access resolution and adjacency information about a face.
PtexTriangleFilter
Definition PtexTriangleFilter.h:47
PtexWidth4Filter
Separable filter with width=4 support.
Definition PtexFilters.cpp:117
PtexWidth4Filter::blur
float blur(float x)
Definition PtexFilters.cpp:133
PtexWidth4Filter::PtexWidth4Filter
PtexWidth4Filter(PtexTexture *tx, const PtexFilter::Options &opts, KernelFn k, const float *c=0)
Definition PtexFilters.cpp:121
PtexWidth4Filter::_k
KernelFn * _k
Definition PtexFilters.cpp:246
PtexWidth4Filter::_c
const float * _c
Definition PtexFilters.cpp:247
PtexWidth4Filter::buildKernelAxis
void buildKernelAxis(int8_t &k_ureslog2, int &k_u, int &k_uw, float *ku, float u, float uw, int f_ureslog2)
Definition PtexFilters.cpp:141
PtexWidth4Filter::KernelFn
float KernelFn(float x, const float *c)
Definition PtexFilters.cpp:119
PtexWidth4Filter::buildKernel
virtual void buildKernel(PtexSeparableKernel &k, float u, float v, float uw, float vw, Res faceRes)
Definition PtexFilters.cpp:124
PTEX_NAMESPACE_BEGIN
Definition PtexSeparableKernel.cpp:42
PtexUtils::reciprocalPow2
float reciprocalPow2(int power)
Definition PtexUtils.h:92
PtexUtils::clamp
T clamp(T x, T lo, T hi)
Definition PtexUtils.h:154
PtexUtils::abs
T abs(T x)
Definition PtexUtils.h:134
PtexUtils::min
T min(T a, T b)
Definition PtexUtils.h:148
PtexUtils::calcResFromWidth
int calcResFromWidth(float w)
Definition PtexUtils.h:103
PtexUtils::max
T max(T a, T b)
Definition PtexUtils.h:151
Ptex::mt_triangle
@ mt_triangle
Mesh is triangle-based.
Definition Ptexture.h:67
Ptex::mt_quad
@ mt_quad
Mesh is quad-based.
Definition Ptexture.h:68
PtexFilter::Options
Choose filter options.
Definition Ptexture.h:956
PtexFilter::Options::filter
FilterType filter
Filter type.
Definition Ptexture.h:958
PtexFilter::Options::sharpness
float sharpness
Filter sharpness, 0..1 (for general bi-cubic filter only).
Definition Ptexture.h:960
PtexFilter::Options::lerp
bool lerp
Interpolate between mipmap levels.
Definition Ptexture.h:959
Ptex::FaceInfo::res
Res res
Resolution of face.
Definition Ptexture.h:230
Ptex::Res::u
int u() const
U resolution in texels.
Definition Ptexture.h:173