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_IPolyMesh_h
38 #define Alembic_AbcGeom_IPolyMesh_h
39 
40 #include <Alembic/Util/Export.h>
41 #include <Alembic/AbcGeom/Foundation.h>
42 #include <Alembic/AbcGeom/SchemaInfoDeclarations.h>
43 #include <Alembic/AbcGeom/IFaceSet.h>
44 #include <Alembic/AbcGeom/IGeomParam.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 IPolyMeshSchema
53     : public IGeomBaseSchema<PolyMeshSchemaInfo>
54 {
55 public:
56     class Sample
57     {
58     public:
59         typedef Sample this_type;
60 
61         // Users don't ever create this data directly.
Sample()62         Sample() { reset(); }
63 
getPositions()64         Abc::P3fArraySamplePtr getPositions() const { return m_positions; }
getVelocities()65         Abc::V3fArraySamplePtr getVelocities() const { return m_velocities; }
getFaceIndices()66         Abc::Int32ArraySamplePtr getFaceIndices() const { return m_indices; }
getFaceCounts()67         Abc::Int32ArraySamplePtr getFaceCounts() const { return m_counts; }
getSelfBounds()68         Abc::Box3d getSelfBounds() const { return m_selfBounds; }
69 
valid()70         bool valid() const
71         {
72             return m_positions && m_indices && m_counts;
73         }
74 
reset()75         void reset()
76         {
77             m_positions.reset();
78             m_velocities.reset();
79             m_indices.reset();
80             m_counts.reset();
81             m_selfBounds.makeEmpty();
82         }
83 
84         ALEMBIC_OPERATOR_BOOL( valid() );
85 
86     protected:
87         friend class IPolyMeshSchema;
88         Abc::P3fArraySamplePtr m_positions;
89         Abc::V3fArraySamplePtr m_velocities;
90         Abc::Int32ArraySamplePtr m_indices;
91         Abc::Int32ArraySamplePtr m_counts;
92         Abc::Box3d m_selfBounds;
93     };
94 
95     //-*************************************************************************
96     // POLY MESH SCHEMA
97     //-*************************************************************************
98 public:
99     //! By convention we always define this_type in AbcGeom classes.
100     //! Used by unspecified-bool-type conversion below
101     typedef IPolyMeshSchema this_type;
102 
103     //-*************************************************************************
104     // CONSTRUCTION, DESTRUCTION, ASSIGNMENT
105     //-*************************************************************************
106 
107     //! The default constructor creates an empty OPolyMeshSchema
108     //! ...
IPolyMeshSchema()109     IPolyMeshSchema() {}
110 
111     //! This constructor creates a new mesh reader.
112     //! The first argument is the parent ICompoundProperty, from which the
113     //! error handler policy for is derived.  The second argument is the name
114     //! of the ICompoundProperty that contains this schemas properties.  The
115     //! remaining optional arguments can be used to override the
116     //! ErrorHandlerPolicy and to specify schema interpretation matching.
117     IPolyMeshSchema( const ICompoundProperty &iParent,
118                      const std::string &iName,
119 
120                      const Abc::Argument &iArg0 = Abc::Argument(),
121                      const Abc::Argument &iArg1 = Abc::Argument() )
122       : IGeomBaseSchema<PolyMeshSchemaInfo>( iParent, iName, iArg0, iArg1 )
123     {
124         init( iArg0, iArg1 );
125     }
126 
127     //! This constructor wraps an existing ICompoundProperty as the mesh
128     //! reader, and the error handler policy is derived from it.
129     //! The  remaining optional arguments can be used to override the
130     //! ErrorHandlerPolicy and to specify schema interpretation matching.
131     IPolyMeshSchema( const ICompoundProperty &iProp,
132                      const Abc::Argument &iArg0 = Abc::Argument(),
133                      const Abc::Argument &iArg1 = Abc::Argument() )
134       : IGeomBaseSchema<PolyMeshSchemaInfo>( iProp, iArg0, iArg1 )
135     {
136         init( iArg0, iArg1 );
137     }
138 
139     //! Copy constructor.
IPolyMeshSchema(const IPolyMeshSchema & iCopy)140     IPolyMeshSchema(const IPolyMeshSchema& iCopy)
141         : IGeomBaseSchema<PolyMeshSchemaInfo>()
142     {
143         *this = iCopy;
144     }
145     const IPolyMeshSchema & operator=(const IPolyMeshSchema & rhs);
146 
147 
148     //! Return the number of samples contained in the property.
149     //! This can be any number, including zero.
150     //! This returns the number of samples that were written, independently
151     //! of whether or not they were constant.
getNumSamples()152     size_t getNumSamples() const
153     { return  m_positionsProperty.getNumSamples(); }
154 
155     //! Return the topological variance.
156     //! This indicates how the mesh may change.
157     MeshTopologyVariance getTopologyVariance() const;
158 
159     //! Ask if we're constant - no change in value amongst samples,
160     //! regardless of the time sampling.
isConstant()161     bool isConstant() const { return getTopologyVariance() == kConstantTopology; }
162 
163     //! Time information.
164     //! Any of the properties could be the bearer of the time
165     //! sampling information, which otherwise defaults to Identity.
getTimeSampling()166     AbcA::TimeSamplingPtr getTimeSampling() const
167     {
168         if ( m_positionsProperty.valid() )
169         {
170             return m_positionsProperty.getTimeSampling();
171         }
172         else
173         {
174             return getObject().getArchive().getTimeSampling( 0 );
175         }
176     }
177 
178     //-*************************************************************************
179     void get( Sample &oSample,
180               const Abc::ISampleSelector &iSS = Abc::ISampleSelector() ) const
181     {
182         ALEMBIC_ABC_SAFE_CALL_BEGIN( "IPolyMeshSchema::get()" );
183 
184         m_positionsProperty.get( oSample.m_positions, iSS );
185         m_indicesProperty.get( oSample.m_indices, iSS );
186         m_countsProperty.get( oSample.m_counts, iSS );
187 
188         m_selfBoundsProperty.get( oSample.m_selfBounds, iSS );
189 
190         if ( m_velocitiesProperty && m_velocitiesProperty.getNumSamples() > 0 )
191         {
192             m_velocitiesProperty.get( oSample.m_velocities, iSS );
193         }
194 
195         // Could error check here.
196 
197         ALEMBIC_ABC_SAFE_CALL_END();
198     }
199 
200     Sample getValue( const Abc::ISampleSelector &iSS = Abc::ISampleSelector() ) const
201     {
202         Sample smp;
203         get( smp, iSS );
204         return smp;
205     }
206 
getUVsParam()207     IV2fGeomParam getUVsParam() const
208     {
209         return m_uvsParam;
210     }
211 
getNormalsParam()212     IN3fGeomParam getNormalsParam() const
213     {
214         return m_normalsParam;
215     }
216 
getFaceCountsProperty()217     Abc::IInt32ArrayProperty getFaceCountsProperty() const
218     {
219         return m_countsProperty;
220     }
221 
getFaceIndicesProperty()222     Abc::IInt32ArrayProperty getFaceIndicesProperty() const
223     {
224         return m_indicesProperty;
225     }
226 
getPositionsProperty()227     Abc::IP3fArrayProperty getPositionsProperty() const
228     {
229         return m_positionsProperty;
230     }
231 
getVelocitiesProperty()232     Abc::IV3fArrayProperty getVelocitiesProperty() const
233     {
234         return m_velocitiesProperty;
235     }
236 
237     //-*************************************************************************
238     // ABC BASE MECHANISMS
239     // These functions are used by Abc to deal with errors, rewrapping,
240     // and so on.
241     //-*************************************************************************
242 
243     //! Reset returns this function set to an empty, default
244     //! state.
reset()245     void reset()
246     {
247         m_positionsProperty.reset();
248         m_velocitiesProperty.reset();
249         m_indicesProperty.reset();
250         m_countsProperty.reset();
251 
252         m_uvsParam.reset();
253         m_normalsParam.reset();
254 
255         IGeomBaseSchema<PolyMeshSchemaInfo>::reset();
256     }
257 
258     //! Valid returns whether this function set is
259     //! valid.
valid()260     bool valid() const
261     {
262         return ( IGeomBaseSchema<PolyMeshSchemaInfo>::valid() &&
263                  m_positionsProperty.valid() &&
264                  m_indicesProperty.valid() &&
265                  m_countsProperty.valid() );
266     }
267 
268     // FaceSet related
269     //! Appends the names of any FaceSets for this PolyMesh.
270     void getFaceSetNames (std::vector <std::string> & oFaceSetNames);
271     IFaceSet getFaceSet( const std::string &iFaceSetName );
272     bool hasFaceSet( const std::string &iFaceSetName );
273 
274     //! unspecified-bool-type operator overload.
275     //! ...
276     ALEMBIC_OVERRIDE_OPERATOR_BOOL( IPolyMeshSchema::valid() );
277 
278 protected:
279     void init( const Abc::Argument &iArg0,
280                const Abc::Argument &iArg1 );
281 
282     Abc::IP3fArrayProperty m_positionsProperty;
283     Abc::IV3fArrayProperty m_velocitiesProperty;
284     Abc::IInt32ArrayProperty m_indicesProperty;
285     Abc::IInt32ArrayProperty m_countsProperty;
286 
287     IV2fGeomParam m_uvsParam;
288     IN3fGeomParam m_normalsParam;
289 
290     // FaceSets, this starts as empty until client
291     // code attempts to access facesets.
292     bool                              m_faceSetsLoaded;
293     std::map <std::string, IFaceSet>  m_faceSets;
294     Alembic::Util::mutex                      m_faceSetsMutex;
295     void loadFaceSetNames();
296 };
297 
298 //-*****************************************************************************
299 typedef Abc::ISchemaObject<IPolyMeshSchema> IPolyMesh;
300 
301 typedef Util::shared_ptr< IPolyMesh > IPolyMeshPtr;
302 
303 } // End namespace ALEMBIC_VERSION_NS
304 
305 using namespace ALEMBIC_VERSION_NS;
306 
307 } // End namespace AbcGeom
308 } // End namespace Alembic
309 
310 #endif
311