50 static const char* names[] = {
"triangle",
"quad" };
51 const int mtype =
static_cast<int>(mt);
52 if (mtype < 0 || mtype >=
int(
sizeof(names)/
sizeof(
const char*)))
53 return "(invalid mesh type)";
60 static const char* names[] = {
"uint8",
"uint16",
"float16",
"float32" };
61 const int dtype =
static_cast<int>(dt);
62 if (dtype < 0 || dtype >=
int(
sizeof(names)/
sizeof(
const char*)))
63 return "(invalid data type)";
70 static const char* names[] = {
"clamp",
"black",
"periodic" };
71 const int mode =
static_cast<int>(m);
72 if (mode < 0 || mode >=
int(
sizeof(names)/
sizeof(
const char*)))
73 return "(invalid border mode)";
79 static const char* names[] = {
"none",
"tanvec" };
80 const int mode =
static_cast<int>(m);
81 if (mode < 0 || mode >=
int(
sizeof(names)/
sizeof(
const char*)))
82 return "(invalid edge filter mode)";
89 static const char* names[] = {
"bottom",
"right",
"top",
"left" };
90 const int edgeid =
static_cast<int>(eid);
91 if (edgeid < 0 || edgeid >=
int(
sizeof(names)/
sizeof(
const char*)))
92 return "(invalid edge id)";
99 static const char* names[] = {
"string",
"int8",
"int16",
"int32",
"float",
"double" };
100 const int mdtype =
static_cast<int>(mdt);
101 if (mdtype < 0 || mdtype >=
int(
sizeof(names)/
sizeof(
const char*)))
102 return "(invalid meta data type)";
103 return names[mdtype];
108 template<
typename DST,
typename SRC>
109 void ConvertArrayClamped(DST* dst, SRC* src,
int numChannels,
float scale,
float round=0)
111 for (
int i = 0; i < numChannels; i++)
115 template<
typename DST,
typename SRC>
116 void ConvertArray(DST* dst, SRC* src,
int numChannels,
float scale,
float round=0)
118 for (
int i = 0; i < numChannels; i++)
119 dst[i] = DST((
float)src[i] * scale + round);
126 case dt_uint8: ConvertArray(dst,
static_cast<const uint8_t*
>(src), numChannels, 1.f/255.f);
break;
127 case dt_uint16: ConvertArray(dst,
static_cast<const uint16_t*
>(src), numChannels, 1.f/65535.f);
break;
128 case dt_half: ConvertArray(dst,
static_cast<const PtexHalf*
>(src), numChannels, 1.f);
break;
129 case dt_float: memcpy(dst, src,
sizeof(
float)*numChannels);
break;
137 case dt_uint8: ConvertArrayClamped(
static_cast<uint8_t*
>(dst), src, numChannels, 255.0, 0.5);
break;
138 case dt_uint16: ConvertArrayClamped(
static_cast<uint16_t*
>(dst), src, numChannels, 65535.0, 0.5);
break;
139 case dt_half: ConvertArray(
static_cast<PtexHalf*
>(dst), src, numChannels, 1.0);
break;
140 case dt_float: memcpy(dst, src,
sizeof(
float)*numChannels);
break;
147bool isConstant(
const void* data,
int stride,
int ures,
int vres,
150 int rowlen = pixelSize * ures;
151 const char* p = (
const char*) data + stride;
154 for (
int i = 1; i < vres; i++, p += stride)
155 if (0 != memcmp(data, p, rowlen))
return 0;
158 p = (
const char*) data + pixelSize;
159 for (
int i = 1; i < ures; i++, p += pixelSize)
160 if (0 != memcmp(data, p, pixelSize))
return 0;
168 inline void interleave(
const T* src,
int sstride,
int uw,
int vw,
169 T* dst,
int dstride,
int nchan)
171 sstride /= (int)
sizeof(T);
172 dstride /= (int)
sizeof(T);
174 for (T* dstend = dst + nchan; dst != dstend; dst++) {
177 for (
const T* rowend = src + sstride*vw; src != rowend;
178 src += sstride, drow += dstride) {
181 for (
const T* sp = src, * end = sp + uw; sp != end; dp += nchan)
190 void* dst,
int dstride, DataType dt,
int nchan)
193 case dt_uint8:
interleave((
const uint8_t*) src, sstride, uw, vw,
194 (uint8_t*) dst, dstride, nchan);
break;
196 case dt_uint16:
interleave((
const uint16_t*) src, sstride, uw, vw,
197 (uint16_t*) dst, dstride, nchan);
break;
198 case dt_float:
interleave((
const float*) src, sstride, uw, vw,
199 (
float*) dst, dstride, nchan);
break;
205 inline void deinterleave(
const T* src,
int sstride,
int uw,
int vw,
206 T* dst,
int dstride,
int nchan)
208 sstride /= (int)
sizeof(T);
209 dstride /= (int)
sizeof(T);
211 for (
const T* srcend = src + nchan; src != srcend; src++) {
214 for (
const T* rowend = srow + sstride*vw; srow != rowend;
215 srow += sstride, dst += dstride) {
218 for (T* dp = dst, * end = dp + uw; dp != end; sp += nchan)
227 void* dst,
int dstride, DataType dt,
int nchan)
230 case dt_uint8:
deinterleave((
const uint8_t*) src, sstride, uw, vw,
231 (uint8_t*) dst, dstride, nchan);
break;
233 case dt_uint16:
deinterleave((
const uint16_t*) src, sstride, uw, vw,
234 (uint16_t*) dst, dstride, nchan);
break;
235 case dt_float:
deinterleave((
const float*) src, sstride, uw, vw,
236 (
float*) dst, dstride, nchan);
break;
245 size /= (int)
sizeof(T);
246 T* p =
static_cast<T*
>(data), * end = p + size, tmp, prev = 0;
247 while (p != end) { tmp = prev; prev = *p; *p = T(*p - tmp); p++; }
255 case dt_uint16:
encodeDifference(
static_cast<uint16_t*
>(data), size);
break;
265 size /= (int)
sizeof(T);
266 T* p =
static_cast<T*
>(data), * end = p + size, prev = 0;
267 while (p != end) { *p = T(*p + prev); prev = *p++; }
275 case dt_uint16:
decodeDifference(
static_cast<uint16_t*
>(data), size);
break;
283 inline void reduce(
const T* src,
int sstride,
int uw,
int vw,
284 T* dst,
int dstride,
int nchan)
286 sstride /= (int)
sizeof(T);
287 dstride /= (int)
sizeof(T);
288 int rowlen = uw*nchan;
289 int srowskip = 2*sstride - rowlen;
290 int drowskip = dstride - rowlen/2;
291 for (
const T* end = src + vw*sstride; src != end;
292 src += srowskip, dst += drowskip)
293 for (
const T* rowend = src + rowlen; src != rowend; src += nchan)
294 for (
const T* pixend = src+nchan; src != pixend; src++)
295 *dst++ = T(
quarter(src[0] + src[nchan] + src[sstride] + src[sstride+nchan]));
299void reduce(
const void* src,
int sstride,
int uw,
int vw,
300 void* dst,
int dstride, DataType dt,
int nchan)
303 case dt_uint8:
reduce(
static_cast<const uint8_t*
>(src), sstride, uw, vw,
304 static_cast<uint8_t*
>(dst), dstride, nchan);
break;
305 case dt_half:
reduce(
static_cast<const PtexHalf*
>(src), sstride, uw, vw,
306 static_cast<PtexHalf*
>(dst), dstride, nchan);
break;
307 case dt_uint16:
reduce(
static_cast<const uint16_t*
>(src), sstride, uw, vw,
308 static_cast<uint16_t*
>(dst), dstride, nchan);
break;
309 case dt_float:
reduce(
static_cast<const float*
>(src), sstride, uw, vw,
310 static_cast<float*
>(dst), dstride, nchan);
break;
317 inline void reduceu(
const T* src,
int sstride,
int uw,
int vw,
318 T* dst,
int dstride,
int nchan)
320 sstride /= (int)
sizeof(T);
321 dstride /= (int)
sizeof(T);
322 int rowlen = uw*nchan;
323 int srowskip = sstride - rowlen;
324 int drowskip = dstride - rowlen/2;
325 for (
const T* end = src + vw*sstride; src != end;
326 src += srowskip, dst += drowskip)
327 for (
const T* rowend = src + rowlen; src != rowend; src += nchan)
328 for (
const T* pixend = src+nchan; src != pixend; src++)
329 *dst++ = T(
halve(src[0] + src[nchan]));
333void reduceu(
const void* src,
int sstride,
int uw,
int vw,
334 void* dst,
int dstride, DataType dt,
int nchan)
337 case dt_uint8:
reduceu(
static_cast<const uint8_t*
>(src), sstride, uw, vw,
338 static_cast<uint8_t*
>(dst), dstride, nchan);
break;
339 case dt_half:
reduceu(
static_cast<const PtexHalf*
>(src), sstride, uw, vw,
340 static_cast<PtexHalf*
>(dst), dstride, nchan);
break;
341 case dt_uint16:
reduceu(
static_cast<const uint16_t*
>(src), sstride, uw, vw,
342 static_cast<uint16_t*
>(dst), dstride, nchan);
break;
343 case dt_float:
reduceu(
static_cast<const float*
>(src), sstride, uw, vw,
344 static_cast<float*
>(dst), dstride, nchan);
break;
351 inline void reducev(
const T* src,
int sstride,
int uw,
int vw,
352 T* dst,
int dstride,
int nchan)
354 sstride /= (int)
sizeof(T);
355 dstride /= (int)
sizeof(T);
356 int rowlen = uw*nchan;
357 int srowskip = 2*sstride - rowlen;
358 int drowskip = dstride - rowlen;
359 for (
const T* end = src + vw*sstride; src != end;
360 src += srowskip, dst += drowskip)
361 for (
const T* rowend = src + rowlen; src != rowend; src++)
362 *dst++ = T(
halve(src[0] + src[sstride]));
366void reducev(
const void* src,
int sstride,
int uw,
int vw,
367 void* dst,
int dstride, DataType dt,
int nchan)
370 case dt_uint8:
reducev(
static_cast<const uint8_t*
>(src), sstride, uw, vw,
371 static_cast<uint8_t*
>(dst), dstride, nchan);
break;
372 case dt_half:
reducev(
static_cast<const PtexHalf*
>(src), sstride, uw, vw,
373 static_cast<PtexHalf*
>(dst), dstride, nchan);
break;
374 case dt_uint16:
reducev(
static_cast<const uint16_t*
>(src), sstride, uw, vw,
375 static_cast<uint16_t*
>(dst), dstride, nchan);
break;
376 case dt_float:
reducev(
static_cast<const float*
>(src), sstride, uw, vw,
377 static_cast<float*
>(dst), dstride, nchan);
break;
387 inline void reduceTri(
const T* src,
int sstride,
int w,
int ,
388 T* dst,
int dstride,
int nchan)
390 sstride /= (int)
sizeof(T);
391 dstride /= (int)
sizeof(T);
392 int rowlen = w*nchan;
393 const T* src2 = src + (w-1) * sstride + rowlen - nchan;
394 int srowinc2 = -2*sstride - nchan;
395 int srowskip = 2*sstride - rowlen;
396 int srowskip2 = w*sstride - 2 * nchan;
397 int drowskip = dstride - rowlen/2;
398 for (
const T* end = src + w*sstride; src != end;
399 src += srowskip, src2 += srowskip2, dst += drowskip)
400 for (
const T* rowend = src + rowlen; src != rowend; src += nchan, src2 += srowinc2)
401 for (
const T* pixend = src+nchan; src != pixend; src++, src2++)
402 *dst++ = T(
quarter(src[0] + src[nchan] + src[sstride] + src2[0]));
406void reduceTri(
const void* src,
int sstride,
int w,
int ,
407 void* dst,
int dstride, DataType dt,
int nchan)
410 case dt_uint8:
reduceTri(
static_cast<const uint8_t*
>(src), sstride, w, 0,
411 static_cast<uint8_t*
>(dst), dstride, nchan);
break;
413 static_cast<PtexHalf*
>(dst), dstride, nchan);
break;
414 case dt_uint16:
reduceTri(
static_cast<const uint16_t*
>(src), sstride, w, 0,
415 static_cast<uint16_t*
>(dst), dstride, nchan);
break;
416 case dt_float:
reduceTri(
static_cast<const float*
>(src), sstride, w, 0,
417 static_cast<float*
>(dst), dstride, nchan);
break;
422void fill(
const void* src,
void* dst,
int dstride,
423 int ures,
int vres,
int pixelsize)
426 int rowlen = ures*pixelsize;
427 char* ptr = (
char*) dst;
428 char* end = ptr + rowlen;
429 for (; ptr != end; ptr += pixelsize) memcpy(ptr, src, pixelsize);
432 ptr = (
char*) dst + dstride;
433 end = (
char*) dst + vres*dstride;
434 for (; ptr != end; ptr += dstride) memcpy(ptr, dst, rowlen);
438void copy(
const void* src,
int sstride,
void* dst,
int dstride,
439 int vres,
int rowlen)
442 if (sstride == rowlen && dstride == rowlen) {
444 memcpy(dst, src, vres*rowlen);
447 const char* sptr = (
const char*) src;
448 char* dptr = (
char*) dst;
449 for (
const char* end = sptr + vres*sstride; sptr != end;) {
450 memcpy(dptr, sptr, rowlen);
460 inline void blend(
const T* src,
float weight, T* dst,
int rowlen,
int nchan)
462 for (
const T* end = src + rowlen * nchan; src != end; dst++)
463 *dst = T(*dst + T(weight * (
float)*src++));
467 inline void blendflip(
const T* src,
float weight, T* dst,
int rowlen,
int nchan)
469 dst += (rowlen-1) * nchan;
470 for (
const T* end = src + rowlen * nchan; src != end;) {
471 for (
int i = 0; i < nchan; i++, dst++) {
472 *dst = T(*dst + T(weight * (
float)*src++));
480void blend(
const void* src,
float weight,
void* dst,
bool flip,
481 int rowlen, DataType dt,
int nchan)
483 switch ((dt<<1) |
int(flip)) {
484 case (dt_uint8<<1):
blend(
static_cast<const uint8_t*
>(src), weight,
485 static_cast<uint8_t*
>(dst), rowlen, nchan);
break;
486 case (dt_uint8<<1 | 1): blendflip(
static_cast<const uint8_t*
>(src), weight,
487 static_cast<uint8_t*
>(dst), rowlen, nchan);
break;
488 case (dt_half<<1):
blend(
static_cast<const PtexHalf*
>(src), weight,
489 static_cast<PtexHalf*
>(dst), rowlen, nchan);
break;
490 case (dt_half<<1 | 1): blendflip(
static_cast<const PtexHalf*
>(src), weight,
491 static_cast<PtexHalf*
>(dst), rowlen, nchan);
break;
492 case (dt_uint16<<1):
blend(
static_cast<const uint16_t*
>(src), weight,
493 static_cast<uint16_t*
>(dst), rowlen, nchan);
break;
494 case (dt_uint16<<1 | 1): blendflip(
static_cast<const uint16_t*
>(src), weight,
495 static_cast<uint16_t*
>(dst), rowlen, nchan);
break;
496 case (dt_float<<1):
blend(
static_cast<const float*
>(src), weight,
497 static_cast<float*
>(dst), rowlen, nchan);
break;
498 case (dt_float<<1 | 1): blendflip(
static_cast<const float*
>(src), weight,
499 static_cast<float*
>(dst), rowlen, nchan);
break;
506 inline void average(
const T* src,
int sstride,
int uw,
int vw,
509 float* buff = (
float*) alloca(nchan*
sizeof(
float));
510 memset(buff, 0, nchan*
sizeof(
float));
511 sstride /= (int)
sizeof(T);
512 int rowlen = uw*nchan;
513 int rowskip = sstride - rowlen;
514 for (
const T* end = src + vw*sstride; src != end; src += rowskip)
515 for (
const T* rowend = src + rowlen; src != rowend;)
516 for (
int i = 0; i < nchan; i++) buff[i] += (
float)*src++;
517 float scale = 1.0f/(float)(uw*vw);
518 for (
int i = 0; i < nchan; i++) dst[i] = T(buff[i]*scale);
522void average(
const void* src,
int sstride,
int uw,
int vw,
523 void* dst, DataType dt,
int nchan)
526 case dt_uint8:
average(
static_cast<const uint8_t*
>(src), sstride, uw, vw,
527 static_cast<uint8_t*
>(dst), nchan);
break;
528 case dt_half:
average(
static_cast<const PtexHalf*
>(src), sstride, uw, vw,
529 static_cast<PtexHalf*
>(dst), nchan);
break;
530 case dt_uint16:
average(
static_cast<const uint16_t*
>(src), sstride, uw, vw,
531 static_cast<uint16_t*
>(dst), nchan);
break;
532 case dt_float:
average(
static_cast<const float*
>(src), sstride, uw, vw,
533 static_cast<float*
>(dst), nchan);
break;
539 struct CompareRfaceIds {
541 CompareRfaceIds(
const FaceInfo* facesArg) :
faces(facesArg) {}
542 bool operator() (uint32_t faceid1, uint32_t faceid2)
556 inline void multalpha(T* data,
int npixels,
int nchannels,
int alphachan,
float scale)
560 if (alphachan == 0) {
564 nchanmult = nchannels - 1;
568 alphaoffset = alphachan;
569 nchanmult = alphachan;
572 for (T* end = data + npixels*nchannels; data != end; data += nchannels) {
573 float aval = scale * (float)data[alphaoffset];
574 for (
int i = 0; i < nchanmult; i++) data[i] = T((
float)data[i] * aval);
579void multalpha(
void* data,
int npixels, DataType dt,
int nchannels,
int alphachan)
581 float scale = OneValueInv(dt);
583 case dt_uint8:
multalpha(
static_cast<uint8_t*
>(data), npixels, nchannels, alphachan, scale);
break;
584 case dt_uint16:
multalpha(
static_cast<uint16_t*
>(data), npixels, nchannels, alphachan, scale);
break;
585 case dt_half:
multalpha(
static_cast<PtexHalf*
>(data), npixels, nchannels, alphachan, scale);
break;
586 case dt_float:
multalpha(
static_cast<float*
>(data), npixels, nchannels, alphachan, scale);
break;
593 inline void divalpha(T* data,
int npixels,
int nchannels,
int alphachan,
float scale)
597 if (alphachan == 0) {
601 nchandiv = nchannels - 1;
605 alphaoffset = alphachan;
606 nchandiv = alphachan;
609 for (T* end = data + npixels*nchannels; data != end; data += nchannels) {
610 T alpha = data[alphaoffset];
611 if (!alpha)
continue;
612 float aval = scale / (float)alpha;
613 for (
int i = 0; i < nchandiv; i++) data[i] = T((
float)data[i] * aval);
618void divalpha(
void* data,
int npixels, DataType dt,
int nchannels,
int alphachan)
620 float scale = OneValue(dt);
622 case dt_uint8:
divalpha(
static_cast<uint8_t*
>(data), npixels, nchannels, alphachan, scale);
break;
623 case dt_uint16:
divalpha(
static_cast<uint16_t*
>(data), npixels, nchannels, alphachan, scale);
break;
624 case dt_half:
divalpha(
static_cast<PtexHalf*
>(data), npixels, nchannels, alphachan, scale);
break;
625 case dt_float:
divalpha(
static_cast<float*
>(data), npixels, nchannels, alphachan, scale);
break;
631 uint32_t* rfaceids, uint32_t* faceids)
637 for (
int i = 0; i < nfaces; i++) faceids[i] = i;
640 std::stable_sort(faceids, faceids + nfaces, CompareRfaceIds(
faces));
643 for (
int i = 0; i < nfaces; i++) {
645 rfaceids[faceids[i]] = i;
651 template<
class T,
int nChan>
652 void ApplyConst(
float weight,
float* dst,
void* data,
int )
655 VecAccum<T,nChan>()(dst,
static_cast<T*
>(data), weight);
660 void ApplyConstN(
float weight,
float* dst,
void* data,
int nChan)
663 VecAccumN<T>()(dst,
static_cast<T*
>(data), nChan, weight);
669 ApplyConstN<uint8_t>, ApplyConstN<uint16_t>, ApplyConstN<PtexHalf>, ApplyConstN<float>,
670 ApplyConst<uint8_t,1>, ApplyConst<uint16_t,1>, ApplyConst<PtexHalf,1>, ApplyConst<float,1>,
671 ApplyConst<uint8_t,2>, ApplyConst<uint16_t,2>, ApplyConst<PtexHalf,2>, ApplyConst<float,2>,
672 ApplyConst<uint8_t,3>, ApplyConst<uint16_t,3>, ApplyConst<PtexHalf,3>, ApplyConst<float,3>,
673 ApplyConst<uint8_t,4>, ApplyConst<uint16_t,4>, ApplyConst<PtexHalf,4>, ApplyConst<float,4>,
678#ifndef PTEX_USE_STDSTRING
681 if (_str) free(_str);
685String& String::operator=(
const char* str)
687 if (_str) free(_str);
688 _str = str ? strdup(str) : 0;
692std::ostream&
operator << (std::ostream& stream,
const String& str)
694 stream << str.c_str();
Half-precision floating-point type.
const char * EdgeFilterModeName(EdgeFilterMode m)
void ConvertFromFloat(void *dst, const float *src, DataType dt, int numChannels)
const char * MetaDataTypeName(MetaDataType mdt)
const char * BorderModeName(BorderMode m)
const char * EdgeIdName(EdgeId eid)
PTEX_NAMESPACE_BEGIN const char * MeshTypeName(MeshType mt)
void ConvertToFloat(float *dst, const void *src, DataType dt, int numChannels)
std::ostream & operator<<(std::ostream &stream, const String &str)
const char * DataTypeName(DataType dt)
#define PTEX_NAMESPACE_END
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]
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