48 int faceid,
float u,
float v,
49 float uw1,
float vw1,
float uw2,
float vw2,
50 float width,
float blur)
53 if (!
_tx || nChannels <= 0)
return;
54 if (faceid < 0 || faceid >=
_tx->
numFaces())
return;
62 if (f.isNeighborhoodConstant()) {
75 bool return_black =
false;
79 case m_periodic: u = u-PtexUtils::floor(u);
break;
80 case m_black:
if (u <= -1.0f || u >= 2.0f) return_black =
true;
break;
85 case m_periodic: v = v-PtexUtils::floor(v);
break;
86 case m_black:
if (v <= -1.0f || v >= 2.0f) return_black =
true;
break;
90 memset(result, 0,
sizeof(
float)*
_nchan);
98 uw = uw * width + blur * 2.0f;
99 vw = vw * width + blur * 2.0f;
101 Ptex::Res((int8_t)(f.res.ulog2+1),(int8_t)(f.res.vlog2+1)));
104 k.
res.ulog2--; k.
res.vlog2--;
107 uw = uw * width + blur;
108 vw = vw * width + blur;
114 assert(k.
uw > 0 && k.
vw > 0);
128 for (
int i = 0; i <
_nchan; i++) result[i] =
float(
_result[i] * scale);
138 bool splitR = (k.
u+k.
uw > k.
res.u()), splitL = (k.
u < 0);
139 bool splitT = (k.
v+k.
vw > k.
res.v()), splitB = (k.
v < 0);
150 if (splitR || splitL || splitT || splitB) {
220 int rot = eid - aeid + 2;
224 if (fIsSubface != afIsSubface) {
231 int neid = (aeid + 3) % 4;
235 rot += neid - aeid + 2;
245 bool primary = (af->
adjface(aeid) == faceid);
253 else apply(k, afid, *af);
261 int afid = faceid, aeid = eid;
262 const FaceInfo* af = &f;
265 const int MaxValence = 10;
266 int cfaceId[MaxValence];
267 int cedgeId[MaxValence];
268 const FaceInfo* cface[MaxValence];
271 for (
int i = 0; i < MaxValence; i++) {
274 afid = af->adjface(aeid);
275 aeid = (af->adjedge(aeid) + 1) % 4;
281 if (afid < 0 || (afid == faceid && aeid == eid)) {
294 if (prevIsSubface && !isSubface && af->adjface((aeid+3)%4) == prevFace)
298 bool primary = (i==1);
300 k.
rotate(eid - aeid + 3 - primary);
304 prevIsSubface = isSubface;
307 if (numCorners == 1) {
311 else if (numCorners > 1) {
315 float initialWeight = k.
weight();
317 for (
int i = 1; i <= numCorners; i++) {
322 _weight += newWeight * (float)numCorners - initialWeight;
336 if (fIsSubface != cfIsSubface) {
344 else apply(k, cfid, cf);
350 assert(k.
u >= 0 && k.
u + k.
uw <= k.
res.u());
351 assert(k.
v >= 0 && k.
v + k.
vw <= k.
res.v());
353 if (k.
uw <= 0 || k.
vw <= 0)
return;
363 if (dh->isConstant()) {
370 float* result = tanvecMode ? (
float*) alloca(
sizeof(
float)*
_nchan) :
_result;
371 if (tanvecMode) memset(result, 0,
sizeof(
float)*
_nchan);
377 int tileresu = tileres.
u();
378 int tileresv = tileres.
v();
379 int ntilesu = k.
res.u() / tileresu;
380 for (
int v = k.
v, vw = k.
vw; vw > 0; vw -= kt.
vw, v += kt.
vw) {
381 int tilev = v / tileresv;
384 kt.
kv = k.
kv + v - k.
v;
385 for (
int u = k.
u, uw = k.
uw; uw > 0; uw -= kt.
uw, u += kt.
uw) {
386 int tileu = u / tileresu;
389 kt.
ku = k.
ku + u - k.
u;
392 if (th->isConstant())
int v() const
V resolution in texels.
void splitAndApply(PtexSeparableKernel &k, int faceid, const Ptex::FaceInfo &f)
void apply(PtexSeparableKernel &k, int faceid, const Ptex::FaceInfo &f)
void apply(float *dst, void *data, DataType dt, int nChan, int nTxChan)
void applyConst(float *dst, void *data, DataType dt, int nChan)
bool noedgeblend
Disable cross-face filtering. Useful for debugging or rendering on polys.
void mergeL(BorderMode mode)
texel access is clamped to border
Top edge, from UV (1,1) to (0,1)
bool isSubface() const
Determine if face is a subface (by checking a flag).
void mergeB(BorderMode mode)
bool adjustMainToSubface(int eid)
float makeSymmetric(float initialWeight)
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.
texel beyond border are assumed to be black
Values are vectors in tangent space; rotate values.
int adjface(int eid) const
Access an adjacent face id. The eid value must be 0..3.
void mergeR(BorderMode mode)
virtual void getData(int faceid, void *buffer, int stride)=0
Access texture data for a face at highest-resolution.
int u() const
U resolution in texels.
void adjustSubfaceToMain(int eid)
virtual int numFaces()=0
Number of faces stored in file.
void mergeT(BorderMode mode)
Right edge, from UV (1,0) to (1,1)
Bottom edge, from UV (0,0) to (1,0)
virtual void buildKernel(PtexSeparableKernel &k, float u, float v, float uw, float vw, Res faceRes)=0
void splitL(PtexSeparableKernel &k)
Smart-pointer for acquiring and releasing API objects.
void applyToCornerFace(PtexSeparableKernel &k, const Ptex::FaceInfo &f, int eid, int cfaceid, const Ptex::FaceInfo &cf, int ceid)
void splitB(PtexSeparableKernel &k)
texel access wraps to other side of face
void splitT(PtexSeparableKernel &k)
Pixel resolution of a given texture.
Left edge, from UV (0,1) to (0,0)
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.
void applyAcrossEdge(PtexSeparableKernel &k, int faceid, const Ptex::FaceInfo &f, int eid)
virtual const Ptex::FaceInfo & getFaceInfo(int faceid)=0
Access resolution and adjacency information about a face.
void applyToCorner(PtexSeparableKernel &k, int faceid, const Ptex::FaceInfo &f, int eid)
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 splitR(PtexSeparableKernel &k)
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.
EdgeId adjedge(int eid) const
Access an adjacent edge id. The eid value must be 0..3.