45 inline float squared(
float x) {
return x*x; }
51 int faceid,
float u,
float v,
52 float uw1,
float vw1,
float uw2,
float vw2,
53 float width,
float blur)
56 if (!
_tx || nChannels <= 0)
return;
57 if (faceid < 0 || faceid >=
_tx->
numFaces())
return;
67 if (f.isNeighborhoodConstant()) {
74 u = std::clamp(u, 0.0f, 1.0f);
75 v = std::clamp(v, 0.0f, 1.0f);
94 for (
int i = 0; i <
_nchan; i++) result[i] =
float(
_result[i] * scale);
103 float uw1,
float vw1,
float uw2,
float vw2,
104 float width,
float blur, Res faceRes)
106 const float sqrt3 = 1.7320508075688772f;
109 float scaleAC = 0.25f * width*width;
110 float scaleB = -2.0f * scaleAC;
111 float A = (vw1*vw1 + vw2*vw2) * scaleAC;
112 float B = (uw1*vw1 + uw2*vw2) * scaleB;
113 float C = (uw1*uw1 + uw2*uw2) * scaleAC;
116 float Ac = 0.75f * A;
117 float Bc = float(sqrt3/2) * (B-A);
118 float Cc = 0.25f * A - 0.5f * B +
C;
121 const float maxEcc = 15.0f;
122 const float eccRatio = (maxEcc*maxEcc + 1.0f) / (maxEcc*maxEcc - 1.0f);
123 float X = sqrtf(squared(Ac - Cc) + squared(Bc));
124 float b_e = 0.5f * (eccRatio * X - (Ac + Cc));
128 float b_t = squared(0.5f / (
float)faceRes.u());
131 float b_b = 0.25f * blur * blur;
132 float b = std::max(b_b, std::max(b_e, b_t));
137 float m = sqrtf(2.0f*(Ac*Cc - 0.25f*Bc*Bc) / (Ac + Cc + X));
143 A = float(4/3.0) * Ac;
144 B = float(2/sqrt3) * Bc + A;
145 C = -0.25f * A + 0.5f * B + Cc;
154 float uw = std::min(sqrtf(C), 1.0f);
155 float vw = std::min(sqrtf(A), 1.0f);
156 float ww = std::min(sqrtf(A-B+C), 1.0f);
159 float w = 1.0f - u - v;
160 k.
set(Res((int8_t)reslog2, (int8_t)reslog2), u, v, u-uw, v-vw, w-ww, u+uw, v+vw, w+ww, A, B, C);
240 int tileresu = tileres.
u();
241 int tileresv = tileres.
v();
244 int wOffsetBase = k.
rowlen - tileresu;
245 for (
int tilev = k.
v1 / tileresv, tilevEnd = (k.
v2-1) / tileresv; tilev <= tilevEnd; tilev++) {
246 int vOffset = tilev * tileresv;
247 kt.
v = k.
v - (float)vOffset;
248 kt.
v1 = std::max(0, k.
v1 - vOffset);
249 kt.
v2 = std::min(k.
v2 - vOffset, tileresv);
250 for (
int tileu = k.
u1 / tileresu, tileuEnd = (k.
u2-1) / tileresu; tileu <= tileuEnd; tileu++) {
251 int uOffset = tileu * tileresu;
252 int wOffset = wOffsetBase - uOffset - vOffset;
253 kt.
u = k.
u - (float)uOffset;
254 kt.
u1 = std::max(0, k.
u1 - uOffset);
255 kt.
u2 = std::min(k.
u2 - uOffset, tileresu);
256 kt.
w1 = k.
w1 - wOffset;
257 kt.
w2 = k.
w2 - wOffset;
261 if (th->isConstant())
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)
Apply filter to a ptex data file.
void apply(PtexTriangleKernel &k, int faceid, const Ptex::FaceInfo &f)
int adjface(int eid) const
Access an adjacent face id. The eid value must be 0..3.
virtual int numChannels()=0
Number of channels stored in file.
void applyConst(float *dst, void *data, DataType dt, int nChan)
void splitU(PtexTriangleKernel &ka)
bool isConstant() const
Determine if face is constant (by checking a flag).
void apply(float *dst, void *data, DataType dt, int nChan, int nTxChan)
int calcResFromWidth(float w)
void splitV(PtexTriangleKernel &ka)
void buildKernel(PtexTriangleKernel &k, float u, float v, float uw1, float vw1, float uw2, float vw2, float width, float blur, Res faceRes)
virtual void * getConstantData(int faceid)=0
Access the constant (or average) data value for a given face.
void reorient(int eid, int aeid)
Triangle filter kernel iterator (in texel coords)
void splitAndApply(PtexTriangleKernel &k, int faceid, const Ptex::FaceInfo &f)
int v() const
V resolution in texels.
Per-face texture data accessor.
int u() const
U resolution in texels.
virtual void * getData()=0
Access the data from this data block.
virtual PtexFaceData * getTile(int tile)=0
Access a tile from the data block.
virtual void getData(int faceid, void *buffer, int stride)=0
Access texture data for a face at highest-resolution.
virtual int numFaces()=0
Number of faces stored in file.
Triangle filter kernel (in normalized triangle coords)
void set(Res resVal, float uVal, float vVal, float u1Val, float v1Val, float w1Val, float u2Val, float v2Val, float w2Val, float AVal, float BVal, float CVal)
EdgeId adjedge(int eid) const
Access an adjacent edge id. The eid value must be 0..3.
virtual Ptex::DataType dataType()=0
Type of data stored in file.
void getIterators(PtexTriangleKernelIter &ke, PtexTriangleKernelIter &ko)
Smart-pointer for acquiring and releasing API objects.
virtual bool isTiled()=0
True if this data block is tiled.
PTEX_NAMESPACE_BEGIN const float PtexTriangleKernelWidth
virtual bool isConstant()=0
True if this data block is constant.
Pixel resolution of a given texture.
void applyAcrossEdge(PtexTriangleKernel &k, const Ptex::FaceInfo &f, int eid)
int DataSize(DataType dt)
Look up size of given data type (in bytes).
Res res
Resolution of face.
Information about a face, as stored in the Ptex file header.
virtual const Ptex::FaceInfo & getFaceInfo(int faceid)=0
Access resolution and adjacency information about a face.
float OneValue(DataType dt)
Look up value of given data type that corresponds to the normalized value of 1.0. ...
#define PTEX_NAMESPACE_END
void applyIter(PtexTriangleKernelIter &k, PtexFaceData *dh)
void splitW(PtexTriangleKernel &ka)
void ConvertToFloat(float *dst, const void *src, Ptex::DataType dt, int numChannels)
Convert a number of data values from the given data type to float.
virtual Ptex::Res tileRes()=0
Resolution of each tile in this data block.