Go to the documentation of this file.
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;
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;
virtual PtexFaceData * getTile(int tile)=0
Access a tile from the data block.
Pixel resolution of a given texture.
void applyToCorner(PtexSeparableKernel &k, int faceid, const Ptex::FaceInfo &f, int eid)
virtual bool isTiled()=0
True if this data block is tiled.
@ e_top
Top edge, from UV (1,1) to (0,1)
#define PTEX_NAMESPACE_END
void splitT(PtexSeparableKernel &k)
virtual bool isConstant()=0
True if this data block is constant.
void apply(PtexSeparableKernel &k, int faceid, const Ptex::FaceInfo &f)
void applyAcrossEdge(PtexSeparableKernel &k, int faceid, const Ptex::FaceInfo &f, int eid)
virtual Ptex::Res tileRes()=0
Resolution of each tile in this data block.
void mergeT(BorderMode mode)
@ m_clamp
texel access is clamped to border
void adjustSubfaceToMain(int eid)
int DataSize(DataType dt)
Look up size of given data type (in bytes).
void splitR(PtexSeparableKernel &k)
bool isSubface() const
Determine if face is a subface (by checking a flag).
bool adjustMainToSubface(int eid)
int adjface(int eid) const
Access an adjacent face id. The eid value must be 0..3.
@ m_black
texel beyond border are assumed to be black
void splitL(PtexSeparableKernel &k)
Information about a face, as stored in the Ptex file header.
void mergeL(BorderMode mode)
void mergeB(BorderMode mode)
@ efm_tanvec
Values are vectors in tangent space; rotate values.
virtual int numFaces()=0
Number of faces stored in file.
virtual void getData(int faceid, void *buffer, int stride)=0
Access texture data for a face at highest-resolution.
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.
float OneValue(DataType dt)
Look up value of given data type that corresponds to the normalized value of 1.0.
Smart-pointer for acquiring and releasing API objects.
void applyConst(float *dst, void *data, DataType dt, int nChan)
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.
@ e_bottom
Bottom edge, from UV (0,0) to (1,0)
@ m_periodic
texel access wraps to other side of face
int u() const
U resolution in texels.
@ e_right
Right edge, from UV (1,0) to (1,1)
virtual const Ptex::FaceInfo & getFaceInfo(int faceid)=0
Access resolution and adjacency information about a face.
void splitAndApply(PtexSeparableKernel &k, int faceid, const Ptex::FaceInfo &f)
@ e_left
Left edge, from UV (0,1) to (0,0)
virtual void * getData()=0
Access the data from this data block.
int v() const
V resolution in texels.
EdgeId adjedge(int eid) const
Access an adjacent edge id. The eid value must be 0..3.
void splitB(PtexSeparableKernel &k)
void apply(float *dst, void *data, DataType dt, int nChan, int nTxChan)
void mergeR(BorderMode mode)
float makeSymmetric(float initialWeight)
void applyToCornerFace(PtexSeparableKernel &k, const Ptex::FaceInfo &f, int eid, int cfaceid, const Ptex::FaceInfo &cf, int ceid)
Res res
Resolution of face.
bool noedgeblend
Disable cross-face filtering. Useful for debugging or rendering on polys.
virtual void buildKernel(PtexSeparableKernel &k, float u, float v, float uw, float vw, Res faceRes)=0