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);
127 float scale = 1.0f / (
_weight * OneValue(
_dt));
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) {
163 if (f.
adjface(e_bottom) >= 0) {
184 if (f.
adjface(e_bottom) >= 0) {
202 if (f.
adjface(e_bottom) >= 0) {
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()) {
369 bool tanvecMode = (
_efm == efm_tanvec) && (
_nchan >= 2) && (k.
rot > 0);
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())
#define PTEX_NAMESPACE_END
Smart-pointer for acquiring and releasing API objects.
void splitAndApply(PtexSeparableKernel &k, int faceid, const Ptex::FaceInfo &f)
void applyToCornerFace(PtexSeparableKernel &k, const Ptex::FaceInfo &f, int eid, int cfaceid, const Ptex::FaceInfo &cf, int ceid)
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(PtexSeparableKernel &k, int faceid, const Ptex::FaceInfo &f)
void applyAcrossEdge(PtexSeparableKernel &k, int faceid, const Ptex::FaceInfo &f, int eid)
void applyToCorner(PtexSeparableKernel &k, int faceid, const Ptex::FaceInfo &f, int eid)
virtual void buildKernel(PtexSeparableKernel &k, float u, float v, float uw, float vw, Res faceRes)=0
void mergeT(BorderMode mode)
void mergeB(BorderMode mode)
void apply(float *dst, void *data, DataType dt, int nChan, int nTxChan)
float makeSymmetric(float initialWeight)
void splitT(PtexSeparableKernel &k)
void adjustSubfaceToMain(int eid)
void splitB(PtexSeparableKernel &k)
void splitL(PtexSeparableKernel &k)
void mergeR(BorderMode mode)
void applyConst(float *dst, void *data, DataType dt, int nChan)
bool adjustMainToSubface(int eid)
void mergeL(BorderMode mode)
void splitR(PtexSeparableKernel &k)
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.
virtual const Ptex::FaceInfo & getFaceInfo(int faceid)=0
Access resolution and adjacency information about a face.
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.
bool noedgeblend
Disable cross-face filtering. Useful for debugging or rendering on polys.
Information about a face, as stored in the Ptex file header.
bool isSubface() const
Determine if face is a subface (by checking a flag).
Res res
Resolution of face.
EdgeId adjedge(int eid) const
Access an adjacent edge id. The eid value must be 0..3.
int adjface(int eid) const
Access an adjacent face id. The eid value must be 0..3.
Pixel resolution of a given texture.
int v() const
V resolution in texels.
int u() const
U resolution in texels.