Ptex: PtexTriangleFilter.cpp Source File

Ptex

- Main Page
- Related Pages
- Namespaces
- Classes
- Files

- File List
- File Members

PtexTriangleFilter.cpp
Go to the documentation of this file.
1 /*
2 PTEX SOFTWARE
3 Copyright 2009 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 <math.h>
38 #include <assert.h>
39
40 #include "PtexTriangleFilter.h"
41 #include "PtexTriangleKernel.h"
42 #include "PtexUtils.h"
43
44 namespace {
45 inline float squared(float x) { return x*x; }
46 }
47
48 void PtexTriangleFilter::eval(float* result, int firstChan, int nChannels,
49 int faceid, float u, float v,
50 float uw1, float vw1, float uw2, float vw2,
51 float width, float blur)
52 {
53 // init
54 if (!_tx || nChannels <= 0) return;
55 if (faceid < 0 || faceid >= _tx->numFaces()) return;
56 _ntxchan = _tx->numChannels();
57 _dt = _tx->dataType();
58 _firstChanOffset = firstChan*DataSize(_dt);
59 _nchan = PtexUtils::min(nChannels, _ntxchan-firstChan);
60
61 // get face info
62 const FaceInfo& f = _tx->getFaceInfo(faceid);
63
64 // if neighborhood is constant, just return constant value of face
65 if (f.isNeighborhoodConstant()) {
66 PtexPtr<PtexFaceData> data ( _tx->getData(faceid, 0) );
67 if (data) {
68 char* d = (char*) data->getData() + _firstChanOffset;
69 Ptex::ConvertToFloat(result, d, _dt, _nchan);
70 }
71 return;
72 }
73
74 // clamp u and v
75 u = PtexUtils::clamp(u, 0.0f, 1.0f);
76 v = PtexUtils::clamp(v, 0.0f, 1.0f);
77
78 // build kernel
79 PtexTriangleKernel k;
80 buildKernel(k, u, v, uw1, vw1, uw2, vw2, width, blur, f.res);
81
82 // accumulate the weight as we apply
83 _weight = 0;
84
85 // allocate temporary result
86 _result = (float*) alloca(sizeof(float)*_nchan);
87 memset(_result, 0, sizeof(float)*_nchan);
88
89 // apply to faces
90 splitAndApply(k, faceid, f);
91
92 // normalize (both for data type and cumulative kernel weight applied)
93 // and output result
94 float scale = 1.0f / (_weight * OneValue(_dt));
95 for (int i = 0; i < _nchan; i++) result[i] = float(_result[i] * scale);
96
97 // clear temp result
98 _result = 0;
99 }
100
101
102
103 void PtexTriangleFilter::buildKernel(PtexTriangleKernel& k, float u, float v,
104 float uw1, float vw1, float uw2, float vw2,
105 float width, float blur, Res faceRes)
106 {
107 const float sqrt3 = 1.7320508075688772f;
108
109 // compute ellipse coefficients, A*u^2 + B*u*v + C*v^2 == AC - B^2/4
110 float scaleAC = 0.25f * width*width;
111 float scaleB = -2.0f * scaleAC;
112 float A = (vw1*vw1 + vw2*vw2) * scaleAC;
113 float B = (uw1*vw1 + uw2*vw2) * scaleB;
114 float C = (uw1*uw1 + uw2*uw2) * scaleAC;
115
116 // convert to cartesian domain
117 float Ac = 0.75f * A;
118 float Bc = float(sqrt3/2) * (B-A);
119 float Cc = 0.25f * A - 0.5f * B + C;
120
121 // compute min blur for eccentricity clamping
122 const float maxEcc = 15.0f; // max eccentricity
123 const float eccRatio = (maxEcc*maxEcc + 1.0f) / (maxEcc*maxEcc - 1.0f);
124 float X = sqrtf(squared(Ac - Cc) + squared(Bc));
125 float b_e = 0.5f * (eccRatio * X - (Ac + Cc));
126
127 // compute min blur for texel clamping
128 // (ensure that ellipse is no smaller than a texel)
129 float b_t = squared(0.5f / (float)faceRes.u());
130
131 // add blur
132 float b_b = 0.25f * blur * blur;
133 float b = PtexUtils::max(b_b, PtexUtils::max(b_e, b_t));
134 Ac += b;
135 Cc += b;
136
137 // compute minor radius
138 float m = sqrtf(2.0f*(Ac*Cc - 0.25f*Bc*Bc) / (Ac + Cc + X));
139
140 // choose desired resolution
141 int reslog2 = PtexUtils::max(0, PtexUtils::calcResFromWidth(2.0f*m));
142
143 // convert back to triangular domain
144 A = float(4/3.0) * Ac;
145 B = float(2/sqrt3) * Bc + A;
146 C = -0.25f * A + 0.5f * B + Cc;
147
148 // scale by kernel width
149 float scale = PtexTriangleKernelWidth * PtexTriangleKernelWidth;
150 A *= scale;
151 B *= scale;
152 C *= scale;
153
154 // find u,v,w extents
155 float uw = PtexUtils::min(sqrtf(C), 1.0f);
156 float vw = PtexUtils::min(sqrtf(A), 1.0f);
157 float ww = PtexUtils::min(sqrtf(A-B+C), 1.0f);
158
159 // init kernel
160 float w = 1.0f - u - v;
161 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);
162 }
163
164
165 void PtexTriangleFilter::splitAndApply(PtexTriangleKernel& k, int faceid, const Ptex::FaceInfo& f)
166 {
167 // do we need to split? if so, split kernel and apply across edge(s)
168 if (k.u1 < 0 && f.adjface(2) >= 0) {
169 PtexTriangleKernel ka;
170 k.splitU(ka);
171 applyAcrossEdge(ka, f, 2);
172 }
173 if (k.v1 < 0 && f.adjface(0) >= 0) {
174 PtexTriangleKernel ka;
175 k.splitV(ka);
176 applyAcrossEdge(ka, f, 0);
177 }
178 if (k.w1 < 0 && f.adjface(1) >= 0) {
179 PtexTriangleKernel ka;
180 k.splitW(ka);
181 applyAcrossEdge(ka, f, 1);
182 }
183 // apply to local face
184 apply(k, faceid, f);
185 }
186
187
188 void PtexTriangleFilter::applyAcrossEdge(PtexTriangleKernel& k,
189 const Ptex::FaceInfo& f, int eid)
190 {
191 int afid = f.adjface(eid), aeid = f.adjedge(eid);
192 const Ptex::FaceInfo& af = _tx->getFaceInfo(afid);
193 k.reorient(eid, aeid);
194 splitAndApply(k, afid, af);
195 }
196
197
198 void PtexTriangleFilter::apply(PtexTriangleKernel& k, int faceid, const Ptex::FaceInfo& f)
199 {
200 // clamp kernel face (resolution and extent)
201 k.clampRes(f.res);
202 k.clampExtent();
203
204 // build kernel iterators
205 PtexTriangleKernelIter keven, kodd;
206 k.getIterators(keven, kodd);
207 if (!keven.valid && !kodd.valid) return;
208
209 // get face data, and apply
210 PtexPtr<PtexFaceData> dh ( _tx->getData(faceid, k.res) );
211 if (!dh) return;
212
213 if (keven.valid) applyIter(keven, dh);
214 if (kodd.valid) applyIter(kodd, dh);
215 }
216
217
218 void PtexTriangleFilter::applyIter(PtexTriangleKernelIter& k, PtexFaceData* dh)
219 {
220 if (dh->isConstant()) {
221 k.applyConst(_result, (char*)dh->getData()+_firstChanOffset, _dt, _nchan);
222 _weight += k.weight;
223 }
224 else if (dh->isTiled()) {
225 Ptex::Res tileres = dh->tileRes();
226 PtexTriangleKernelIter kt = k;
227 int tileresu = tileres.u();
228 int tileresv = tileres.v();
229 kt.rowlen = tileresu;
230 int ntilesu = k.rowlen / kt.rowlen;
231 int wOffsetBase = k.rowlen - tileresu;
232 for (int tilev = k.v1 / tileresv, tilevEnd = (k.v2-1) / tileresv; tilev <= tilevEnd; tilev++) {
233 int vOffset = tilev * tileresv;
234 kt.v = k.v - (float)vOffset;
235 kt.v1 = PtexUtils::max(0, k.v1 - vOffset);
236 kt.v2 = PtexUtils::min(k.v2 - vOffset, tileresv);
237 for (int tileu = k.u1 / tileresu, tileuEnd = (k.u2-1) / tileresu; tileu <= tileuEnd; tileu++) {
238 int uOffset = tileu * tileresu;
239 int wOffset = wOffsetBase - uOffset - vOffset;
240 kt.u = k.u - (float)uOffset;
241 kt.u1 = PtexUtils::max(0, k.u1 - uOffset);
242 kt.u2 = PtexUtils::min(k.u2 - uOffset, tileresu);
243 kt.w1 = k.w1 - wOffset;
244 kt.w2 = k.w2 - wOffset;
245 PtexPtr<PtexFaceData> th ( dh->getTile(tilev * ntilesu + tileu) );
246 if (th) {
247 kt.weight = 0;
248 if (th->isConstant())
249 kt.applyConst(_result, (char*)th->getData()+_firstChanOffset, _dt, _nchan);
250 else
251 kt.apply(_result, (char*)th->getData()+_firstChanOffset, _dt, _nchan, _ntxchan);
252 _weight += kt.weight;
253 }
254 }
255 }
256 }
257 else {
258 k.apply(_result, (char*)dh->getData()+_firstChanOffset, _dt, _nchan, _ntxchan);
259 _weight += k.weight;
260 }
261 }
PtexTriangleFilter::apply
void apply(PtexTriangleKernel &k, int faceid, const Ptex::FaceInfo &f)
Definition: PtexTriangleFilter.cpp:198
Ptex::FaceInfo::adjface
int adjface(int eid) const
Access an adjacent face id. The eid value must be 0..3.
Definition: Ptexture.h:267
PtexTexture::numChannels
virtual int numChannels()=0
Number of channels stored in file.
PtexTriangleFilter::_ntxchan
int _ntxchan
Definition: PtexTriangleFilter.h:74
PtexTriangleKernel::w1
float w1
Definition: PtexTriangleKernel.h:84
PtexTriangleKernelIter::applyConst
void applyConst(float *dst, void *data, DataType dt, int nChan)
Definition: PtexTriangleKernel.cpp:156
PtexTriangleKernelIter::rowlen
int rowlen
Definition: PtexTriangleKernel.h:54
PtexTriangleKernel::splitU
void splitU(PtexTriangleKernel &ka)
Definition: PtexTriangleKernel.h:114
PtexTriangleFilter::_tx
PtexTexture * _tx
Definition: PtexTriangleFilter.h:68
PtexTriangleKernel.h
Ptex::DataSize
static int DataSize(DataType dt)
Look up size of given data type (in bytes).
Definition: Ptexture.h:132
PtexTriangleKernelIter::apply
void apply(float *dst, void *data, DataType dt, int nChan, int nTxChan)
Definition: PtexTriangleKernel.h:63
PtexTriangleKernelIter::weight
float weight
Definition: PtexTriangleKernel.h:61
PtexTriangleKernel::splitV
void splitV(PtexTriangleKernel &ka)
Definition: PtexTriangleKernel.h:121
PtexTriangleFilter::_weight
float _weight
Definition: PtexTriangleFilter.h:71
PtexTriangleFilter::buildKernel
void buildKernel(PtexTriangleKernel &k, float u, float v, float uw1, float vw1, float uw2, float vw2, float width, float blur, Res faceRes)
Definition: PtexTriangleFilter.cpp:103
PtexTriangleKernel::reorient
void reorient(int eid, int aeid)
Definition: PtexTriangleKernel.h:149
PtexTriangleKernelIter::valid
bool valid
Definition: PtexTriangleKernel.h:59
PtexUtils::min
static T min(T a, T b)
Definition: PtexUtils.h:116
PtexTriangleKernelIter::v
float v
Definition: PtexTriangleKernel.h:55
PtexTriangleFilter.h
PtexTriangleKernelIter
Triangle filter kernel iterator (in texel coords)
Definition: PtexTriangleKernel.h:52
Ptex::FaceInfo::isNeighborhoodConstant
bool isNeighborhoodConstant() const
Determine if neighborhood of face is constant (by checking a flag).
Definition: Ptexture.h:273
PtexTriangleKernel::clampExtent
void clampExtent()
Definition: PtexTriangleKernel.h:176
PtexTriangleFilter::splitAndApply
void splitAndApply(PtexTriangleKernel &k, int faceid, const Ptex::FaceInfo &f)
Definition: PtexTriangleFilter.cpp:165
PtexPlatform.h
Platform-specific classes, functions, and includes.
PtexTriangleKernel::v1
float v1
Definition: PtexTriangleKernel.h:84
Ptex::Res::v
int v() const
V resolution in texels.
Definition: Ptexture.h:181
Ptex::OneValue
static float OneValue(DataType dt)
Look up value of given data type that corresponds to the normalized value of 1.0. ...
Definition: Ptexture.h:138
C
#define C(eid, aeid)
PtexTriangleKernelIter::v2
int v2
Definition: PtexTriangleKernel.h:57
PtexTriangleKernelIter::u2
int u2
Definition: PtexTriangleKernel.h:57
PtexFaceData
Per-face texture data accessor.
Definition: Ptexture.h:388
Ptex::Res::u
int u() const
U resolution in texels.
Definition: Ptexture.h:178
PtexTriangleKernelIter::w2
int w2
Definition: PtexTriangleKernel.h:57
PtexFaceData::getData
virtual void * getData()=0
Access the data from this data block.
PtexUtils::clamp
static T clamp(T x, T lo, T hi)
Definition: PtexUtils.h:122
PtexFaceData::getTile
virtual PtexFaceData * getTile(int tile)=0
Access a tile from the data block.
PtexTriangleKernel::res
Res res
Definition: PtexTriangleKernel.h:82
PtexTexture::getData
virtual void getData(int faceid, void *buffer, int stride)=0
Access texture data for a face at highest-resolution.
PtexTriangleFilter::_result
float * _result
Definition: PtexTriangleFilter.h:70
PtexUtils::calcResFromWidth
static int calcResFromWidth(float w)
Definition: PtexUtils.h:82
PtexTriangleKernelIter::u1
int u1
Definition: PtexTriangleKernel.h:56
PtexTriangleKernelIter::w1
int w1
Definition: PtexTriangleKernel.h:56
PtexTexture::numFaces
virtual int numFaces()=0
Number of faces stored in file.
PtexTriangleKernel
Triangle filter kernel (in normalized triangle coords)
Definition: PtexTriangleKernel.h:80
PtexTriangleKernel::set
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)
Definition: PtexTriangleKernel.h:88
Ptex::FaceInfo::adjedge
EdgeId adjedge(int eid) const
Access an adjacent edge id. The eid value must be 0..3.
Definition: Ptexture.h:264
PtexTriangleKernelIter::u
float u
Definition: PtexTriangleKernel.h:55
PtexTriangleKernel::u1
float u1
Definition: PtexTriangleKernel.h:84
PtexTexture::dataType
virtual Ptex::DataType dataType()=0
Type of data stored in file.
PtexTriangleKernel::getIterators
void getIterators(PtexTriangleKernelIter &ke, PtexTriangleKernelIter &ko)
Definition: PtexTriangleKernel.h:186
PtexPtr
Smart-pointer for acquiring and releasing API objects.
Definition: Ptexture.h:955
PtexFaceData::isTiled
virtual bool isTiled()=0
True if this data block is tiled.
PtexFaceData::isConstant
virtual bool isConstant()=0
True if this data block is constant.
PtexTriangleFilter::_firstChanOffset
int _firstChanOffset
Definition: PtexTriangleFilter.h:72
Ptex::Res
Pixel resolution of a given texture.
Definition: Ptexture.h:161
PtexTriangleFilter::applyAcrossEdge
void applyAcrossEdge(PtexTriangleKernel &k, const Ptex::FaceInfo &f, int eid)
Definition: PtexTriangleFilter.cpp:188
PtexTriangleFilter::_nchan
int _nchan
Definition: PtexTriangleFilter.h:73
Ptex::FaceInfo::res
Res res
Resolution of face.
Definition: Ptexture.h:238
PtexTriangleKernelWidth
static const float PtexTriangleKernelWidth
Definition: PtexTriangleKernel.h:48
Ptex::FaceInfo
Information about a face, as stored in the Ptex file header.
Definition: Ptexture.h:237
PtexTriangleFilter::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: PtexTriangleFilter.cpp:48
Ptex::ConvertToFloat
static 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.
Definition: PtexUtils.cpp:107
PtexTexture::getFaceInfo
virtual const Ptex::FaceInfo & getFaceInfo(int faceid)=0
Access resolution and adjacency information about a face.
PtexTriangleKernel::clampRes
void clampRes(Res fres)
Definition: PtexTriangleKernel.h:170
PtexUtils.h
PtexTriangleKernelIter::v1
int v1
Definition: PtexTriangleKernel.h:56
PtexTriangleFilter::_dt
DataType _dt
Definition: PtexTriangleFilter.h:75
PtexTriangleFilter::applyIter
void applyIter(PtexTriangleKernelIter &k, PtexFaceData *dh)
Definition: PtexTriangleFilter.cpp:218
PtexTriangleKernel::splitW
void splitW(PtexTriangleKernel &ka)
Definition: PtexTriangleKernel.h:128
PtexFaceData::tileRes
virtual Ptex::Res tileRes()=0
Resolution of each tile in this data block.
PtexUtils::max
static T max(T a, T b)
Definition: PtexUtils.h:119