HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
GU_UVPack.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: GU Library (C++)
7  *
8  * COMMENTS: UVPack GU
9  */
10 
11 #ifndef __GU_UVPack_h__
12 #define __GU_UVPack_h__
13 
14 #include "GU_API.h"
15 #include "GU_Detail.h"
16 #include <GEO/GEO_HedgeInterface.h>
17 
19 {
20 public:
21  GU_UVPack(GU_Detail *gdp,
22  const GA_PrimitiveGroup *grp = nullptr,
23  int resolution = 1000,
24  int padding = 10, bool pad_boundary = false,
25  bool correct_area_proprtions = false,
26  bool axis_align_islands = false,
27  bool repack_wasted = false);
28 
29  ~GU_UVPack();
30 
31  void setPadding(int padding)
32  { myPadding = padding; }
33 
34  // Pack all islands into a single tile (unit square) at maximum
35  // possible scale.
36  int tilePack(UT_IntArray *islands = NULL,
37  int tile_u = 0, int tile_v = 0);
38 
39  // Pack islands into as few squares as possible a the given fixed scale.
40  void scalePack(fpreal scale);
41 
42  // Packs everything according to the udim attribute
43  void udimPack(bool guess_udim_from_uvs = false);
44 
45 
46  // a structure presenting a rasterized copy of a UV island
47  struct GU_API Raster
48  {
49  Raster(int w, int h, int res, fpreal orig_scale);
50  void setScale(fpreal scale);
51  inline void updateLow(int x, int y)
52  { if (y < myOrigLow(x)) myOrigLow(x) = y; }
53 
54  inline void updateHigh(int x, int y)
55  { if (y > myOrigHigh(x)) myOrigHigh(x) = y; }
56 
57  inline int getLow(int x)
58  { return myTrivialRaster ? 0 : myLow(x); }
59 
60  inline int getInvertedLow(int x)
61  { return myTrivialRaster ? 0 :
62  myHeight - 1 - myHigh(myWidth - 1 - x); }
63 
64  inline int getHigh(int x)
65  { return myTrivialRaster ?
66  myHeight - 1: myHigh(x); }
67 
68  inline int getInvertedHigh(int x)
69  { return myTrivialRaster ? myHeight - 1:
70  myHeight - 1 - myLow(myWidth - 1 - x); }
71 
72  inline int getWidth() { return myWidth; }
73  inline int getHeight() { return myHeight; }
74  inline fpreal getOrigScale() { return myOrigScale; }
75 
76  inline void setMaxU(fpreal u) { myMaxU = u; }
77  inline void setMaxV(fpreal v) { myMaxV = v; }
78  inline fpreal getMaxU() { return myMaxU; }
79  inline fpreal getMaxV() { return myMaxV; }
80 
81  void dumpOrig(int xstep, int ystep);
82  void dump(int xstep, int ystep);
83  inline bool isTrivial() { return myTrivialRaster; }
84 
85  private:
86 
87  int myOrigWidth;
88  int myOrigHeight;
89  fpreal myOrigScale;
90  UT_IntArray myOrigLow; // lower horizon
91  UT_IntArray myOrigHigh; // upper horizon
92 
93  int myWidth; // width at current scale
94  int myHeight; // height at current scale
95  fpreal myScale; // current scale
96  UT_IntArray myLow; // current scale lower horizon
97  UT_IntArray myHigh; // current sacle upper horizon
98 
99  int myRes;
100  bool myTrivialRaster;
101  fpreal myMaxU, myMaxV;
102  };
103 
104  struct Horizon
105  {
106  Horizon(int width);
107  void clear();
108  int getMinHeight();
109  int getMaxHeight() { return myMaxHeight; }
110  inline int getHeight(int i) { return myHeight(i); }
111  inline void updateHeight(int i, int h)
112  { if (h > myHeight(i)) myHeight(i) = h; }
113  inline void updateMaxHeight(int h)
114  { if (h > myMaxHeight) myMaxHeight = h; }
115  int getWidth() { return myHeight.entries(); }
116  const UT_IntArray& getHeightData() const { return myHeight; }
117  private:
118  UT_IntArray myHeight;
119  int myMaxHeight;
120  };
121 
122  Raster *getRaster(int island, int inst)
123  {
124  return myRasters(myNumInstances * island + inst);
125  }
126 
127 private:
128  inline int vertexIsland(GA_Offset v)
129  { return myPrimIsland(myGdp->vertexPrimitive(v)); }
130 
131  // Shifts UVs of all island vertices so that the minimum U and V
132  // values are both zero.
133  void translateIslandsToOrigin();
134 
135  // computes and writes area of all UV islands into array myArea
136  void computeIslandAreas(bool correct_area_proportions);
137 
138  // transforms an island to a set of texels
139  Raster *rasterizeIsland(int island, int inst, int resolution,
140  fpreal scale);
141 
142  void prepareIslandRasters(UT_IntArray &islands,
143  int resolution, fpreal scale);
144 
145  void resetRasters();
146  bool isIslandTooLarge(int island, int resolutino);
147 
148  void axisAlignIslands();
149 
150  enum IslandPackStatus
151  {
152  PACKED,
153  NO_ROOM, // island fits in empty tile but not enough room now
154  TOO_LARGE // island wider or taller than the tile
155  };
156 
157  struct Placement
158  {
159  public:
160  Placement() :
161  myBaseU(0.0), myBaseV(0.0), myInstance(0), myInverted(false) {}
162 
163  inline void setBaseU(fpreal u) { myBaseU = u; }
164  inline void setBaseV(fpreal v) { myBaseV = v; }
165  inline void setInverted(bool b) { myInverted = b; }
166  inline void setInstance(int i) { myInstance = i; }
167 
168  inline fpreal getBaseU() { return myBaseU; }
169  inline fpreal getBaseV() { return myBaseV; }
170  inline bool isInverted() { return myInverted; }
171  inline int getInstance() { return myInstance; }
172 
173  private:
174  fpreal myBaseU, myBaseV;
175  int myInstance;
176  bool myInverted;
177  };
178 
179  // Structure which tracks lost lower space after horizon adjustment.
180  struct WastedSpace
181  {
182  public:
183  WastedSpace(int w, int x, int y) :
184  myMinHeight(std::numeric_limits<int>::max()),
185  myMaxHeight(std::numeric_limits<int>::min()),
186  myWidth(w), myPosX(x), myPosY(y)
187  {
188  mySpaceLower.entries(w);
189  mySpaceUpper.entries(w);
190  }
191 
192  inline void updateBounds(int x, int lower, int upper)
193  {
194  mySpaceLower(x) = lower;
195  mySpaceUpper(x) = upper;
196 
197  int height = upper - lower;
198 
199  if (height < myMinHeight)
200  myMinHeight = height;
201 
202  if (height > myMaxHeight)
203  {
204  myMaxHeight = height;
205  }
206  }
207 
208  inline int getMinHeight() const
209  {
210  return myMinHeight;
211  }
212 
213  inline int getMaxHeight() const
214  {
215  return myMaxHeight;
216  }
217 
218  inline int getWidth() const
219  {
220  return myWidth;
221  }
222 
223  inline int getPosX() const
224  {
225  return myPosX;
226  }
227 
228  inline int getPosY() const
229  {
230  return myPosY;
231  }
232 
233  inline int getLower(int i) const
234  {
235  return mySpaceLower(i);
236  }
237 
238  inline int getUpper(int i) const
239  {
240  return mySpaceUpper(i);
241  }
242 
243  private:
244  UT_IntArray mySpaceLower;
245  UT_IntArray mySpaceUpper;
246  int myMinHeight, myMaxHeight;
247  int myWidth;
248  int myPosX, myPosY;
249  };
250 
251  IslandPackStatus packIsland(int i, Horizon &horizon,
252  UT_Array<WastedSpace> &wasted_spaces,
253  int padding, Placement &placement);
254 
255  void updateUVs(bool all_tiles, int tile_u, int tile_v,
256  int resolution, fpreal scale);
257 
258  // Calculate "island" attribute based on UV connectivity.
259  void findIslands(const GA_PrimitiveGroup *grp);
260 
261  // Finds the best location to drop the island raster into one of the
262  // recorded lower wasted spaces.
263  IslandPackStatus findBestWastedPacking(int island,
264  UT_Array<WastedSpace> &wasted_spaces, int &inst,
265  int &x, int &y, bool &inverted, int padding);
266 
267  // Finds the best location to drop the island raster into a horizon.
268  // Returns true if the best packing requires turning the island upside-down.
269  bool findBestPacking(Raster &raster,
270  Horizon &horizon, int &x, int &y);
271 
272  IslandPackStatus findBestPacking(int island, Horizon &hor, int &inst,
273  int &x, int &y, bool &inverted);
274 
275  bool verifyWastedSpaceHorizonPacking(const WastedSpace &wasted_space,
276  int horizon_value, int shift, int padding, int pos) const;
277 
278  void setRaster(int island, int inst, Raster *raster)
279  {
280  int idx = myNumInstances * island + inst;
281  if (myRasters(idx))
282  delete myRasters(idx);
283  myRasters(idx) = raster;
284  }
285 
286 
287  int myResolution; // packing horizon width
288  int myPadding;
289  bool myPadBoundary; // apply padding to square frame
290  bool myUse3DArea;
291  int myNumInstances;
292  int myNumIslands;
293  bool myAxisAlignIslands;
294  bool myRepackWasted;
295 
296  // Maximum UV values for each island, after being translated to origin
297  UT_FprealArray myMaxU;
298  UT_FprealArray myMaxV;
299  UT_FprealArray myIslandArea; // UV Area of islands
300  UT_IntArray myIslandsOrder; // Order to pack islands
301  UT_IntArray myIslandTile; // tile assigned to each island
302  UT_IntArray myOrigIslandTileU; // tile assigned to each island
303  UT_IntArray myOrigIslandTileV; // tile assigned to each island
304  UT_IntArray myIslandTileU; // tile assigned to each island
305  UT_IntArray myIslandTileV; // tile assigned to each island
306  UT_IntArray myIslandDefaultUdim; // lowest udim number tiles
307  // containing vertices of island
308 
309  // Final placement of UV islands in their respective tiles
310  UT_Array<Placement> myPlacement;
311 
312  // Array of rasters (one raster per instance per island)
313  // Raster j of island i will be at index (i * myNumInstances + j)
314  UT_Array<Raster *> myRasters;
315 
316  UT_Array<GEO_Hedge> myBoundaryHedges;
317 
318 
319  UT_IntArray myPrimIsland; // maps prim offset to island
320 
321  GA_RWHandleV3 myUV;
322  GU_Detail *myGdp;
323 
325 };
326 
327 
328 #endif
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
std::string upper(string_view a)
Return an all-upper case version of a (locale-independent).
Definition: strutil.h:402
int getHeight(int i)
Definition: GU_UVPack.h:110
const GLdouble * v
Definition: glcorearb.h:837
ImageBuf OIIO_API min(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
GLint y
Definition: glcorearb.h:103
Raster * getRaster(int island, int inst)
Definition: GU_UVPack.h:122
fpreal getMaxU()
Definition: GU_UVPack.h:78
GA_Size GA_Offset
Definition: GA_Types.h:646
int getLow(int x)
Definition: GU_UVPack.h:57
GA_API const UT_StringHolder scale
GLint GLsizei GLsizei height
Definition: glcorearb.h:103
void updateHigh(int x, int y)
Definition: GU_UVPack.h:54
bool isTrivial()
Definition: GU_UVPack.h:83
HUSD_API const char * raster()
const UT_IntArray & getHeightData() const
Definition: GU_UVPack.h:116
#define GU_API
Definition: GU_API.h:14
HUSD_API const char * resolution()
int getInvertedHigh(int x)
Definition: GU_UVPack.h:68
void updateHeight(int i, int h)
Definition: GU_UVPack.h:111
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
GLint GLenum GLint x
Definition: glcorearb.h:409
fpreal getMaxV()
Definition: GU_UVPack.h:79
int getInvertedLow(int x)
Definition: GU_UVPack.h:60
fpreal getOrigScale()
Definition: GU_UVPack.h:74
GLfloat GLfloat GLfloat GLfloat h
Definition: glcorearb.h:2002
std::string lower(string_view a)
Return an all-upper case version of a (locale-independent).
Definition: strutil.h:395
fpreal64 fpreal
Definition: SYS_Types.h:277
ImageBuf OIIO_API max(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
GLint GLsizei width
Definition: glcorearb.h:103
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:857
void setPadding(int padding)
Definition: GU_UVPack.h:31
void updateLow(int x, int y)
Definition: GU_UVPack.h:51
void setMaxU(fpreal u)
Definition: GU_UVPack.h:76
void updateMaxHeight(int h)
Definition: GU_UVPack.h:113
void setMaxV(fpreal v)
Definition: GU_UVPack.h:77
int getHigh(int x)
Definition: GU_UVPack.h:64