50 static const char* names[] = {
"triangle",
"quad" };
51 if (mt < 0 || mt >=
int(
sizeof(names)/
sizeof(
const char*)))
52 return "(invalid mesh type)";
59 static const char* names[] = {
"uint8",
"uint16",
"float16",
"float32" };
60 if (dt < 0 || dt >=
int(
sizeof(names)/
sizeof(
const char*)))
61 return "(invalid data type)";
68 static const char* names[] = {
"clamp",
"black",
"periodic" };
69 if (m < 0 || m >=
int(
sizeof(names)/
sizeof(
const char*)))
70 return "(invalid border mode)";
76 static const char* names[] = {
"none",
"tanvec" };
77 if (m < 0 || m >=
int(
sizeof(names)/
sizeof(
const char*)))
78 return "(invalid edge filter mode)";
85 static const char* names[] = {
"bottom",
"right",
"top",
"left" };
86 if (eid < 0 || eid >=
int(
sizeof(names)/
sizeof(
const char*)))
87 return "(invalid edge id)";
94 static const char* names[] = {
"string",
"int8",
"int16",
"int32",
"float",
"double" };
95 if (mdt < 0 || mdt >=
int(
sizeof(names)/
sizeof(
const char*)))
96 return "(invalid meta data type)";
102 template<
typename DST,
typename SRC>
103 void ConvertArrayClamped(DST* dst, SRC* src,
int numChannels,
float scale,
float round=0)
105 for (
int i = 0; i < numChannels; i++)
109 template<
typename DST,
typename SRC>
110 void ConvertArray(DST* dst, SRC* src,
int numChannels,
float scale,
float round=0)
112 for (
int i = 0; i < numChannels; i++)
113 dst[i] = DST((
float)src[i] * scale + round);
120 case dt_uint8: ConvertArray(dst,
static_cast<const uint8_t*
>(src), numChannels, 1.f/255.f);
break;
121 case dt_uint16: ConvertArray(dst,
static_cast<const uint16_t*
>(src), numChannels, 1.f/65535.f);
break;
122 case dt_half: ConvertArray(dst,
static_cast<const PtexHalf*
>(src), numChannels, 1.f);
break;
123 case dt_float: memcpy(dst, src,
sizeof(
float)*numChannels);
break;
131 case dt_uint8: ConvertArrayClamped(
static_cast<uint8_t*
>(dst), src, numChannels, 255.0, 0.5);
break;
132 case dt_uint16: ConvertArrayClamped(
static_cast<uint16_t*
>(dst), src, numChannels, 65535.0, 0.5);
break;
133 case dt_half: ConvertArray(
static_cast<PtexHalf*
>(dst), src, numChannels, 1.0);
break;
134 case dt_float: memcpy(dst, src,
sizeof(
float)*numChannels);
break;
141 bool isConstant(
const void* data,
int stride,
int ures,
int vres,
144 int rowlen = pixelSize * ures;
145 const char* p = (
const char*) data + stride;
148 for (
int i = 1; i < vres; i++, p += stride)
149 if (0 != memcmp(data, p, rowlen))
return 0;
152 p = (
const char*) data + pixelSize;
153 for (
int i = 1; i < ures; i++, p += pixelSize)
154 if (0 != memcmp(data, p, pixelSize))
return 0;
162 inline void interleave(
const T* src,
int sstride,
int uw,
int vw,
163 T* dst,
int dstride,
int nchan)
165 sstride /= (int)
sizeof(T);
166 dstride /= (int)
sizeof(T);
168 for (T* dstend = dst + nchan; dst != dstend; dst++) {
171 for (
const T* rowend = src + sstride*vw; src != rowend;
172 src += sstride, drow += dstride) {
175 for (
const T* sp = src, * end = sp + uw; sp != end; dp += nchan)
183 void interleave(
const void* src,
int sstride,
int uw,
int vw,
184 void* dst,
int dstride,
DataType dt,
int nchan)
188 (uint8_t*) dst, dstride, nchan);
break;
191 (uint16_t*) dst, dstride, nchan);
break;
193 (
float*) dst, dstride, nchan);
break;
199 inline void deinterleave(
const T* src,
int sstride,
int uw,
int vw,
200 T* dst,
int dstride,
int nchan)
202 sstride /= (int)
sizeof(T);
203 dstride /= (int)
sizeof(T);
205 for (
const T* srcend = src + nchan; src != srcend; src++) {
208 for (
const T* rowend = srow + sstride*vw; srow != rowend;
209 srow += sstride, dst += dstride) {
212 for (T* dp = dst, * end = dp + uw; dp != end; sp += nchan)
221 void* dst,
int dstride,
DataType dt,
int nchan)
225 (uint8_t*) dst, dstride, nchan);
break;
228 (uint16_t*) dst, dstride, nchan);
break;
230 (
float*) dst, dstride, nchan);
break;
239 size /= (int)
sizeof(T);
240 T* p =
static_cast<T*
>(data), * end = p + size, tmp, prev = 0;
241 while (p != end) { tmp = prev; prev = *p; *p = T(*p - tmp); p++; }
259 size /= (int)
sizeof(T);
260 T* p =
static_cast<T*
>(data), * end = p + size, prev = 0;
261 while (p != end) { *p = T(*p + prev); prev = *p++; }
277 inline void reduce(
const T* src,
int sstride,
int uw,
int vw,
278 T* dst,
int dstride,
int nchan)
280 sstride /= (int)
sizeof(T);
281 dstride /= (int)
sizeof(T);
282 int rowlen = uw*nchan;
283 int srowskip = 2*sstride - rowlen;
284 int drowskip = dstride - rowlen/2;
285 for (
const T* end = src + vw*sstride; src != end;
286 src += srowskip, dst += drowskip)
287 for (
const T* rowend = src + rowlen; src != rowend; src += nchan)
288 for (
const T* pixend = src+nchan; src != pixend; src++)
289 *dst++ = T(
quarter(src[0] + src[nchan] + src[sstride] + src[sstride+nchan]));
293 void reduce(
const void* src,
int sstride,
int uw,
int vw,
294 void* dst,
int dstride,
DataType dt,
int nchan)
297 case dt_uint8:
reduce(
static_cast<const uint8_t*
>(src), sstride, uw, vw,
298 static_cast<uint8_t*
>(dst), dstride, nchan);
break;
300 static_cast<PtexHalf*
>(dst), dstride, nchan);
break;
301 case dt_uint16:
reduce(
static_cast<const uint16_t*
>(src), sstride, uw, vw,
302 static_cast<uint16_t*
>(dst), dstride, nchan);
break;
303 case dt_float:
reduce(
static_cast<const float*
>(src), sstride, uw, vw,
304 static_cast<float*
>(dst), dstride, nchan);
break;
311 inline void reduceu(
const T* src,
int sstride,
int uw,
int vw,
312 T* dst,
int dstride,
int nchan)
314 sstride /= (int)
sizeof(T);
315 dstride /= (int)
sizeof(T);
316 int rowlen = uw*nchan;
317 int srowskip = sstride - rowlen;
318 int drowskip = dstride - rowlen/2;
319 for (
const T* end = src + vw*sstride; src != end;
320 src += srowskip, dst += drowskip)
321 for (
const T* rowend = src + rowlen; src != rowend; src += nchan)
322 for (
const T* pixend = src+nchan; src != pixend; src++)
323 *dst++ = T(
halve(src[0] + src[nchan]));
327 void reduceu(
const void* src,
int sstride,
int uw,
int vw,
328 void* dst,
int dstride,
DataType dt,
int nchan)
331 case dt_uint8:
reduceu(
static_cast<const uint8_t*
>(src), sstride, uw, vw,
332 static_cast<uint8_t*
>(dst), dstride, nchan);
break;
334 static_cast<PtexHalf*
>(dst), dstride, nchan);
break;
336 static_cast<uint16_t*
>(dst), dstride, nchan);
break;
337 case dt_float:
reduceu(
static_cast<const float*
>(src), sstride, uw, vw,
338 static_cast<float*
>(dst), dstride, nchan);
break;
345 inline void reducev(
const T* src,
int sstride,
int uw,
int vw,
346 T* dst,
int dstride,
int nchan)
348 sstride /= (int)
sizeof(T);
349 dstride /= (int)
sizeof(T);
350 int rowlen = uw*nchan;
351 int srowskip = 2*sstride - rowlen;
352 int drowskip = dstride - rowlen;
353 for (
const T* end = src + vw*sstride; src != end;
354 src += srowskip, dst += drowskip)
355 for (
const T* rowend = src + rowlen; src != rowend; src++)
356 *dst++ = T(
halve(src[0] + src[sstride]));
360 void reducev(
const void* src,
int sstride,
int uw,
int vw,
361 void* dst,
int dstride,
DataType dt,
int nchan)
364 case dt_uint8:
reducev(
static_cast<const uint8_t*
>(src), sstride, uw, vw,
365 static_cast<uint8_t*
>(dst), dstride, nchan);
break;
367 static_cast<PtexHalf*
>(dst), dstride, nchan);
break;
369 static_cast<uint16_t*
>(dst), dstride, nchan);
break;
370 case dt_float:
reducev(
static_cast<const float*
>(src), sstride, uw, vw,
371 static_cast<float*
>(dst), dstride, nchan);
break;
381 inline void reduceTri(
const T* src,
int sstride,
int w,
int ,
382 T* dst,
int dstride,
int nchan)
384 sstride /= (int)
sizeof(T);
385 dstride /= (int)
sizeof(T);
386 int rowlen = w*nchan;
387 const T* src2 = src + (w-1) * sstride + rowlen - nchan;
388 int srowinc2 = -2*sstride - nchan;
389 int srowskip = 2*sstride - rowlen;
390 int srowskip2 = w*sstride - 2 * nchan;
391 int drowskip = dstride - rowlen/2;
392 for (
const T* end = src + w*sstride; src != end;
393 src += srowskip, src2 += srowskip2, dst += drowskip)
394 for (
const T* rowend = src + rowlen; src != rowend; src += nchan, src2 += srowinc2)
395 for (
const T* pixend = src+nchan; src != pixend; src++, src2++)
396 *dst++ = T(
quarter(src[0] + src[nchan] + src[sstride] + src2[0]));
400 void reduceTri(
const void* src,
int sstride,
int w,
int ,
401 void* dst,
int dstride,
DataType dt,
int nchan)
405 static_cast<uint8_t*
>(dst), dstride, nchan);
break;
407 static_cast<PtexHalf*
>(dst), dstride, nchan);
break;
409 static_cast<uint16_t*
>(dst), dstride, nchan);
break;
411 static_cast<float*
>(dst), dstride, nchan);
break;
416 void fill(
const void* src,
void* dst,
int dstride,
417 int ures,
int vres,
int pixelsize)
420 int rowlen = ures*pixelsize;
421 char* ptr = (
char*) dst;
422 char* end = ptr + rowlen;
423 for (; ptr != end; ptr += pixelsize) memcpy(ptr, src, pixelsize);
426 ptr = (
char*) dst + dstride;
427 end = (
char*) dst + vres*dstride;
428 for (; ptr != end; ptr += dstride) memcpy(ptr, dst, rowlen);
432 void copy(
const void* src,
int sstride,
void* dst,
int dstride,
433 int vres,
int rowlen)
436 if (sstride == rowlen && dstride == rowlen) {
438 memcpy(dst, src, vres*rowlen);
441 const char* sptr = (
const char*) src;
442 char* dptr = (
char*) dst;
443 for (
const char* end = sptr + vres*sstride; sptr != end;) {
444 memcpy(dptr, sptr, rowlen);
454 inline void blend(
const T* src,
float weight, T* dst,
int rowlen,
int nchan)
456 for (
const T* end = src + rowlen * nchan; src != end; dst++)
457 *dst = T(*dst + T(weight * (
float)*src++));
461 inline void blendflip(
const T* src,
float weight, T* dst,
int rowlen,
int nchan)
463 dst += (rowlen-1) * nchan;
464 for (
const T* end = src + rowlen * nchan; src != end;) {
465 for (
int i = 0; i < nchan; i++, dst++) {
466 *dst = T(*dst + T(weight * (
float)*src++));
474 void blend(
const void* src,
float weight,
void* dst,
bool flip,
477 switch ((dt<<1) |
int(flip)) {
478 case (
dt_uint8<<1):
blend(
static_cast<const uint8_t*
>(src), weight,
479 static_cast<uint8_t*
>(dst), rowlen, nchan);
break;
480 case (
dt_uint8<<1 | 1): blendflip(
static_cast<const uint8_t*
>(src), weight,
481 static_cast<uint8_t*
>(dst), rowlen, nchan);
break;
483 static_cast<PtexHalf*
>(dst), rowlen, nchan);
break;
484 case (
dt_half<<1 | 1): blendflip(
static_cast<const PtexHalf*
>(src), weight,
485 static_cast<PtexHalf*
>(dst), rowlen, nchan);
break;
486 case (
dt_uint16<<1):
blend(
static_cast<const uint16_t*
>(src), weight,
487 static_cast<uint16_t*
>(dst), rowlen, nchan);
break;
488 case (
dt_uint16<<1 | 1): blendflip(
static_cast<const uint16_t*
>(src), weight,
489 static_cast<uint16_t*
>(dst), rowlen, nchan);
break;
490 case (
dt_float<<1):
blend(
static_cast<const float*
>(src), weight,
491 static_cast<float*
>(dst), rowlen, nchan);
break;
492 case (
dt_float<<1 | 1): blendflip(
static_cast<const float*
>(src), weight,
493 static_cast<float*
>(dst), rowlen, nchan);
break;
500 inline void average(
const T* src,
int sstride,
int uw,
int vw,
503 float* buff = (
float*) alloca(nchan*
sizeof(
float));
504 memset(buff, 0, nchan*
sizeof(
float));
505 sstride /= (int)
sizeof(T);
506 int rowlen = uw*nchan;
507 int rowskip = sstride - rowlen;
508 for (
const T* end = src + vw*sstride; src != end; src += rowskip)
509 for (
const T* rowend = src + rowlen; src != rowend;)
510 for (
int i = 0; i < nchan; i++) buff[i] += (
float)*src++;
511 float scale = 1.0f/(float)(uw*vw);
512 for (
int i = 0; i < nchan; i++) dst[i] = T(buff[i]*scale);
516 void average(
const void* src,
int sstride,
int uw,
int vw,
520 case dt_uint8:
average(
static_cast<const uint8_t*
>(src), sstride, uw, vw,
521 static_cast<uint8_t*
>(dst), nchan);
break;
523 static_cast<PtexHalf*
>(dst), nchan);
break;
525 static_cast<uint16_t*
>(dst), nchan);
break;
526 case dt_float:
average(
static_cast<const float*
>(src), sstride, uw, vw,
527 static_cast<float*
>(dst), nchan);
break;
533 struct CompareRfaceIds {
535 CompareRfaceIds(
const FaceInfo* facesArg) :
faces(facesArg) {}
536 bool operator() (uint32_t faceid1, uint32_t faceid2)
550 inline void multalpha(T* data,
int npixels,
int nchannels,
int alphachan,
float scale)
554 if (alphachan == 0) {
558 nchanmult = nchannels - 1;
562 alphaoffset = alphachan;
563 nchanmult = alphachan;
566 for (T* end = data + npixels*nchannels; data != end; data += nchannels) {
567 float aval = scale * (float)data[alphaoffset];
568 for (
int i = 0; i < nchanmult; i++) data[i] = T((
float)data[i] * aval);
577 case dt_uint8:
multalpha(
static_cast<uint8_t*
>(data), npixels, nchannels, alphachan, scale);
break;
578 case dt_uint16:
multalpha(
static_cast<uint16_t*
>(data), npixels, nchannels, alphachan, scale);
break;
580 case dt_float:
multalpha(
static_cast<float*
>(data), npixels, nchannels, alphachan, scale);
break;
587 inline void divalpha(T* data,
int npixels,
int nchannels,
int alphachan,
float scale)
591 if (alphachan == 0) {
595 nchandiv = nchannels - 1;
599 alphaoffset = alphachan;
600 nchandiv = alphachan;
603 for (T* end = data + npixels*nchannels; data != end; data += nchannels) {
604 T alpha = data[alphaoffset];
605 if (!alpha)
continue;
606 float aval = scale / (float)alpha;
607 for (
int i = 0; i < nchandiv; i++) data[i] = T((
float)data[i] * aval);
616 case dt_uint8:
divalpha(
static_cast<uint8_t*
>(data), npixels, nchannels, alphachan, scale);
break;
617 case dt_uint16:
divalpha(
static_cast<uint16_t*
>(data), npixels, nchannels, alphachan, scale);
break;
619 case dt_float:
divalpha(
static_cast<float*
>(data), npixels, nchannels, alphachan, scale);
break;
625 uint32_t* rfaceids, uint32_t* faceids)
631 for (
int i = 0; i < nfaces; i++) faceids[i] = i;
634 std::stable_sort(faceids, faceids + nfaces, CompareRfaceIds(
faces));
637 for (
int i = 0; i < nfaces; i++) {
639 rfaceids[faceids[i]] = i;
645 template<
class T,
int nChan>
646 void ApplyConst(
float weight,
float* dst,
void* data,
int )
649 VecAccum<T,nChan>()(dst,
static_cast<T*
>(data), weight);
654 void ApplyConstN(
float weight,
float* dst,
void* data,
int nChan)
657 VecAccumN<T>()(dst,
static_cast<T*
>(data), nChan, weight);
663 ApplyConstN<uint8_t>, ApplyConstN<uint16_t>, ApplyConstN<PtexHalf>, ApplyConstN<float>,
664 ApplyConst<uint8_t,1>, ApplyConst<uint16_t,1>, ApplyConst<PtexHalf,1>, ApplyConst<float,1>,
665 ApplyConst<uint8_t,2>, ApplyConst<uint16_t,2>, ApplyConst<PtexHalf,2>, ApplyConst<float,2>,
666 ApplyConst<uint8_t,3>, ApplyConst<uint16_t,3>, ApplyConst<PtexHalf,3>, ApplyConst<float,3>,
667 ApplyConst<uint8_t,4>, ApplyConst<uint16_t,4>, ApplyConst<PtexHalf,4>, ApplyConst<float,4>,
672 #ifndef PTEX_USE_STDSTRING
675 if (_str) free(_str);
679 String& String::operator=(
const char* str)
681 if (_str) free(_str);
682 _str = str ? strdup(str) : 0;
686 std::ostream&
operator << (std::ostream& stream,
const String& str)
688 stream << str.c_str();
Half-precision floating-point type.
const char * EdgeFilterModeName(EdgeFilterMode m)
const char * BorderModeName(BorderMode m)
void ConvertFromFloat(void *dst, const float *src, DataType dt, int numChannels)
const char * EdgeIdName(EdgeId eid)
const char * DataTypeName(DataType dt)
const char * MetaDataTypeName(MetaDataType mdt)
PTEX_NAMESPACE_BEGIN const char * MeshTypeName(MeshType mt)
void ConvertToFloat(float *dst, const void *src, DataType dt, int numChannels)
#define PTEX_NAMESPACE_END
std::ostream & operator<<(std::ostream &stream, const Ptex::String &str)
std::stream output operator.
void genRfaceids(const FaceInfo *faces, int nfaces, uint32_t *rfaceids, uint32_t *faceids)
void reduceu(const void *src, int sstride, int uw, int vw, void *dst, int dstride, DataType dt, int nchan)
bool isConstant(const void *data, int stride, int ures, int vres, int pixelSize)
void divalpha(void *data, int npixels, DataType dt, int nchannels, int alphachan)
void encodeDifference(void *data, int size, DataType dt)
void reduce(const void *src, int sstride, int uw, int vw, void *dst, int dstride, DataType dt, int nchan)
void deinterleave(const void *src, int sstride, int uw, int vw, void *dst, int dstride, DataType dt, int nchan)
void blend(const void *src, float weight, void *dst, bool flip, int rowlen, DataType dt, int nchan)
void decodeDifference(void *data, int size, DataType dt)
void reducev(const void *src, int sstride, int uw, int vw, void *dst, int dstride, DataType dt, int nchan)
void fill(const void *src, void *dst, int dstride, int ures, int vres, int pixelsize)
void reduceTri(const void *src, int sstride, int w, int, void *dst, int dstride, DataType dt, int nchan)
void copy(const void *src, int sstride, void *dst, int dstride, int vres, int rowlen)
void multalpha(void *data, int npixels, DataType dt, int nchannels, int alphachan)
void interleave(const void *src, int sstride, int uw, int vw, void *dst, int dstride, DataType dt, int nchan)
void(* ApplyConstFn)(float weight, float *dst, void *data, int nChan)
void average(const void *src, int sstride, int uw, int vw, void *dst, DataType dt, int nchan)
ApplyConstFn applyConstFunctions[20]
EdgeId
Edge IDs used in adjacency data in the Ptex::FaceInfo struct.
DataType
Type of data stored in texture file.
@ dt_half
Half-precision (16-bit) floating point.
@ dt_float
Single-precision (32-bit) floating point.
@ dt_uint16
Unsigned, 16-bit integer.
@ dt_uint8
Unsigned, 8-bit integer.
float OneValue(DataType dt)
Look up value of given data type that corresponds to the normalized value of 1.0.
MeshType
Type of base mesh for which the textures are defined.
BorderMode
How to handle mesh border when filtering.
MetaDataType
Type of meta data entry.
EdgeFilterMode
How to handle transformation across edges when filtering.
float OneValueInv(DataType dt)
Lookup up inverse value of given data type that corresponds to the normalized value of 1....
Half-precision (16-bit) floating-point type.
Information about a face, as stored in the Ptex file header.
Res res
Resolution of face.
bool isConstant() const
Determine if face is constant (by checking a flag).
int8_t ulog2
log base 2 of u resolution, in texels
int8_t vlog2
log base 2 of v resolution, in texels