Coverage Report

Created: 2026-05-23 07:04

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/assimp/code/AssetLib/FBX/FBXProperties.h
Line
Count
Source
1
/*
2
Open Asset Import Library (assimp)
3
----------------------------------------------------------------------
4
5
Copyright (c) 2006-2026, assimp team
6
7
All rights reserved.
8
9
Redistribution and use of this software in source and binary forms,
10
with or without modification, are permitted provided that the
11
following conditions are met:
12
13
* Redistributions of source code must retain the above
14
  copyright notice, this list of conditions and the
15
  following disclaimer.
16
17
* Redistributions in binary form must reproduce the above
18
  copyright notice, this list of conditions and the
19
  following disclaimer in the documentation and/or other
20
  materials provided with the distribution.
21
22
* Neither the name of the assimp team, nor the names of its
23
  contributors may be used to endorse or promote products
24
  derived from this software without specific prior
25
  written permission of the assimp team.
26
27
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38
39
----------------------------------------------------------------------
40
*/
41
42
/** @file  FBXProperties.h
43
 *  @brief FBX dynamic properties
44
 */
45
#ifndef INCLUDED_AI_FBX_PROPERTIES_H
46
#define INCLUDED_AI_FBX_PROPERTIES_H
47
48
#include "FBXCompileConfig.h"
49
#include <memory>
50
#include <string>
51
52
namespace Assimp {
53
namespace FBX {
54
55
// Forward declarations
56
class Element;
57
58
/**
59
 * Represents a dynamic property. Type info added by deriving classes,
60
 * see #TypedProperty.
61
 * Example:
62
 *
63
 * @verbatim
64
 *  P: "ShininessExponent", "double", "Number", "",0.5
65
 * @endvebatim
66
 */
67
class Property {
68
69
public:
70
31.4k
    virtual ~Property() = default;
71
72
    template <typename T>
73
120k
    const T* As() const {
74
120k
        return dynamic_cast<const T*>(this);
75
120k
    }
Assimp::FBX::TypedProperty<aiVector3t<float> > const* Assimp::FBX::Property::As<Assimp::FBX::TypedProperty<aiVector3t<float> > >() const
Line
Count
Source
73
81.7k
    const T* As() const {
74
81.7k
        return dynamic_cast<const T*>(this);
75
81.7k
    }
Assimp::FBX::TypedProperty<float> const* Assimp::FBX::Property::As<Assimp::FBX::TypedProperty<float> >() const
Line
Count
Source
73
4.96k
    const T* As() const {
74
4.96k
        return dynamic_cast<const T*>(this);
75
4.96k
    }
Assimp::FBX::TypedProperty<int> const* Assimp::FBX::Property::As<Assimp::FBX::TypedProperty<int> >() const
Line
Count
Source
73
17.9k
    const T* As() const {
74
17.9k
        return dynamic_cast<const T*>(this);
75
17.9k
    }
Assimp::FBX::TypedProperty<bool> const* Assimp::FBX::Property::As<Assimp::FBX::TypedProperty<bool> >() const
Line
Count
Source
73
10.3k
    const T* As() const {
74
10.3k
        return dynamic_cast<const T*>(this);
75
10.3k
    }
Assimp::FBX::TypedProperty<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > const* Assimp::FBX::Property::As<Assimp::FBX::TypedProperty<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > >() const
Line
Count
Source
73
264
    const T* As() const {
74
264
        return dynamic_cast<const T*>(this);
75
264
    }
Assimp::FBX::TypedProperty<long> const* Assimp::FBX::Property::As<Assimp::FBX::TypedProperty<long> >() const
Line
Count
Source
73
1.84k
    const T* As() const {
74
1.84k
        return dynamic_cast<const T*>(this);
75
1.84k
    }
Assimp::FBX::TypedProperty<unsigned long> const* Assimp::FBX::Property::As<Assimp::FBX::TypedProperty<unsigned long> >() const
Line
Count
Source
73
1.77k
    const T* As() const {
74
1.77k
        return dynamic_cast<const T*>(this);
75
1.77k
    }
Assimp::FBX::TypedProperty<unsigned int> const* Assimp::FBX::Property::As<Assimp::FBX::TypedProperty<unsigned int> >() const
Line
Count
Source
73
1.36k
    const T* As() const {
74
1.36k
        return dynamic_cast<const T*>(this);
75
1.36k
    }
Assimp::FBX::TypedProperty<aiColor3D> const* Assimp::FBX::Property::As<Assimp::FBX::TypedProperty<aiColor3D> >() const
Line
Count
Source
73
106
    const T* As() const {
74
106
        return dynamic_cast<const T*>(this);
75
106
    }
Assimp::FBX::TypedProperty<aiColor4t<float> > const* Assimp::FBX::Property::As<Assimp::FBX::TypedProperty<aiColor4t<float> > >() const
Line
Count
Source
73
106
    const T* As() const {
74
106
        return dynamic_cast<const T*>(this);
75
106
    }
76
77
protected:
78
31.4k
    Property() = default;
79
};
80
81
template<typename T>
82
class TypedProperty : public Property {
83
public:
84
31.4k
    explicit TypedProperty(const T& value) : value(value) {}
Assimp::FBX::TypedProperty<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::TypedProperty(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Line
Count
Source
84
21
    explicit TypedProperty(const T& value) : value(value) {}
Assimp::FBX::TypedProperty<aiVector3t<float> >::TypedProperty(aiVector3t<float> const&)
Line
Count
Source
84
14.8k
    explicit TypedProperty(const T& value) : value(value) {}
Unexecuted instantiation: Assimp::FBX::TypedProperty<aiColor4t<float> >::TypedProperty(aiColor4t<float> const&)
Assimp::FBX::TypedProperty<bool>::TypedProperty(bool const&)
Line
Count
Source
84
1.40k
    explicit TypedProperty(const T& value) : value(value) {}
Assimp::FBX::TypedProperty<int>::TypedProperty(int const&)
Line
Count
Source
84
10.1k
    explicit TypedProperty(const T& value) : value(value) {}
Unexecuted instantiation: Assimp::FBX::TypedProperty<unsigned long>::TypedProperty(unsigned long const&)
Assimp::FBX::TypedProperty<long>::TypedProperty(long const&)
Line
Count
Source
84
892
    explicit TypedProperty(const T& value) : value(value) {}
Assimp::FBX::TypedProperty<float>::TypedProperty(float const&)
Line
Count
Source
84
4.22k
    explicit TypedProperty(const T& value) : value(value) {}
85
86
104k
    const T& Value() const {
87
104k
        return value;
88
104k
    }
Assimp::FBX::TypedProperty<aiVector3t<float> >::Value() const
Line
Count
Source
86
81.6k
    const T& Value() const {
87
81.6k
        return value;
88
81.6k
    }
Assimp::FBX::TypedProperty<float>::Value() const
Line
Count
Source
86
4.70k
    const T& Value() const {
87
4.70k
        return value;
88
4.70k
    }
Assimp::FBX::TypedProperty<int>::Value() const
Line
Count
Source
86
16.4k
    const T& Value() const {
87
16.4k
        return value;
88
16.4k
    }
Assimp::FBX::TypedProperty<bool>::Value() const
Line
Count
Source
86
1.38k
    const T& Value() const {
87
1.38k
        return value;
88
1.38k
    }
Assimp::FBX::TypedProperty<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::Value() const
Line
Count
Source
86
24
    const T& Value() const {
87
24
        return value;
88
24
    }
Assimp::FBX::TypedProperty<long>::Value() const
Line
Count
Source
86
478
    const T& Value() const {
87
478
        return value;
88
478
    }
Unexecuted instantiation: Assimp::FBX::TypedProperty<unsigned long>::Value() const
Unexecuted instantiation: Assimp::FBX::TypedProperty<unsigned int>::Value() const
Unexecuted instantiation: Assimp::FBX::TypedProperty<aiColor3D>::Value() const
Unexecuted instantiation: Assimp::FBX::TypedProperty<aiColor4t<float> >::Value() const
89
90
private:
91
    T value;
92
};
93
94
using DirectPropertyMap = std::fbx_unordered_map<std::string,std::shared_ptr<Property> >;
95
using PropertyMap = std::fbx_unordered_map<std::string,const Property*>;
96
using LazyPropertyMap = std::fbx_unordered_map<std::string,const Element*>;
97
98
/**
99
 *  Represents a property table as can be found in the newer FBX files (Properties60, Properties70)
100
 */
101
class PropertyTable {
102
public:
103
    // in-memory property table with no source element
104
3.27k
    PropertyTable() : element() {}
105
    PropertyTable(const Element& element, std::shared_ptr<const PropertyTable> templateProps);
106
    ~PropertyTable();
107
108
    const Property* Get(const std::string& name) const;
109
110
    // PropertyTable's need not be coupled with FBX elements so this can be nullptr
111
0
    const Element* GetElement() const {
112
0
        return element;
113
0
    }
114
115
107
    const PropertyTable* TemplateProps() const {
116
107
        return templateProps.get();
117
107
    }
118
119
    DirectPropertyMap GetUnparsedProperties() const;
120
121
private:
122
    LazyPropertyMap lazyProps;
123
    mutable PropertyMap props;
124
    const std::shared_ptr<const PropertyTable> templateProps;
125
    const Element* const element;
126
};
127
128
// ------------------------------------------------------------------------------------------------
129
template <typename T>
130
25.3k
inline T PropertyGet(const PropertyTable& in, const std::string& name, const T& defaultValue) {
131
25.3k
    const Property* const prop = in.Get(name);
132
25.3k
    if( nullptr == prop) {
133
4.38k
        return defaultValue;
134
4.38k
    }
135
136
    // strong typing, no need to be lenient
137
20.9k
    const TypedProperty<T>* const tprop = prop->As< TypedProperty<T> >();
138
20.9k
    if( nullptr == tprop) {
139
466
        return defaultValue;
140
466
    }
141
142
20.5k
    return tprop->Value();
143
20.9k
}
aiVector3t<float> Assimp::FBX::PropertyGet<aiVector3t<float> >(Assimp::FBX::PropertyTable const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, aiVector3t<float> const&)
Line
Count
Source
130
8.58k
inline T PropertyGet(const PropertyTable& in, const std::string& name, const T& defaultValue) {
131
8.58k
    const Property* const prop = in.Get(name);
132
8.58k
    if( nullptr == prop) {
133
67
        return defaultValue;
134
67
    }
135
136
    // strong typing, no need to be lenient
137
8.51k
    const TypedProperty<T>* const tprop = prop->As< TypedProperty<T> >();
138
8.51k
    if( nullptr == tprop) {
139
0
        return defaultValue;
140
0
    }
141
142
8.51k
    return tprop->Value();
143
8.51k
}
float Assimp::FBX::PropertyGet<float>(Assimp::FBX::PropertyTable const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, float const&)
Line
Count
Source
130
2.72k
inline T PropertyGet(const PropertyTable& in, const std::string& name, const T& defaultValue) {
131
2.72k
    const Property* const prop = in.Get(name);
132
2.72k
    if( nullptr == prop) {
133
145
        return defaultValue;
134
145
    }
135
136
    // strong typing, no need to be lenient
137
2.57k
    const TypedProperty<T>* const tprop = prop->As< TypedProperty<T> >();
138
2.57k
    if( nullptr == tprop) {
139
0
        return defaultValue;
140
0
    }
141
142
2.57k
    return tprop->Value();
143
2.57k
}
int Assimp::FBX::PropertyGet<int>(Assimp::FBX::PropertyTable const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, int const&)
Line
Count
Source
130
9.54k
inline T PropertyGet(const PropertyTable& in, const std::string& name, const T& defaultValue) {
131
9.54k
    const Property* const prop = in.Get(name);
132
9.54k
    if( nullptr == prop) {
133
555
        return defaultValue;
134
555
    }
135
136
    // strong typing, no need to be lenient
137
8.99k
    const TypedProperty<T>* const tprop = prop->As< TypedProperty<T> >();
138
8.99k
    if( nullptr == tprop) {
139
54
        return defaultValue;
140
54
    }
141
142
8.93k
    return tprop->Value();
143
8.99k
}
Unexecuted instantiation: bool Assimp::FBX::PropertyGet<bool>(Assimp::FBX::PropertyTable const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool const&)
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > Assimp::FBX::PropertyGet<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(Assimp::FBX::PropertyTable const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)
Line
Count
Source
130
3.56k
inline T PropertyGet(const PropertyTable& in, const std::string& name, const T& defaultValue) {
131
3.56k
    const Property* const prop = in.Get(name);
132
3.56k
    if( nullptr == prop) {
133
3.56k
        return defaultValue;
134
3.56k
    }
135
136
    // strong typing, no need to be lenient
137
0
    const TypedProperty<T>* const tprop = prop->As< TypedProperty<T> >();
138
0
    if( nullptr == tprop) {
139
0
        return defaultValue;
140
0
    }
141
142
0
    return tprop->Value();
143
0
}
long Assimp::FBX::PropertyGet<long>(Assimp::FBX::PropertyTable const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, long const&)
Line
Count
Source
130
490
inline T PropertyGet(const PropertyTable& in, const std::string& name, const T& defaultValue) {
131
490
    const Property* const prop = in.Get(name);
132
490
    if( nullptr == prop) {
133
12
        return defaultValue;
134
12
    }
135
136
    // strong typing, no need to be lenient
137
478
    const TypedProperty<T>* const tprop = prop->As< TypedProperty<T> >();
138
478
    if( nullptr == tprop) {
139
0
        return defaultValue;
140
0
    }
141
142
478
    return tprop->Value();
143
478
}
unsigned long Assimp::FBX::PropertyGet<unsigned long>(Assimp::FBX::PropertyTable const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned long const&)
Line
Count
Source
130
454
inline T PropertyGet(const PropertyTable& in, const std::string& name, const T& defaultValue) {
131
454
    const Property* const prop = in.Get(name);
132
454
    if( nullptr == prop) {
133
42
        return defaultValue;
134
42
    }
135
136
    // strong typing, no need to be lenient
137
412
    const TypedProperty<T>* const tprop = prop->As< TypedProperty<T> >();
138
412
    if( nullptr == tprop) {
139
412
        return defaultValue;
140
412
    }
141
142
0
    return tprop->Value();
143
412
}
144
145
// ------------------------------------------------------------------------------------------------
146
template <typename T>
147
94.0k
inline T PropertyGet(const PropertyTable& in, const std::string& name, bool& result, bool useTemplate=false ) {
148
94.0k
    const Property* prop = in.Get(name);
149
94.0k
    if( nullptr == prop) {
150
20.2k
        if ( ! useTemplate ) {
151
20.1k
            result = false;
152
20.1k
            return T();
153
20.1k
        }
154
107
        const PropertyTable* templ = in.TemplateProps();
155
107
        if ( nullptr == templ ) {
156
29
            result = false;
157
29
            return T();
158
29
        }
159
78
        prop = templ->Get(name);
160
78
        if ( nullptr == prop ) {
161
78
            result = false;
162
78
            return T();
163
78
        }
164
78
    }
165
166
    // strong typing, no need to be lenient
167
73.7k
    const TypedProperty<T>* const tprop = prop->As< TypedProperty<T> >();
168
73.7k
    if( nullptr == tprop) {
169
1
        result = false;
170
1
        return T();
171
1
    }
172
173
73.7k
    result = true;
174
73.7k
    return tprop->Value();
175
73.7k
}
aiVector3t<float> Assimp::FBX::PropertyGet<aiVector3t<float> >(Assimp::FBX::PropertyTable const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool&, bool)
Line
Count
Source
147
92.3k
inline T PropertyGet(const PropertyTable& in, const std::string& name, bool& result, bool useTemplate=false ) {
148
92.3k
    const Property* prop = in.Get(name);
149
92.3k
    if( nullptr == prop) {
150
19.5k
        if ( ! useTemplate ) {
151
19.4k
            result = false;
152
19.4k
            return T();
153
19.4k
        }
154
100
        const PropertyTable* templ = in.TemplateProps();
155
100
        if ( nullptr == templ ) {
156
23
            result = false;
157
23
            return T();
158
23
        }
159
77
        prop = templ->Get(name);
160
77
        if ( nullptr == prop ) {
161
77
            result = false;
162
77
            return T();
163
77
        }
164
77
    }
165
166
    // strong typing, no need to be lenient
167
72.8k
    const TypedProperty<T>* const tprop = prop->As< TypedProperty<T> >();
168
72.8k
    if( nullptr == tprop) {
169
1
        result = false;
170
1
        return T();
171
1
    }
172
173
72.8k
    result = true;
174
72.8k
    return tprop->Value();
175
72.8k
}
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > Assimp::FBX::PropertyGet<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(Assimp::FBX::PropertyTable const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool&, bool)
Line
Count
Source
147
6
inline T PropertyGet(const PropertyTable& in, const std::string& name, bool& result, bool useTemplate=false ) {
148
6
    const Property* prop = in.Get(name);
149
6
    if( nullptr == prop) {
150
0
        if ( ! useTemplate ) {
151
0
            result = false;
152
0
            return T();
153
0
        }
154
0
        const PropertyTable* templ = in.TemplateProps();
155
0
        if ( nullptr == templ ) {
156
0
            result = false;
157
0
            return T();
158
0
        }
159
0
        prop = templ->Get(name);
160
0
        if ( nullptr == prop ) {
161
0
            result = false;
162
0
            return T();
163
0
        }
164
0
    }
165
166
    // strong typing, no need to be lenient
167
6
    const TypedProperty<T>* const tprop = prop->As< TypedProperty<T> >();
168
6
    if( nullptr == tprop) {
169
0
        result = false;
170
0
        return T();
171
0
    }
172
173
6
    result = true;
174
6
    return tprop->Value();
175
6
}
float Assimp::FBX::PropertyGet<float>(Assimp::FBX::PropertyTable const&, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool&, bool)
Line
Count
Source
147
1.62k
inline T PropertyGet(const PropertyTable& in, const std::string& name, bool& result, bool useTemplate=false ) {
148
1.62k
    const Property* prop = in.Get(name);
149
1.62k
    if( nullptr == prop) {
150
707
        if ( ! useTemplate ) {
151
700
            result = false;
152
700
            return T();
153
700
        }
154
7
        const PropertyTable* templ = in.TemplateProps();
155
7
        if ( nullptr == templ ) {
156
6
            result = false;
157
6
            return T();
158
6
        }
159
1
        prop = templ->Get(name);
160
1
        if ( nullptr == prop ) {
161
1
            result = false;
162
1
            return T();
163
1
        }
164
1
    }
165
166
    // strong typing, no need to be lenient
167
919
    const TypedProperty<T>* const tprop = prop->As< TypedProperty<T> >();
168
919
    if( nullptr == tprop) {
169
0
        result = false;
170
0
        return T();
171
0
    }
172
173
919
    result = true;
174
919
    return tprop->Value();
175
919
}
176
177
} //! FBX
178
} //! Assimp
179
180
#endif // INCLUDED_AI_FBX_PROPERTIES_H