Coverage Report

Created: 2023-03-26 07:07

/src/alembic/lib/Alembic/AbcGeom/XformSample.cpp
Line
Count
Source (jump to first uncovered line)
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
#include <Alembic/AbcGeom/XformSample.h>
38
#include <Alembic/AbcGeom/XformOp.h>
39
40
#include <ImathMatrix.h>
41
#include <ImathMatrixAlgo.h>
42
#include <ImathQuat.h>
43
44
#include <math.h>
45
#ifndef M_PI
46
#define M_PI 3.14159265358979323846
47
#endif
48
49
50
namespace Alembic {
51
namespace AbcGeom {
52
namespace ALEMBIC_VERSION_NS {
53
54
//-*****************************************************************************
55
XformSample::XformSample()
56
0
{
57
0
    m_setWithOpStack = 0;
58
0
    m_inherits = true;
59
0
    m_opIndex = 0;
60
0
    m_hasBeenRead = false;
61
0
}
62
63
//-*****************************************************************************
64
std::size_t XformSample::addOp( XformOp iOp, const Abc::V3d &iVal )
65
0
{
66
0
    for ( size_t i = 0 ; i < 3 ; ++i )
67
0
    {
68
0
        iOp.setChannelValue( i, iVal[i] );
69
0
    }
70
71
0
    if ( ! m_hasBeenRead )
72
0
    {
73
0
        ABCA_ASSERT( m_setWithOpStack == 0 || m_setWithOpStack == 1,
74
0
                     "Cannot mix addOp() and set<Foo>() methods." );
75
76
0
        m_setWithOpStack = 1;
77
78
0
        m_ops.push_back( iOp );
79
80
0
        return m_ops.size() - 1;
81
0
    }
82
0
    else
83
0
    {
84
0
        std::size_t ret = m_opIndex;
85
86
0
        ABCA_ASSERT( m_setWithOpStack == 1,
87
0
                     "Cannot mix addOp() and set<Foo>() methods." );
88
89
0
        ABCA_ASSERT( iOp.getType() == m_ops[ret].getType(),
90
0
                     "Cannot update mismatched op-type in already-setted "
91
0
                     << "XformSample!" );
92
93
0
        m_ops[ret] = iOp;
94
0
        ++m_opIndex;
95
0
        m_opIndex = m_opIndex % m_ops.size();
96
97
0
        return ret;
98
0
    }
99
0
}
100
101
//-*****************************************************************************
102
std::size_t XformSample::addOp( XformOp iOp, const Abc::V3d &iAxis,
103
                                const double iAngleInDegrees )
104
105
0
{
106
0
    for ( size_t i = 0 ; i < 3 ; ++i )
107
0
    {
108
0
        iOp.setChannelValue( i, iAxis[i] );
109
0
    }
110
0
    iOp.setChannelValue( 3, iAngleInDegrees );
111
112
0
    if ( ! m_hasBeenRead )
113
0
    {
114
0
        ABCA_ASSERT( m_setWithOpStack == 0 || m_setWithOpStack == 1,
115
0
                     "Cannot mix addOp() and set<Foo>() methods." );
116
117
0
        m_setWithOpStack = 1;
118
119
0
        m_ops.push_back( iOp );
120
121
0
        return m_ops.size() - 1;
122
0
    }
123
0
    else
124
0
    {
125
0
        std::size_t ret = m_opIndex;
126
127
0
        ABCA_ASSERT( iOp.getType() == m_ops[ret].getType(),
128
0
                     "Cannot update mismatched op-type in already-setted "
129
0
                     << "XformSample!" );
130
131
0
        ABCA_ASSERT( m_setWithOpStack == 1,
132
0
                     "Cannot mix addOp() and set<Foo>() methods." );
133
134
0
        m_ops[ret] = iOp;
135
0
        ++m_opIndex;
136
0
        m_opIndex = m_opIndex % m_ops.size();
137
138
0
        return ret;
139
0
    }
140
0
}
141
142
//-*****************************************************************************
143
std::size_t XformSample::addOp( XformOp iOp,
144
                                const double iSingleAxisRotationInDegrees )
145
146
0
{
147
0
    iOp.setChannelValue( 0, iSingleAxisRotationInDegrees );
148
149
0
    if ( ! m_hasBeenRead )
150
0
    {
151
0
        ABCA_ASSERT( m_setWithOpStack == 0 || m_setWithOpStack == 1,
152
0
                     "Cannot mix addOp() and set<Foo>() methods." );
153
154
0
        m_setWithOpStack = 1;
155
156
0
        m_ops.push_back( iOp );
157
158
0
        return m_ops.size() - 1;
159
0
    }
160
0
    else
161
0
    {
162
0
        std::size_t ret = m_opIndex;
163
164
0
        ABCA_ASSERT( iOp.getType() == m_ops[ret].getType(),
165
0
                     "Cannot update mismatched op-type in already-setted "
166
0
                     << "XformSample!" );
167
168
0
        ABCA_ASSERT( m_setWithOpStack == 1,
169
0
                     "Cannot mix addOp() and set<Foo>() methods." );
170
171
0
        m_ops[ret] = iOp;
172
0
        ++m_opIndex;
173
0
        m_opIndex = m_opIndex % m_ops.size();
174
175
0
        return ret;
176
0
    }
177
0
}
178
179
//-*****************************************************************************
180
std::size_t XformSample::addOp( XformOp iOp, const Abc::M44d &iVal )
181
0
{
182
0
    for ( size_t i = 0 ; i < 4 ; ++i )
183
0
    {
184
0
        for ( size_t j = 0 ; j < 4 ; ++j )
185
0
        {
186
0
            iOp.setChannelValue( ( i * 4 ) + j, iVal.x[i][j] );
187
0
        }
188
0
    }
189
190
0
    if ( ! m_hasBeenRead )
191
0
    {
192
0
        ABCA_ASSERT( m_setWithOpStack == 0 || m_setWithOpStack == 1,
193
0
                     "Cannot mix addOp() and set<Foo>() methods." );
194
195
0
        m_setWithOpStack = 1;
196
197
0
        m_ops.push_back( iOp );
198
199
0
        return m_ops.size() - 1;
200
0
    }
201
0
    else
202
0
    {
203
0
        std::size_t ret = m_opIndex;
204
205
0
        ABCA_ASSERT( iOp.getType() == m_ops[ret].getType(),
206
0
                     "Cannot update mismatched op-type in already-setted "
207
0
                     << "XformSample!" );
208
209
0
        ABCA_ASSERT( m_setWithOpStack == 1,
210
0
                     "Cannot mix addOp() and set<Foo>() methods." );
211
212
0
        m_ops[ret] = iOp;
213
0
        ++m_opIndex;
214
0
        m_opIndex = m_opIndex % m_ops.size();
215
216
0
        return ret;
217
0
    }
218
0
}
219
220
//-*****************************************************************************
221
std::size_t XformSample::addOp( const XformOp &iOp )
222
0
{
223
0
    if ( ! m_hasBeenRead )
224
0
    {
225
0
        ABCA_ASSERT( m_setWithOpStack == 0 || m_setWithOpStack == 1,
226
0
                     "Cannot mix addOp() and set<Foo>() methods." );
227
228
0
        m_setWithOpStack = 1;
229
230
0
        m_ops.push_back( iOp );
231
232
0
        return m_ops.size() - 1;
233
0
    }
234
0
    else
235
0
    {
236
0
        std::size_t ret = m_opIndex;
237
238
0
        ABCA_ASSERT( iOp.getType() == m_ops[ret].getType(),
239
0
                     "Cannot update mismatched op-type in already-setted "
240
0
                     << "XformSample!" );
241
242
0
        ABCA_ASSERT( m_setWithOpStack == 1,
243
0
                     "Cannot mix addOp() and set<Foo>() methods." );
244
245
0
        m_ops[ret] = iOp;
246
0
        ++m_opIndex;
247
0
        m_opIndex = m_opIndex % m_ops.size();
248
249
0
        return ret;
250
0
    }
251
0
}
252
253
//-*****************************************************************************
254
XformOp XformSample::getOp( std::size_t iIndex ) const
255
0
{
256
0
    return m_ops[iIndex];
257
0
}
258
259
//-*****************************************************************************
260
XformOp &XformSample::operator[]( const std::size_t &iIndex )
261
0
{
262
0
    return m_ops[iIndex];
263
0
}
264
265
//-*****************************************************************************
266
const XformOp &XformSample::operator[]( const std::size_t &iIndex ) const
267
0
{
268
0
    return m_ops[iIndex];
269
0
}
270
271
//-*****************************************************************************
272
std::size_t XformSample::getNumOps() const
273
0
{
274
0
    return m_ops.size();
275
0
}
276
277
//-*****************************************************************************
278
std::size_t XformSample::getNumOpChannels() const
279
0
{
280
0
    std::size_t ret = 0;
281
0
    for ( size_t i = 0 ; i < m_ops.size() ; ++i )
282
0
    {
283
0
        ret += m_ops[i].getNumChannels();
284
0
    }
285
286
0
    return ret;
287
0
}
288
289
//-*****************************************************************************
290
void XformSample::setInheritsXforms( bool iInherits )
291
0
{
292
0
    m_inherits = iInherits;
293
0
}
294
295
//-*****************************************************************************
296
bool XformSample::getInheritsXforms() const
297
0
{
298
0
    return m_inherits;
299
0
}
300
301
//-*****************************************************************************
302
void XformSample::setTranslation( const Abc::V3d &iTrans )
303
0
{
304
0
    XformOp op( kTranslateOperation, kTranslateHint );
305
306
0
    for ( size_t i = 0 ; i < 3 ; ++i )
307
0
    {
308
0
        op.setChannelValue( i, iTrans[i] );
309
0
    }
310
311
0
    if ( ! m_hasBeenRead )
312
0
    {
313
0
        ABCA_ASSERT( m_setWithOpStack == 0 || m_setWithOpStack == 2,
314
0
                     "Cannot mix addOp() and set<Foo>() methods." );
315
316
0
        m_setWithOpStack = 2;
317
318
0
        m_ops.push_back( op );
319
0
    }
320
0
    else
321
0
    {
322
0
        std::size_t ret = m_opIndex;
323
324
0
        ABCA_ASSERT( m_setWithOpStack == 2,
325
0
                     "Cannot mix addOp() and set<Foo>() methods." );
326
327
0
        ABCA_ASSERT( op.getType() == m_ops[ret].getType(),
328
0
                     "Cannot update mismatched op-type in already-setted "
329
0
                     << "XformSample!" );
330
331
0
        m_ops[ret] = op;
332
0
        ++m_opIndex;
333
0
        m_opIndex = m_opIndex % m_ops.size();
334
0
    }
335
0
}
336
337
//-*****************************************************************************
338
void XformSample::setRotation( const Abc::V3d &iAxis,
339
                               const double iAngleInDegrees )
340
0
{
341
0
    XformOp op( kRotateOperation, kRotateHint );
342
343
0
    for ( size_t i = 0 ; i < 3 ; ++i )
344
0
    {
345
0
        op.setChannelValue( i, iAxis[i] );
346
0
    }
347
0
    op.setChannelValue( 3, iAngleInDegrees );
348
349
0
    if ( ! m_hasBeenRead )
350
0
    {
351
0
        ABCA_ASSERT( m_setWithOpStack == 0 || m_setWithOpStack == 2,
352
0
                     "Cannot mix addOp() and set<Foo>() methods." );
353
354
0
        m_setWithOpStack = 2;
355
356
0
        m_ops.push_back( op );
357
0
    }
358
0
    else
359
0
    {
360
0
        std::size_t ret = m_opIndex;
361
362
0
        ABCA_ASSERT( m_setWithOpStack == 2,
363
0
                     "Cannot mix addOp() and set<Foo>() methods." );
364
365
0
        ABCA_ASSERT( op.getType() == m_ops[ret].getType(),
366
0
                     "Cannot update mismatched op-type in already-setted "
367
0
                     << "XformSample!" );
368
369
0
        m_ops[ret] = op;
370
0
        ++m_opIndex;
371
0
        m_opIndex = m_opIndex % m_ops.size();
372
0
    }
373
0
}
374
375
//-*****************************************************************************
376
void XformSample::setScale( const Abc::V3d &iScale )
377
0
{
378
0
    XformOp op( kScaleOperation, kScaleHint );
379
380
0
    for ( size_t i = 0 ; i < 3 ; ++i )
381
0
    {
382
0
        op.setChannelValue( i, iScale[i] );
383
0
    }
384
385
0
    if ( ! m_hasBeenRead )
386
0
    {
387
0
        ABCA_ASSERT( m_setWithOpStack == 0 || m_setWithOpStack == 2,
388
0
                     "Cannot mix addOp() and set<Foo>() methods." );
389
390
0
        m_setWithOpStack = 2;
391
392
0
        m_ops.push_back( op );
393
0
    }
394
0
    else
395
0
    {
396
0
        std::size_t ret = m_opIndex;
397
398
0
        ABCA_ASSERT( m_setWithOpStack == 2,
399
0
                     "Cannot mix addOp() and set<Foo>() methods." );
400
401
0
        ABCA_ASSERT( op.getType() == m_ops[ret].getType(),
402
0
                     "Cannot update mismatched op-type in already-setted "
403
0
                     << "XformSample!" );
404
405
0
        m_ops[ret] = op;
406
0
        ++m_opIndex;
407
0
        m_opIndex = m_opIndex % m_ops.size();
408
0
    }
409
0
}
410
411
//-*****************************************************************************
412
void XformSample::setXRotation( const double iAngleInDegrees )
413
0
{
414
0
    XformOp op( kRotateXOperation, kRotateHint );
415
416
0
    op.setChannelValue( 0, iAngleInDegrees );
417
418
0
    if ( ! m_hasBeenRead )
419
0
    {
420
0
        ABCA_ASSERT( m_setWithOpStack == 0 || m_setWithOpStack == 2,
421
0
                     "Cannot mix addOp() and set<Foo>() methods." );
422
423
0
        m_setWithOpStack = 2;
424
425
0
        m_ops.push_back( op );
426
0
    }
427
0
    else
428
0
    {
429
0
        std::size_t ret = m_opIndex;
430
431
0
        ABCA_ASSERT( m_setWithOpStack == 2,
432
0
                     "Cannot mix addOp() and set<Foo>() methods." );
433
434
0
        ABCA_ASSERT( op.getType() == m_ops[ret].getType(),
435
0
                     "Cannot update mismatched op-type in already-setted "
436
0
                     << "XformSample!" );
437
438
0
        m_ops[ret] = op;
439
0
        ++m_opIndex;
440
0
        m_opIndex = m_opIndex % m_ops.size();
441
0
    }
442
0
}
443
444
//-*****************************************************************************
445
void XformSample::setYRotation( const double iAngleInDegrees )
446
0
{
447
0
    XformOp op( kRotateYOperation, kRotateHint );
448
449
0
    op.setChannelValue( 0, iAngleInDegrees );
450
451
0
    if ( ! m_hasBeenRead )
452
0
    {
453
0
        ABCA_ASSERT( m_setWithOpStack == 0 || m_setWithOpStack == 2,
454
0
                     "Cannot mix addOp() and set<Foo>() methods." );
455
456
0
        m_setWithOpStack = 2;
457
458
0
        m_ops.push_back( op );
459
0
    }
460
0
    else
461
0
    {
462
0
        std::size_t ret = m_opIndex;
463
464
0
        ABCA_ASSERT( m_setWithOpStack == 2,
465
0
                     "Cannot mix addOp() and set<Foo>() methods." );
466
467
0
        ABCA_ASSERT( op.getType() == m_ops[ret].getType(),
468
0
                     "Cannot update mismatched op-type in already-setted "
469
0
                     << "XformSample!" );
470
471
0
        m_ops[ret] = op;
472
0
        ++m_opIndex;
473
0
        m_opIndex = m_opIndex % m_ops.size();
474
0
    }
475
0
}
476
477
//-*****************************************************************************
478
void XformSample::setZRotation( const double iAngleInDegrees )
479
0
{
480
0
    XformOp op( kRotateZOperation, kRotateHint );
481
482
0
    op.setChannelValue( 0, iAngleInDegrees );
483
484
0
    if ( ! m_hasBeenRead )
485
0
    {
486
0
        ABCA_ASSERT( m_setWithOpStack == 0 || m_setWithOpStack == 2,
487
0
                     "Cannot mix addOp() and set<Foo>() methods." );
488
489
0
        m_setWithOpStack = 2;
490
491
0
        m_ops.push_back( op );
492
0
    }
493
0
    else
494
0
    {
495
0
        std::size_t ret = m_opIndex;
496
497
0
        ABCA_ASSERT( m_setWithOpStack == 2,
498
0
                     "Cannot mix addOp() and set<Foo>() methods." );
499
500
0
        ABCA_ASSERT( op.getType() == m_ops[ret].getType(),
501
0
                     "Cannot update mismatched op-type in already-setted "
502
0
                     << "XformSample!" );
503
504
0
        m_ops[ret] = op;
505
0
        ++m_opIndex;
506
0
        m_opIndex = m_opIndex % m_ops.size();
507
0
    }
508
0
}
509
510
//-*****************************************************************************
511
void XformSample::setMatrix( const Abc::M44d &iMatrix )
512
0
{
513
0
    XformOp op( kMatrixOperation, kMatrixHint );
514
515
0
    for ( size_t i = 0 ; i < 4 ; ++i )
516
0
    {
517
0
        for ( size_t j = 0 ; j < 4 ; ++j )
518
0
        {
519
0
            op.setChannelValue( ( i * 4 ) + j, iMatrix.x[i][j] );
520
0
        }
521
0
    }
522
523
0
    if ( ! m_hasBeenRead )
524
0
    {
525
0
        ABCA_ASSERT( m_setWithOpStack == 0 || m_setWithOpStack == 2,
526
0
                     "Cannot mix addOp() and set<Foo>() methods." );
527
528
0
        m_setWithOpStack = 2;
529
530
0
        m_ops.push_back( op );
531
0
    }
532
0
    else
533
0
    {
534
0
        std::size_t ret = m_opIndex;
535
536
0
        ABCA_ASSERT( m_setWithOpStack == 2,
537
0
                     "Cannot mix addOp() and set<Foo>() methods." );
538
539
0
        ABCA_ASSERT( op.getType() == m_ops[ret].getType(),
540
0
                     "Cannot update mismatched op-type in already-setted "
541
0
                     << "XformSample!" );
542
543
0
        m_ops[ret] = op;
544
0
        ++m_opIndex;
545
0
        m_opIndex = m_opIndex % m_ops.size();
546
0
    }
547
0
}
548
549
//-*****************************************************************************
550
Abc::M44d XformSample::getMatrix() const
551
0
{
552
0
    Abc::M44d ret;
553
0
    ret.makeIdentity();
554
555
0
    for ( std::size_t i = 0 ; i < m_ops.size() ; ++i )
556
0
    {
557
0
        Abc::M44d m;
558
0
        m.makeIdentity();
559
560
0
        XformOp op = m_ops[i];
561
562
0
        XformOperationType otype = op.getType();
563
564
0
        if ( otype == kMatrixOperation )
565
0
        {
566
0
            for ( std::size_t j = 0 ; j < 4 ; ++j )
567
0
            {
568
0
                for ( std::size_t k = 0 ; k < 4 ; ++k )
569
0
                {
570
0
                    m.x[j][k] = op.getChannelValue( ( 4 * j ) + k );
571
0
                }
572
0
            }
573
0
        }
574
0
        else if ( otype == kRotateXOperation )
575
0
        {
576
0
            m.setAxisAngle( Abc::V3d( 1.0, 0.0, 0.0 ),
577
0
                            DegreesToRadians( op.getChannelValue( 0 ) ) );
578
0
        }
579
0
        else if ( otype == kRotateYOperation )
580
0
        {
581
0
            m.setAxisAngle( Abc::V3d( 0.0, 1.0, 0.0 ),
582
0
                            DegreesToRadians( op.getChannelValue( 0 ) ) );
583
0
        }
584
0
        else if ( otype == kRotateZOperation )
585
0
        {
586
0
            m.setAxisAngle( Abc::V3d( 0.0, 0.0, 1.0 ),
587
0
                            DegreesToRadians( op.getChannelValue( 0 ) ) );
588
0
        }
589
0
        else
590
0
        {
591
0
            Abc::V3d vec( op.getChannelValue( 0 ),
592
0
                          op.getChannelValue( 1 ),
593
0
                          op.getChannelValue( 2 ) );
594
595
0
            if ( otype == kScaleOperation )
596
0
            {
597
0
                m.setScale( vec );
598
0
            }
599
0
            else if ( otype == kTranslateOperation )
600
0
            {
601
0
                m.setTranslation( vec );
602
0
            }
603
0
            else if ( otype == kRotateOperation )
604
0
            {
605
0
                m.setAxisAngle( vec,
606
0
                                DegreesToRadians( op.getChannelValue( 3 ) ) );
607
0
            }
608
609
0
        }
610
0
        ret = m * ret;
611
0
    }
612
613
0
    return ret;
614
0
}
615
616
//-*****************************************************************************
617
Abc::V3d XformSample::getTranslation() const
618
0
{
619
0
    Abc::M44d m = this->getMatrix();
620
0
    return m.translation();
621
0
}
622
623
//-*****************************************************************************
624
Abc::V3d XformSample::getScale() const
625
0
{
626
0
    Abc::V3d scl;
627
0
    Imath::extractScaling( this->getMatrix(), scl );
628
0
    return scl;
629
0
}
630
631
//-*****************************************************************************
632
Abc::V3d XformSample::getAxis() const
633
0
{
634
0
    Imath::Quatd q = Imath::extractQuat( this->getMatrix() );
635
636
0
    return q.axis();
637
0
}
638
639
//-*****************************************************************************
640
double XformSample::getAngle() const
641
0
{
642
0
    Imath::Quatd q = Imath::extractQuat( this->getMatrix() );
643
644
0
    return RadiansToDegrees( q.angle() );
645
0
}
646
647
//-*****************************************************************************
648
double XformSample::getXRotation() const
649
0
{
650
0
    Abc::V3d rot;
651
0
    Imath::extractEulerXYZ( this->getMatrix(), rot );
652
653
0
    return RadiansToDegrees( rot[0] );
654
0
}
655
656
//-*****************************************************************************
657
double XformSample::getYRotation() const
658
0
{
659
0
    Abc::V3d rot;
660
0
    Imath::extractEulerXYZ( this->getMatrix(), rot );
661
662
0
    return RadiansToDegrees( rot[1] );
663
0
}
664
665
//-*****************************************************************************
666
double XformSample::getZRotation() const
667
0
{
668
0
    Abc::V3d rot;
669
0
    Imath::extractEulerXYZ( this->getMatrix(), rot );
670
671
0
    return RadiansToDegrees( rot[2] );
672
0
}
673
674
//-*****************************************************************************
675
void XformSample::freezeTopology()
676
0
{
677
0
    m_hasBeenRead = true;
678
0
}
679
680
//-*****************************************************************************
681
void XformSample::clear()
682
0
{
683
0
    m_hasBeenRead = false;
684
0
    m_ops.resize( 0 );
685
0
    m_setWithOpStack = 0;
686
0
    m_opIndex = 0;
687
0
    m_inherits = true;
688
0
}
689
690
//-*****************************************************************************
691
void XformSample::reset()
692
0
{
693
0
    this->clear();
694
0
}
695
696
//-*****************************************************************************
697
bool XformSample::isTopologyEqual( const XformSample & iSample )
698
0
{
699
0
    if (getNumOps() != iSample.getNumOps())
700
0
    {
701
0
        return false;
702
0
    }
703
704
0
    std::vector<XformOp>::const_iterator opA, opB;
705
0
    for ( opA = m_ops.begin(), opB = iSample.m_ops.begin(); opA != m_ops.end();
706
0
          ++opA, ++opB )
707
0
    {
708
0
        if ( opA->getType() != opB->getType() )
709
0
        {
710
0
            return false;
711
0
        }
712
0
    }
713
714
0
    return true;
715
0
}
716
717
} // End namespace ALEMBIC_VERSION_NS
718
} // End namespace AbcGeom
719
} // End namespace Alembic