1 //-***************************************************************************** 2 // 3 // Copyright (c) 2009-2011, 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_IGeometrySchema_h 38 #define Alembic_AbcGeom_IGeometrySchema_h 39 40 #include <Alembic/Abc/ISchema.h> 41 #include <Alembic/AbcGeom/Foundation.h> 42 #include <Alembic/AbcGeom/IGeomParam.h> 43 #include <Alembic/AbcGeom/SchemaInfoDeclarations.h> 44 45 namespace Alembic { 46 namespace AbcGeom { 47 namespace ALEMBIC_VERSION_NS { 48 49 50 //! This class holds properties common to all geometric classes that have a 51 //! physical volume. 52 //! - selfBounds 53 //! - childBounds (optional) 54 //! - GeomParams (optional) 55 //! - UserProperties (optional) 56 //! 57 //! This class is used to encapsulate common functionality of the 58 //! real Geometry schema classes, like IPoints and IPolyMesh and so on 59 template <class INFO> 60 class IGeomBaseSchema : public Abc::ISchema<INFO> 61 { 62 public: 63 //-************************************************************************* 64 // TYPEDEFS AND IDENTIFIERS 65 //-************************************************************************* 66 67 typedef INFO info_type; 68 69 70 //-************************************************************************* 71 // Constructors that pass through to ISchema 72 //-************************************************************************* 73 // 74 //! The default constructor creates an empty ISchema. 75 //! Used to create "NULL/invalid" instances. IGeomBaseSchema()76 IGeomBaseSchema() {} 77 78 //! Delegates to Abc/ISchema, and then creates 79 //! properties that are present. 80 IGeomBaseSchema( const ICompoundProperty & iParent, 81 const std::string &iName, 82 const Argument &iArg0 = Argument(), 83 const Argument &iArg1 = Argument() ) 84 : Abc::ISchema<info_type>( iParent, iName, iArg0, iArg1 ) 85 { 86 init( iArg0, iArg1 ); 87 } 88 89 //! Wrap an existing schema object 90 IGeomBaseSchema( const ICompoundProperty & iProp, 91 const Abc::Argument &iArg0 = Abc::Argument(), 92 const Abc::Argument &iArg1 = Abc::Argument() ) 93 : Abc::ISchema<info_type>( iProp, iArg0, iArg1 ) 94 { 95 init( iArg0, iArg1 ); 96 } 97 98 // Deprecated in favor of the constructor above 99 IGeomBaseSchema( const ICompoundProperty & iProp, 100 Abc::WrapExistingFlag iFlag, 101 const Abc::Argument &iArg0 = Abc::Argument(), 102 const Abc::Argument &iArg1 = Abc::Argument() ) 103 : Abc::ISchema<info_type>( iProp, iArg0, iArg1 ) 104 { 105 init( iArg0, iArg1 ); 106 } 107 108 //! Copy constructor IGeomBaseSchema(const IGeomBaseSchema & iCopy)109 IGeomBaseSchema( const IGeomBaseSchema& iCopy ) 110 : Abc::ISchema<info_type>() 111 { 112 *this = iCopy; 113 } 114 init(const Abc::Argument & iArg0,const Abc::Argument & iArg1)115 void init( const Abc::Argument &iArg0, const Abc::Argument &iArg1 ) 116 { 117 ALEMBIC_ABC_SAFE_CALL_BEGIN( "IGeomBaseSchema::init()" ); 118 119 Abc::Arguments args; 120 iArg0.setInto( args ); 121 iArg1.setInto( args ); 122 123 AbcA::CompoundPropertyReaderPtr _this = this->getPtr(); 124 125 m_selfBoundsProperty = Abc::IBox3dProperty( _this, ".selfBnds", 126 iArg0, iArg1 ); 127 if ( this->getPropertyHeader( ".childBnds" ) != NULL ) 128 { 129 m_childBoundsProperty = Abc::IBox3dProperty( _this, 130 ".childBnds", iArg0, iArg1 ); 131 } 132 133 if ( this->getPropertyHeader( ".arbGeomParams" ) != NULL ) 134 { 135 m_arbGeomParams = Abc::ICompoundProperty( _this, ".arbGeomParams", 136 args.getErrorHandlerPolicy() ); 137 } 138 if ( this->getPropertyHeader( ".userProperties" ) != NULL ) 139 { 140 m_userProperties = Abc::ICompoundProperty( _this, ".userProperties", 141 args.getErrorHandlerPolicy() ); 142 } 143 144 ALEMBIC_ABC_SAFE_CALL_END(); 145 } 146 reset()147 virtual void reset () 148 { 149 m_selfBoundsProperty.reset(); 150 m_childBoundsProperty.reset(); 151 m_arbGeomParams.reset(); 152 m_userProperties.reset(); 153 Abc::ISchema<info_type>::reset(); 154 } 155 valid()156 virtual bool valid() const 157 { 158 // Only selfBounds is required, all others are optional 159 return ( Abc::ISchema<info_type>::valid() && 160 m_selfBoundsProperty.valid() ); 161 } 162 getSelfBoundsProperty()163 Abc::IBox3dProperty getSelfBoundsProperty() const 164 { 165 return m_selfBoundsProperty; 166 } 167 getChildBoundsProperty()168 Abc::IBox3dProperty getChildBoundsProperty() const 169 { 170 return m_childBoundsProperty; 171 } 172 173 // compound property to use as parent for any arbitrary GeomParams 174 // underneath it getArbGeomParams()175 ICompoundProperty getArbGeomParams() const { return m_arbGeomParams; } 176 177 // compound property to use as parent for any user workflow specific 178 // properties getUserProperties()179 ICompoundProperty getUserProperties() const { return m_userProperties; } 180 181 protected: 182 // Only selfBounds is required, all others are optional 183 Abc::IBox3dProperty m_selfBoundsProperty; 184 Abc::IBox3dProperty m_childBoundsProperty; 185 186 Abc::ICompoundProperty m_arbGeomParams; 187 Abc::ICompoundProperty m_userProperties; 188 189 }; 190 191 //-***************************************************************************** 192 //! IGeomBase - A generic base set of properties and methods that encapsulate 193 //! things common to AbcGeom types that have a physical volume. 194 //! - self bounds 195 //! - children bounds (optional) 196 //! - argbGeomParams (optional) 197 //! - userProperties (optional) 198 //! This class is a concrete instantiation of IGeomBaseSchema. 199 //! Your archive might contain PolyMesh and SubD and Curves 200 //! and Points objects etc. This class, IGeomBase, gives you 201 //! access to the generic parts of those objects. For example, if you 202 //! just wish to iterate through an archive's hierarchy to examine bounding 203 //! regions this class could be helpful to you. Then when you actually 204 //! need to access the real data in the geometric type you can 205 //! always create the needed type of I<geom type> object> via kWrapExisting. 206 class IGeomBase : public IGeomBaseSchema<GeomBaseSchemaInfo> 207 { 208 public: 209 typedef IGeomBase this_type; 210 211 class Sample 212 { 213 public: 214 typedef Sample this_type; 215 216 // Users don't ever create this data directly. Sample()217 Sample() { reset(); } 218 getSelfBounds()219 Abc::Box3d getSelfBounds() const { return m_selfBounds; } 220 reset()221 void reset() 222 { 223 m_selfBounds.makeEmpty(); 224 } 225 226 protected: 227 friend class IGeomBase; 228 Abc::Box3d m_selfBounds; 229 }; 230 231 public: 232 //! By convention we always define this_type in AbcGeom classes. 233 //! Used by unspecified-bool-type conversion below 234 235 //-************************************************************************* 236 // CONSTRUCTION, DESTRUCTION, ASSIGNMENT 237 //-************************************************************************* 238 239 //! The default constructor creates an empty GeomBase IGeomBase()240 IGeomBase() {} 241 242 IGeomBase( const ICompoundProperty &iParent, 243 const std::string &iName, 244 const Abc::Argument &iArg0 = Abc::Argument(), 245 const Abc::Argument &iArg1 = Abc::Argument() ) 246 247 // We don't want strict matching of the title because the real schema 248 // is going to be something like "AbcGeom_<type>_vX" 249 : IGeomBaseSchema<GeomBaseSchemaInfo>( iParent, iName, kNoMatching ) 250 { 251 init( iArg0, iArg1 ); 252 } 253 254 IGeomBase( const ICompoundProperty & iThis, 255 const Abc::Argument &iArg0 = Abc::Argument(), 256 const Abc::Argument &iArg1 = Abc::Argument() ) 257 // We don't want strict matching of the title because the real schema 258 // is going to be something like "AbcGeom_<type>_vX" 259 : IGeomBaseSchema<GeomBaseSchemaInfo>( iThis, kNoMatching ) 260 { 261 init( iArg0, iArg1 ); 262 } 263 264 IGeomBase( const ICompoundProperty & iThis, 265 Abc::WrapExistingFlag iFlag, 266 const Abc::Argument &iArg0 = Abc::Argument(), 267 const Abc::Argument &iArg1 = Abc::Argument() ) 268 : IGeomBaseSchema<GeomBaseSchemaInfo>( iThis, kNoMatching ) 269 { 270 init( iArg0, iArg1 ); 271 } 272 273 //! Copy constructor. IGeomBase(const IGeomBase & iCopy)274 IGeomBase(const IGeomBase & iCopy) 275 : IGeomBaseSchema<GeomBaseSchemaInfo>() 276 { 277 *this = iCopy; 278 } 279 280 //! Default assignment operator used. 281 282 //-************************************************************************* 283 // SCALAR PROPERTY READER FUNCTIONALITY 284 //-************************************************************************* 285 286 //! Return the number of samples contained in the property. 287 //! This can be any number, including zero. 288 //! This returns the number of samples that were written, independently 289 //! of whether or not they were constant. getNumSamples()290 size_t getNumSamples() const 291 { return m_selfBoundsProperty.getNumSamples(); } 292 293 //! Ask if we're constant - no change in value amongst samples, 294 //! regardless of the time sampling. isConstant()295 bool isConstant() const 296 { return m_selfBoundsProperty.isConstant(); } 297 298 //! Time sampling Information. 299 //! getTimeSampling()300 AbcA::TimeSamplingPtr getTimeSampling() const 301 { 302 if ( m_selfBoundsProperty.valid() ) 303 { 304 return m_selfBoundsProperty.getTimeSampling(); 305 } 306 else 307 { 308 return getObject().getArchive().getTimeSampling( 0 ); 309 } 310 } 311 312 //-************************************************************************* 313 void get( Sample &oSample, 314 const Abc::ISampleSelector &iSS = Abc::ISampleSelector() ) const 315 { 316 ALEMBIC_ABC_SAFE_CALL_BEGIN( "IGeomBase::get()" ); 317 318 m_selfBoundsProperty.get( oSample.m_selfBounds, iSS ); 319 320 ALEMBIC_ABC_SAFE_CALL_END(); 321 } 322 323 //-************************************************************************* 324 Sample getValue( const Abc::ISampleSelector &iSS = Abc::ISampleSelector() ) const 325 { 326 Sample smp; 327 get( smp, iSS ); 328 return smp; 329 } 330 331 //-************************************************************************* getArbGeomParams()332 Abc::ICompoundProperty getArbGeomParams() const { return m_arbGeomParams; } 333 334 //-************************************************************************* getUserProperties()335 Abc::ICompoundProperty getUserProperties() const { return m_userProperties; } 336 337 //-************************************************************************* 338 //! Reset returns this function set to an empty, default 339 //! state. reset()340 void reset() 341 { 342 IGeomBaseSchema<GeomBaseSchemaInfo>::reset(); 343 } 344 345 //-************************************************************************* 346 //! Valid returns whether this function set is 347 //! valid. valid()348 bool valid() const 349 { 350 return ( IGeomBaseSchema<GeomBaseSchemaInfo>::valid() ); 351 } 352 353 //-************************************************************************* 354 //! unspecified-bool-type operator overload. 355 //! ... 356 ALEMBIC_OVERRIDE_OPERATOR_BOOL( IGeomBase::valid() ); 357 358 //-************************************************************************* 359 //! This will check whether or not a given entity (as represented by 360 //! metadata) strictly matches the interpretation of this 361 //! schema object. 362 static bool matches( const AbcA::MetaData &iMetaData, 363 SchemaInterpMatching iMatching = kStrictMatching ) 364 { 365 if ( iMatching == kNoMatching ) 366 { return true; } 367 368 if ( iMatching == kStrictMatching || iMatching == kSchemaTitleMatching ) 369 { 370 return iMetaData.get( "schemaBaseType" ) == 371 GeomBaseSchemaInfo::title(); 372 } 373 374 return false; 375 } 376 377 //-************************************************************************* 378 //! This will check whether or not a given object (as represented by 379 //! an object header) strictly matches the interpretation of this 380 //! schema object, as well as the data type. 381 static bool matches( const AbcA::PropertyHeader &iHeader, 382 SchemaInterpMatching iMatching = kStrictMatching ) 383 { 384 return matches( iHeader.getMetaData(), iMatching ); 385 } 386 387 }; 388 389 //-***************************************************************************** 390 typedef Abc::ISchemaObject<IGeomBase> IGeomBaseObject; 391 392 } // End namespace ALEMBIC_VERSION_NS 393 394 using namespace ALEMBIC_VERSION_NS; 395 396 } // End namespace AbcGeom 397 } // End namespace Alembic 398 399 #endif 400