Ptex
PtexSeparableFilter.cpp
Go to the documentation of this file.
1 /*
2 PTEX SOFTWARE
3 Copyright 2014 Disney Enterprises, Inc. All rights reserved
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are
7 met:
8 
9  * Redistributions of source code must retain the above copyright
10  notice, this list of conditions and the following disclaimer.
11 
12  * Redistributions in binary form must reproduce the above copyright
13  notice, this list of conditions and the following disclaimer in
14  the documentation and/or other materials provided with the
15  distribution.
16 
17  * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation
18  Studios" or the names of its contributors may NOT be used to
19  endorse or promote products derived from this software without
20  specific prior written permission from Walt Disney Pictures.
21 
22 Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND
23 CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
24 BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
25 FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED.
26 IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR
27 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY
31 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
34 */
35 
36 #include "PtexPlatform.h"
37 #include <cmath>
38 #include <assert.h>
39 
40 #include "PtexSeparableFilter.h"
41 #include "PtexSeparableKernel.h"
42 #include "PtexUtils.h"
43 
44 
46 
47 void PtexSeparableFilter::eval(float* result, int firstChan, int nChannels,
48  int faceid, float u, float v,
49  float uw1, float vw1, float uw2, float vw2,
50  float width, float blur)
51 {
52  // init
53  if (!_tx || nChannels <= 0) return;
54  if (faceid < 0 || faceid >= _tx->numFaces()) return;
55  _firstChanOffset = firstChan*DataSize(_dt);
56  _nchan = PtexUtils::min(nChannels, _ntxchan-firstChan);
57 
58  // get face info
59  const FaceInfo& f = _tx->getFaceInfo(faceid);
60 
61  // if neighborhood is constant, just return constant value of face
62  if (f.isNeighborhoodConstant()) {
63  PtexPtr<PtexFaceData> data ( _tx->getData(faceid, 0) );
64  if (data) {
65  char* d = (char*) data->getData() + _firstChanOffset;
66  Ptex::ConvertToFloat(result, d, _dt, _nchan);
67  }
68  return;
69  }
70 
71  // find filter width as bounding box of vectors w1 and w2
72  float uw = PtexUtils::abs(uw1) + PtexUtils::abs(uw2), vw = PtexUtils::abs(vw1) + PtexUtils::abs(vw2);
73 
74  // handle border modes
75  bool return_black = false;
76 
77  switch (_uMode) {
78  case m_clamp: u = PtexUtils::clamp(u, 0.0f, 1.0f); break;
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;
81  }
82 
83  switch (_vMode) {
84  case m_clamp: v = PtexUtils::clamp(v, 0.0f, 1.0f); 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;
87  }
88 
89  if (return_black) {
90  memset(result, 0, sizeof(float)*_nchan);
91  return;
92  }
93 
94  // build kernel
96  if (f.isSubface()) {
97  // for a subface, build the kernel as if it were on a main face and then downres
98  uw = uw * width + blur * 2.0f;
99  vw = vw * width + blur * 2.0f;
100  buildKernel(k, u*.5f, v*.5f, uw*.5f, vw*.5f,
101  Ptex::Res((int8_t)(f.res.ulog2+1),(int8_t)(f.res.vlog2+1)));
102  if (k.res.ulog2 == 0) k.upresU();
103  if (k.res.vlog2 == 0) k.upresV();
104  k.res.ulog2--; k.res.vlog2--;
105  }
106  else {
107  uw = uw * width + blur;
108  vw = vw * width + blur;
109  buildKernel(k, u, v, uw, vw, f.res);
110  }
111  k.stripZeros();
112 
113  // check kernel (debug only)
114  assert(k.uw > 0 && k.vw > 0);
116  _weight = k.weight();
117 
118  // allocate temporary result
119  _result = (float*) alloca(sizeof(float)*_nchan);
120  memset(_result, 0, sizeof(float)*_nchan);
121 
122  // apply to faces
123  splitAndApply(k, faceid, f);
124 
125  // normalize (both for data type and cumulative kernel weight applied)
126  // and output result
127  float scale = 1.0f / (_weight * OneValue(_dt));
128  for (int i = 0; i < _nchan; i++) result[i] = float(_result[i] * scale);
129 
130  // clear temp result
131  _result = 0;
132 }
133 
134 
136 {
137  // do we need to split? (i.e. does kernel span an edge?)
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);
140 
141  if (_options.noedgeblend) {
142  if (splitR) k.mergeR(_uMode);
143  if (splitL) k.mergeL(_uMode);
144  if (splitT) k.mergeT(_vMode);
145  if (splitB) k.mergeB(_vMode);
146  apply(k, faceid, f);
147  return;
148  }
149 
150  if (splitR || splitL || splitT || splitB) {
151  PtexSeparableKernel ka, kc;
152  if (splitR) {
153  if (f.adjface(e_right) >= 0) {
154  k.splitR(ka);
155  if (splitT) {
156  if (f.adjface(e_top) >= 0) {
157  ka.splitT(kc);
158  applyToCorner(kc, faceid, f, e_top);
159  }
160  else ka.mergeT(_vMode);
161  }
162  if (splitB) {
163  if (f.adjface(e_bottom) >= 0) {
164  ka.splitB(kc);
165  applyToCorner(kc, faceid, f, e_right);
166  }
167  else ka.mergeB(_vMode);
168  }
169  applyAcrossEdge(ka, faceid, f, e_right);
170  }
171  else k.mergeR(_uMode);
172  }
173  if (splitL) {
174  if (f.adjface(e_left) >= 0) {
175  k.splitL(ka);
176  if (splitT) {
177  if (f.adjface(e_top) >= 0) {
178  ka.splitT(kc);
179  applyToCorner(kc, faceid, f, e_left);
180  }
181  else ka.mergeT(_vMode);
182  }
183  if (splitB) {
184  if (f.adjface(e_bottom) >= 0) {
185  ka.splitB(kc);
186  applyToCorner(kc, faceid, f, e_bottom);
187  }
188  else ka.mergeB(_vMode);
189  }
190  applyAcrossEdge(ka, faceid, f, e_left);
191  }
192  else k.mergeL(_uMode);
193  }
194  if (splitT) {
195  if (f.adjface(e_top) >= 0) {
196  k.splitT(ka);
197  applyAcrossEdge(ka, faceid, f, e_top);
198  }
199  else k.mergeT(_vMode);
200  }
201  if (splitB) {
202  if (f.adjface(e_bottom) >= 0) {
203  k.splitB(ka);
204  applyAcrossEdge(ka, faceid, f, e_bottom);
205  }
206  else k.mergeB(_vMode);
207  }
208  }
209 
210  // do local face
211  apply(k, faceid, f);
212 }
213 
214 
216  int faceid, const Ptex::FaceInfo& f, int eid)
217 {
218  int afid = f.adjface(eid), aeid = f.adjedge(eid);
219  const Ptex::FaceInfo* af = &_tx->getFaceInfo(afid);
220  int rot = eid - aeid + 2;
221 
222  // adjust uv coord and res for face/subface boundary
223  bool fIsSubface = f.isSubface(), afIsSubface = af->isSubface();
224  if (fIsSubface != afIsSubface) {
225  if (afIsSubface) {
226  // main face to subface transition
227  // adjust res and offset uv coord for primary subface
228  bool primary = k.adjustMainToSubface(eid);
229  if (!primary) {
230  // advance ajacent face and edge id to secondary subface
231  int neid = (aeid + 3) % 4;
232  afid = af->adjface(neid);
233  aeid = af->adjedge(neid);
234  af = &_tx->getFaceInfo(afid);
235  rot += neid - aeid + 2;
236  }
237  }
238  else {
239  // subface to main face transition
240  // Note: the transform depends on which subface the kernel is
241  // coming from. The "primary" subface is the one the main
242  // face is pointing at. The secondary subface adjustment
243  // happens to be the same as for the primary subface for the
244  // next edge, so the cases can be combined.
245  bool primary = (af->adjface(aeid) == faceid);
246  k.adjustSubfaceToMain(eid - primary);
247  }
248  }
249 
250  // rotate and apply (resplit if going to a subface)
251  k.rotate(rot);
252  if (afIsSubface) splitAndApply(k, afid, *af);
253  else apply(k, afid, *af);
254 }
255 
256 
258  const Ptex::FaceInfo& f, int eid)
259 {
260  // traverse clockwise around corner vertex and gather corner faces
261  int afid = faceid, aeid = eid;
262  const FaceInfo* af = &f;
263  bool prevIsSubface = af->isSubface();
264 
265  const int MaxValence = 10;
266  int cfaceId[MaxValence];
267  int cedgeId[MaxValence];
268  const FaceInfo* cface[MaxValence];
269 
270  int numCorners = 0;
271  for (int i = 0; i < MaxValence; i++) {
272  // advance to next face
273  int prevFace = afid;
274  afid = af->adjface(aeid);
275  aeid = (af->adjedge(aeid) + 1) % 4;
276 
277  // we hit a boundary or reached starting face
278  // note: we need to check edge id too because we might have
279  // a periodic texture (w/ toroidal topology) where all 4 corners
280  // are from the same face
281  if (afid < 0 || (afid == faceid && aeid == eid)) {
282  numCorners = i - 2;
283  break;
284  }
285 
286  // record face info
287  af = &_tx->getFaceInfo(afid);
288  cfaceId[i] = afid;
289  cedgeId[i] = aeid;
290  cface[i] = af;
291 
292  // check to see if corner is a subface "tee"
293  bool isSubface = af->isSubface();
294  if (prevIsSubface && !isSubface && af->adjface((aeid+3)%4) == prevFace)
295  {
296  // adjust the eid depending on whether we started from
297  // the primary or secondary subface.
298  bool primary = (i==1);
299  k.adjustSubfaceToMain(eid + primary * 2);
300  k.rotate(eid - aeid + 3 - primary);
301  splitAndApply(k, afid, *af);
302  return;
303  }
304  prevIsSubface = isSubface;
305  }
306 
307  if (numCorners == 1) {
308  // regular case (valence 4)
309  applyToCornerFace(k, f, eid, cfaceId[1], *cface[1], cedgeId[1]);
310  }
311  else if (numCorners > 1) {
312  // valence 5+, make kernel symmetric and apply equally to each face
313  // first, rotate to standard orientation, u=v=0
314  k.rotate(eid + 2);
315  float initialWeight = k.weight();
316  float newWeight = k.makeSymmetric(initialWeight);
317  for (int i = 1; i <= numCorners; i++) {
318  PtexSeparableKernel kc = k;
319  applyToCornerFace(kc, f, 2, cfaceId[i], *cface[i], cedgeId[i]);
320  }
321  // adjust weight for symmetrification and for additional corners
322  _weight += newWeight * (float)numCorners - initialWeight;
323  }
324  else {
325  // valence 2 or 3, ignore corner face (just adjust weight)
326  _weight -= k.weight();
327  }
328 }
329 
330 
332  int cfid, const Ptex::FaceInfo& cf, int ceid)
333 {
334  // adjust uv coord and res for face/subface boundary
335  bool fIsSubface = f.isSubface(), cfIsSubface = cf.isSubface();
336  if (fIsSubface != cfIsSubface) {
337  if (cfIsSubface) k.adjustMainToSubface(eid + 3);
338  else k.adjustSubfaceToMain(eid + 3);
339  }
340 
341  // rotate and apply (resplit if going to a subface)
342  k.rotate(eid - ceid + 2);
343  if (cfIsSubface) splitAndApply(k, cfid, cf);
344  else apply(k, cfid, cf);
345 }
346 
347 
349 {
350  assert(k.u >= 0 && k.u + k.uw <= k.res.u());
351  assert(k.v >= 0 && k.v + k.vw <= k.res.v());
352 
353  if (k.uw <= 0 || k.vw <= 0) return;
354 
355  // downres kernel if needed
356  while (k.res.u() > f.res.u()) k.downresU();
357  while (k.res.v() > f.res.v()) k.downresV();
358 
359  // get face data, and apply
360  PtexPtr<PtexFaceData> dh ( _tx->getData(faceid, k.res) );
361  if (!dh) return;
362 
363  if (dh->isConstant()) {
365  return;
366  }
367 
368  // allocate temporary result for tanvec mode (if needed)
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);
372 
373  if (dh->isTiled()) {
374  Ptex::Res tileres = dh->tileRes();
376  kt.res = tileres;
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;
382  kt.v = v % tileresv;
383  kt.vw = PtexUtils::min(vw, tileresv - kt.v);
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;
387  kt.u = u % tileresu;
388  kt.uw = PtexUtils::min(uw, tileresu - kt.u);
389  kt.ku = k.ku + u - k.u;
390  PtexPtr<PtexFaceData> th ( dh->getTile(tilev * ntilesu + tileu) );
391  if (th) {
392  if (th->isConstant())
393  kt.applyConst(result, (char*)th->getData()+_firstChanOffset, _dt, _nchan);
394  else
395  kt.apply(result, (char*)th->getData()+_firstChanOffset, _dt, _nchan, _ntxchan);
396  }
397  }
398  }
399  }
400  else {
401  k.apply(result, (char*)dh->getData()+_firstChanOffset, _dt, _nchan, _ntxchan);
402  }
403 
404  if (tanvecMode) {
405  // rotate tangent-space vector data and update main result
406  switch (k.rot) {
407  case 0: // rot==0 included for completeness, but tanvecMode should be false in this case
408  _result[0] += result[0];
409  _result[1] += result[1];
410  break;
411  case 1:
412  _result[0] -= result[1];
413  _result[1] += result[0];
414  break;
415  case 2:
416  _result[0] -= result[0];
417  _result[1] -= result[1];
418  break;
419  case 3:
420  _result[0] += result[1];
421  _result[1] -= result[0];
422  break;
423  }
424  for (int i = 2; i < _nchan; i++) _result[i] += result[i];
425  }
426 }
427 
PtexFaceData::getTile
virtual PtexFaceData * getTile(int tile)=0
Access a tile from the data block.
Ptex::Res
Pixel resolution of a given texture.
Definition: Ptexture.h:172
PtexUtils::min
T min(T a, T b)
Definition: PtexUtils.h:147
PtexSeparableFilter::applyToCorner
void applyToCorner(PtexSeparableKernel &k, int faceid, const Ptex::FaceInfo &f, int eid)
Definition: PtexSeparableFilter.cpp:257
PtexFaceData::isTiled
virtual bool isTiled()=0
True if this data block is tiled.
PtexSeparableKernel::v
int v
Definition: PtexSeparableKernel.h:51
PtexSeparableKernel::stripZeros
void stripZeros()
Definition: PtexSeparableKernel.h:96
PtexUtils::clamp
T clamp(T x, T lo, T hi)
Definition: PtexUtils.h:153
PtexSeparableKernel::upresV
void upresV()
Definition: PtexSeparableKernel.h:384
PtexSeparableKernel::uw
int uw
Definition: PtexSeparableKernel.h:52
Ptex::e_top
@ e_top
Top edge, from UV (1,1) to (0,1)
Definition: Ptexture.h:110
PTEX_NAMESPACE_END
#define PTEX_NAMESPACE_END
Definition: PtexVersion.h:62
PtexSeparableKernel::splitT
void splitT(PtexSeparableKernel &k)
Definition: PtexSeparableKernel.h:214
PtexSeparableKernel::upresU
void upresU()
Definition: PtexSeparableKernel.h:371
PtexSeparableFilter::_vMode
BorderMode _vMode
Definition: PtexSeparableFilter.h:86
PtexFaceData::isConstant
virtual bool isConstant()=0
True if this data block is constant.
PtexSeparableFilter::apply
void apply(PtexSeparableKernel &k, int faceid, const Ptex::FaceInfo &f)
Definition: PtexSeparableFilter.cpp:348
PtexSeparableFilter::applyAcrossEdge
void applyAcrossEdge(PtexSeparableKernel &k, int faceid, const Ptex::FaceInfo &f, int eid)
Definition: PtexSeparableFilter.cpp:215
PtexFaceData::tileRes
virtual Ptex::Res tileRes()=0
Resolution of each tile in this data block.
PtexUtils.h
PtexSeparableKernel::mergeT
void mergeT(BorderMode mode)
Definition: PtexSeparableKernel.h:139
Ptex::m_clamp
@ m_clamp
texel access is clamped to border
Definition: Ptexture.h:100
PtexSeparableKernel::adjustSubfaceToMain
void adjustSubfaceToMain(int eid)
Definition: PtexSeparableKernel.h:302
Ptex::DataSize
int DataSize(DataType dt)
Look up size of given data type (in bytes).
Definition: Ptexture.h:143
PtexSeparableKernel::splitR
void splitR(PtexSeparableKernel &k)
Definition: PtexSeparableKernel.h:171
PtexSeparableFilter.h
Ptex::FaceInfo::isSubface
bool isSubface() const
Determine if face is a subface (by checking a flag).
Definition: Ptexture.h:284
PtexSeparableKernel::adjustMainToSubface
bool adjustMainToSubface(int eid)
Definition: PtexSeparableKernel.h:266
PtexSeparableKernel::rotate
void rotate(int rotVal)
Definition: PtexSeparableKernel.h:254
Ptex::FaceInfo::adjface
int adjface(int eid) const
Access an adjacent face id. The eid value must be 0..3.
Definition: Ptexture.h:272
PtexSeparableKernel
Definition: PtexSeparableKernel.h:48
Ptex::m_black
@ m_black
texel beyond border are assumed to be black
Definition: Ptexture.h:101
PtexSeparableKernel::splitL
void splitL(PtexSeparableKernel &k)
Definition: PtexSeparableKernel.h:148
PtexSeparableKernel::vw
int vw
Definition: PtexSeparableKernel.h:52
Ptex::FaceInfo
Information about a face, as stored in the Ptex file header.
Definition: Ptexture.h:242
PtexSeparableKernel::mergeL
void mergeL(BorderMode mode)
Definition: PtexSeparableKernel.h:110
PtexSeparableFilter::_tx
PtexTexture * _tx
Definition: PtexSeparableFilter.h:78
PtexSeparableKernel::ku
float * ku
Definition: PtexSeparableKernel.h:53
PtexSeparableKernel::mergeB
void mergeB(BorderMode mode)
Definition: PtexSeparableKernel.h:129
Ptex::efm_tanvec
@ efm_tanvec
Values are vectors in tangent space; rotate values.
Definition: Ptexture.h:95
PtexTexture::numFaces
virtual int numFaces()=0
Number of faces stored in file.
PtexTexture::getData
virtual void getData(int faceid, void *buffer, int stride)=0
Access texture data for a face at highest-resolution.
PTEX_NAMESPACE_BEGIN
Definition: PtexSeparableKernel.cpp:42
Ptex::ConvertToFloat
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.
Ptex::OneValue
float OneValue(DataType dt)
Look up value of given data type that corresponds to the normalized value of 1.0.
Definition: Ptexture.h:149
PtexSeparableFilter::_weight
float _weight
Definition: PtexSeparableFilter.h:81
PtexSeparableKernel::downresV
void downresV()
Definition: PtexSeparableKernel.h:342
PtexPtr
Smart-pointer for acquiring and releasing API objects.
Definition: Ptexture.h:1045
PtexSeparableKernel.h
PtexSeparableKernel::applyConst
void applyConst(float *dst, void *data, DataType dt, int nChan)
Definition: PtexSeparableKernel.h:464
PtexSeparableKernel::res
Res res
Definition: PtexSeparableKernel.h:50
PtexSeparableFilter::eval
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.
Definition: PtexSeparableFilter.cpp:47
PtexSeparableFilter::_ntxchan
int _ntxchan
Definition: PtexSeparableFilter.h:84
Ptex::e_bottom
@ e_bottom
Bottom edge, from UV (0,0) to (1,0)
Definition: Ptexture.h:108
Ptex::m_periodic
@ m_periodic
texel access wraps to other side of face
Definition: Ptexture.h:102
Ptex::Res::u
int u() const
U resolution in texels.
Definition: Ptexture.h:186
Ptex::e_right
@ e_right
Right edge, from UV (1,0) to (1,1)
Definition: Ptexture.h:109
PtexSeparableKernel::u
int u
Definition: PtexSeparableKernel.h:51
PtexTexture::getFaceInfo
virtual const Ptex::FaceInfo & getFaceInfo(int faceid)=0
Access resolution and adjacency information about a face.
PtexSeparableFilter::_uMode
BorderMode _uMode
Definition: PtexSeparableFilter.h:86
PtexSeparableFilter::splitAndApply
void splitAndApply(PtexSeparableKernel &k, int faceid, const Ptex::FaceInfo &f)
Definition: PtexSeparableFilter.cpp:135
Ptex::e_left
@ e_left
Left edge, from UV (0,1) to (0,0)
Definition: Ptexture.h:111
PtexUtils::abs
T abs(T x)
Definition: PtexUtils.h:133
PtexSeparableFilter::_firstChanOffset
int _firstChanOffset
Definition: PtexSeparableFilter.h:82
PtexFaceData::getData
virtual void * getData()=0
Access the data from this data block.
PtexSeparableKernel::kv
float * kv
Definition: PtexSeparableKernel.h:54
Ptex::Res::v
int v() const
V resolution in texels.
Definition: Ptexture.h:189
PtexSeparableFilter::_result
float * _result
Definition: PtexSeparableFilter.h:80
Ptex::FaceInfo::adjedge
EdgeId adjedge(int eid) const
Access an adjacent edge id. The eid value must be 0..3.
Definition: Ptexture.h:269
PtexSeparableKernel::splitB
void splitB(PtexSeparableKernel &k)
Definition: PtexSeparableKernel.h:192
PtexSeparableKernel::apply
void apply(float *dst, void *data, DataType dt, int nChan, int nTxChan)
Definition: PtexSeparableKernel.h:457
PtexSeparableFilter::_nchan
int _nchan
Definition: PtexSeparableFilter.h:83
PtexSeparableFilter::_options
Options _options
Definition: PtexSeparableFilter.h:79
PtexSeparableKernel::mergeR
void mergeR(BorderMode mode)
Definition: PtexSeparableKernel.h:120
PtexSeparableKernel::makeSymmetric
float makeSymmetric(float initialWeight)
Definition: PtexSeparableKernel.h:397
PtexSeparableKernel::weight
float weight() const
Definition: PtexSeparableKernel.h:105
PtexSeparableFilter::applyToCornerFace
void applyToCornerFace(PtexSeparableKernel &k, const Ptex::FaceInfo &f, int eid, int cfaceid, const Ptex::FaceInfo &cf, int ceid)
Definition: PtexSeparableFilter.cpp:331
PtexSeparableFilter::_dt
DataType _dt
Definition: PtexSeparableFilter.h:85
PtexSeparableKernel::rot
int rot
Definition: PtexSeparableKernel.h:58
PtexSeparableKernel::downresU
void downresU()
Definition: PtexSeparableKernel.h:313
Ptex::FaceInfo::res
Res res
Resolution of face.
Definition: Ptexture.h:243
PtexSeparableKernel::kmax
static const int kmax
Definition: PtexSeparableKernel.h:55
PtexSeparableFilter::_efm
EdgeFilterMode _efm
Definition: PtexSeparableFilter.h:87
PtexFilter::Options::noedgeblend
bool noedgeblend
Disable cross-face filtering. Useful for debugging or rendering on polys.
Definition: Ptexture.h:974
PtexPlatform.h
Platform-specific classes, functions, and includes.
PtexSeparableFilter::buildKernel
virtual void buildKernel(PtexSeparableKernel &k, float u, float v, float uw, float vw, Res faceRes)=0