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)
194 (uint8_t*) dst, dstride, nchan);
break;
197 (uint16_t*) dst, dstride, nchan);
break;
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)
231 (uint8_t*) dst, dstride, nchan);
break;
234 (uint16_t*) dst, dstride, nchan);
break;
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++; }
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++; }
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;
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;
340 static_cast<PtexHalf*
>(dst), dstride, nchan);
break;
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;
373 static_cast<PtexHalf*
>(dst), dstride, nchan);
break;
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)
411 static_cast<uint8_t*
>(dst), dstride, nchan);
break;
413 static_cast<PtexHalf*
>(dst), dstride, nchan);
break;
415 static_cast<uint16_t*
>(dst), dstride, nchan);
break;
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,
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;
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,
526 case dt_uint8:
average(
static_cast<const uint8_t*
>(src), sstride, uw, vw,
527 static_cast<uint8_t*
>(dst), nchan);
break;
529 static_cast<PtexHalf*
>(dst), nchan);
break;
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);
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;
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);
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;
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)
const char * DataTypeName(DataType dt)
#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