Coverage Report

Created: 2024-09-08 06:41

/src/alembic/lib/Alembic/AbcGeom/OSubD.h
Line
Count
Source (jump to first uncovered line)
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_OSubD_h
38
#define Alembic_AbcGeom_OSubD_h
39
40
#include <map>
41
#include <Alembic/Util/Export.h>
42
#include <Alembic/AbcGeom/Foundation.h>
43
#include <Alembic/AbcGeom/SchemaInfoDeclarations.h>
44
#include <Alembic/AbcGeom/OGeomBase.h>
45
#include <Alembic/AbcGeom/OFaceSet.h>
46
#include <Alembic/AbcGeom/OGeomParam.h>
47
48
namespace Alembic {
49
namespace AbcGeom {
50
namespace ALEMBIC_VERSION_NS {
51
52
//-*****************************************************************************
53
// for default values for int scalar properties here (INT_MIN / 2)
54
static const int32_t ABC_GEOM_SUBD_NULL_INT_VALUE( -1073741824 );
55
56
//-*****************************************************************************
57
class ALEMBIC_EXPORT OSubDSchema : public OGeomBaseSchema<SubDSchemaInfo>
58
{
59
public:
60
    //-*************************************************************************
61
    // SUBD SCHEMA SAMPLE TYPE
62
    //-*************************************************************************
63
    class Sample
64
    {
65
    public:
66
        //! Creates a default sample with no data in it.
67
        //! ...
68
0
        Sample() { reset(); }
69
70
        //! Creates a sample with position data, index data, and count data.
71
        //! For specifying samples with an explicit topology. The first
72
        //! sample must be full like this. Subsequent samples may also
73
        //! be full like this, which would indicate a change of topology
74
        Sample( const Abc::P3fArraySample &iPositions,
75
                const Abc::Int32ArraySample &iFaceIndices,
76
                const Abc::Int32ArraySample &iFaceCounts,
77
78
                const Abc::Int32ArraySample &iCreaseIndices =
79
                Abc::Int32ArraySample(),
80
                const Abc::Int32ArraySample &iCreaseLengths =
81
                Abc::Int32ArraySample(),
82
                const Abc::FloatArraySample &iCreaseSharpnesses =
83
                Abc::FloatArraySample(),
84
85
                const Abc::Int32ArraySample &iCornerIndices =
86
                Abc::Int32ArraySample(),
87
                const Abc::FloatArraySample &iCornerSharpnesses =
88
                Abc::FloatArraySample(),
89
90
                const Abc::Int32ArraySample &iHoles = Abc::Int32ArraySample()
91
              )
92
93
          : m_positions( iPositions )
94
          , m_faceIndices( iFaceIndices )
95
          , m_faceCounts( iFaceCounts )
96
          , m_faceVaryingInterpolateBoundary( ABC_GEOM_SUBD_NULL_INT_VALUE )
97
          , m_faceVaryingPropagateCorners( ABC_GEOM_SUBD_NULL_INT_VALUE )
98
          , m_interpolateBoundary( ABC_GEOM_SUBD_NULL_INT_VALUE )
99
          , m_creaseIndices     ( iCreaseIndices )
100
          , m_creaseLengths     ( iCreaseLengths )
101
          , m_creaseSharpnesses ( iCreaseSharpnesses )
102
          , m_cornerIndices     ( iCornerIndices )
103
          , m_cornerSharpnesses ( iCornerSharpnesses )
104
          , m_holes             ( iHoles )
105
          , m_subdScheme        ( "catmull-clark" )
106
0
        {}
107
108
        // main stuff
109
0
        const Abc::P3fArraySample &getPositions() const { return m_positions; }
110
        void setPositions( const Abc::P3fArraySample &iSmp )
111
0
        { m_positions = iSmp; }
112
113
0
        const Abc::Int32ArraySample &getFaceIndices() const { return m_faceIndices; }
114
        void setFaceIndices( const Abc::Int32ArraySample &iSmp )
115
0
        { m_faceIndices = iSmp; }
116
117
0
        const Abc::Int32ArraySample &getFaceCounts() const { return m_faceCounts; }
118
        void setFaceCounts( const Abc::Int32ArraySample &iCnt )
119
0
        { m_faceCounts = iCnt; }
120
121
122
        // misc subd stuff
123
        int32_t getFaceVaryingInterpolateBoundary() const
124
0
        { return m_faceVaryingInterpolateBoundary; }
125
        void setFaceVaryingInterpolateBoundary( int32_t i )
126
0
        { m_faceVaryingInterpolateBoundary = i; }
127
128
        int32_t getFaceVaryingPropagateCorners() const
129
0
        { return m_faceVaryingPropagateCorners; }
130
        void setFaceVaryingPropagateCorners( int32_t i )
131
0
        { m_faceVaryingPropagateCorners = i; }
132
133
        int32_t getInterpolateBoundary() const
134
0
        { return m_interpolateBoundary; }
135
        void setInterpolateBoundary( int32_t i )
136
0
        { m_interpolateBoundary = i; }
137
138
        // creases
139
        const Abc::Int32ArraySample &getCreaseIndices() const
140
0
        { return m_creaseIndices; }
141
        void setCreaseIndices( const Abc::Int32ArraySample &iCreaseIndices )
142
0
        { m_creaseIndices = iCreaseIndices; }
143
144
        const Abc::Int32ArraySample &getCreaseLengths() const
145
0
        { return m_creaseLengths; }
146
        void setCreaseLengths( const Abc::Int32ArraySample &iCreaseLengths )
147
0
        { m_creaseLengths = iCreaseLengths; }
148
149
        const Abc::FloatArraySample &getCreaseSharpnesses() const
150
0
        { return m_creaseSharpnesses; }
151
        void setCreaseSharpnesses( const Abc::FloatArraySample
152
                                   &iCreaseSharpnesses )
153
0
        { m_creaseSharpnesses = iCreaseSharpnesses; }
154
155
        void setCreases( const Abc::Int32ArraySample &iCreaseIndices,
156
                         const Abc::Int32ArraySample &iCreaseLengths )
157
0
        {
158
0
            m_creaseIndices = iCreaseIndices;
159
0
            m_creaseLengths = iCreaseLengths;
160
0
        }
161
162
        void setCreases( const Abc::Int32ArraySample   &iCreaseIndices,
163
                         const Abc::Int32ArraySample   &iCreaseLengths,
164
                         const Abc::FloatArraySample &iCreaseSharpnesses )
165
0
        {
166
0
            m_creaseIndices = iCreaseIndices;
167
0
            m_creaseLengths = iCreaseLengths;
168
0
            m_creaseSharpnesses = iCreaseSharpnesses;
169
0
        }
170
171
        // corners
172
        const Abc::Int32ArraySample &getCornerIndices() const
173
0
        { return m_cornerIndices; }
174
        void setCornerIndices( const Abc::Int32ArraySample &iCornerIndices )
175
0
        { m_cornerIndices = iCornerIndices; }
176
177
        const Abc::FloatArraySample &getCornerSharpnesses() const
178
0
        { return m_cornerSharpnesses; }
179
        void setCornerSharpnesses( const Abc::FloatArraySample
180
                                   &iCornerSharpnesses )
181
0
        { m_cornerSharpnesses = iCornerSharpnesses; }
182
183
        void setCorners( const Abc::Int32ArraySample &iCornerIndices,
184
                         const Abc::FloatArraySample &iCornerSharpnesses )
185
0
        {
186
0
            m_cornerIndices = iCornerIndices;
187
0
            m_cornerSharpnesses = iCornerSharpnesses;
188
0
        }
189
190
        // Holes
191
        const Abc::Int32ArraySample &getHoles() const
192
0
        { return m_holes; }
193
        void setHoles( const Abc::Int32ArraySample &iHoles )
194
0
        { m_holes = iHoles; }
195
196
        // subdivision scheme
197
        std::string getSubdivisionScheme() const
198
0
        { return m_subdScheme; }
199
        void setSubdivisionScheme( const std::string &iScheme )
200
0
        { m_subdScheme = iScheme; }
201
202
        // bounding boxes
203
0
        const Abc::Box3d &getSelfBounds() const { return m_selfBounds; }
204
        void setSelfBounds( const Abc::Box3d &iBnds )
205
0
        { m_selfBounds = iBnds; }
206
207
        // velocities accessor
208
0
        const Abc::V3fArraySample &getVelocities() const { return m_velocities; }
209
        void setVelocities( const Abc::V3fArraySample &iVelocities )
210
0
        { m_velocities = iVelocities; }
211
212
        // UVs; need to set these outside the Sample constructor
213
0
        const OV2fGeomParam::Sample &getUVs() const { return m_uvs; }
214
        void setUVs( const OV2fGeomParam::Sample &iUVs )
215
0
        { m_uvs = iUVs; }
216
217
        void reset()
218
0
        {
219
0
            m_positions.reset();
220
0
            m_faceIndices.reset();
221
0
            m_faceCounts.reset();
222
0
223
0
            m_faceVaryingInterpolateBoundary = ABC_GEOM_SUBD_NULL_INT_VALUE;
224
0
            m_faceVaryingPropagateCorners = ABC_GEOM_SUBD_NULL_INT_VALUE;
225
0
            m_interpolateBoundary = ABC_GEOM_SUBD_NULL_INT_VALUE;
226
0
227
0
            m_creaseIndices.reset();
228
0
            m_creaseLengths.reset();
229
0
            m_creaseSharpnesses.reset();
230
0
231
0
            m_cornerIndices.reset();
232
0
            m_cornerSharpnesses.reset();
233
0
234
0
            m_holes.reset();
235
0
236
0
            m_subdScheme = "catmull-clark";
237
0
238
0
            m_velocities.reset();
239
0
240
0
            m_selfBounds.makeEmpty();
241
0
242
0
            m_uvs.reset();
243
0
        }
244
245
        bool isPartialSample() const
246
0
        {
247
0
            if( !m_positions.getData() && !m_faceIndices.getData() && !m_faceCounts.getData() )
248
0
            {
249
0
                if( m_uvs.getVals() || m_velocities.getData() ||
250
0
                    (m_faceVaryingInterpolateBoundary != ABC_GEOM_SUBD_NULL_INT_VALUE) ||
251
0
                    (m_faceVaryingPropagateCorners != ABC_GEOM_SUBD_NULL_INT_VALUE) ||
252
0
                    (m_interpolateBoundary != ABC_GEOM_SUBD_NULL_INT_VALUE) ||
253
0
                    m_creaseIndices.getData() ||
254
0
                    m_creaseLengths.getData() || m_creaseSharpnesses.getData() ||
255
0
                    m_cornerIndices.getData() || m_cornerSharpnesses.getData() ||
256
0
                    m_holes.getData() )
257
0
                {
258
0
                    return true;
259
0
                }
260
0
            }
261
0
262
0
            return false;
263
0
        }
264
265
    protected:
266
        friend class OSubDSchema;
267
268
        Abc::P3fArraySample m_positions;
269
        Abc::Int32ArraySample m_faceIndices;
270
        Abc::Int32ArraySample m_faceCounts;
271
272
        int32_t m_faceVaryingInterpolateBoundary;
273
        int32_t m_faceVaryingPropagateCorners;
274
        int32_t m_interpolateBoundary;
275
276
        // Creases
277
        Abc::Int32ArraySample m_creaseIndices;
278
        Abc::Int32ArraySample m_creaseLengths;
279
        Abc::FloatArraySample m_creaseSharpnesses;
280
281
        // Corners
282
        Abc::Int32ArraySample m_cornerIndices;
283
        Abc::FloatArraySample m_cornerSharpnesses;
284
285
        // Holes
286
        Abc::Int32ArraySample m_holes;
287
288
        // subdivision scheme
289
        std::string m_subdScheme;
290
291
        // bounds
292
        Abc::Box3d m_selfBounds;
293
294
        Abc::V3fArraySample m_velocities;
295
296
        // UVs
297
        OV2fGeomParam::Sample m_uvs;
298
299
    }; // end OSubDSchema::Sample
300
301
    //-*************************************************************************
302
    // SUBD SCHEMA
303
    //-*************************************************************************
304
public:
305
    //! By convention we always define this_type in AbcGeom classes.
306
    //! Used by unspecified-bool-type conversion below
307
    typedef OSubDSchema this_type;
308
309
    //-*************************************************************************
310
    // CONSTRUCTION, DESTRUCTION, ASSIGNMENT
311
    //-*************************************************************************
312
313
    //! The default constructor creates an empty OSubDSchema
314
    //! ...
315
    OSubDSchema()
316
0
    {
317
0
        m_selectiveExport = false;
318
0
        m_numSamples = 0;
319
0
        m_timeSamplingIndex = 0;
320
0
    }
321
322
    //! This constructor creates a new subd writer.
323
    //! The first argument is an CompoundPropertyWriterPtr to use as a parent.
324
    //! The next is the name to give the schema which is usually the default
325
    //! name given by OSubD (.geom)   The remaining optional arguments
326
    //! can be used to override the ErrorHandlerPolicy, to specify
327
    //! MetaData, specify sparse sampling and to set TimeSampling.
328
    OSubDSchema( AbcA::CompoundPropertyWriterPtr iParent,
329
                     const std::string &iName,
330
                     const Abc::Argument &iArg0 = Abc::Argument(),
331
                     const Abc::Argument &iArg1 = Abc::Argument(),
332
                     const Abc::Argument &iArg2 = Abc::Argument(),
333
                     const Abc::Argument &iArg3 = Abc::Argument() );
334
335
    //! This constructor creates a new subd writer.
336
    //! The first argument is an OCompundProperty to use as a parent, and from
337
    //! which the ErrorHandlerPolicy is derived.  The next is the name to give
338
    //! the schema which is usually the default name given by OSubD (.geom)
339
    //! The remaining optional arguments can be used to specify MetaData,
340
    //! specify sparse sampling and to set TimeSampling.
341
    OSubDSchema( Abc::OCompoundProperty iParent,
342
                     const std::string &iName,
343
                     const Abc::Argument &iArg0 = Abc::Argument(),
344
                     const Abc::Argument &iArg1 = Abc::Argument(),
345
                     const Abc::Argument &iArg2 = Abc::Argument() );
346
347
    //! Default assignment and copy operator used.
348
349
    //-*************************************************************************
350
    // SCHEMA STUFF
351
    //-*************************************************************************
352
353
    //! Return the time sampling, which is stored on each of the
354
    //! sub properties.
355
    AbcA::TimeSamplingPtr getTimeSampling() const
356
0
    {
357
0
        if( m_positionsProperty.valid() )
358
0
        {
359
0
            return m_positionsProperty.getTimeSampling();
360
0
        }
361
0
        else
362
0
        {
363
0
            return getObject().getArchive().getTimeSampling( 0 );
364
0
        }
365
0
    }
366
367
    //-*************************************************************************
368
    // SAMPLE STUFF
369
    //-*************************************************************************
370
371
    //! Get number of samples written so far.
372
    //! ...
373
    size_t getNumSamples() const
374
0
    { return m_numSamples; }
375
376
    //! Set a sample! Sample zero has to have non-degenerate
377
    //! positions, indices and counts.
378
    void set( const Sample &iSamp );
379
380
    //! Set from previous sample. Will apply to each of positions,
381
    //! indices, and counts.
382
    void setFromPrevious( );
383
384
    void setTimeSampling( uint32_t iIndex );
385
    void setTimeSampling( AbcA::TimeSamplingPtr iTime );
386
387
    //-*************************************************************************
388
    // ABC BASE MECHANISMS
389
    // These functions are used by Abc to deal with errors, validity,
390
    // and so on.
391
    //-*************************************************************************
392
393
    //! Reset returns this function set to an empty, default
394
    //! state.
395
    void reset()
396
0
    {
397
0
        m_positionsProperty.reset();
398
0
        m_faceIndicesProperty.reset();
399
0
        m_faceCountsProperty.reset();
400
0
401
0
        m_faceVaryingInterpolateBoundaryProperty.reset();
402
0
        m_faceVaryingPropagateCornersProperty.reset();
403
0
        m_interpolateBoundaryProperty.reset();
404
0
405
0
        m_creaseIndicesProperty.reset();
406
0
        m_creaseLengthsProperty.reset();
407
0
        m_creaseSharpnessesProperty.reset();
408
0
409
0
        m_cornerIndicesProperty.reset();
410
0
        m_cornerSharpnessesProperty.reset();
411
0
412
0
        m_holesProperty.reset();
413
0
414
0
        m_subdSchemeProperty.reset();
415
0
416
0
        m_velocitiesProperty.reset();
417
0
418
0
        m_uvsParam.reset();
419
0
420
0
        m_faceSets.clear ();
421
0
422
0
        OGeomBaseSchema<SubDSchemaInfo>::reset();
423
0
    }
424
425
    //! Valid returns whether this function set is
426
    //! valid.
427
    bool valid() const
428
0
    {
429
0
        return ( OGeomBaseSchema<SubDSchemaInfo>::valid() &&
430
0
                 m_positionsProperty.valid() &&
431
0
                 m_faceIndicesProperty.valid() &&
432
0
                 m_faceCountsProperty.valid() ) ||
433
0
                 m_selectiveExport;
434
0
    }
435
436
    // FaceSet stuff
437
    OFaceSet & createFaceSet( const std::string &iFaceSetName );
438
    //! Appends the names of any FaceSets for this SubD.
439
    void getFaceSetNames( std::vector <std::string> & oFaceSetNames );
440
    OFaceSet getFaceSet( const std::string &iFaceSetName );
441
    bool hasFaceSet( const std::string &iFaceSetName );
442
443
444
    //! Optional source name for the UV param.
445
    //! Must be set before the first UV sample is set.
446
    void setUVSourceName(const std::string & iName);
447
448
    //! unspecified-bool-type operator overload.
449
    //! ...
450
    ALEMBIC_OVERRIDE_OPERATOR_BOOL( OSubDSchema::valid() );
451
452
protected:
453
    void init( uint32_t iTsIdx, bool isSparse );
454
455
    //! Set only some property data. Does not need to be a valid schema sample
456
    //! This is to be used when created a file which will be layered in to
457
    //! another file.
458
    void selectiveSet( const Sample &iSamp );
459
460
    Abc::OP3fArrayProperty m_positionsProperty;
461
    Abc::OInt32ArrayProperty m_faceIndicesProperty;
462
    Abc::OInt32ArrayProperty m_faceCountsProperty;
463
464
    // misc
465
    Abc::OInt32Property m_faceVaryingInterpolateBoundaryProperty;
466
    Abc::OInt32Property m_faceVaryingPropagateCornersProperty;
467
    Abc::OInt32Property m_interpolateBoundaryProperty;
468
469
    // Creases
470
    Abc::OInt32ArrayProperty m_creaseIndicesProperty;
471
    Abc::OInt32ArrayProperty m_creaseLengthsProperty;
472
    Abc::OFloatArrayProperty m_creaseSharpnessesProperty;
473
474
    // Corners
475
    Abc::OInt32ArrayProperty m_cornerIndicesProperty;
476
    Abc::OFloatArrayProperty m_cornerSharpnessesProperty;
477
478
    // Holes
479
    Abc::OInt32ArrayProperty m_holesProperty;
480
481
    // subdivision scheme
482
    Abc::OStringProperty m_subdSchemeProperty;
483
484
    Abc::OV3fArrayProperty m_velocitiesProperty;
485
486
    // UVs
487
    OV2fGeomParam m_uvsParam;
488
489
490
    // optional source name for the UVs
491
    std::string m_uvSourceName;
492
493
private:
494
    void initCreases(uint32_t iNumSamples);
495
    void initCorners(uint32_t iNumSamples);
496
    void initHoles(uint32_t iNumSamples);
497
498
    // FaceSets created on this SubD
499
    std::map <std::string, OFaceSet>  m_faceSets;
500
501
    // Write out only some properties (UVs, normals).
502
    // This is to export data to layer into another file later.
503
    bool m_selectiveExport;
504
505
    // Number of times OSubDSchema::set() has been called
506
    size_t m_numSamples;
507
508
    uint32_t m_timeSamplingIndex;
509
510
    void createSubDSchemeProperty();
511
512
    void createFaceVaryingInterpolateBoundaryProperty();
513
514
    void createFaceVaryingPropagateCornersProperty();
515
516
    void createInterpolateBoundaryProperty();
517
518
    void createVelocitiesProperty();
519
520
    void createUVsProperty( const Sample &iSamp );
521
522
    void createPositionsProperty();
523
524
    friend class OFaceSetSchema;;
525
};
526
527
//-*****************************************************************************
528
// SCHEMA OBJECT
529
//-*****************************************************************************
530
typedef Abc::OSchemaObject<OSubDSchema> OSubD;
531
532
typedef Util::shared_ptr< OSubD > OSubDPtr;
533
534
} // End namespace ALEMBIC_VERSION_NS
535
536
using namespace ALEMBIC_VERSION_NS;
537
538
} // End namespace AbcGeom
539
} // End namespace Alembic
540
541
#endif