HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
GABC_OGTGeometry.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) COPYRIGHTYEAR
3  * Side Effects Software Inc. All rights reserved.
4  *
5  * Redistribution and use of Houdini Development Kit samples in source and
6  * binary forms, with or without modification, are permitted provided that the
7  * following conditions are met:
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  * 2. The name of Side Effects Software may not be used to endorse or
11  * promote products derived from this software without specific prior
12  * written permission.
13  *
14  * THIS SOFTWARE IS PROVIDED BY SIDE EFFECTS SOFTWARE `AS IS' AND ANY EXPRESS
15  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
17  * NO EVENT SHALL SIDE EFFECTS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
20  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
21  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
22  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
23  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  *
25  *----------------------------------------------------------------------------
26  */
27 
28 #ifndef __GABC_OGTGeometry__
29 #define __GABC_OGTGeometry__
30 
31 #include "GABC_API.h"
32 #include "GABC_Include.h"
33 #include "GABC_Util.h"
34 #include <Alembic/AbcGeom/All.h>
35 #include <GT/GT_Primitive.h>
36 #include <UT/UT_StringSet.h>
37 
38 namespace GABC_NAMESPACE
39 {
40 
41 class GABC_OError;
42 class GABC_OOptions;
43 class GABC_OProperty;
44 
45 /// This class will translate and output a GT_Primitive to Alembic.
46 /// Each time the update function is called, this class will write a sample
47 /// to it's Alembic object. If updateFromPrevious is called, the most recent
48 /// sample will be reused. Before either of these functions can be called, the
49 /// start function must be called to setup the Alembic OObject. Start will also
50 /// call update for the first time.
52 {
53 public:
56 
64 
68  /// A simple set of strings
69  class IgnoreList
70  : public UT_StringSet
71  {
72  public:
74  : UT_StringSet()
75  {}
76  IgnoreList(const char *arg0, ...);
78 
80  { insert(skip); }
82  { return erase(skip); }
83  bool contains(const UT_StringRef &token) const
84  { return count(token) > 0; }
85  };
86 
87  /// The intrinsic cache is used to cache array values frame to frame when
88  /// optimizing the .abc file for space. Only arrays which change will be
89  /// written to the file. The cache has storage for most primitive types.
91  {
92  public:
94  ~IntrinsicCache() { clear(); }
95 
96  void clear();
97 
98  /// @{
99  /// Test whether topology arrays need to be written
100  bool needVertex(const GABC_OOptions &ctx,
101  const GT_DataArrayHandle &vertex_list)
102  { return needWrite(ctx, vertex_list, myVertexList); }
103  bool needCounts(const GABC_OOptions &ctx,
104  const GT_DataArrayHandle &counts)
105  { return needWrite(ctx, counts, myCounts); }
106  /// @}
107 
108  /// Test to see if the attribute needs to be written (true) or whether
109  /// we can use the sample from the previous frame (false)
110  bool needWrite(const GABC_OOptions &ctx,
111  const char *name, const GT_DataArrayHandle &data);
112 
113  GT_DataArrayHandle &vertexList() { return myVertexList; }
114  GT_DataArrayHandle &counts() { return myCounts; }
115  GT_DataArrayHandle &P() { return myP; }
116  GT_DataArrayHandle &Pw() { return myPw; }
117  GT_DataArrayHandle &N() { return myN; }
118  GT_DataArrayHandle &uv() { return myUV; }
119  GT_DataArrayHandle &v() { return myVel; }
120  GT_DataArrayHandle &id() { return myId; }
121  GT_DataArrayHandle &width() { return myWidth; }
122  GT_DataArrayHandle &uknots() { return myUKnots; }
123  GT_DataArrayHandle &vknots() { return myVKnots; }
124 
125  private:
126  bool needWrite(const GABC_OOptions &ctx,
127  const GT_DataArrayHandle &data,
128  GT_DataArrayHandle &cache);
129  GT_DataArrayHandle myVertexList;
130  GT_DataArrayHandle myCounts;
131  GT_DataArrayHandle myP;
132  GT_DataArrayHandle myPw;
133  GT_DataArrayHandle myN;
134  GT_DataArrayHandle myUV;
135  GT_DataArrayHandle myVel;
136  GT_DataArrayHandle myId;
137  GT_DataArrayHandle myWidth;
138  GT_DataArrayHandle myUKnots;
139  GT_DataArrayHandle myVKnots;
140  };
141 
142  /// Secondary cache is used to cache values for subdivision tags and trim
143  /// curves. This is an optional cache and is only created for some
144  /// primitive types.
146  {
147  public:
149  ~SecondaryCache() { clear(); }
150 
151  /// @{
152  /// Access trim curve information
153  GT_DataArrayHandle &trimNCurves() { return myData[0]; }
154  GT_DataArrayHandle &trimN() { return myData[1]; }
155  GT_DataArrayHandle &trimOrder() { return myData[2]; }
156  GT_DataArrayHandle &trimKnot() { return myData[3]; }
157  GT_DataArrayHandle &trimMin() { return myData[4]; }
158  GT_DataArrayHandle &trimMax() { return myData[5]; }
159  GT_DataArrayHandle &trimU() { return myData[6]; }
160  GT_DataArrayHandle &trimV() { return myData[7]; }
161  GT_DataArrayHandle &trimW() { return myData[8]; }
162  /// @}
163 
164  /// Updates the cache with the current values and returns @c true if
165  /// the values have changed or @c false if the previous values can be
166  /// used. There's no way in the Alembic API to set trim components
167  /// individually.
169  const GT_DataArrayHandle &data)
170  {
171  { return needWrite(ctx, data, trimNCurves()); }
172  }
173  bool needTrimN(const GABC_OOptions &ctx,
174  const GT_DataArrayHandle &data)
175  {
176  { return needWrite(ctx, data, trimN()); }
177  }
178  bool needTrimOrder(const GABC_OOptions &ctx,
179  const GT_DataArrayHandle &data)
180  {
181  { return needWrite(ctx, data, trimOrder()); }
182  }
183  bool needTrimKnot(const GABC_OOptions &ctx,
184  const GT_DataArrayHandle &data)
185  {
186  { return needWrite(ctx, data, trimKnot()); }
187  }
188  bool needTrimMin(const GABC_OOptions &ctx,
189  const GT_DataArrayHandle &data)
190  {
191  { return needWrite(ctx, data, trimMin()); }
192  }
193  bool needTrimMax(const GABC_OOptions &ctx,
194  const GT_DataArrayHandle &data)
195  {
196  { return needWrite(ctx, data, trimMax()); }
197  }
198  bool needTrimU(const GABC_OOptions &ctx,
199  const GT_DataArrayHandle &data)
200  {
201  { return needWrite(ctx, data, trimU()); }
202  }
203  bool needTrimV(const GABC_OOptions &ctx,
204  const GT_DataArrayHandle &data)
205  {
206  { return needWrite(ctx, data, trimV()); }
207  }
208  bool needTrimW(const GABC_OOptions &ctx,
209  const GT_DataArrayHandle &data)
210  {
211  { return needWrite(ctx, data, trimW()); }
212  }
213 
214  /// @{
215  /// Access to fixed subdivision tags
216  GT_DataArrayHandle &creaseIndices() { return myData[0]; }
217  GT_DataArrayHandle &creaseLengths() { return myData[1]; }
218  GT_DataArrayHandle &creaseSharpnesses() { return myData[2]; }
219  GT_DataArrayHandle &cornerIndices() { return myData[3]; }
220  GT_DataArrayHandle &cornerSharpnesses() { return myData[4]; }
221  GT_DataArrayHandle &holeIndices() { return myData[5]; }
222  /// @}
223 
224  /// @{
225  /// Check whether subdivision tags need to be written
227  const GT_DataArrayHandle &data)
228  { return needWrite(ctx, data, creaseIndices()); }
230  const GT_DataArrayHandle &data)
231  { return needWrite(ctx, data, creaseLengths()); }
233  const GT_DataArrayHandle &data)
234  { return needWrite(ctx, data, creaseSharpnesses()); }
236  const GT_DataArrayHandle &data)
237  { return needWrite(ctx, data, cornerIndices()); }
239  const GT_DataArrayHandle &data)
240  { return needWrite(ctx, data, cornerSharpnesses()); }
242  const GT_DataArrayHandle &data)
243  { return needWrite(ctx, data, holeIndices()); }
244  /// @}
245 
246  private:
247  void clear();
248  bool needWrite(const GABC_OOptions &ctx,
249  const GT_DataArrayHandle &data,
250  GT_DataArrayHandle &cache);
251  GT_DataArrayHandle myData[9];
252  };
253 
254  static const IgnoreList &getDefaultSkip();
255 
257  ~GABC_OGTGeometry();
258 
259  /// Return true if the primitive can be processed
260  static bool isPrimitiveSupported(const GT_PrimitiveHandle &prim);
261 
262  // Create the output Alembic object, as well as it's attribute and user
263  // properties (if it has them and they are to be output).
264  bool start(const GT_PrimitiveHandle &prim,
265  const OObject &parent,
266  const GABC_OOptions &ctx,
267  GABC_OError &err,
269  // Output geometry, attribute, and user property samples to Alembic for the
270  // current frame.
271  bool update(const GT_PrimitiveHandle &prim,
272  const GABC_OOptions &ctx,
273  GABC_OError &err,
275  // Output samples to Alembic, reusing the samples for the previous frame.
276  bool updateFromPrevious(GABC_OError &err,
278  exint frames = 1);
279 
280  /// Return the OObject for this shape
281  OObject getOObject() const;
282 
283  /// Return the user properties for this shape.
284  OCompoundProperty getUserProperties() const;
285 
286  /// Return the secondary cache (allocating if needed)
287  SecondaryCache &getSecondaryCache();
288 
289  /// Dump information
290  void dump(int indent=0) const;
291 
292 protected:
293  // Make Alembic OFaceSet objects from groups of polygons.
294  void makeFaceSets(const GT_PrimitiveHandle &prim,
295  const GABC_OOptions &ctx);
296 
297  // Make Alembic arbGeomProperties from Houdini attributes.
298  bool makeArbProperties(const GT_PrimitiveHandle &prim,
299  GABC_OError &err,
300  const GABC_OOptions &ctx);
301  // Output samples of attribute data to Alembic for current frame.
302  bool writeArbProperties(const GT_PrimitiveHandle &prim,
303  GABC_OError &err,
304  const GABC_OOptions &ctx);
305  // Reuse previous samples of attribute data for current frame.
306  void writeArbPropertiesFromPrevious();
307  // Clear out existing data.
308  void clearProperties();
309  void clearArbProperties();
310  void clearShape();
311  void clearCache();
312 
313 private:
314  // Attribute scopes.
315  enum
316  {
317  VERTEX_PROPERTIES,
318  POINT_PROPERTIES,
319  UNIFORM_PROPERTIES,
320  DETAIL_PROPERTIES,
321  MAX_PROPERTIES
322  };
323 
324  union {
330  void *myVoidPtr;
331  } myShape;
332 
333  IntrinsicCache myCache; // Cache for space optimization
334  OVisibilityProperty myVisibility;
335  CollisionResolver myKnownArbCollisionResolver;
336  UT_Set<std::string> myKnownArbProperties;
337  PropertyMap myArbProperties[MAX_PROPERTIES];
338  SecondaryCache *mySecondaryCache;
339  UT_StringArray myFaceSetNames;
340  std::string myName;
341  exint myElapsedFrames;
342  int myType;
343 };
344 
345 } // GABC_NAMESPACE
346 
347 #endif
Alembic::AbcGeom::OSubD OSubD
GABC_Util::PropertyMap PropertyMap
bool needTrimMin(const GABC_OOptions &ctx, const GT_DataArrayHandle &data)
bool needTrimOrder(const GABC_OOptions &ctx, const GT_DataArrayHandle &data)
Unsorted map container.
Definition: UT_Map.h:83
void skip(T &in, int n)
Definition: ImfXdr.h:885
GLuint start
Definition: glcorearb.h:474
GLsizei const GLchar *const * string
Definition: glcorearb.h:813
bool contains(const UT_StringRef &token) const
bool needTrimNCurves(const GABC_OOptions &ctx, const GT_DataArrayHandle &data)
bool needTrimU(const GABC_OOptions &ctx, const GT_DataArrayHandle &data)
bool needVertex(const GABC_OOptions &ctx, const GT_DataArrayHandle &vertex_list)
#define GABC_NAMESPACE
Definition: GABC_API.h:42
Alembic::AbcGeom::ObjectVisibility ObjectVisibility
The object has been explicitly made hidden.
Definition: Visibility.h:70
void addSkip(const UT_StringHolder &skip)
int64 exint
Definition: SYS_Types.h:115
bool deleteSkip(const UT_StringRef &skip)
bool needHoleIndices(const GABC_OOptions &ctx, const GT_DataArrayHandle &data)
bool needTrimN(const GABC_OOptions &ctx, const GT_DataArrayHandle &data)
Alembic::AbcGeom::OVisibilityProperty OVisibilityProperty
GLboolean * data
Definition: glcorearb.h:130
GLuint const GLchar * name
Definition: glcorearb.h:785
Alembic::AbcGeom::OPoints OPoints
Class to efficiently find a new name when a collision is detected.
Definition: GABC_Util.h:361
GLint GLsizei count
Definition: glcorearb.h:404
bool needCounts(const GABC_OOptions &ctx, const GT_DataArrayHandle &counts)
Alembic::AbcGeom::ONuPatch ONuPatch
bool needTrimW(const GABC_OOptions &ctx, const GT_DataArrayHandle &data)
bool needCreaseSharpnesses(const GABC_OOptions &ctx, const GT_DataArrayHandle &data)
ObjectVisibility
Values for the visibility property The top-compound object of AbcGeom Schema objects can include an o...
Definition: Visibility.h:60
bool needCreaseLengths(const GABC_OOptions &ctx, const GT_DataArrayHandle &data)
Alembic::Abc::OCompoundProperty OCompoundProperty
Abc::OCharProperty OVisibilityProperty
Definition: Visibility.h:81
#define GABC_API
Definition: GABC_API.h:37
bool needCreaseIndices(const GABC_OOptions &ctx, const GT_DataArrayHandle &data)
Alembic::AbcGeom::OPolyMesh OPolyMesh
bool needTrimV(const GABC_OOptions &ctx, const GT_DataArrayHandle &data)
std::pair< std::string, GABC_OProperty * > PropertyMapInsert
Definition: GABC_Util.h:70
Alembic::AbcGeom::OCurves OCurves
bool needCornerSharpnesses(const GABC_OOptions &ctx, const GT_DataArrayHandle &data)
bool needCornerIndices(const GABC_OOptions &ctx, const GT_DataArrayHandle &data)
GABC_Util::PropertyMapInsert PropertyMapInsert
bool needTrimMax(const GABC_OOptions &ctx, const GT_DataArrayHandle &data)
bool needTrimKnot(const GABC_OOptions &ctx, const GT_DataArrayHandle &data)
GABC_Util::CollisionResolver CollisionResolver