1 //-*****************************************************************************
2 //
3 // Copyright (c) 2009-2012,
4 //  Sony Pictures Imageworks, Inc. and
5 //  Industrial Light & Magic, a division of Lucasfilm Entertainment Company Ltd.
6 //
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions are
11 // met:
12 // *       Redistributions of source code must retain the above copyright
13 // notice, this list of conditions and the following disclaimer.
14 // *       Redistributions in binary form must reproduce the above
15 // copyright notice, this list of conditions and the following disclaimer
16 // in the documentation and/or other materials provided with the
17 // distribution.
18 // *       Neither the name of Sony Pictures Imageworks, nor
19 // Industrial Light & Magic nor the names of their contributors may be used
20 // to endorse or promote products derived from this software without specific
21 // prior written permission.
22 //
23 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 //
35 //-*****************************************************************************
36 
37 #ifndef Alembic_AbcGeom_ISubD_h
38 #define Alembic_AbcGeom_ISubD_h
39 
40 #include <Alembic/Util/Export.h>
41 #include <Alembic/AbcGeom/Foundation.h>
42 #include <Alembic/AbcGeom/SchemaInfoDeclarations.h>
43 #include <Alembic/AbcGeom/IGeomParam.h>
44 #include <Alembic/AbcGeom/IFaceSet.h>
45 #include <Alembic/AbcGeom/IGeomBase.h>
46 
47 namespace Alembic {
48 namespace AbcGeom {
49 namespace ALEMBIC_VERSION_NS {
50 
51 //-*****************************************************************************
52 class ALEMBIC_EXPORT ISubDSchema : public IGeomBaseSchema<SubDSchemaInfo>
53 {
54 public:
55     //-*************************************************************************
56     // SUBD SCHEMA SAMPLE TYPE
57     //-*************************************************************************
58     class Sample
59     {
60     public:
61         typedef Sample this_type;
62 
63         //! Users never create this data directly
Sample()64         Sample() { reset(); }
65 
66         // main stuff
getPositions()67         Abc::P3fArraySamplePtr getPositions() const { return m_positions; }
getFaceIndices()68         Abc::Int32ArraySamplePtr getFaceIndices() const { return m_faceIndices; }
getFaceCounts()69         Abc::Int32ArraySamplePtr getFaceCounts() const { return m_faceCounts; }
70 
71         // misc subd stuff
getFaceVaryingInterpolateBoundary()72         int32_t getFaceVaryingInterpolateBoundary() const
73         { return m_faceVaryingInterpolateBoundary; }
74 
getFaceVaryingPropagateCorners()75         int32_t getFaceVaryingPropagateCorners() const
76         { return m_faceVaryingPropagateCorners; }
77 
getInterpolateBoundary()78         int32_t getInterpolateBoundary() const
79         { return m_interpolateBoundary; }
80 
81         // creases
getCreaseIndices()82         Abc::Int32ArraySamplePtr getCreaseIndices() const
83         { return m_creaseIndices; }
84 
getCreaseLengths()85         Abc::Int32ArraySamplePtr getCreaseLengths() const
86         { return m_creaseLengths; }
87 
getCreaseSharpnesses()88         Abc::FloatArraySamplePtr getCreaseSharpnesses() const
89         { return m_creaseSharpnesses; }
90 
91         // corners
getCornerIndices()92         Abc::Int32ArraySamplePtr getCornerIndices() const
93         { return m_cornerIndices; }
94 
getCornerSharpnesses()95         Abc::FloatArraySamplePtr getCornerSharpnesses() const
96         { return m_cornerSharpnesses; }
97 
98         // Holes
getHoles()99         Abc::Int32ArraySamplePtr getHoles() const { return m_holes; }
100 
101         // subdivision scheme
getSubdivisionScheme()102         std::string getSubdivisionScheme() const
103         { return m_subdScheme; }
104 
getVelocities()105         Abc::V3fArraySamplePtr getVelocities() const { return m_velocities; }
106 
107         // bounds
getSelfBounds()108         Abc::Box3d getSelfBounds() const { return m_selfBounds; }
109 
valid()110         bool valid() const
111         {
112             return m_positions && m_faceIndices && m_faceCounts;
113         }
114 
reset()115         void reset()
116         {
117             m_positions.reset();
118             m_velocities.reset();
119             m_faceIndices.reset();
120             m_faceCounts.reset();
121 
122             m_faceVaryingInterpolateBoundary = 0;
123             m_faceVaryingPropagateCorners = 0;
124             m_interpolateBoundary = 0;
125 
126             m_creaseIndices.reset();
127             m_creaseLengths.reset();
128             m_creaseSharpnesses.reset();
129 
130             m_cornerIndices.reset();
131             m_cornerSharpnesses.reset();
132 
133             m_holes.reset();
134 
135             m_subdScheme = "catmull-clark";
136 
137             m_selfBounds.makeEmpty();
138         }
139 
140         ALEMBIC_OPERATOR_BOOL( valid() );
141 
142     protected:
143         friend class ISubDSchema;
144 
145         Abc::P3fArraySamplePtr m_positions;
146         Abc::V3fArraySamplePtr m_velocities;
147         Abc::Int32ArraySamplePtr m_faceIndices;
148         Abc::Int32ArraySamplePtr m_faceCounts;
149 
150         int32_t m_faceVaryingInterpolateBoundary;
151         int32_t m_faceVaryingPropagateCorners;
152         int32_t m_interpolateBoundary;
153 
154         // Creases
155         Abc::Int32ArraySamplePtr    m_creaseIndices;
156         Abc::Int32ArraySamplePtr    m_creaseLengths;
157         Abc::FloatArraySamplePtr  m_creaseSharpnesses;
158 
159         // Corners
160         Abc::Int32ArraySamplePtr    m_cornerIndices;
161         Abc::FloatArraySamplePtr  m_cornerSharpnesses;
162 
163         // Holes
164         Abc::Int32ArraySamplePtr    m_holes;
165 
166         // subdivision scheme
167         std::string m_subdScheme;
168 
169         // bounds
170         Abc::Box3d m_selfBounds;
171 
172     }; // end ISubDSchema::Sample
173 
174     //-*************************************************************************
175     // SUBD SCHEMA
176     //-*************************************************************************
177 public:
178     //! By convention we always define this_type in AbcGeom classes.
179     //! Used by unspecified-bool-type conversion below
180     typedef ISubDSchema this_type;
181 
182     //-*************************************************************************
183     // CONSTRUCTION, DESTRUCTION, ASSIGNMENT
184     //-*************************************************************************
185 
186     //! The default constructor creates an empty ISubDSchema
187     //! ...
ISubDSchema()188     ISubDSchema()
189     {
190         m_faceSetsLoaded = false;
191     }
192 
193     //! This constructor creates a new subd reader.
194     //! The first argument is the parent ICompoundProperty, from which the
195     //! error handler policy for is derived.  The second argument is the name
196     //! of the ICompoundProperty that contains this schemas properties.  The
197     //! remaining optional arguments can be used to override the
198     //! ErrorHandlerPolicy and to specify schema interpretation matching.
199     ISubDSchema( const ICompoundProperty &iParent,
200                  const std::string &iName,
201 
202                  const Abc::Argument &iArg0 = Abc::Argument(),
203                  const Abc::Argument &iArg1 = Abc::Argument() )
204       : IGeomBaseSchema<SubDSchemaInfo>( iParent, iName, iArg0, iArg1 )
205     {
206         init(  iArg0, iArg1 );
207     }
208 
209     //! This constructor wraps an existing ICompoundProperty as the subd
210     //! reader, and the error handler policy is derived from it.
211     //! The  remaining optional arguments can be used to override the
212     //! ErrorHandlerPolicy and to specify schema interpretation matching.
213     ISubDSchema( const ICompoundProperty &iProp,
214                  const Abc::Argument &iArg0 = Abc::Argument(),
215                  const Abc::Argument &iArg1 = Abc::Argument() )
216       : IGeomBaseSchema<SubDSchemaInfo>( iProp, iArg0, iArg1 )
217     {
218         init( iArg0, iArg1 );
219     }
220 
221     //! Default assignment operator used.
222 
223     //-*************************************************************************
224     // SCHEMA STUFF
225     //-*************************************************************************
226 
227 
228     MeshTopologyVariance getTopologyVariance() const;
229 
230     //! if isConstant() is true, the mesh contains no time-varying values
isConstant()231     bool isConstant() const { return getTopologyVariance() == kConstantTopology; }
232 
233     //-*************************************************************************
234     // SAMPLE STUFF
235     //-*************************************************************************
236 
237     //! Get number of samples written so far.
238     //! ...
239     size_t getNumSamples() const;
240 
241     //! Return the time sampling
getTimeSampling()242     AbcA::TimeSamplingPtr getTimeSampling() const
243     {
244         if ( m_positionsProperty.valid() )
245         {
246             return m_positionsProperty.getTimeSampling();
247         }
248         else
249         {
250             return getObject().getArchive().getTimeSampling( 0 );
251         }
252     }
253 
254     void get( Sample &iSamp,
255               const Abc::ISampleSelector &iSS = Abc::ISampleSelector() ) const;
256 
257     Sample getValue( const Abc::ISampleSelector &iSS = Abc::ISampleSelector() ) const
258     {
259         Sample smp;
260         get( smp, iSS );
261         return smp;
262     }
263 
getFaceCountsProperty()264     Abc::IInt32ArrayProperty getFaceCountsProperty() const
265     { return m_faceCountsProperty; }
getFaceIndicesProperty()266     Abc::IInt32ArrayProperty getFaceIndicesProperty() const
267     { return m_faceIndicesProperty; }
getPositionsProperty()268     Abc::IP3fArrayProperty getPositionsProperty() const
269     { return m_positionsProperty; }
270 
getFaceVaryingInterpolateBoundaryProperty()271     Abc::IInt32Property getFaceVaryingInterpolateBoundaryProperty() const
272     { return m_faceVaryingInterpolateBoundaryProperty; }
273 
getFaceVaryingPropagateCornersProperty()274     Abc::IInt32Property getFaceVaryingPropagateCornersProperty() const
275     { return m_faceVaryingPropagateCornersProperty; }
276 
getInterpolateBoundaryProperty()277     Abc::IInt32Property getInterpolateBoundaryProperty() const
278     { return m_interpolateBoundaryProperty; }
279 
getCreaseIndicesProperty()280     Abc::IInt32ArrayProperty getCreaseIndicesProperty() const
281     { return m_creaseIndicesProperty; }
getCreaseLengthsProperty()282     Abc::IInt32ArrayProperty getCreaseLengthsProperty() const
283     { return m_creaseLengthsProperty; }
getCreaseSharpnessesProperty()284     Abc::IFloatArrayProperty getCreaseSharpnessesProperty() const
285     { return m_creaseSharpnessesProperty; }
286 
getCornerIndicesProperty()287     Abc::IInt32ArrayProperty getCornerIndicesProperty() const
288     { return m_cornerIndicesProperty; }
getCornerSharpnessesProperty()289     Abc::IFloatArrayProperty getCornerSharpnessesProperty() const
290     { return m_cornerSharpnessesProperty; }
291 
getHolesProperty()292     Abc::IInt32ArrayProperty getHolesProperty() const { return m_holesProperty; }
293 
getSubdivisionSchemeProperty()294     Abc::IStringProperty getSubdivisionSchemeProperty() const
295     { return m_subdSchemeProperty; }
296 
getVelocitiesProperty()297     Abc::IV3fArrayProperty getVelocitiesProperty() const
298     { return m_velocitiesProperty; }
299 
getUVsParam()300     IV2fGeomParam getUVsParam() const
301     {
302         return m_uvsParam;
303     }
304 
305     //-*************************************************************************
306     // ABC BASE MECHANISMS
307     // These functions are used by Abc to deal with errors, rewrapping,
308     // and so on.
309     //-*************************************************************************
310 
311     //! Reset returns this function set to an empty, default
312     //! state.
reset()313     void reset()
314     {
315         m_positionsProperty.reset();
316         m_velocitiesProperty.reset();
317         m_faceIndicesProperty.reset();
318         m_faceCountsProperty.reset();
319 
320         m_faceVaryingInterpolateBoundaryProperty.reset();
321         m_faceVaryingPropagateCornersProperty.reset();
322         m_interpolateBoundaryProperty.reset();
323 
324         m_creaseIndicesProperty.reset();
325         m_creaseLengthsProperty.reset();
326         m_creaseSharpnessesProperty.reset();
327 
328         m_cornerIndicesProperty.reset();
329         m_cornerSharpnessesProperty.reset();
330 
331         m_holesProperty.reset();
332 
333         m_subdSchemeProperty.reset();
334 
335         m_uvsParam.reset();
336 
337         IGeomBaseSchema<SubDSchemaInfo>::reset();
338     }
339 
340     //! Valid returns whether this function set is
341     //! valid.
valid()342     bool valid() const
343     {
344         return ( IGeomBaseSchema<SubDSchemaInfo>::valid() &&
345                  m_positionsProperty.valid() &&
346                  m_faceIndicesProperty.valid() &&
347                  m_faceCountsProperty.valid() );
348     }
349 
350     // FaceSet related
351     //! Appends the names of any FaceSets for this SubD.
352     void getFaceSetNames( std::vector <std::string> &oFaceSetNames );
353     IFaceSet getFaceSet( const std::string &iFaceSetName );
354     bool hasFaceSet( const std::string &iFaceSetName );
355 
356     //! unspecified-bool-type operator overload.
357     //! ...
358     ALEMBIC_OVERRIDE_OPERATOR_BOOL( ISubDSchema::valid() );
359 
360     // Copy constructors
ISubDSchema(const ISubDSchema & iCopy)361     ISubDSchema(const ISubDSchema& iCopy)
362         : IGeomBaseSchema<SubDSchemaInfo>()
363     {
364         *this = iCopy;
365     }
366     const ISubDSchema & operator=(const ISubDSchema & rhs);
367 
368 protected:
369     void init( const Abc::Argument &iArg0, const Abc::Argument &iArg1 );
370 
371     Abc::IP3fArrayProperty   m_positionsProperty;
372     Abc::IInt32ArrayProperty m_faceIndicesProperty;
373     Abc::IInt32ArrayProperty m_faceCountsProperty;
374 
375     // misc
376     Abc::IInt32Property m_faceVaryingInterpolateBoundaryProperty;
377     Abc::IInt32Property m_faceVaryingPropagateCornersProperty;
378     Abc::IInt32Property m_interpolateBoundaryProperty;
379 
380     // Creases
381     Abc::IInt32ArrayProperty  m_creaseIndicesProperty;
382     Abc::IInt32ArrayProperty  m_creaseLengthsProperty;
383     Abc::IFloatArrayProperty  m_creaseSharpnessesProperty;
384 
385     // Corners
386     Abc::IInt32ArrayProperty  m_cornerIndicesProperty;
387     Abc::IFloatArrayProperty  m_cornerSharpnessesProperty;
388 
389     // Holes
390     Abc::IInt32ArrayProperty  m_holesProperty;
391 
392     // subdivision scheme
393     Abc::IStringProperty      m_subdSchemeProperty;
394 
395     // UVs
396     IV2fGeomParam m_uvsParam;
397 
398     IV3fArrayProperty m_velocitiesProperty;
399 
400     // FaceSets, this starts as empty until client
401     // code attempts to access facesets.
402     bool                              m_faceSetsLoaded;
403     std::map <std::string, IFaceSet>  m_faceSets;
404     Alembic::Util::mutex              m_faceSetsMutex;
405     void loadFaceSetNames();
406 
407 };
408 
409 //-*****************************************************************************
410 // SCHEMA OBJECT
411 //-*****************************************************************************
412 typedef Abc::ISchemaObject<ISubDSchema> ISubD;
413 
414 typedef Util::shared_ptr< ISubD > ISubDPtr;
415 
416 } // End namespace ALEMBIC_VERSION_NS
417 
418 using namespace ALEMBIC_VERSION_NS;
419 
420 } // End namespace AbcGeom
421 } // End namespace Alembic
422 
423 #endif
424