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_OGeomParam_h
38 #define Alembic_AbcGeom_OGeomParam_h
39 
40 #include <Alembic/AbcGeom/Foundation.h>
41 #include <Alembic/AbcGeom/GeometryScope.h>
42 
43 namespace Alembic {
44 namespace AbcGeom {
45 namespace ALEMBIC_VERSION_NS {
46 
47 //-*****************************************************************************
48 template <class TRAITS>
49 class OTypedGeomParam
50 {
51 public:
52     typedef typename TRAITS::value_type value_type;
53     typedef OTypedArrayProperty<TRAITS> prop_type;
54 
55 
56     //-*************************************************************************
57     // inner class for setting
58     class Sample
59     {
60     public:
61         typedef Sample this_type;
62 
Sample()63         Sample()
64           : m_scope( kUnknownScope )
65         {}
66 
Sample(const Abc::TypedArraySample<TRAITS> & iVals,GeometryScope iScope)67         Sample( const Abc::TypedArraySample<TRAITS> &iVals,
68                 GeometryScope iScope )
69           : m_vals( iVals )
70           , m_scope( iScope )
71         {}
72 
Sample(const Abc::TypedArraySample<TRAITS> & iVals,const Abc::UInt32ArraySample & iIndices,GeometryScope iScope)73         Sample( const Abc::TypedArraySample<TRAITS> &iVals,
74                 const Abc::UInt32ArraySample &iIndices,
75                 GeometryScope iScope )
76           : m_vals( iVals )
77           , m_indices( iIndices )
78           , m_scope ( iScope )
79         {}
80 
setVals(const Abc::TypedArraySample<TRAITS> & iVals)81         void setVals( const Abc::TypedArraySample<TRAITS> &iVals )
82         { m_vals = iVals; }
getVals()83         const Abc::TypedArraySample<TRAITS> &getVals() const
84         { return m_vals; }
85 
setIndices(const Abc::UInt32ArraySample & iIndices)86         void setIndices( const Abc::UInt32ArraySample &iIndices )
87         { m_indices = iIndices; }
getIndices()88         const Abc::UInt32ArraySample &getIndices() const
89         { return m_indices; }
90 
setScope(GeometryScope iScope)91         void setScope( GeometryScope iScope )
92         { m_scope = iScope; }
getScope()93         GeometryScope getScope() const
94         { return m_scope; }
95 
reset()96         void reset()
97         {
98             m_vals.reset();
99             m_indices.reset();
100             m_scope = kUnknownScope;
101         }
102 
valid()103         bool valid() const { return m_vals; }
104 
105         ALEMBIC_OPERATOR_BOOL( valid() );
106 
107     protected:
108         Abc::TypedArraySample<TRAITS> m_vals;
109         Abc::UInt32ArraySample m_indices;
110         GeometryScope m_scope;
111     };
112 
113     //-*************************************************************************
114     typedef OTypedGeomParam<TRAITS> this_type;
115     typedef typename this_type::Sample sample_type;
116 
getInterpretation()117     static const char * getInterpretation()
118     {
119         return TRAITS::interpretation();
120     }
121 
122     static bool matches( const AbcA::PropertyHeader &iHeader,
123                          SchemaInterpMatching iMatching = kStrictMatching )
124     {
125         if ( iHeader.isCompound() )
126         {
127             return ( iHeader.getMetaData().get( "podName" ) ==
128                     Alembic::Util::PODName( TRAITS::dataType().getPod() ) &&
129                     ( std::string() == getInterpretation() ||
130                       atoi(
131                         iHeader.getMetaData().get( "podExtent" ).c_str() ) ==
132                      TRAITS::dataType().getExtent() ) ) &&
133                     prop_type::matches( iHeader.getMetaData(), iMatching );
134         }
135         else if ( iHeader.isArray() )
136         {
137             return prop_type::matches( iHeader, iMatching );
138         }
139 
140         return false;
141 
142     }
143 
OTypedGeomParam()144     OTypedGeomParam()
145     : m_isIndexed(false)
146     , m_scope(kUnknownScope)
147 
148     {
149     }
150 
151     OTypedGeomParam( OCompoundProperty iParent,
152                      const std::string &iName,
153                      bool iIsIndexed,
154                      GeometryScope iScope,
155                      size_t iArrayExtent,
156                      const Argument &iArg0 = Argument(),
157                      const Argument &iArg1 = Argument(),
158                      const Argument &iArg2 = Argument()
159                      )
m_name(iName)160         : m_name( iName )
161         , m_isIndexed( iIsIndexed )
162         , m_scope( iScope )
163     {
164         *this = OTypedGeomParam( iParent.getPtr(), iName, iIsIndexed, iScope,
165             iArrayExtent, iArg0, iArg1, iArg2 );
166     }
167 
168     OTypedGeomParam( AbcA::CompoundPropertyWriterPtr iParent,
169                      const std::string &iName,
170                      bool iIsIndexed,
171                      GeometryScope iScope,
172                      size_t iArrayExtent,
173                      const Argument &iArg0 = Argument(),
174                      const Argument &iArg1 = Argument(),
175                      const Argument &iArg2 = Argument()
176                  )
m_name(iName)177       : m_name( iName )
178       , m_isIndexed( iIsIndexed )
179       , m_scope( iScope )
180     {
181         Arguments args( Abc::GetErrorHandlerPolicy( iParent ) );
182         iArg0.setInto( args );
183         iArg1.setInto( args );
184         iArg2.setInto( args );
185 
186         AbcA::MetaData md = args.getMetaData();
187 
188         SetGeometryScope( md, iScope );
189 
190         md.set( "isGeomParam", "true" );
191 
192         std::string podName( Alembic::Util::PODName(
193                                  TRAITS::dataType().getPod() ) );
194 
195         size_t extent = TRAITS::dataType().getExtent();
196 
197         md.set( "podName", podName );
198 
199         std::ostringstream extentStrm;
200         extentStrm << extent;
201         std::string extentStr = extentStrm.str();
202         md.set( "podExtent", extentStr );
203 
204         std::ostringstream arrayExtentStrm;
205         arrayExtentStrm << iArrayExtent;
206         std::string arrayExtentStr = arrayExtentStrm.str();
207         md.set( "arrayExtent", arrayExtentStr );
208 
209         md.set( "interpretation", TRAITS::interpretation() );
210 
211         Abc::ErrorHandler::Policy ehp = args.getErrorHandlerPolicy();
212 
213         AbcA::TimeSamplingPtr tsPtr = args.getTimeSampling();
214         uint32_t tsIndex = args.getTimeSamplingIndex();
215 
216         // if we specified a valid TimeSamplingPtr, use it to determine the
217         // index otherwise we'll use the index, which defaults to the
218         // intrinsic 0 index
219         if (tsPtr)
220         {
221             AbcA::CompoundPropertyWriterPtr parent =
222                 GetCompoundPropertyWriterPtr( iParent );
223             tsIndex =
224                 parent->getObject()->getArchive()->addTimeSampling(*tsPtr);
225         }
226 
227         if ( m_isIndexed )
228         {
229             m_cprop = Abc::OCompoundProperty( iParent, iName, md, ehp );
230 
231             m_valProp = prop_type( m_cprop, ".vals", md, ehp, tsIndex );
232 
233             m_indicesProperty = Abc::OUInt32ArrayProperty( m_cprop, ".indices",
234                 tsIndex );
235         }
236         else
237         {
238             m_valProp = prop_type( iParent, iName, md, ehp, tsIndex );
239         }
240     }
241 
242 public:
243 
set(const sample_type & iSamp)244     void set( const sample_type &iSamp )
245     {
246         ALEMBIC_ABC_SAFE_CALL_BEGIN( "OTypedGeomParam::set()" );
247 
248         if ( m_valProp.getNumSamples() == 0 )
249         {
250             m_valProp.set( iSamp.getVals() );
251             if ( m_isIndexed ) { m_indicesProperty.set( iSamp.getIndices() ); }
252         }
253         else
254         {
255             SetPropUsePrevIfNull( m_valProp, iSamp.getVals() );
256             if ( m_isIndexed )
257             {
258                 SetPropUsePrevIfNull( m_indicesProperty, iSamp.getIndices() );
259             }
260         }
261 
262         ALEMBIC_ABC_SAFE_CALL_END_RESET();
263     }
264 
setFromPrevious()265     void setFromPrevious()
266     {
267         ALEMBIC_ABC_SAFE_CALL_BEGIN( "OTypedGeomParam::setFromPrevious()" );
268 
269         m_valProp.setFromPrevious();
270 
271         if ( m_isIndexed ) { m_indicesProperty.setFromPrevious(); }
272 
273         ALEMBIC_ABC_SAFE_CALL_END();
274     }
275 
setTimeSampling(uint32_t iIndex)276     void setTimeSampling( uint32_t iIndex )
277     {
278         ALEMBIC_ABC_SAFE_CALL_BEGIN(
279             "OTypedGeomParam::setTimeSampling( uint32_t )" );
280 
281         m_valProp.setTimeSampling( iIndex );
282 
283         if ( m_isIndexed ) { m_indicesProperty.setTimeSampling( iIndex ); }
284 
285         ALEMBIC_ABC_SAFE_CALL_END();
286     }
287 
setTimeSampling(AbcA::TimeSamplingPtr iTime)288     void setTimeSampling( AbcA::TimeSamplingPtr iTime )
289     {
290         ALEMBIC_ABC_SAFE_CALL_BEGIN(
291             "OTypedGeomParam::setTimeSampling( TimeSamplingPtr )" );
292 
293         if (iTime)
294         {
295             uint32_t tsIndex =
296                 m_valProp.getParent().getObject().getArchive().addTimeSampling(
297                     *iTime);
298             setTimeSampling( tsIndex );
299         }
300 
301         ALEMBIC_ABC_SAFE_CALL_END();
302     }
303 
getNumSamples()304     size_t getNumSamples() const
305     {
306         ALEMBIC_ABC_SAFE_CALL_BEGIN( "OTypedGeomParam::getNumSamples()" );
307 
308         if ( m_isIndexed )
309         {
310             if ( m_indicesProperty )
311             {
312                 return std::max( m_indicesProperty.getNumSamples(),
313                                  m_valProp.getNumSamples() );
314             }
315             else { return 0; }
316         }
317         else
318         {
319             if ( m_valProp ) { return m_valProp.getNumSamples(); }
320             else { return 0; }
321         }
322 
323         ALEMBIC_ABC_SAFE_CALL_END();
324 
325         return 0;
326     }
327 
getDataType()328     AbcA::DataType getDataType() const { return TRAITS::dataType(); }
329 
isIndexed()330     bool isIndexed() const { return m_isIndexed; }
331 
getScope()332     GeometryScope getScope() const { return m_scope; }
333 
getTimeSampling()334     AbcA::TimeSamplingPtr getTimeSampling() const
335     {
336         return m_valProp.getTimeSampling();
337     }
338 
getName()339     const std::string &getName() const { return m_name; }
340 
valid()341     bool valid() const
342     {
343         return ( m_valProp.valid()
344                  && ( ( ! m_isIndexed ) || m_indicesProperty ) );
345     }
346 
347     ALEMBIC_OPERATOR_BOOL( this_type::valid() );
348 
reset()349     void reset()
350     {
351         m_name = "";
352         m_valProp.reset();
353         m_indicesProperty.reset();
354         m_cprop.reset();
355         m_scope = kUnknownScope;
356         m_isIndexed = false;
357     }
358 
getValueProperty()359     prop_type getValueProperty() const { return m_valProp; }
360 
getIndexProperty()361     OUInt32ArrayProperty getIndexProperty() const { return m_indicesProperty; }
362 
363 private:
getErrorHandler()364     Abc::ErrorHandler &getErrorHandler() const
365     { return m_valProp.getErrorHandler(); }
366 
367 protected:
368     std::string m_name;
369 
370     prop_type m_valProp;
371     OUInt32ArrayProperty m_indicesProperty;
372     bool m_isIndexed;
373 
374     GeometryScope m_scope;
375 
376     // if the GeomParam is not indexed, this will not exist.
377     Abc::OCompoundProperty m_cprop;
378 };
379 
380 //-*****************************************************************************
381 // TYPEDEFS
382 //-*****************************************************************************
383 
384 typedef OTypedGeomParam<BooleanTPTraits>         OBoolGeomParam;
385 typedef OTypedGeomParam<Uint8TPTraits>           OUcharGeomParam;
386 typedef OTypedGeomParam<Int8TPTraits>            OCharGeomParam;
387 typedef OTypedGeomParam<Uint16TPTraits>          OUInt16GeomParam;
388 typedef OTypedGeomParam<Int16TPTraits>           OInt16GeomParam;
389 typedef OTypedGeomParam<Uint32TPTraits>          OUInt32GeomParam;
390 typedef OTypedGeomParam<Int32TPTraits>           OInt32GeomParam;
391 typedef OTypedGeomParam<Uint64TPTraits>          OUInt64GeomParam;
392 typedef OTypedGeomParam<Int64TPTraits>           OInt64GeomParam;
393 typedef OTypedGeomParam<Float16TPTraits>         OHalfGeomParam;
394 typedef OTypedGeomParam<Float32TPTraits>         OFloatGeomParam;
395 typedef OTypedGeomParam<Float64TPTraits>         ODoubleGeomParam;
396 typedef OTypedGeomParam<StringTPTraits>          OStringGeomParam;
397 typedef OTypedGeomParam<WstringTPTraits>         OWstringGeomParam;
398 
399 typedef OTypedGeomParam<V2sTPTraits>             OV2sGeomParam;
400 typedef OTypedGeomParam<V2iTPTraits>             OV2iGeomParam;
401 typedef OTypedGeomParam<V2fTPTraits>             OV2fGeomParam;
402 typedef OTypedGeomParam<V2dTPTraits>             OV2dGeomParam;
403 
404 typedef OTypedGeomParam<V3sTPTraits>             OV3sGeomParam;
405 typedef OTypedGeomParam<V3iTPTraits>             OV3iGeomParam;
406 typedef OTypedGeomParam<V3fTPTraits>             OV3fGeomParam;
407 typedef OTypedGeomParam<V3dTPTraits>             OV3dGeomParam;
408 
409 typedef OTypedGeomParam<P2sTPTraits>             OP2sGeomParam;
410 typedef OTypedGeomParam<P2iTPTraits>             OP2iGeomParam;
411 typedef OTypedGeomParam<P2fTPTraits>             OP2fGeomParam;
412 typedef OTypedGeomParam<P2dTPTraits>             OP2dGeomParam;
413 
414 typedef OTypedGeomParam<P3sTPTraits>             OP3sGeomParam;
415 typedef OTypedGeomParam<P3iTPTraits>             OP3iGeomParam;
416 typedef OTypedGeomParam<P3fTPTraits>             OP3fGeomParam;
417 typedef OTypedGeomParam<P3dTPTraits>             OP3dGeomParam;
418 
419 typedef OTypedGeomParam<Box2sTPTraits>           OBox2sGeomParam;
420 typedef OTypedGeomParam<Box2iTPTraits>           OBox2iGeomParam;
421 typedef OTypedGeomParam<Box2fTPTraits>           OBox2fGeomParam;
422 typedef OTypedGeomParam<Box2dTPTraits>           OBox2dGeomParam;
423 
424 typedef OTypedGeomParam<Box3sTPTraits>           OBox3sGeomParam;
425 typedef OTypedGeomParam<Box3iTPTraits>           OBox3iGeomParam;
426 typedef OTypedGeomParam<Box3fTPTraits>           OBox3fGeomParam;
427 typedef OTypedGeomParam<Box3dTPTraits>           OBox3dGeomParam;
428 
429 typedef OTypedGeomParam<M33fTPTraits>            OM33fGeomParam;
430 typedef OTypedGeomParam<M33dTPTraits>            OM33dGeomParam;
431 typedef OTypedGeomParam<M44fTPTraits>            OM44fGeomParam;
432 typedef OTypedGeomParam<M44dTPTraits>            OM44dGeomParam;
433 
434 typedef OTypedGeomParam<QuatfTPTraits>           OQuatfGeomParam;
435 typedef OTypedGeomParam<QuatdTPTraits>           OQuatdGeomParam;
436 
437 typedef OTypedGeomParam<C3hTPTraits>             OC3hGeomParam;
438 typedef OTypedGeomParam<C3fTPTraits>             OC3fGeomParam;
439 typedef OTypedGeomParam<C3cTPTraits>             OC3cGeomParam;
440 
441 typedef OTypedGeomParam<C4hTPTraits>             OC4hGeomParam;
442 typedef OTypedGeomParam<C4fTPTraits>             OC4fGeomParam;
443 typedef OTypedGeomParam<C4cTPTraits>             OC4cGeomParam;
444 
445 typedef OTypedGeomParam<N2fTPTraits>             ON2fGeomParam;
446 typedef OTypedGeomParam<N2dTPTraits>             ON2dGeomParam;
447 
448 typedef OTypedGeomParam<N3fTPTraits>             ON3fGeomParam;
449 typedef OTypedGeomParam<N3dTPTraits>             ON3dGeomParam;
450 
451 } // End namespace ALEMBIC_VERSION_NS
452 
453 using namespace ALEMBIC_VERSION_NS;
454 
455 } // End namespace AbcGeom
456 } // End namespace Alembic
457 
458 #endif
459