Coverage Report

Created: 2023-09-25 06:10

/src/alembic/lib/Alembic/AbcMaterial/IMaterial.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
38
#include <Alembic/AbcMaterial/IMaterial.h>
39
#include "InternalUtil.h"
40
41
#include <set>
42
43
namespace Alembic {
44
namespace AbcMaterial {
45
namespace ALEMBIC_VERSION_NS {
46
47
void IMaterialSchema::init()
48
0
{
49
0
    ALEMBIC_ABC_SAFE_CALL_BEGIN( "IMaterialSchema::init()" );
50
51
0
    AbcCoreAbstract::CompoundPropertyReaderPtr _this = this->getPtr();
52
53
0
    if ( this->getPropertyHeader( ".nodes" ) != NULL )
54
0
    {
55
0
        m_node = Abc::ICompoundProperty( _this, ".nodes" );
56
0
    }
57
58
0
    if ( this->getPropertyHeader( ".interfaceParams" ) != NULL )
59
0
    {
60
0
        m_interfaceParams = Abc::ICompoundProperty( _this, ".interfaceParams" );
61
0
    }
62
63
0
    if ( this->getPropertyHeader( ".terminals" ) != NULL )
64
0
    {
65
0
        Abc::IStringArrayProperty termProp( _this, ".terminals" );
66
0
        Abc::StringArraySamplePtr samp;
67
0
        termProp.get( samp );
68
69
0
        size_t numTerms = samp->size() / 2;
70
0
        for( size_t i = 0; i < numTerms; ++i )
71
0
        {
72
0
            m_terminals[( *samp )[2 * i]] = ( *samp )[2 * i + 1];
73
0
        }
74
0
    }
75
76
0
    if ( this->getPropertyHeader( ".shaderNames" ) != NULL )
77
0
    {
78
0
        Abc::IStringArrayProperty shaderProp( _this, ".shaderNames" );
79
0
        Abc::StringArraySamplePtr samp;
80
0
        shaderProp.get( samp );
81
82
0
        size_t numShaders = samp->size() / 2;
83
0
        for( size_t i = 0; i < numShaders; ++i )
84
0
        {
85
0
            m_shaderNames[( *samp )[2 * i]] = ( *samp )[2 * i + 1];
86
0
        }
87
0
    }
88
89
0
    if ( this->getPropertyHeader( ".interface" ) != NULL )
90
0
    {
91
0
        Abc::IStringArrayProperty interfaceProp( _this, ".interface" );
92
0
        Abc::StringArraySamplePtr samp;
93
0
        interfaceProp.get( samp );
94
95
0
        size_t numInterface = samp->size() / 2;
96
0
        m_interface.reserve( numInterface );
97
0
        for( size_t i = 0; i < numInterface; ++i )
98
0
        {
99
0
            m_interfaceMap[( *samp )[2 * i]] = ( *samp )[2 * i + 1];
100
0
            m_interface.push_back( ( *samp )[2 * i] );
101
0
        }
102
0
    }
103
0
    ALEMBIC_ABC_SAFE_CALL_END_RESET();
104
0
}
105
106
void IMaterialSchema::getTargetNames( std::vector<std::string> & oTargetNames )
107
0
{
108
0
    ALEMBIC_ABC_SAFE_CALL_BEGIN( "IMaterial::getTargetNames" );
109
0
    std::set<std::string> uniqueNames;
110
111
0
    std::vector<std::string> tokens;
112
113
0
    std::map<std::string, std::string>::iterator i;
114
0
    for ( i = m_shaderNames.begin(); i != m_shaderNames.end(); ++i )
115
0
    {
116
0
        Util::split_tokens( i->first, tokens );
117
118
        // target.shaderType
119
0
        if ( tokens.size() == 2 )
120
0
        {
121
0
            uniqueNames.insert( tokens[0] );
122
0
        }
123
0
    }
124
125
0
    oTargetNames.clear();
126
0
    oTargetNames.reserve( uniqueNames.size() );
127
0
    oTargetNames.insert( oTargetNames.end(), uniqueNames.begin(),
128
0
                         uniqueNames.end() );
129
130
0
    ALEMBIC_ABC_SAFE_CALL_END_RESET();
131
0
}
132
133
134
void IMaterialSchema::getShaderTypesForTarget( const std::string & iTargetName,
135
    std::vector<std::string> & oShaderTypeNames )
136
0
{
137
0
    ALEMBIC_ABC_SAFE_CALL_BEGIN( "IMaterialSchema::getShaderTypesForTarget" );
138
0
    std::set<std::string> uniqueNames;
139
140
0
    std::vector<std::string> tokens;
141
142
0
    std::map<std::string, std::string>::iterator i;
143
0
    for ( i = m_shaderNames.begin(); i != m_shaderNames.end(); ++i )
144
0
    {
145
0
        Util::split_tokens( i->first, tokens );
146
147
0
        if ( tokens.size() == 2 )
148
0
        {
149
0
            if ( tokens[0] == iTargetName )
150
0
            {
151
0
                uniqueNames.insert( tokens[1] );
152
0
            }
153
0
        }
154
0
    }
155
156
0
    oShaderTypeNames.clear();
157
0
    oShaderTypeNames.reserve( uniqueNames.size() );
158
0
    oShaderTypeNames.insert( oShaderTypeNames.end(),
159
0
            uniqueNames.begin(), uniqueNames.end() );
160
0
    ALEMBIC_ABC_SAFE_CALL_END_RESET();
161
0
}
162
163
bool IMaterialSchema::getShader( const std::string & iTarget,
164
                                 const std::string & iShaderType,
165
                                 std::string & oResult )
166
0
{
167
0
    ALEMBIC_ABC_SAFE_CALL_BEGIN( "IMaterialSchema::getShader" );
168
0
    std::string propName = Util::buildTargetName( iTarget, iShaderType, "" );
169
170
0
    std::map<std::string, std::string>::iterator i =
171
0
        m_shaderNames.find( propName );
172
173
0
    if ( i != m_shaderNames.end() )
174
0
    {
175
0
        oResult = i->second;
176
0
        return true;
177
0
    }
178
179
0
    ALEMBIC_ABC_SAFE_CALL_END_RESET();
180
0
    return false;
181
0
}
182
183
184
Abc::ICompoundProperty IMaterialSchema::getShaderParameters(
185
        const std::string & iTarget,
186
        const std::string & iShaderType )
187
0
{
188
0
    Abc::ICompoundProperty result;
189
190
0
    ALEMBIC_ABC_SAFE_CALL_BEGIN( "IMaterialSchema::getShaderParameters" );
191
0
    std::string propName = Util::buildTargetName( iTarget, iShaderType,
192
0
                                                  "params" );
193
194
0
    if (const AbcCoreAbstract::PropertyHeader * header =
195
0
        getPropertyHeader( propName ) )
196
0
    {
197
0
        if ( header->isCompound() )
198
0
        {
199
0
            result = Abc::ICompoundProperty( *this, propName );
200
0
        }
201
0
    }
202
0
    ALEMBIC_ABC_SAFE_CALL_END_RESET();
203
204
0
    return result;
205
0
}
206
207
size_t IMaterialSchema::getNumNetworkNodes()
208
0
{
209
0
    ALEMBIC_ABC_SAFE_CALL_BEGIN( "IMaterialSchema::getNumNetworkNodes" );
210
0
    if ( m_node.valid() )
211
0
    {
212
0
        return m_node.getNumProperties();
213
0
    }
214
0
    ALEMBIC_ABC_SAFE_CALL_END_RESET();
215
216
0
    return 0;
217
0
}
218
219
void IMaterialSchema::getNetworkNodeNames( std::vector<std::string> & oNames )
220
0
{
221
0
    ALEMBIC_ABC_SAFE_CALL_BEGIN( "IMateriaSchema::getNetworkNodeNames" );
222
0
    oNames.clear();
223
224
0
    if ( !m_node.valid() )
225
0
    {
226
0
        return;
227
0
    }
228
229
0
    oNames.reserve( m_node.getNumProperties() );
230
231
0
    for ( size_t i = 0, e = m_node.getNumProperties(); i < e; ++i )
232
0
    {
233
0
        const AbcCoreAbstract::PropertyHeader &header =
234
0
            m_node.getPropertyHeader( i );
235
236
0
        if ( header.isCompound() )
237
0
        {
238
0
            oNames.push_back( header.getName() );
239
0
        }
240
0
    }
241
0
    ALEMBIC_ABC_SAFE_CALL_END_RESET();
242
0
}
243
244
IMaterialSchema::NetworkNode IMaterialSchema::getNetworkNode( size_t iIndex )
245
0
{
246
0
    ALEMBIC_ABC_SAFE_CALL_BEGIN( "IMateriaSchema::getNetworkNode" );
247
0
    if ( !m_node.valid() || iIndex >= m_node.getNumProperties() )
248
0
    {
249
0
        return NetworkNode();
250
0
    }
251
252
0
    const AbcCoreAbstract::PropertyHeader &header =
253
0
        m_node.getPropertyHeader( iIndex );
254
255
0
    if ( !header.isCompound() )
256
0
    {
257
0
        return NetworkNode();
258
0
    }
259
260
0
    return NetworkNode(
261
0
            Abc::ICompoundProperty( m_node, header.getName() ) );
262
0
    ALEMBIC_ABC_SAFE_CALL_END_RESET();
263
264
0
    return NetworkNode();
265
0
}
266
267
268
IMaterialSchema::NetworkNode IMaterialSchema::getNetworkNode(
269
    const std::string & iNodeName )
270
0
{
271
0
    return NetworkNode( m_node, iNodeName );
272
0
}
273
274
275
void IMaterialSchema::getNetworkTerminalTargetNames(
276
    std::vector<std::string> & oTargetNames )
277
0
{
278
0
    ALEMBIC_ABC_SAFE_CALL_BEGIN(
279
0
        "IMateriaSchema::getNetworkTerminalTargetNames" );
280
0
    oTargetNames.clear();
281
282
0
    std::set<std::string> uniqueNames;
283
284
0
    std::vector<std::string> tokens;
285
0
    std::map<std::string, std::string>::iterator i;
286
0
    for ( i = m_terminals.begin(); i != m_terminals.end(); ++i )
287
0
    {
288
0
        Util::split_tokens( i->first, tokens );
289
290
        // target.shaderType
291
0
        if ( tokens.size() == 2 )
292
0
        {
293
0
            uniqueNames.insert( tokens[0] );
294
0
        }
295
0
    }
296
297
0
    oTargetNames.reserve( uniqueNames.size() );
298
0
    oTargetNames.insert( oTargetNames.end(),
299
0
            uniqueNames.begin(), uniqueNames.end() );
300
0
    ALEMBIC_ABC_SAFE_CALL_END_RESET();
301
0
}
302
303
void IMaterialSchema::getNetworkTerminalShaderTypesForTarget(
304
    const std::string & iTargetName,
305
    std::vector<std::string> & oShaderTypeNames)
306
0
{
307
0
    ALEMBIC_ABC_SAFE_CALL_BEGIN(
308
0
        "IMateriaSchema::getNetworkTerminalShaderTypesForTarget" );
309
310
0
    oShaderTypeNames.clear();
311
312
0
    std::set<std::string> uniqueNames;
313
314
0
    std::vector<std::string> tokens;
315
0
    std::map<std::string, std::string>::iterator i;
316
0
    for ( i = m_terminals.begin(); i != m_terminals.end(); ++i )
317
0
    {
318
0
        Util::split_tokens( i->first, tokens );
319
320
0
        if ( tokens.size() == 2 )
321
0
        {
322
0
            if ( tokens[0] == iTargetName )
323
0
            {
324
0
                uniqueNames.insert( tokens[1] );
325
0
            }
326
0
        }
327
0
    }
328
329
0
    oShaderTypeNames.reserve( uniqueNames.size() );
330
0
    oShaderTypeNames.insert( oShaderTypeNames.end(),
331
0
        uniqueNames.begin(), uniqueNames.end() );
332
333
0
    ALEMBIC_ABC_SAFE_CALL_END_RESET();
334
0
}
335
336
bool IMaterialSchema::getNetworkTerminal(
337
        const std::string & iTarget,
338
        const std::string & iShaderType,
339
        std::string & oNodeName,
340
        std::string & oOutputName)
341
0
{
342
0
    ALEMBIC_ABC_SAFE_CALL_BEGIN(
343
0
        "IMateriaSchema::getNetworkTerminal" );
344
345
0
    std::string propName = iTarget + "." + iShaderType;
346
347
0
    std::map<std::string, std::string>::iterator i =
348
0
        m_terminals.find( propName );
349
350
0
    if ( i == m_terminals.end() )
351
0
    {
352
0
        return false;
353
0
    }
354
355
0
    std::vector<std::string> tokens;
356
0
    Util::split_tokens( i->second, tokens, 1 );
357
358
0
    oNodeName = tokens[0];
359
0
    oOutputName = tokens.size() > 1 ? tokens[1] : "";
360
361
0
    return true;
362
0
    ALEMBIC_ABC_SAFE_CALL_END_RESET();
363
364
0
    return false;
365
0
}
366
367
size_t IMaterialSchema::getNumNetworkInterfaceParameterMappings()
368
0
{
369
0
    return m_interface.size();
370
0
}
371
372
373
bool IMaterialSchema::getNetworkInterfaceParameterMapping( size_t iIndex,
374
    std::string & oInterfaceParamName, std::string & oMapToNodeName,
375
    std::string & oMapToParamName )
376
0
{
377
0
    ALEMBIC_ABC_SAFE_CALL_BEGIN(
378
0
        "IMateriaSchema::getNetworkInterfaceParameterMapping(size_t,...)" );
379
380
0
    if ( iIndex >= m_interface.size() )
381
0
    {
382
0
        return false;
383
0
    }
384
385
0
    oInterfaceParamName = m_interface[iIndex];
386
387
0
    return getNetworkInterfaceParameterMapping( oInterfaceParamName,
388
0
                                                oMapToNodeName,
389
0
                                                oMapToParamName );
390
0
    ALEMBIC_ABC_SAFE_CALL_END_RESET();
391
392
0
    return false;
393
0
}
394
395
396
397
398
void IMaterialSchema::getNetworkInterfaceParameterMappingNames(
399
    std::vector<std::string> & oNames )
400
0
{
401
0
    oNames = m_interface;
402
0
}
403
404
405
bool IMaterialSchema::getNetworkInterfaceParameterMapping(
406
    const std::string & iInterfaceParamName,
407
    std::string & oMapToNodeName,
408
    std::string & oMapToParamName )
409
0
{
410
0
    ALEMBIC_ABC_SAFE_CALL_BEGIN(
411
0
        "IMateriaSchema::getNetworkInterfaceParameterMapping" );
412
413
0
    std::map<std::string, std::string>::iterator i =
414
0
        m_interfaceMap.find( iInterfaceParamName );
415
416
0
    if ( i == m_interfaceMap.end() )
417
0
    {
418
0
        return false;
419
0
    }
420
421
0
    std::vector<std::string> tokens;
422
423
0
    Util::split_tokens( i->second, tokens, 1 );
424
425
0
    oMapToNodeName = tokens[0];
426
0
    oMapToParamName = tokens.size() > 1 ? tokens[1] : "";
427
428
0
    return true;
429
0
    ALEMBIC_ABC_SAFE_CALL_END_RESET();
430
431
0
    return false;
432
0
}
433
434
Abc::ICompoundProperty IMaterialSchema::getNetworkInterfaceParameters()
435
0
{
436
0
    return m_interfaceParams;
437
0
}
438
439
440
///////////////////////////////////////////////////////////////////////////////
441
442
IMaterialSchema::NetworkNode::NetworkNode()
443
: m_connectionsChecked( false )
444
0
{
445
0
}
446
447
448
IMaterialSchema::NetworkNode::NetworkNode( Abc::ICompoundProperty iCompound )
449
: m_compound( iCompound )
450
, m_connectionsChecked( false )
451
0
{
452
0
}
453
454
455
IMaterialSchema::NetworkNode::NetworkNode( Abc::ICompoundProperty iParent,
456
                                           const std::string & iNodeName )
457
: m_connectionsChecked( false )
458
0
{
459
0
    if ( iParent.valid() )
460
0
    {
461
0
        if ( const AbcCoreAbstract::PropertyHeader * header =
462
0
            iParent.getPropertyHeader( iNodeName ) )
463
0
        {
464
0
            if ( header->isCompound() )
465
0
            {
466
0
                m_compound =  Abc::ICompoundProperty( iParent, iNodeName );
467
0
            }
468
0
        }
469
0
    }
470
0
}
471
472
bool IMaterialSchema::NetworkNode::valid()
473
0
{
474
0
    return m_compound.valid();
475
0
}
476
477
478
std::string IMaterialSchema::NetworkNode::getName()
479
0
{
480
0
    if ( valid() )
481
0
    {
482
0
        return m_compound.getName();
483
0
    }
484
485
0
    return "";
486
0
}
487
488
489
bool IMaterialSchema::NetworkNode::getTarget( std::string & oResult )
490
0
{
491
0
    if ( !valid() )
492
0
    {
493
0
        return false;
494
0
    }
495
496
0
    if ( const AbcCoreAbstract::PropertyHeader * header =
497
0
        m_compound.getPropertyHeader( "target" ) )
498
0
    {
499
0
        if ( header->isScalar() && Abc::IStringProperty::matches( *header) )
500
0
        {
501
0
            Abc::IStringProperty prop( m_compound, header->getName() );
502
503
0
            oResult = prop.getValue();
504
0
            return true;
505
0
        }
506
0
    }
507
508
0
    return false;
509
0
}
510
511
bool IMaterialSchema::NetworkNode::getNodeType( std::string & oResult )
512
0
{
513
0
    if ( !valid() )
514
0
    {
515
0
        return false;
516
0
    }
517
518
0
    if ( const AbcCoreAbstract::PropertyHeader * header =
519
0
        m_compound.getPropertyHeader( "type" ) )
520
0
    {
521
0
        if ( header->isScalar() && Abc::IStringProperty::matches( *header ) )
522
0
        {
523
0
            Abc::IStringProperty prop( m_compound, header->getName() );
524
525
0
            oResult = prop.getValue();
526
0
            return true;
527
0
        }
528
0
    }
529
530
0
    return false;
531
0
}
532
533
Abc::ICompoundProperty IMaterialSchema::NetworkNode::getParameters()
534
0
{
535
0
    Abc::ICompoundProperty result;
536
0
    if ( !valid() )
537
0
    {
538
0
        return result;
539
0
    }
540
541
0
    if (const AbcCoreAbstract::PropertyHeader * header =
542
0
        m_compound.getPropertyHeader( "params" ) )
543
0
    {
544
0
        if ( header->isCompound() )
545
0
        {
546
0
            result = Abc::ICompoundProperty( m_compound, "params" );
547
0
        }
548
0
    }
549
550
0
    return result;
551
0
}
552
553
size_t IMaterialSchema::NetworkNode::getNumConnections()
554
0
{
555
0
    if ( ! m_connectionsChecked )
556
0
    {
557
0
        if ( m_compound.getPropertyHeader( ".connections" ) != NULL )
558
0
        {
559
0
            Abc::IStringArrayProperty connectProp( m_compound, ".connections" );
560
0
            Abc::StringArraySamplePtr samp;
561
0
            connectProp.get( samp );
562
563
0
            size_t numConnect = samp->size() / 2;
564
0
            m_connections.reserve( numConnect );
565
0
            for( size_t i = 0; i < numConnect; ++i )
566
0
            {
567
0
                m_connectionsMap[( *samp )[2 * i]] = ( *samp )[2 * i + 1];
568
0
                m_connections.push_back( ( *samp )[2 * i] );
569
0
            }
570
0
        }
571
0
        m_connectionsChecked = true;
572
0
    }
573
574
0
    return m_connections.size();
575
576
0
}
577
578
void IMaterialSchema::NetworkNode::splitConnectionValue( const std::string & v,
579
    std::string & a, std::string & b )
580
0
{
581
0
    std::vector<std::string> tokens;
582
583
0
    Util::split_tokens(v, tokens, 1);
584
585
0
    a = tokens[0];
586
0
    b = tokens.size() > 1 ? tokens[1] : "";
587
0
}
588
589
bool IMaterialSchema::NetworkNode::getConnection(
590
    size_t iIndex,
591
    std::string & oInputName,
592
    std::string & oConnectedNodeName,
593
    std::string & oConnectedOutputName )
594
0
{
595
0
    if ( iIndex >= getNumConnections() )
596
0
    {
597
0
        return false;
598
0
    }
599
600
0
    oInputName = m_connections[iIndex];
601
0
    return getConnection( oInputName, oConnectedNodeName,
602
0
        oConnectedOutputName );
603
0
}
604
605
bool IMaterialSchema::NetworkNode::getConnection(
606
    const std::string & iInputName,
607
    std::string & oConnectedNodeName,
608
    std::string & oConnectedOutputName )
609
0
{
610
    // loads the connections if it hasn't already
611
0
    getNumConnections();
612
613
0
    std::map< std::string, std::string >::iterator i =
614
0
        m_connectionsMap.find( iInputName );
615
616
0
    if ( i == m_connectionsMap.end() )
617
0
    {
618
0
        return false;
619
0
    }
620
621
0
    std::string value = i->second;
622
0
    splitConnectionValue( value, oConnectedNodeName, oConnectedOutputName );
623
624
0
    return true;
625
0
}
626
627
} // End namespace ALEMBIC_VERSION_NS
628
} // End namespace AbcMaterial
629
} // End namespace Alembic
630