1 //-*****************************************************************************
2 //
3 // Copyright (c) 2009-2014,
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_IGeomParam_h
38 #define Alembic_AbcGeom_IGeomParam_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 ITypedGeomParam
50 {
51 public:
52 typedef typename TRAITS::value_type value_type;
53 typedef Abc::ITypedArrayProperty<TRAITS> prop_type;
54
55 class Sample
56 {
57 public:
58 typedef Sample this_type;
59 typedef Alembic::Util::shared_ptr< Abc::TypedArraySample<TRAITS> > samp_ptr_type;
60
Sample()61 Sample()
62 {}
63
getIndices()64 Abc::UInt32ArraySamplePtr getIndices() const { return m_indices; }
getVals()65 samp_ptr_type getVals() const { return m_vals; }
getScope()66 GeometryScope getScope() const { return m_scope; }
isIndexed()67 bool isIndexed() const { return m_isIndexed; }
68
reset()69 void reset()
70 {
71 m_vals.reset();
72 m_indices.reset();
73 m_scope = kUnknownScope;
74 m_isIndexed = false;
75 }
76
valid()77 bool valid() const { return m_vals.get() != NULL; }
78
79 ALEMBIC_OPERATOR_BOOL( valid() );
80
81 protected:
82 friend class ITypedGeomParam<TRAITS>;
83 samp_ptr_type m_vals;
84 Abc::UInt32ArraySamplePtr m_indices;
85 GeometryScope m_scope;
86 bool m_isIndexed;
87 };
88
89 //-*************************************************************************
90 typedef ITypedGeomParam<TRAITS> this_type;
91 typedef typename this_type::Sample sample_type;
92
getInterpretation()93 static const char * getInterpretation()
94 {
95 return TRAITS::interpretation();
96 }
97
98 static bool matches( const AbcA::PropertyHeader &iHeader,
99 SchemaInterpMatching iMatching = kStrictMatching )
100 {
101 if ( iHeader.isCompound() )
102 {
103 return ( iHeader.getMetaData().get( "podName" ) ==
104 Alembic::Util::PODName( TRAITS::dataType().getPod() ) &&
105 ( std::string() == getInterpretation() ||
106 atoi(
107 iHeader.getMetaData().get( "podExtent" ).c_str() ) ==
108 TRAITS::dataType().getExtent() ) ) &&
109 prop_type::matches( iHeader.getMetaData(), iMatching );
110 }
111 else if ( iHeader.isArray() )
112 {
113 return prop_type::matches( iHeader, iMatching );
114 }
115
116 return false;
117 }
118
ITypedGeomParam()119 ITypedGeomParam() {m_isIndexed = false;}
120
121 template <class CPROP>
122 ITypedGeomParam( CPROP iParent,
123 const std::string &iName,
124 const Abc::Argument &iArg0 = Abc::Argument(),
125 const Abc::Argument &iArg1 = Abc::Argument() );
126
127 template <class PROP>
128 ITypedGeomParam( PROP iThis,
129 WrapExistingFlag iWrapFlag,
130 const Abc::Argument &iArg0 = Abc::Argument(),
131 const Abc::Argument &iArg1 = Abc::Argument() );
132
133 void getIndexed( sample_type &oSamp,
134 const Abc::ISampleSelector &iSS = Abc::ISampleSelector() ) const;
135
136 void getExpanded( sample_type &oSamp,
137 const Abc::ISampleSelector &iSS = Abc::ISampleSelector() ) const;
138
139 sample_type getIndexedValue( const Abc::ISampleSelector &iSS = \
140 Abc::ISampleSelector() ) const
141 {
142 sample_type ret;
143 getIndexed( ret, iSS );
144 return ret;
145 }
146
147 sample_type getExpandedValue( const Abc::ISampleSelector &iSS = \
148 Abc::ISampleSelector() ) const
149 {
150 sample_type ret;
151 getExpanded( ret, iSS );
152 return ret;
153 }
154
155 size_t getNumSamples() const;
156
getDataType()157 AbcA::DataType getDataType() const { return TRAITS::dataType(); }
158
getArrayExtent()159 size_t getArrayExtent() const
160 {
161 std::string e = m_valProp.getMetaData().get( "arrayExtent" );
162 if ( e == "" ) { return 1; }
163 else { return atoi( e.c_str() ); }
164 }
165
isIndexed()166 bool isIndexed() const { return m_isIndexed; }
167
getScope()168 GeometryScope getScope() const
169 { return GetGeometryScope( m_valProp.getMetaData() ); }
170
171 AbcA::TimeSamplingPtr getTimeSampling() const;
172
173 const std::string &getName() const;
174
175 Abc::ICompoundProperty getParent() const;
176
177 const AbcA::PropertyHeader &getHeader() const;
178
179 const AbcA::MetaData &getMetaData() const;
180
181 bool isConstant() const;
182
reset()183 void reset()
184 {
185 m_valProp.reset();
186 m_indicesProperty.reset();
187 m_cprop.reset();
188 m_isIndexed = false;
189 }
190
valid()191 bool valid() const
192 {
193 return ( m_valProp.valid()
194 && ( ( ! m_cprop ) || m_indicesProperty ) );
195 }
196
197 ALEMBIC_OPERATOR_BOOL( this_type::valid() );
198
getValueProperty()199 prop_type getValueProperty() { return m_valProp; }
200
getIndexProperty()201 Abc::IUInt32ArrayProperty getIndexProperty() { return m_indicesProperty; }
202
203 private:
getErrorHandler()204 Abc::ErrorHandler &getErrorHandler() const
205 { return m_valProp.getErrorHandler(); }
206
207 protected:
208 prop_type m_valProp;
209
210 // if the GeomParam is not indexed, these will not exist.
211 Abc::IUInt32ArrayProperty m_indicesProperty;
212 Abc::ICompoundProperty m_cprop;
213
214 bool m_isIndexed;
215 };
216
217 //-*****************************************************************************
218 // TEMPLATED METHODS AND CONSTRUCTORS
219 //-*****************************************************************************
220 template <class TRAITS>
221 template <class CPROP>
ITypedGeomParam(CPROP iParent,const std::string & iName,const Abc::Argument & iArg0,const Abc::Argument & iArg1)222 ITypedGeomParam<TRAITS>::ITypedGeomParam( CPROP iParent,
223 const std::string &iName,
224 const Abc::Argument &iArg0,
225 const Abc::Argument &iArg1 )
226 {
227 Arguments args( GetErrorHandlerPolicy( iParent ) );
228 iArg0.setInto( args );
229 iArg1.setInto( args );
230
231 getErrorHandler().setPolicy( args.getErrorHandlerPolicy() );
232
233 ALEMBIC_ABC_SAFE_CALL_BEGIN( "ITypedGeomParam::ITypedGeomParam()" );
234
235 AbcA::CompoundPropertyReaderPtr parent =
236 GetCompoundPropertyReaderPtr( iParent );
237 ABCA_ASSERT( parent != NULL,
238 "NULL CompoundPropertyReader passed into "
239 << "ITypedGeomParam ctor" );
240
241 const AbcA::PropertyHeader *pheader =
242 parent->getPropertyHeader( iName );
243 ABCA_ASSERT( pheader != NULL,
244 "Nonexistent GeomParam: " << iName );
245
246 if ( pheader->isCompound() )
247 {
248 // we're indexed
249 m_cprop = ICompoundProperty( iParent, iName,
250 args.getErrorHandlerPolicy() );
251 m_indicesProperty = IUInt32ArrayProperty( m_cprop, ".indices", iArg0,
252 iArg1 );
253 m_valProp = ITypedArrayProperty<TRAITS>( m_cprop, ".vals", iArg0,
254 iArg1 );
255 m_isIndexed = true;
256 }
257 else if ( pheader->isArray() )
258 {
259 // not indexed
260 m_valProp = ITypedArrayProperty<TRAITS>( iParent, iName, iArg0,
261 iArg1 );
262 m_isIndexed = false;
263 }
264 else
265 {
266 ABCA_ASSERT( false, "Invalid ITypedGeomParam: " << iName );
267 }
268
269 ALEMBIC_ABC_SAFE_CALL_END();
270 }
271
272 //-*****************************************************************************
273 template <class TRAITS>
274 template <class PROP>
ITypedGeomParam(PROP iThis,WrapExistingFlag iWrapFlag,const Abc::Argument & iArg0,const Abc::Argument & iArg1)275 ITypedGeomParam<TRAITS>::ITypedGeomParam( PROP iThis,
276 WrapExistingFlag iWrapFlag,
277 const Abc::Argument &iArg0,
278 const Abc::Argument &iArg1 )
279 {
280 Arguments args( GetErrorHandlerPolicy( iThis ) );
281 iArg0.setInto( args );
282 iArg1.setInto( args );
283
284 getErrorHandler().setPolicy( args.getErrorHandlerPolicy() );
285
286 ALEMBIC_ABC_SAFE_CALL_BEGIN( "ITypedGeomParam::ITypedGeomParam( wrap )" );
287
288 const AbcA::PropertyHeader &ph = iThis.getHeader();
289
290 ABCA_ASSERT( matches( ph,
291 Abc::GetSchemaInterpMatching( iArg0, iArg1 ) ),
292 "Property " << ph.getName() << " is not an "
293 << "ITypedGeomParam" );
294
295 ABCA_ASSERT( ! ph.isScalar(), "Property " << ph.getName()
296 << " cannot be an ITypedGeomParam" );
297
298 if ( ph.isCompound() )
299 {
300 // we're indexed
301 m_cprop = ICompoundProperty( iThis, iWrapFlag, iArg0, iArg1 );
302 m_indicesProperty = IUInt32ArrayProperty( m_cprop, ".indices", iArg0,
303 iArg1 );
304 m_valProp = ITypedArrayProperty<TRAITS>( m_cprop, ".vals", iArg0,
305 iArg1 );
306 m_isIndexed = true;
307 }
308 else
309 {
310 // not indexed
311 m_valProp = ITypedArrayProperty<TRAITS>( iThis, iWrapFlag, iArg0,
312 iArg1 );
313 m_isIndexed = false;
314 }
315
316 ALEMBIC_ABC_SAFE_CALL_END_RESET();
317 }
318
319 //-*****************************************************************************
320 template <class TRAITS>
321 void
getIndexed(typename ITypedGeomParam<TRAITS>::Sample & oSamp,const Abc::ISampleSelector & iSS)322 ITypedGeomParam<TRAITS>::getIndexed( typename ITypedGeomParam<TRAITS>::Sample &oSamp,
323 const Abc::ISampleSelector &iSS ) const
324 {
325 m_valProp.get( oSamp.m_vals, iSS );
326 if ( m_indicesProperty ) { m_indicesProperty.get( oSamp.m_indices, iSS ); }
327 else
328 {
329 uint32_t size = static_cast< uint32_t > ( oSamp.m_vals->size() );
330
331 uint32_t *v = new uint32_t[size];
332
333 for ( uint32_t i = 0 ; i < size ; ++i )
334 {
335 v[i] = i;
336 }
337
338 const Alembic::Util::Dimensions dims( size );
339
340 oSamp.m_indices.reset( new Abc::UInt32ArraySample( v, dims ),
341 AbcA::TArrayDeleter<uint32_t>() );
342 }
343
344 oSamp.m_scope = this->getScope();
345 oSamp.m_isIndexed = m_isIndexed;
346 }
347
348
349 //-*****************************************************************************
350 template <class TRAITS>
351 void
getExpanded(typename ITypedGeomParam<TRAITS>::Sample & oSamp,const Abc::ISampleSelector & iSS)352 ITypedGeomParam<TRAITS>::getExpanded( typename ITypedGeomParam<TRAITS>::Sample &oSamp,
353 const Abc::ISampleSelector &iSS ) const
354 {
355 oSamp.m_scope = this->getScope();
356 oSamp.m_isIndexed = m_isIndexed;
357
358 if ( ! m_indicesProperty )
359 {
360 m_valProp.get( oSamp.m_vals, iSS );
361 }
362 else
363 {
364 Abc::UInt32ArraySamplePtr idxPtr = m_indicesProperty.getValue( iSS );
365
366 size_t size = idxPtr->size();
367
368 // no indices? just return what we have in our values
369 if (size == 0)
370 {
371 m_valProp.get( oSamp.m_vals, iSS );
372 return;
373 }
374
375 Alembic::Util::shared_ptr< Abc::TypedArraySample<TRAITS> > valPtr = \
376 m_valProp.getValue( iSS );
377
378 typename TRAITS::value_type *v = new typename TRAITS::value_type[size];
379
380 for ( size_t i = 0 ; i < size ; ++i )
381 {
382 v[i] = (*valPtr)[ (*idxPtr)[i] ];
383 }
384
385 // NOTE: we could create an ArraySampleKey and insert this into the
386 // cache. If it were in the cache, we'd return the shared pointer
387 // from there and call delete[] on v, thus preventing potentially
388 // unbounded heap growth. We should probably do this, but for now,
389 // we'll assume that we don't have too many of these, and we're not
390 // tightly memory-constrained. Ha!
391
392 const Alembic::Util::Dimensions dims( size );
393
394 oSamp.m_vals.reset( new Abc::TypedArraySample<TRAITS>( v, dims ),
395 AbcA::TArrayDeleter<typename TRAITS::value_type>());
396 }
397
398 }
399
400 //-*****************************************************************************
401 template <class TRAITS>
getNumSamples()402 size_t ITypedGeomParam<TRAITS>::getNumSamples() const
403 {
404 ALEMBIC_ABC_SAFE_CALL_BEGIN( "ITypedGeomParam::getNumSamples()" );
405
406 if ( m_isIndexed )
407 {
408 return std::max( m_indicesProperty.getNumSamples(),
409 m_valProp.getNumSamples() );
410 }
411 else
412 {
413 if ( m_valProp ) { return m_valProp.getNumSamples(); }
414 else { return 0; }
415 }
416
417 ALEMBIC_ABC_SAFE_CALL_END();
418
419 return 0;
420 }
421
422 //-*****************************************************************************
423 template <class TRAITS>
isConstant()424 bool ITypedGeomParam<TRAITS>::isConstant() const
425 {
426 ALEMBIC_ABC_SAFE_CALL_BEGIN( "ITypedGeomParam::isConstant()" );
427
428 if ( m_isIndexed )
429 {
430 return m_valProp.isConstant() && m_indicesProperty.isConstant();
431 }
432 else
433 {
434 return m_valProp.isConstant();
435 }
436
437 ALEMBIC_ABC_SAFE_CALL_END();
438
439 return false;
440 }
441
442 namespace {
443 const std::string g_emptyStr;
444 }
445 //-*****************************************************************************
446 template <class TRAITS>
getName()447 const std::string &ITypedGeomParam<TRAITS>::getName() const
448 {
449 ALEMBIC_ABC_SAFE_CALL_BEGIN( "ITypedGeomParam::getName()" );
450
451 if ( m_isIndexed ) { return m_cprop.getName(); }
452 else { return m_valProp.getName(); }
453
454 ALEMBIC_ABC_SAFE_CALL_END();
455
456 return g_emptyStr;
457 }
458
459 //-*****************************************************************************
460 template <class TRAITS>
getParent()461 Abc::ICompoundProperty ITypedGeomParam<TRAITS>::getParent() const
462 {
463 if ( m_isIndexed ) { return m_cprop.getParent(); }
464 else { return m_valProp.getParent(); }
465 }
466
467 //-*****************************************************************************
468 template <class TRAITS>
getHeader()469 const AbcA::PropertyHeader &ITypedGeomParam<TRAITS>::getHeader() const
470 {
471 if ( m_isIndexed ) { return m_cprop.getHeader(); }
472 else { return m_valProp.getHeader(); }
473 }
474
475 //-*****************************************************************************
476 template <class TRAITS>
getMetaData()477 const AbcA::MetaData &ITypedGeomParam<TRAITS>::getMetaData() const
478 {
479 if ( m_isIndexed ) { return m_cprop.getMetaData(); }
480 else { return m_valProp.getMetaData(); }
481 }
482
483 //-*****************************************************************************
484 template <class TRAITS>
getTimeSampling()485 AbcA::TimeSamplingPtr ITypedGeomParam<TRAITS>::getTimeSampling() const
486 {
487 if ( m_valProp )
488 {
489 return m_valProp.getTimeSampling();
490 }
491 else if ( m_indicesProperty )
492 {
493 return m_indicesProperty.getTimeSampling();
494 }
495
496 return AbcA::TimeSamplingPtr();
497 }
498
499 //-*****************************************************************************
500 // TYPEDEFS
501 //-*****************************************************************************
502
503 typedef ITypedGeomParam<BooleanTPTraits> IBoolGeomParam;
504 typedef ITypedGeomParam<Uint8TPTraits> IUcharGeomParam;
505 typedef ITypedGeomParam<Int8TPTraits> ICharGeomParam;
506 typedef ITypedGeomParam<Uint16TPTraits> IUInt16GeomParam;
507 typedef ITypedGeomParam<Int16TPTraits> IInt16GeomParam;
508 typedef ITypedGeomParam<Uint32TPTraits> IUInt32GeomParam;
509 typedef ITypedGeomParam<Int32TPTraits> IInt32GeomParam;
510 typedef ITypedGeomParam<Uint64TPTraits> IUInt64GeomParam;
511 typedef ITypedGeomParam<Int64TPTraits> IInt64GeomParam;
512 typedef ITypedGeomParam<Float16TPTraits> IHalfGeomParam;
513 typedef ITypedGeomParam<Float32TPTraits> IFloatGeomParam;
514 typedef ITypedGeomParam<Float64TPTraits> IDoubleGeomParam;
515 typedef ITypedGeomParam<StringTPTraits> IStringGeomParam;
516 typedef ITypedGeomParam<WstringTPTraits> IWstringGeomParam;
517
518 typedef ITypedGeomParam<V2sTPTraits> IV2sGeomParam;
519 typedef ITypedGeomParam<V2iTPTraits> IV2iGeomParam;
520 typedef ITypedGeomParam<V2fTPTraits> IV2fGeomParam;
521 typedef ITypedGeomParam<V2dTPTraits> IV2dGeomParam;
522
523 typedef ITypedGeomParam<V3sTPTraits> IV3sGeomParam;
524 typedef ITypedGeomParam<V3iTPTraits> IV3iGeomParam;
525 typedef ITypedGeomParam<V3fTPTraits> IV3fGeomParam;
526 typedef ITypedGeomParam<V3dTPTraits> IV3dGeomParam;
527
528 typedef ITypedGeomParam<P2sTPTraits> IP2sGeomParam;
529 typedef ITypedGeomParam<P2iTPTraits> IP2iGeomParam;
530 typedef ITypedGeomParam<P2fTPTraits> IP2fGeomParam;
531 typedef ITypedGeomParam<P2dTPTraits> IP2dGeomParam;
532
533 typedef ITypedGeomParam<P3sTPTraits> IP3sGeomParam;
534 typedef ITypedGeomParam<P3iTPTraits> IP3iGeomParam;
535 typedef ITypedGeomParam<P3fTPTraits> IP3fGeomParam;
536 typedef ITypedGeomParam<P3dTPTraits> IP3dGeomParam;
537
538 typedef ITypedGeomParam<Box2sTPTraits> IBox2sGeomParam;
539 typedef ITypedGeomParam<Box2iTPTraits> IBox2iGeomParam;
540 typedef ITypedGeomParam<Box2fTPTraits> IBox2fGeomParam;
541 typedef ITypedGeomParam<Box2dTPTraits> IBox2dGeomParam;
542
543 typedef ITypedGeomParam<Box3sTPTraits> IBox3sGeomParam;
544 typedef ITypedGeomParam<Box3iTPTraits> IBox3iGeomParam;
545 typedef ITypedGeomParam<Box3fTPTraits> IBox3fGeomParam;
546 typedef ITypedGeomParam<Box3dTPTraits> IBox3dGeomParam;
547
548 typedef ITypedGeomParam<M33fTPTraits> IM33fGeomParam;
549 typedef ITypedGeomParam<M33dTPTraits> IM33dGeomParam;
550 typedef ITypedGeomParam<M44fTPTraits> IM44fGeomParam;
551 typedef ITypedGeomParam<M44dTPTraits> IM44dGeomParam;
552
553 typedef ITypedGeomParam<QuatfTPTraits> IQuatfGeomParam;
554 typedef ITypedGeomParam<QuatdTPTraits> IQuatdGeomParam;
555
556 typedef ITypedGeomParam<C3hTPTraits> IC3hGeomParam;
557 typedef ITypedGeomParam<C3fTPTraits> IC3fGeomParam;
558 typedef ITypedGeomParam<C3cTPTraits> IC3cGeomParam;
559
560 typedef ITypedGeomParam<C4hTPTraits> IC4hGeomParam;
561 typedef ITypedGeomParam<C4fTPTraits> IC4fGeomParam;
562 typedef ITypedGeomParam<C4cTPTraits> IC4cGeomParam;
563
564 typedef ITypedGeomParam<N2fTPTraits> IN2fGeomParam;
565 typedef ITypedGeomParam<N2dTPTraits> IN2dGeomParam;
566
567 typedef ITypedGeomParam<N3fTPTraits> IN3fGeomParam;
568 typedef ITypedGeomParam<N3dTPTraits> IN3dGeomParam;
569
570 } // End namespace ALEMBIC_VERSION_NS
571
572 using namespace ALEMBIC_VERSION_NS;
573
574 } // End namespace AbcGeom
575 } // End namespace Alembic
576
577 #endif
578