Coverage Report

Created: 2026-04-01 06:27

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/assimp/code/Common/scene.cpp
Line
Count
Source
1
/*
2
---------------------------------------------------------------------------
3
Open Asset Import Library (assimp)
4
---------------------------------------------------------------------------
5
6
Copyright (c) 2006-2026, assimp team
7
8
All rights reserved.
9
10
Redistribution and use of this software in source and binary forms,
11
with or without modification, are permitted provided that the following
12
conditions are met:
13
14
* Redistributions of source code must retain the above
15
copyright notice, this list of conditions and the
16
following disclaimer.
17
18
* Redistributions in binary form must reproduce the above
19
copyright notice, this list of conditions and the
20
following disclaimer in the documentation and/or other
21
materials provided with the distribution.
22
23
* Neither the name of the assimp team, nor the names of its
24
contributors may be used to endorse or promote products
25
derived from this software without specific prior
26
written permission of the assimp team.
27
28
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39
---------------------------------------------------------------------------
40
*/
41
#include <assimp/scene.h>
42
43
#include "ScenePrivate.h"
44
45
aiScene::aiScene() :
46
402
        mFlags(0),
47
402
        mRootNode(nullptr),
48
402
        mNumMeshes(0),
49
402
        mMeshes(nullptr),
50
402
        mNumMaterials(0),
51
402
        mMaterials(nullptr),
52
402
        mNumAnimations(0),
53
402
        mAnimations(nullptr),
54
402
        mNumTextures(0),
55
402
        mTextures(nullptr),
56
402
        mNumLights(0),
57
402
        mLights(nullptr),
58
402
        mNumCameras(0),
59
402
        mCameras(nullptr),
60
402
        mMetaData(nullptr),
61
402
        mName(),
62
402
        mNumSkeletons(0),
63
402
        mSkeletons(nullptr),
64
402
        mPrivate(new Assimp::ScenePrivateData()) {
65
    // empty
66
402
}
67
68
402
aiScene::~aiScene() {
69
    // delete all sub-objects recursively
70
402
    delete mRootNode;
71
72
    // To make sure we won't crash if the data is invalid it's
73
    // much better to check whether both mNumXXX and mXXX are
74
    // valid instead of relying on just one of them.
75
402
    if (mNumMeshes && mMeshes) {
76
1.09k
        for (unsigned int a = 0; a < mNumMeshes; ++a) {
77
936
            delete mMeshes[a];
78
936
        }
79
159
    }
80
402
    delete[] mMeshes;
81
82
402
    if (mNumMaterials && mMaterials) {
83
495
        for (unsigned int a = 0; a < mNumMaterials; ++a) {
84
336
            delete mMaterials[a];
85
336
        }
86
159
    }
87
402
    delete[] mMaterials;
88
89
402
    if (mNumAnimations && mAnimations) {
90
430
        for (unsigned int a = 0; a < mNumAnimations; ++a) {
91
215
            delete mAnimations[a];
92
215
        }
93
215
    }
94
402
    delete[] mAnimations;
95
96
402
    if (mNumTextures && mTextures) {
97
12
        for (unsigned int a = 0; a < mNumTextures; ++a) {
98
6
            delete mTextures[a];
99
6
        }
100
6
    }
101
402
    delete[] mTextures;
102
103
402
    if (mNumLights && mLights) {
104
544
        for (unsigned int a = 0; a < mNumLights; ++a) {
105
272
            delete mLights[a];
106
272
        }
107
272
    }
108
402
    delete[] mLights;
109
110
402
    if (mNumCameras && mCameras) {
111
572
        for (unsigned int a = 0; a < mNumCameras; ++a) {
112
286
            delete mCameras[a];
113
286
        }
114
286
    }
115
402
    delete[] mCameras;
116
117
402
    aiMetadata::Dealloc(mMetaData);
118
119
402
    delete[] mSkeletons;
120
121
402
    delete static_cast<Assimp::ScenePrivateData *>(mPrivate);
122
402
}
123
124
aiNode::aiNode() :
125
6.72k
        mName(""),
126
6.72k
        mParent(nullptr),
127
6.72k
        mNumChildren(0),
128
6.72k
        mChildren(nullptr),
129
6.72k
        mNumMeshes(0),
130
6.72k
        mMeshes(nullptr),
131
6.72k
        mMetaData(nullptr) {
132
    // empty
133
6.72k
}
134
135
aiNode::aiNode(const std::string &name) :
136
416
        mName(name),
137
416
        mParent(nullptr),
138
416
        mNumChildren(0),
139
416
        mChildren(nullptr),
140
416
        mNumMeshes(0),
141
416
        mMeshes(nullptr),
142
416
        mMetaData(nullptr) {
143
    // empty
144
416
}
145
146
/** Destructor */
147
7.14k
aiNode::~aiNode() {
148
    // delete all children recursively
149
    // to make sure we won't crash if the data is invalid ...
150
7.14k
    if (mNumChildren && mChildren) {
151
10.9k
        for (unsigned int a = 0; a < mNumChildren; a++)
152
6.63k
            delete mChildren[a];
153
4.33k
    }
154
7.14k
    delete[] mChildren;
155
7.14k
    delete[] mMeshes;
156
7.14k
    delete mMetaData;
157
7.14k
}
158
159
0
const aiNode *aiNode::FindNode(const char *name) const {
160
0
    if (nullptr == name) {
161
0
        return nullptr;
162
0
    }
163
0
    if (!::strcmp(mName.data, name)) {
164
0
        return this;
165
0
    }
166
0
    for (unsigned int i = 0; i < mNumChildren; ++i) {
167
0
        const aiNode *const p = mChildren[i]->FindNode(name);
168
0
        if (p) {
169
0
            return p;
170
0
        }
171
0
    }
172
    // there is definitely no sub-node with this name
173
0
    return nullptr;
174
0
}
175
176
4.24k
aiNode *aiNode::FindNode(const char *name) {
177
4.24k
    if (!::strcmp(mName.data, name)) return this;
178
7.15k
    for (unsigned int i = 0; i < mNumChildren; ++i) {
179
4.15k
        aiNode *const p = mChildren[i]->FindNode(name);
180
4.15k
        if (p) {
181
1.17k
            return p;
182
1.17k
        }
183
4.15k
    }
184
    // there is definitely no sub-node with this name
185
3.00k
    return nullptr;
186
4.17k
}
187
188
0
void aiNode::addChildren(unsigned int numChildren, aiNode **children) {
189
0
    if (nullptr == children || 0 == numChildren) {
190
0
        return;
191
0
    }
192
193
0
    for (unsigned int i = 0; i < numChildren; i++) {
194
0
        aiNode *child = children[i];
195
0
        if (nullptr != child) {
196
0
            child->mParent = this;
197
0
        }
198
0
    }
199
200
0
    if (mNumChildren > 0) {
201
0
        aiNode **tmp = new aiNode *[mNumChildren];
202
0
        ::memcpy(tmp, mChildren, sizeof(aiNode *) * mNumChildren);
203
0
        delete[] mChildren;
204
0
        mChildren = new aiNode *[mNumChildren + numChildren];
205
0
        ::memcpy(mChildren, tmp, sizeof(aiNode *) * mNumChildren);
206
0
        ::memcpy(&mChildren[mNumChildren], children, sizeof(aiNode *) * numChildren);
207
0
        mNumChildren += numChildren;
208
0
        delete[] tmp;
209
0
    } else {
210
0
        mChildren = new aiNode *[numChildren];
211
0
        for (unsigned int i = 0; i < numChildren; i++) {
212
0
            mChildren[i] = children[i];
213
0
        }
214
0
        mNumChildren = numChildren;
215
0
    }
216
0
}