1 #ifndef Ptexture_h
2 #define Ptexture_h
3
4 /*
5 PTEX SOFTWARE
6 Copyright 2014 Disney Enterprises, Inc. All rights reserved
7
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions are
10 met:
11
12 * Redistributions of source code must retain the above copyright
13 notice, this list of conditions and the following disclaimer.
14
15 * Redistributions in binary form must reproduce the above copyright
16 notice, this list of conditions and the following disclaimer in
17 the documentation and/or other materials provided with the
18 distribution.
19
20 * The names "Disney", "Walt Disney Pictures", "Walt Disney Animation
21 Studios" or the names of its contributors may NOT be used to
22 endorse or promote products derived from this software without
23 specific prior written permission from Walt Disney Pictures.
24
25 Disclaimer: THIS SOFTWARE IS PROVIDED BY WALT DISNEY PICTURES AND
26 CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
27 BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS
28 FOR A PARTICULAR PURPOSE, NONINFRINGEMENT AND TITLE ARE DISCLAIMED.
29 IN NO EVENT SHALL WALT DISNEY PICTURES, THE COPYRIGHT HOLDER OR
30 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND BASED ON ANY
34 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
37 */
38
39 /**
40 @file Ptexture.h
41 @brief Public API classes for reading, writing, caching, and filtering Ptex files.
42 */
43
44 #if defined(_WIN32) || defined(_WINDOWS) || defined(_MSC_VER)
45 # ifndef PTEXAPI
46 # ifndef PTEX_STATIC
47 # ifdef PTEX_EXPORTS
48 # define PTEXAPI __declspec(dllexport)
49 # else
50 # define PTEXAPI __declspec(dllimport)
51 # endif
52 # else
53 # define PTEXAPI
54 # endif
55 # endif
56 #else
57 # ifndef PTEXAPI
58 # define PTEXAPI
59 # endif
60 # ifndef DOXYGEN
61 # define PTEX_USE_STDSTRING
62 # endif
63 #endif
64
65 #include "PtexInt.h"
66 #include <ostream>
67
68 #include "PtexVersion.h"
69 #ifdef DOXYGEN
70 /** Common data structures and enums used throughout the API */
71 namespace Ptex {
72 #else
73 PTEX_NAMESPACE_BEGIN
74 #endif
75
76 /** Type of base mesh for which the textures are defined. A mesh
77 can be triangle-based (with triangular textures) or quad-based
78 (with rectangular textures). */
79 enum MeshType {
80 mt_triangle, ///< Mesh is triangle-based.
81 mt_quad ///< Mesh is quad-based.
82 };
83
84 /** Type of data stored in texture file. */
85 enum DataType {
86 dt_uint8, ///< Unsigned, 8-bit integer.
87 dt_uint16, ///< Unsigned, 16-bit integer.
88 dt_half, ///< Half-precision (16-bit) floating point.
89 dt_float ///< Single-precision (32-bit) floating point.
90 };
91
92 /** How to handle transformation across edges when filtering */
93 enum EdgeFilterMode {
94 efm_none, ///< Don't do anything with the values.
95 efm_tanvec ///< Values are vectors in tangent space; rotate values.
96 };
97
98 /** How to handle mesh border when filtering. */
99 enum BorderMode {
100 m_clamp, ///< texel access is clamped to border
101 m_black, ///< texel beyond border are assumed to be black
102 m_periodic ///< texel access wraps to other side of face
103 };
104
105 /** Edge IDs used in adjacency data in the Ptex::FaceInfo struct.
106 Edge ID usage for triangle meshes is TBD. */
107 enum EdgeId {
108 e_bottom, ///< Bottom edge, from UV (0,0) to (1,0)
109 e_right, ///< Right edge, from UV (1,0) to (1,1)
110 e_top, ///< Top edge, from UV (1,1) to (0,1)
111 e_left ///< Left edge, from UV (0,1) to (0,0)
112 };
113
114 /** Type of meta data entry. */
115 enum MetaDataType {
116 mdt_string, ///< Null-terminated string.
117 mdt_int8, ///< Signed 8-bit integer.
118 mdt_int16, ///< Signed 16-bit integer.
119 mdt_int32, ///< Signed 32-bit integer.
120 mdt_float, ///< Single-precision (32-bit) floating point.
121 mdt_double ///< Double-precision (32-bit) floating point.
122 };
123
124 /** Look up name of given mesh type. */
125 PTEXAPI const char* MeshTypeName(MeshType mt);
126
127 /** Look up name of given data type. */
128 PTEXAPI const char* DataTypeName(DataType dt);
129
130 /** Look up name of given border mode. */
131 PTEXAPI const char* BorderModeName(BorderMode m);
132
133 /** Look up name of given edge filter mode. */
134 PTEXAPI const char* EdgeFilterModeName(EdgeFilterMode m);
135
136 /** Look up name of given edge ID. */
137 PTEXAPI const char* EdgeIdName(EdgeId eid);
138
139 /** Look up name of given meta data type. */
140 PTEXAPI const char* MetaDataTypeName(MetaDataType mdt);
141
142 /** Look up size of given data type (in bytes). */
DataSize(DataType dt)143 inline int DataSize(DataType dt) {
144 static const int sizes[] = { 1,2,2,4 };
145 return sizes[dt];
146 }
147
148 /** Look up value of given data type that corresponds to the normalized value of 1.0. */
OneValue(DataType dt)149 inline float OneValue(DataType dt) {
150 static const float one[] = { 255.f, 65535.f, 1.f, 1.f };
151 return one[dt];
152 }
153
154 /** Lookup up inverse value of given data type that corresponds to the normalized value of 1.0. */
OneValueInv(DataType dt)155 inline float OneValueInv(DataType dt) {
156 static const float one[] = { 1.f/255.f, 1.f/65535.f, 1.f, 1.f };
157 return one[dt];
158 }
159
160 /** Convert a number of data values from the given data type to float. */
161 PTEXAPI void ConvertToFloat(float* dst, const void* src,
162 Ptex::DataType dt, int numChannels);
163
164 /** Convert a number of data values from float to the given data type. */
165 PTEXAPI void ConvertFromFloat(void* dst, const float* src,
166 Ptex::DataType dt, int numChannels);
167
168 /** Pixel resolution of a given texture.
169 The resolution is stored in log form: ulog2 = log2(ures), vlog2 = log2(vres)).
170 Note: negative ulog2 or vlog2 values are reserved for internal use.
171 */
172 struct Res {
173 int8_t ulog2; ///< log base 2 of u resolution, in texels
174 int8_t vlog2; ///< log base 2 of v resolution, in texels
175
176 /// Default constructor, sets res to 0 (1x1 texel).
ResRes177 Res() : ulog2(0), vlog2(0) {}
178
179 /// Constructor.
ResRes180 Res(int8_t ulog2_, int8_t vlog2_) : ulog2(ulog2_), vlog2(vlog2_) {}
181
182 /// Constructor.
ResRes183 Res(uint16_t value) : ulog2(int8_t(value&0xff)), vlog2(int8_t((value>>8)&0xff)) {}
184
185 /// U resolution in texels.
uRes186 int u() const { return 1<<(unsigned)ulog2; }
187
188 /// V resolution in texels.
vRes189 int v() const { return 1<<(unsigned)vlog2; }
190
191 /// Resolution as a single 16-bit integer value.
valRes192 uint16_t val() const { return uint16_t(ulog2 | (vlog2<<8)); }
193
194 /// Total size of specified texture in texels (u * v).
sizeRes195 int size() const { return u() * v(); }
196
197 /// Comparison operator.
198 bool operator==(const Res& r) const { return r.ulog2 == ulog2 && r.vlog2 == vlog2; }
199
200 /// Comparison operator.
201 bool operator!=(const Res& r) const { return !(r==*this); }
202
203 /// True if res is >= given res in both u and v directions.
204 bool operator>=(const Res& r) const { return ulog2 >= r.ulog2 && vlog2 >= r.vlog2; }
205
206 /// Get value of resolution with u and v swapped.
swappeduvRes207 Res swappeduv() const { return Res(vlog2, ulog2); }
208
209 /// Swap the u and v resolution values in place.
swapuvRes210 void swapuv() { *this = swappeduv(); }
211
212 /// Clamp the resolution value against the given value.
clampRes213 void clamp(const Res& r) {
214 if (ulog2 > r.ulog2) ulog2 = r.ulog2;
215 if (vlog2 > r.vlog2) vlog2 = r.vlog2;
216 }
217
218 /// Determine the number of tiles in the u direction for the given tile res.
ntilesuRes219 int ntilesu(Res tileres) const { return 1<<(ulog2-tileres.ulog2); }
220
221 /// Determine the number of tiles in the v direction for the given tile res.
ntilesvRes222 int ntilesv(Res tileres) const { return 1<<(vlog2-tileres.vlog2); }
223
224 /// Determine the total number of tiles for the given tile res.
ntilesRes225 int ntiles(Res tileres) const { return ntilesu(tileres) * ntilesv(tileres); }
226 };
227
228 /** Information about a face, as stored in the Ptex file header.
229 The FaceInfo data contains the face resolution and neighboring face
230 adjacency information as well as a set of flags describing the face.
231
232 The adjfaces data member contains the face ids of the four neighboring faces.
233 The neighbors are accessed in EdgeId order, CCW, starting with the bottom edge.
234 The adjedges data member contains the corresponding edge id for each neighboring face.
235
236 If a face has no neighbor for a given edge, the adjface id should be -1, and the
237 adjedge id doesn't matter (but is typically zero).
238
239 If an adjacent face is a pair of subfaces, the id of the first subface as encountered
240 in a CCW traversal should be stored as the adjface id.
241 */
242 struct FaceInfo {
243 Res res; ///< Resolution of face.
244 uint8_t adjedges; ///< Adjacent edges, 2 bits per edge.
245 uint8_t flags; ///< Flags.
246 int32_t adjfaces[4]; ///< Adjacent faces (-1 == no adjacent face).
247
248 /// Default constructor
FaceInfoFaceInfo249 FaceInfo() : res(), adjedges(0), flags(0)
250 {
251 adjfaces[0] = adjfaces[1] = adjfaces[2] = adjfaces[3] = -1;
252 }
253
254 /// Constructor.
FaceInfoFaceInfo255 FaceInfo(Res res_) : res(res_), adjedges(0), flags(0)
256 {
257 adjfaces[0] = adjfaces[1] = adjfaces[2] = adjfaces[3] = -1;
258 }
259
260 /// Constructor.
261 FaceInfo(Res res_, int adjfaces_[4], int adjedges_[4], bool isSubface_=false)
resFaceInfo262 : res(res_), flags(isSubface_ ? flag_subface : 0)
263 {
264 setadjfaces(adjfaces_[0], adjfaces_[1], adjfaces_[2], adjfaces_[3]);
265 setadjedges(adjedges_[0], adjedges_[1], adjedges_[2], adjedges_[3]);
266 }
267
268 /// Access an adjacent edge id. The eid value must be 0..3.
adjedgeFaceInfo269 EdgeId adjedge(int eid) const { return EdgeId((adjedges >> (2*eid)) & 3); }
270
271 /// Access an adjacent face id. The eid value must be 0..3.
adjfaceFaceInfo272 int adjface(int eid) const { return adjfaces[eid]; }
273
274 /// Determine if face is constant (by checking a flag).
isConstantFaceInfo275 bool isConstant() const { return (flags & flag_constant) != 0; }
276
277 /// Determine if neighborhood of face is constant (by checking a flag).
isNeighborhoodConstantFaceInfo278 bool isNeighborhoodConstant() const { return (flags & flag_nbconstant) != 0; }
279
280 /// Determine if face has edits in the file (by checking a flag).
hasEditsFaceInfo281 bool hasEdits() const { return (flags & flag_hasedits) != 0; }
282
283 /// Determine if face is a subface (by checking a flag).
isSubfaceFaceInfo284 bool isSubface() const { return (flags & flag_subface) != 0; }
285
286 /// Set the adjfaces data.
setadjfacesFaceInfo287 void setadjfaces(int f0, int f1, int f2, int f3)
288 { adjfaces[0] = f0, adjfaces[1] = f1, adjfaces[2] = f2; adjfaces[3] = f3; }
289
290 /// Set the adjedges data.
setadjedgesFaceInfo291 void setadjedges(int e0, int e1, int e2, int e3)
292 { adjedges = (uint8_t)((e0&3) | ((e1&3)<<2) | ((e2&3)<<4) | ((e3&3)<<6)); }
293
294 /// Flag bit values (for internal use).
295 enum { flag_constant = 1, flag_hasedits = 2, flag_nbconstant = 4, flag_subface = 8 };
296 };
297
298
299 /** Memory-managed string. Used for returning error messages from
300 API functions. On most platforms, this is a typedef to
301 std::string. For Windows, this is a custom class that
302 implements a subset of std::string. (Note: std::string cannot
303 be passed through a Windows DLL interface).
304 */
305 #ifdef PTEX_USE_STDSTRING
306 typedef std::string String;
307 #else
308 class String
309 {
310 public:
String()311 String() : _str(0) {}
String(const String & str)312 String(const String& str) : _str(0) { *this = str; }
313 PTEXAPI ~String();
314 PTEXAPI String& operator=(const char* str);
315 String& operator=(const String& str) { *this = str._str; return *this; }
316 String& operator=(const std::string& str) { *this = str.c_str(); return *this; }
c_str()317 const char* c_str() const { return _str ? _str : ""; }
empty()318 bool empty() const { return _str == 0 || _str[0] == '\0'; }
319
320 private:
321 char* _str;
322 };
323 #endif
324
325 /// std::stream output operator. \relates Ptex::String
326 #ifndef PTEX_USE_STDSTRING
327 std::ostream& operator << (std::ostream& stream, const Ptex::String& str);
328 #endif
329
330
331 #ifdef DOXYGEN
332 } // end namespace Ptex
333 #endif
334
335 /**
336 @class PtexMetaData
337 @brief Meta data accessor
338
339 Meta data is acquired from PtexTexture and accessed through this interface.
340 */
341 class PtexMetaData {
342 protected:
343 /// Destructor not for public use. Use release() instead.
~PtexMetaData()344 virtual ~PtexMetaData() {}
345
346 public:
347 /// Release resources held by this pointer (pointer becomes invalid).
348 virtual void release() = 0;
349
350 /// Query number of meta data entries stored in file.
351 virtual int numKeys() = 0;
352
353 /// Query the name and type of a meta data entry.
354 virtual void getKey(int index, const char*& key, Ptex::MetaDataType& type) = 0;
355
356 /// Query the index and type of a meta data entry by name.
357 virtual bool findKey(const char* key, int& index, Ptex::MetaDataType& type) = 0;
358
359 /** Query the value of a given meta data entry.
360 If the key doesn't exist or the type doesn't match, value is set to null */
361 virtual void getValue(const char* key, const char*& value) = 0;
362
363 /** Query the value of a given meta data entry by index.
364 If the index is out of range or the type doesn't match, value is set to null */
365 virtual void getValue(int index, const char*& value) = 0;
366
367 /** Query the value of a given meta data entry.
368 If the key doesn't exist or the type doesn't match, value is set to null */
369 virtual void getValue(const char* key, const int8_t*& value, int& count) = 0;
370
371 /** Query the value of a given meta data entry by index.
372 If the index is out of range or the type doesn't match, value is set to null */
373 virtual void getValue(int index, const int8_t*& value, int& count) = 0;
374
375 /** Query the value of a given meta data entry.
376 If the key doesn't exist or the type doesn't match, value is set to null */
377 virtual void getValue(const char* key, const int16_t*& value, int& count) = 0;
378
379 /** Query the value of a given meta data entry by index.
380 If the index is out of range or the type doesn't match, value is set to null */
381 virtual void getValue(int index, const int16_t*& value, int& count) = 0;
382
383 /** Query the value of a given meta data entry.
384 If the key doesn't exist or the type doesn't match, value is set to null */
385 virtual void getValue(const char* key, const int32_t*& value, int& count) = 0;
386
387 /** Query the value of a given meta data entry by index.
388 If the index is out of range or the type doesn't match, value is set to null */
389 virtual void getValue(int index, const int32_t*& value, int& count) = 0;
390
391 /** Query the value of a given meta data entry.
392 If the key doesn't exist or the type doesn't match, value is set to null */
393 virtual void getValue(const char* key, const float*& value, int& count) = 0;
394
395 /** Query the value of a given meta data entry by index.
396 If the index is out of range or the type doesn't match, value is set to null */
397 virtual void getValue(int index, const float*& value, int& count) = 0;
398
399 /** Query the value of a given meta data entry.
400 If the key doesn't exist or the type doesn't match, value is set to null */
401 virtual void getValue(const char* key, const double*& value, int& count) = 0;
402
403 /** Query the value of a given meta data entry by index.
404 If the index is out of range or the type doesn't match, value is set to null */
405 virtual void getValue(int index, const double*& value, int& count) = 0;
406 };
407
408
409 /**
410 @class PtexFaceData
411 @brief Per-face texture data accessor
412
413 Per-face texture data is acquired from PtexTexture and accessed
414 through this interface. This interface provides low-level access
415 to the data as stored on disk for maximum efficiency. If this
416 isn't needed, face data can be more conveniently read directly
417 from PtexTexture.
418 */
419 class PtexFaceData {
420 protected:
421 /// Destructor not for public use. Use release() instead.
~PtexFaceData()422 virtual ~PtexFaceData() {}
423
424 public:
425 /// Release resources held by this pointer (pointer becomes invalid).
426 virtual void release() = 0;
427
428 /** True if this data block is constant. */
429 virtual bool isConstant() = 0;
430
431 /** Resolution of the texture held by this data block. Note: the
432 indicated texture res may be larger than 1x1 even if the
433 texture data is constant. */
434 virtual Ptex::Res res() = 0;
435
436 /** Read a single texel from the data block. The texel coordinates, u and v, have
437 a range of [0..ures-1, 0..vres-1]. Note: this method will work correctly even if
438 the face is constant or tiled. */
439 virtual void getPixel(int u, int v, void* result) = 0;
440
441 /** Access the data from this data block.
442
443 If the data block is constant, getData will return a pointer to a single texel's data value.
444
445 If the data block is tiled, then getData will return null and
446 the data must be accessed per-tile via the getTile() function. */
447 virtual void* getData() = 0;
448
449 /** True if this data block is tiled.
450 If tiled, the data must be access per-tile via getTile(). */
451 virtual bool isTiled() = 0;
452
453 /** Resolution of each tile in this data block. */
454 virtual Ptex::Res tileRes() = 0;
455
456 /** Access a tile from the data block. Tiles are accessed in v-major order. */
457 virtual PtexFaceData* getTile(int tile) = 0;
458 };
459
460
461 /**
462 @class PtexTexture
463 @brief Interface for reading data from a ptex file
464
465 PtexTexture instances can be acquired via the static open() method, or via
466 the PtexCache interface.
467
468 Data access through this interface is returned in v-major order with all data channels interleaved per texel.
469 */
470 class PtexTexture {
471 protected:
472 /// Destructor not for public use. Use release() instead.
~PtexTexture()473 virtual ~PtexTexture() {}
474
475 public:
476 /** Open a ptex file for reading.
477
478 If an error occurs, an error message will be stored in the
479 error string param and a null pointer will be returned.
480
481 If the premultiply param is set to true and the texture file has a specified alpha channel,
482 then all data stored in the file will be multiplied by alpha when read from disk. If premultiply
483 is false, then the full-resolution textures will be returned as stored on disk which is assumed
484 to be unmultiplied. Reductions (both stored mip-maps and dynamically generated reductions) are
485 always premultiplied with alpha. See PtexWriter for more information about alpha channels.
486 */
487 PTEXAPI static PtexTexture* open(const char* path, Ptex::String& error, bool premultiply=0);
488
489
490 /// Release resources held by this pointer (pointer becomes invalid).
491 virtual void release() = 0;
492
493 /** Path that file was opened with. If the file was opened using a search path (via PtexCache),
494 the the path will be the path as found in the search path. Otherwise, the path will be
495 the path as supplied to open. */
496 virtual const char* path() = 0;
497
498 /** Get most commonly used info in a single call for convenience / efficiency */
499 struct Info {
500 MeshType meshType;
501 DataType dataType;
502 BorderMode uBorderMode;
503 BorderMode vBorderMode;
504 EdgeFilterMode edgeFilterMode;
505 int alphaChannel;
506 int numChannels;
507 int numFaces;
508 };
509 virtual Info getInfo() = 0;
510
511 /** Type of mesh for which texture data is defined. */
512 virtual Ptex::MeshType meshType() = 0;
513
514 /** Type of data stored in file. */
515 virtual Ptex::DataType dataType() = 0;
516
517 /** Mode for filtering texture access beyond mesh border. */
518 virtual Ptex::BorderMode uBorderMode() = 0;
519
520 /** Mode for filtering texture access beyond mesh border. */
521 virtual Ptex::BorderMode vBorderMode() = 0;
522
523 /** Mode for filtering textures across edges. */
524 virtual Ptex::EdgeFilterMode edgeFilterMode() = 0;
525
526 /** Index of alpha channel (if any). One channel in the file can be flagged to be the alpha channel.
527 If no channel is acting as the alpha channel, -1 is returned.
528 See PtexWriter for more details. */
529 virtual int alphaChannel() = 0;
530
531 /** Number of channels stored in file. */
532 virtual int numChannels() = 0;
533
534 /** Number of faces stored in file. */
535 virtual int numFaces() = 0;
536
537 /** True if the file has edit blocks. See PtexWriter for more details. */
538 virtual bool hasEdits() = 0;
539
540 /** True if the file has mipmaps. See PtexWriter for more details. */
541 virtual bool hasMipMaps() = 0;
542
543 /** Access meta data. */
544 virtual PtexMetaData* getMetaData() = 0;
545
546 /** Access resolution and adjacency information about a face. */
547 virtual const Ptex::FaceInfo& getFaceInfo(int faceid) = 0;
548
549 /** Access texture data for a face at highest-resolution.
550
551 The texture data is copied into the user-supplied buffer.
552 The buffer must be at least this size (in bytes):
553 DataSize(dataType()) * numChannels() * getFaceInfo(faceid).res.size().
554
555 If a stride is given, then (stride-row_length) bytes will be
556 skipped after each row. If stride is zero, then no bytes will
557 be skipped. Note: the image can be flipped vertically by using
558 an appropriate negative stride value.
559
560 @param faceid Face index [0..numFaces-1]
561 @param buffer User-supplied buffer
562 @param stride Size of each row in user buffer (in bytes)
563 */
564 virtual void getData(int faceid, void* buffer, int stride) = 0;
565
566 /** Access texture data for a face at a specific resolution.
567
568 The specified resolution may be lower than the full resolution
569 for the face. If it is lower, then the texture data is
570 accessed from the stored mip-maps. If the requested
571 resolution doesn't match a stored resolution, the desired
572 resolution will be generated from the nearest available
573 resolution.
574
575 See previous getData() method for interface details.
576 */
577 virtual void getData(int faceid, void* buffer, int stride, Ptex::Res res) = 0;
578
579 /** Access texture data for a face at highest-resolution as stored on disk. */
580 virtual PtexFaceData* getData(int faceid) = 0;
581
582 /** Access texture data for a face at a specific resolution as stored on disk.
583
584 The specified resolution may be lower (but not higher) than
585 the full resolution for the face. If it is lower, then the
586 texture data is accessed from the stored mip-maps. If the
587 requested resolution doesn't match a stored resolution, the
588 desired resolution will be generated from the nearest
589 available resolution.
590 */
591 virtual PtexFaceData* getData(int faceid, Ptex::Res res) = 0;
592
593 /** Access a single texel from the highest resolution texture .
594 The texel data is converted to floating point (integer types
595 are normalized 0.0 to 1.0). A subset of the available
596 channels may be accessed.
597
598 @param faceid Face index [0..numFaces-1]
599 @param u U coordinate [0..ures-1]
600 @param v V coordinate [0..vres-1]
601 @param result Result data
602 @param firstchan First channel to access [0..numChannels-1]
603 @param nchannels Number of channels to access.
604 */
605 virtual void getPixel(int faceid, int u, int v,
606 float* result, int firstchan, int nchannels) = 0;
607
608 /** Access a single texel for a face at a particular resolution.
609
610 The specified resolution may be lower (but not higher) than
611 the full resolution for the face. If it is lower, then the
612 texture data is accessed from the stored mip-maps. If the
613 requested resolution doesn't match a stored resolution, the
614 desired resolution will be generated from the nearest
615 available resolution.
616
617 See previous getPixel() method for details.
618 */
619 virtual void getPixel(int faceid, int u, int v,
620 float* result, int firstchan, int nchannels,
621 Ptex::Res res) = 0;
622 };
623
624
625 /** @class PtexInputHandler
626 @brief Custom handler interface for intercepting and redirecting Ptex input stream calls
627
628 A custom instance of this class can be defined and supplied to the PtexCache class.
629 Files accessed through the cache will have their input streams redirected through this
630 interface.
631 */
632 class PtexInputHandler {
633 protected:
~PtexInputHandler()634 virtual ~PtexInputHandler() {}
635
636 public:
637 typedef void* Handle;
638
639 /** Open a file in read mode.
640 Returns null if there was an error.
641 If an error occurs, the error string is available via lastError().
642 */
643 virtual Handle open(const char* path) = 0;
644
645 /** Seek to an absolute byte position in the input stream. */
646 virtual void seek(Handle handle, int64_t pos) = 0;
647
648 /** Read a number of bytes from the file.
649 Returns the number of bytes successfully read.
650 If less than the requested number of bytes is read, the error string
651 is available via lastError().
652 */
653 virtual size_t read(void* buffer, size_t size, Handle handle) = 0;
654
655 /** Close a file. Returns false if an error occurs, and the error
656 string is available via lastError(). */
657 virtual bool close(Handle handle) = 0;
658
659 /** Return the last error message encountered. */
660 virtual const char* lastError() = 0;
661 };
662
663
664 /** @class PtexErrorHandler
665 @brief Custom handler interface redirecting Ptex error messages
666
667 A custom instance of this class can be defined and supplied to the PtexCache class.
668 Files accessed through the cache will have their error streams redirected through this
669 interface.
670 */
671 class PtexErrorHandler {
672 protected:
~PtexErrorHandler()673 virtual ~PtexErrorHandler() {}
674
675 public:
676 virtual void reportError(const char* error) = 0;
677 };
678
679
680 /**
681 @class PtexCache
682 @brief File-handle and memory cache for reading ptex files
683
684 The PtexCache class allows cached read access to multiple ptex
685 files while constraining the open file count and memory usage to
686 specified limits. File and data objects accessed via the cache
687 are added back to the cache when their release method is called.
688 Released objects are maintained in an LRU list and only destroyed
689 when the specified resource limits are exceeded.
690
691 The cache is fully multi-threaded. Cached data will be shared among
692 all threads that have access to the cache, and the data are protected
693 with internal locks. See PtexCache.cpp for details about the caching
694 and locking implementation.
695 */
696
697 class PtexCache {
698 protected:
699 /// Destructor not for public use. Use release() instead.
~PtexCache()700 virtual ~PtexCache() {}
701
702 public:
703 /** Create a cache with the specified limits.
704
705 @param maxFiles Maximum open file handles. If zero,
706 limit is set to 100 open files.
707
708 @param maxMem Maximum allocated memory, in bytes. If zero
709 the cache is unlimited.
710
711 @param premultiply If true, textures will be premultiplied by
712 the alpha channel (if any) when read from disk. For authoring
713 purposes, this should generally be set to false, and for
714 rendering purposes, this should generally be set to true. See
715 PtexTexture and PtexWriter for more details.
716
717 @param inputHandler If specified, all input calls made through this cache will
718 be directed through the handler.
719
720 @param errorHandler If specified, errors encounted with files access through
721 this cache will be directed to the handler. By default, errors will be
722 reported to stderr.
723 */
724 PTEXAPI static PtexCache* create(int maxFiles,
725 size_t maxMem,
726 bool premultiply=false,
727 PtexInputHandler* inputHandler=0,
728 PtexErrorHandler* errorHandler=0);
729
730 /// Release PtexCache. Cache will be immediately destroyed and all resources will be released.
731 virtual void release() = 0;
732
733 /** Set a search path for finding textures.
734 Note: if an input handler is installed the search path will be ignored.
735
736 @param path colon-delimited search path.
737 */
738 virtual void setSearchPath(const char* path) = 0;
739
740 /** Query the search path. Returns string set via setSearchPath. */
741 virtual const char* getSearchPath() = 0;
742
743 /** Access a texture. If the specified path was previously accessed
744 from the cache, then a pointer to the cached texture will be
745 returned.
746
747 If the specified path hasn't been opened yet or was purged
748 from the cache (via the purge or purgeAll methods) then the
749 file will be opened. If the path is relative (i.e. doesn't
750 begin with a '/') then the search path will be used to locate
751 the file.
752
753 The texture will be accessible until the PtexTexture::release
754 method is called, at which point the texture will be returned
755 to the cache. Once released, the texture may have it's data
756 pruned (immediately or some time later) to stay within the
757 maximum cache size.
758
759 If the texture could not be opened, null will be returned and
760 an error string will be set. If an error were previously
761 encountered with the file (include the file not being found),
762 null will be returned and no error string will be set.
763
764 @param path File path. If path is relative, search path will
765 be used to find the file.
766
767 @param error Error string set if texture could not be
768 opened.
769 */
770 virtual PtexTexture* get(const char* path, Ptex::String& error) = 0;
771
772 /** Remove a texture file from the cache. If the texture is in use
773 by another thread, that reference will remain valid and the file
774 will be purged once it is no longer in use. This texture
775 should be released immediately after purging.
776 */
777 virtual void purge(PtexTexture* texture) = 0;
778
779 /** Remove a texture file from the cache by pathname. The path must
780 match the full path as opened. This function will not search
781 for the file, but if a search path was used, the path must
782 match the path as found by the search path.
783 */
784 virtual void purge(const char* path) = 0;
785
786 /** Remove all texture files from the cache. Textures with
787 active PtexTexture* handles will remain valid and will be purged
788 upon release.
789 */
790 virtual void purgeAll() = 0;
791
792 struct Stats {
793 uint64_t memUsed;
794 uint64_t peakMemUsed;
795 uint64_t filesOpen;
796 uint64_t peakFilesOpen;
797 uint64_t filesAccessed;
798 uint64_t fileReopens;
799 uint64_t blockReads;
800 };
801
802 /** Get stats. */
803 virtual void getStats(Stats& stats) = 0;
804 };
805
806
807 /**
808 @class PtexWriter
809 @brief Interface for writing data to a ptex file.
810
811 Note: if an alpha channel is specified, then the textures being
812 written to the file are expected to have unmultiplied-alpha data.
813 Generated mipmaps will be premultiplied by the Ptex library. On
814 read, PtexTexture will (if requested) premultiply all textures by
815 alpha when getData is called; by default only reductions are
816 premultiplied. If the source textures are already premultiplied,
817 then alphachan can be set to -1 and the library will just leave all
818 the data as-is. The only reason to store unmultiplied-alpha
819 textures in the file is to preserve the original texture data for
820 later editing.
821 */
822
823 class PtexWriter {
824 protected:
825 /// Destructor not for public use. Use release() instead.
~PtexWriter()826 virtual ~PtexWriter() {}
827
828 public:
829 /** Open a new texture file for writing.
830 @param path Path to file.
831 @param mt Type of mesh for which the textures are defined.
832 @param dt Type of data stored within file.
833 @param nchannels Number of data channels.
834 @param alphachan Index of alpha channel, [0..nchannels-1] or -1 if no alpha channel is present.
835 @param nfaces Number of faces in mesh.
836 @param error String containing error message if open failed.
837 @param genmipmaps Specify true if mipmaps should be generated.
838 */
839 PTEXAPI
840 static PtexWriter* open(const char* path,
841 Ptex::MeshType mt, Ptex::DataType dt,
842 int nchannels, int alphachan, int nfaces,
843 Ptex::String& error, bool genmipmaps=true);
844
845 /** Open an existing texture file for writing.
846
847 If the incremental param is specified as true, then data
848 values written to the file are appended to the file as "edit
849 blocks". This is the fastest way to write data to the file, but
850 edit blocks are slower to read back, and they have no mipmaps so
851 filtering can be inefficient.
852
853 If incremental is false, then the edits are applied to the
854 file and the entire file is regenerated on close as if it were
855 written all at once with open().
856
857 If the file doesn't exist it will be created and written as if
858 open() were used. If the file exists, the mesh type, data
859 type, number of channels, alpha channel, and number of faces
860 must agree with those stored in the file.
861 */
862 PTEXAPI
863 static PtexWriter* edit(const char* path, bool incremental,
864 Ptex::MeshType mt, Ptex::DataType dt,
865 int nchannels, int alphachan, int nfaces,
866 Ptex::String& error, bool genmipmaps=true);
867
868 /** Apply edits to a file.
869
870 If a file has pending edits, the edits will be applied and the
871 file will be regenerated with no edits. This is equivalent to
872 calling edit() with incremental set to false. The advantage
873 is that the file attributes such as mesh type, data type,
874 etc., don't need to be known in advance.
875 */
876 PTEXAPI
877 static bool applyEdits(const char* path, Ptex::String& error);
878
879 /** Release resources held by this pointer (pointer becomes invalid). */
880 virtual void release() = 0;
881
882 /** Set border modes */
883 virtual void setBorderModes(Ptex::BorderMode uBorderMode, Ptex::BorderMode vBorderMode) = 0;
884
885 /** Set edge filter mode */
886 virtual void setEdgeFilterMode(Ptex::EdgeFilterMode edgeFilterMode) = 0;
887
888 /** Write a string as meta data. Both the key and string params must be null-terminated strings. */
889 virtual void writeMeta(const char* key, const char* string) = 0;
890
891 /** Write an array of signed 8-bit integers as meta data. The key must be a null-terminated string. */
892 virtual void writeMeta(const char* key, const int8_t* value, int count) = 0;
893
894 /** Write an array of signed 16-bit integers as meta data. The key must be a null-terminated string. */
895 virtual void writeMeta(const char* key, const int16_t* value, int count) = 0;
896
897 /** Write an array of signed 32-bit integers as meta data. The key must be a null-terminated string. */
898 virtual void writeMeta(const char* key, const int32_t* value, int count) = 0;
899
900 /** Write an array of signed 32-bit floats as meta data. The key must be a null-terminated string. */
901 virtual void writeMeta(const char* key, const float* value, int count) = 0;
902
903 /** Write an array of signed 32-bit doubles as meta data. The key must be a null-terminated string. */
904 virtual void writeMeta(const char* key, const double* value, int count) = 0;
905
906 /** Copy meta data from an existing meta data block. */
907 virtual void writeMeta(PtexMetaData* data) = 0;
908
909 /** Write texture data for a face.
910 The data is assumed to be channel-interleaved per texel and stored in v-major order.
911
912 @param faceid Face index [0..nfaces-1].
913 @param info Face resolution and adjacency information.
914 @param data Texel data.
915 @param stride Distance between rows, in bytes (if zero, data is assumed packed).
916
917 If an error is encountered while writing, false is returned and an error message can be
918 retrieved when close is called.
919 */
920 virtual bool writeFace(int faceid, const Ptex::FaceInfo& info, const void* data, int stride=0) = 0;
921
922 /** Write constant texture data for a face.
923 The data is written as a single constant texel value. Note: the resolution specified in the
924 info param may indicate a resolution greater than 1x1 and the value will be preserved when
925 reading. This is useful to indicate a texture's logical resolution even when the data is
926 constant. */
927 virtual bool writeConstantFace(int faceid, const Ptex::FaceInfo& info, const void* data) = 0;
928
929 /** Close the file. This operation can take some time if mipmaps are being generated or if there
930 are many edit blocks. If an error occurs while writing, false is returned and an error string
931 is written into the error parameter. */
932 virtual bool close(Ptex::String& error) = 0;
933
934 #if NEW_API
935 virtual bool writeFaceReduction(int faceid, const Ptex::Res& res, const void* data, int stride=0) = 0;
936 virtual bool writeConstantFaceReduction(int faceid, const Ptex::Res& res, const void* data) = 0;
937 #endif
938 };
939
940
941 /**
942 @class PtexFilter
943 @brief Interface for filtered sampling of ptex data files.
944
945 PtexFilter instances are obtained by calling one of the particular static methods. When finished using
946 the filter, it must be returned to the library using release().
947
948 To apply the filter to a ptex data file, use the eval() method.
949 */
950 class PtexFilter {
951 protected:
952 /// Destructor not for public use. Use release() instead.
~PtexFilter()953 virtual ~PtexFilter() {}
954
955 public:
956 /// Filter types
957 enum FilterType {
958 f_point, ///< Point-sampled (no filtering)
959 f_bilinear, ///< Bi-linear interpolation
960 f_box, ///< Box filter
961 f_gaussian, ///< Gaussian filter
962 f_bicubic, ///< General bi-cubic filter (uses sharpness option)
963 f_bspline, ///< BSpline (equivalent to bi-cubic w/ sharpness=0)
964 f_catmullrom, ///< Catmull-Rom (equivalent to bi-cubic w/ sharpness=1)
965 f_mitchell ///< Mitchell (equivalent to bi-cubic w/ sharpness=2/3)
966 };
967
968 /// Choose filter options
969 struct Options {
970 int __structSize; ///< (for internal use only)
971 FilterType filter; ///< Filter type.
972 bool lerp; ///< Interpolate between mipmap levels.
973 float sharpness; ///< Filter sharpness, 0..1 (for general bi-cubic filter only).
974 bool noedgeblend; ///< Disable cross-face filtering. Useful for debugging or rendering on polys.
975
976 /// Constructor - sets defaults
977 Options(FilterType filter_=f_box, bool lerp_=0, float sharpness_=0, bool noedgeblend_=0) :
__structSizeOptions978 __structSize(sizeof(Options)),
979 filter(filter_), lerp(lerp_), sharpness(sharpness_), noedgeblend(noedgeblend_) {}
980 };
981
982 /* Construct a filter for the given texture.
983 */
984 PTEXAPI static PtexFilter* getFilter(PtexTexture* tx, const Options& opts);
985
986 /** Release resources held by this pointer (pointer becomes invalid). */
987 virtual void release() = 0;
988
989 /** Apply filter to a ptex data file.
990
991 The filter region is a parallelogram centered at the given
992 (u,v) coordinate with sides defined by two vectors [uw1, vw1]
993 and [uw2, vw2]. For an axis-aligned rectangle, the vectors
994 are [uw, 0] and [0, vw]. See \link filterfootprint Filter
995 Footprint \endlink for details.
996
997 @param result Buffer to hold filter result. Must be large enough to hold nchannels worth of data.
998 @param firstchan First channel to evaluate [0..tx->numChannels()-1]
999 @param nchannels Number of channels to evaluate
1000 @param faceid Face index [0..tx->numFaces()-1]
1001 @param u U coordinate, normalized [0..1]
1002 @param v V coordinate, normalized [0..1]
1003 @param uw1 U filter width 1, normalized [0..1]
1004 @param vw1 V filter width 1, normalized [0..1]
1005 @param uw2 U filter width 2, normalized [0..1]
1006 @param vw2 V filter width 2, normalized [0..1]
1007 @param width scale factor for filter width
1008 @param blur amount to add to filter width [0..1]
1009 */
1010 virtual void eval(float* result, int firstchan, int nchannels,
1011 int faceid, float u, float v, float uw1, float vw1, float uw2, float vw2,
1012 float width=1, float blur=0) = 0;
1013 };
1014
1015
1016 /**
1017 @class PtexPtr
1018 @brief Smart-pointer for acquiring and releasing API objects
1019
1020 All public API objects must be released back to the Ptex library
1021 via the release() method. This smart-pointer class can wrap any of
1022 the Ptex API objects and will automatically release the object when
1023 the pointer goes out of scope. Usage of PtexPtr is optional, but
1024 recommended.
1025
1026 Note: for efficiency and safety, PtexPtr is noncopyable. However,
1027 ownership can be transferred between PtexPtr instances via the
1028 PtexPtr::swap member function.
1029
1030 Example:
1031 \code
1032 {
1033 Ptex::String error;
1034 PtexPtr<PtexTexture> inptx(PtexTexture::open(inptxname, error));
1035 if (!inptx) {
1036 std::cerr << error << std::endl;
1037 }
1038 else {
1039 // read some data
1040 inptx->getData(faceid, buffer, stride);
1041 }
1042 }
1043 \endcode
1044 */
1045 template <class T> class PtexPtr {
1046 T* _ptr;
1047 public:
1048 /// Constructor.
_ptr(ptr)1049 PtexPtr(T* ptr=0) : _ptr(ptr) {}
1050
1051 /// Destructor, calls ptr->release().
~PtexPtr()1052 ~PtexPtr() { if (_ptr) _ptr->release(); }
1053
1054 /// Use as pointer value.
1055 operator T* () const { return _ptr; }
1056
1057 /// Access members of pointer.
1058 T* operator-> () const { return _ptr; }
1059
1060 /// Get pointer value.
get()1061 T* get() const { return _ptr; }
1062
1063 /// Swap pointer values.
swap(PtexPtr & p)1064 void swap(PtexPtr& p)
1065 {
1066 T* tmp = p._ptr;
1067 p._ptr = _ptr;
1068 _ptr = tmp;
1069 }
1070
1071 /// Deallocate object pointed to, and optionally set to new value.
1072 void reset(T* ptr=0) {
1073 if (_ptr) _ptr->release();
1074 _ptr = ptr;
1075 }
1076
1077 private:
1078 /// Copying prohibited
1079 PtexPtr(const PtexPtr& p);
1080
1081 /// Assignment prohibited
1082 void operator= (PtexPtr& p);
1083 };
1084
1085 #ifndef DOXYGEN
1086 namespace PtexUtils {}
1087
1088 PTEX_NAMESPACE_END
1089
1090 using Ptex::PtexMetaData;
1091 using Ptex::PtexFaceData;
1092 using Ptex::PtexTexture;
1093 using Ptex::PtexInputHandler;
1094 using Ptex::PtexErrorHandler;
1095 using Ptex::PtexCache;
1096 using Ptex::PtexWriter;
1097 using Ptex::PtexFilter;
1098 using Ptex::PtexPtr;
1099 namespace PtexUtils = Ptex::PtexUtils;
1100
1101 #endif
1102 #endif
1103