Coverage Report

Created: 2026-05-16 06:12

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/alembic/lib/Alembic/AbcGeom/IPolyMesh.cpp
Line
Count
Source
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/IPolyMesh.h>
38
39
namespace Alembic {
40
namespace AbcGeom {
41
namespace ALEMBIC_VERSION_NS {
42
43
//-*****************************************************************************
44
MeshTopologyVariance IPolyMeshSchema::getTopologyVariance() const
45
0
{
46
0
    ALEMBIC_ABC_SAFE_CALL_BEGIN( "IPolyMeshSchema::getTopologyVariance()" );
47
48
0
    if ( m_indicesProperty.isConstant() && m_countsProperty.isConstant() )
49
0
    {
50
0
        if ( m_positionsProperty.isConstant() )
51
0
        {
52
0
            return kConstantTopology;
53
0
        }
54
0
        else
55
0
        {
56
0
            return kHomogenousTopology;
57
0
        }
58
0
    }
59
0
    else
60
0
    {
61
0
        return kHeterogenousTopology;
62
0
    }
63
64
0
    ALEMBIC_ABC_SAFE_CALL_END();
65
66
    // Not all error handlers throw
67
0
    return kConstantTopology;
68
0
}
69
70
//-*****************************************************************************
71
void IPolyMeshSchema::init( const Abc::Argument &iArg0,
72
                            const Abc::Argument &iArg1 )
73
0
{
74
0
    ALEMBIC_ABC_SAFE_CALL_BEGIN( "IPolyMeshSchema::init()" );
75
76
0
    Abc::Arguments args;
77
0
    iArg0.setInto( args );
78
0
    iArg1.setInto( args );
79
80
0
    AbcA::CompoundPropertyReaderPtr _this = this->getPtr();
81
82
    // no matching so we pick up old assets written as V3f
83
0
    m_positionsProperty = Abc::IP3fArrayProperty( _this, "P", kNoMatching,
84
0
        args.getErrorHandlerPolicy() );
85
86
0
    m_indicesProperty = Abc::IInt32ArrayProperty( _this, ".faceIndices",
87
0
                                                  iArg0, iArg1 );
88
0
    m_countsProperty = Abc::IInt32ArrayProperty( _this, ".faceCounts",
89
0
                                                 iArg0, iArg1 );
90
91
    // none of the things below here are guaranteed to exist
92
0
    if ( this->getPropertyHeader( "uv" ) != NULL )
93
0
    {
94
0
        m_uvsParam = IV2fGeomParam( _this, "uv", iArg0, iArg1 );
95
0
    }
96
97
0
    if ( this->getPropertyHeader( "N" ) != NULL )
98
0
    {
99
0
        m_normalsParam = IN3fGeomParam( _this, "N", iArg0, iArg1 );
100
0
    }
101
102
0
    if ( this->getPropertyHeader( ".velocities" ) != NULL )
103
0
    {
104
0
        m_velocitiesProperty = Abc::IV3fArrayProperty( _this, ".velocities",
105
0
                                                       iArg0, iArg1 );
106
0
    }
107
108
0
    m_faceSetsLoaded = false;
109
110
0
    ALEMBIC_ABC_SAFE_CALL_END_RESET();
111
0
}
112
113
//-*****************************************************************************
114
const IPolyMeshSchema &
115
IPolyMeshSchema::operator=(const IPolyMeshSchema & rhs)
116
0
{
117
0
    IGeomBaseSchema<PolyMeshSchemaInfo>::operator=(rhs);
118
119
0
    m_positionsProperty = rhs.m_positionsProperty;
120
0
    m_velocitiesProperty = rhs.m_velocitiesProperty;
121
0
    m_indicesProperty   = rhs.m_indicesProperty;
122
0
    m_countsProperty    = rhs.m_countsProperty;
123
124
0
    m_uvsParam          = rhs.m_uvsParam;
125
0
    m_normalsParam      = rhs.m_normalsParam;
126
127
    // lock, reset
128
0
    Alembic::Util::scoped_lock l(m_faceSetsMutex);
129
0
    m_faceSetsLoaded = false;
130
0
    m_faceSets.clear ();
131
132
0
    return *this;
133
0
}
134
135
//-*****************************************************************************
136
void IPolyMeshSchema::loadFaceSetNames()
137
0
{
138
    // Caller must ensure they have locked m_faceSetsMutex.
139
    // (allows us to use non-recursive mutex)
140
0
    ALEMBIC_ABC_SAFE_CALL_BEGIN( "IPolyMeshSchema::loadFaceSetNames()" );
141
142
0
    if (!m_faceSetsLoaded)
143
0
    {
144
        // iterate over childHeaders, and if header matches
145
        // FaceSet add to our vec
146
0
        IObject _thisObject = getObject();
147
148
0
        size_t numChildren = _thisObject.getNumChildren();
149
0
        for ( size_t childIndex = 0 ; childIndex < numChildren; childIndex++ )
150
0
        {
151
0
            ObjectHeader const & header = _thisObject.getChildHeader (childIndex);
152
0
            if ( IFaceSet::matches( header ) )
153
0
            {
154
                // start out with an empty (invalid IFaceSet)
155
                // accessor later on will create real IFaceSet object.
156
0
                m_faceSets [header.getName ()] = IFaceSet ();
157
0
            }
158
0
        }
159
0
        m_faceSetsLoaded = true;
160
0
    }
161
162
0
    ALEMBIC_ABC_SAFE_CALL_END();
163
0
}
164
165
//-*****************************************************************************
166
void IPolyMeshSchema::getFaceSetNames( std::vector<std::string> &oFaceSetNames )
167
0
{
168
0
    ALEMBIC_ABC_SAFE_CALL_BEGIN( "IPolyMeshSchema::getFaceSetNames()" );
169
170
0
    Alembic::Util::scoped_lock l(m_faceSetsMutex);
171
0
    loadFaceSetNames();
172
173
0
    for ( std::map<std::string, IFaceSet>::const_iterator faceSetIter =
174
0
              m_faceSets.begin(); faceSetIter != m_faceSets.end();
175
0
          ++faceSetIter )
176
0
    {
177
0
        oFaceSetNames.push_back( faceSetIter->first );
178
0
    }
179
180
0
    ALEMBIC_ABC_SAFE_CALL_END();
181
0
}
182
183
//-*****************************************************************************
184
bool
185
IPolyMeshSchema::hasFaceSet( const std::string &iFaceSetName )
186
0
{
187
0
    ALEMBIC_ABC_SAFE_CALL_BEGIN( "IPolyMeshSchema::hasFaceSet (iFaceSetName)" );
188
189
0
    Alembic::Util::scoped_lock l(m_faceSetsMutex);
190
0
    if (!m_faceSetsLoaded)
191
0
    {
192
0
        loadFaceSetNames();
193
0
    }
194
195
0
    return (m_faceSets.find (iFaceSetName) != m_faceSets.end ());
196
197
0
    ALEMBIC_ABC_SAFE_CALL_END();
198
199
0
    return false;
200
0
}
201
202
//-*****************************************************************************
203
IFaceSet
204
IPolyMeshSchema::getFaceSet ( const std::string &iFaceSetName )
205
0
{
206
0
    ALEMBIC_ABC_SAFE_CALL_BEGIN( "IPolyMeshSchema::getFaceSet()" );
207
0
    Alembic::Util::scoped_lock l(m_faceSetsMutex);
208
0
    if (!m_faceSetsLoaded)
209
0
    {
210
0
        loadFaceSetNames();
211
0
    }
212
213
0
    ABCA_ASSERT( m_faceSets.find (iFaceSetName) != m_faceSets.end (),
214
0
        "The requested FaceSet name can't be found in PolyMesh.");
215
216
0
    if (!m_faceSets [iFaceSetName])
217
0
    {
218
0
        IObject thisObject = getObject();
219
        // We haven't yet loaded the faceSet, so create/load it
220
0
        m_faceSets [iFaceSetName] = IFaceSet ( thisObject, iFaceSetName );
221
0
    }
222
223
0
    return m_faceSets [iFaceSetName];
224
225
0
    ALEMBIC_ABC_SAFE_CALL_END();
226
227
0
    IFaceSet emptyFaceSet;
228
0
    return emptyFaceSet;
229
0
}
230
231
232
} // End namespace ALEMBIC_VERSION_NS
233
} // End namespace AbcGeom
234
} // End namespace Alembic