Coverage Report

Created: 2025-06-22 07:30

/src/assimp/code/AssetLib/Blender/BlenderCustomData.cpp
Line
Count
Source (jump to first uncovered line)
1
#include "BlenderCustomData.h"
2
#include "BlenderDNA.h"
3
#include <array>
4
#include <functional>
5
6
namespace Assimp {
7
namespace Blender {
8
/**
9
        *   @brief  read/convert of Structure array to memory
10
        */
11
template <typename T>
12
0
bool read(const Structure &s, T *p, const size_t cnt, const FileDatabase &db) {
13
0
    for (size_t i = 0; i < cnt; ++i) {
14
0
        T read;
15
0
        s.Convert(read, db);
16
0
        *p = read;
17
0
        p++;
18
0
    }
19
0
    return true;
20
0
}
Unexecuted instantiation: bool Assimp::Blender::read<Assimp::Blender::MVert>(Assimp::Blender::Structure const&, Assimp::Blender::MVert*, unsigned long, Assimp::Blender::FileDatabase const&)
Unexecuted instantiation: bool Assimp::Blender::read<Assimp::Blender::MEdge>(Assimp::Blender::Structure const&, Assimp::Blender::MEdge*, unsigned long, Assimp::Blender::FileDatabase const&)
Unexecuted instantiation: bool Assimp::Blender::read<Assimp::Blender::MFace>(Assimp::Blender::Structure const&, Assimp::Blender::MFace*, unsigned long, Assimp::Blender::FileDatabase const&)
Unexecuted instantiation: bool Assimp::Blender::read<Assimp::Blender::MTFace>(Assimp::Blender::Structure const&, Assimp::Blender::MTFace*, unsigned long, Assimp::Blender::FileDatabase const&)
Unexecuted instantiation: bool Assimp::Blender::read<Assimp::Blender::MTexPoly>(Assimp::Blender::Structure const&, Assimp::Blender::MTexPoly*, unsigned long, Assimp::Blender::FileDatabase const&)
Unexecuted instantiation: bool Assimp::Blender::read<Assimp::Blender::MLoopUV>(Assimp::Blender::Structure const&, Assimp::Blender::MLoopUV*, unsigned long, Assimp::Blender::FileDatabase const&)
Unexecuted instantiation: bool Assimp::Blender::read<Assimp::Blender::MLoopCol>(Assimp::Blender::Structure const&, Assimp::Blender::MLoopCol*, unsigned long, Assimp::Blender::FileDatabase const&)
Unexecuted instantiation: bool Assimp::Blender::read<Assimp::Blender::MPoly>(Assimp::Blender::Structure const&, Assimp::Blender::MPoly*, unsigned long, Assimp::Blender::FileDatabase const&)
Unexecuted instantiation: bool Assimp::Blender::read<Assimp::Blender::MLoop>(Assimp::Blender::Structure const&, Assimp::Blender::MLoop*, unsigned long, Assimp::Blender::FileDatabase const&)
21
22
/**
23
        *   @brief  pointer to function read memory for n CustomData types
24
        */
25
typedef bool (*PRead)(ElemBase *pOut, const size_t cnt, const FileDatabase &db);
26
typedef ElemBase *(*PCreate)(const size_t cnt);
27
typedef void (*PDestroy)(ElemBase *);
28
29
#define IMPL_STRUCT_READ(ty)                                               \
30
0
    bool read##ty(ElemBase *v, const size_t cnt, const FileDatabase &db) { \
31
0
        ty *ptr = dynamic_cast<ty *>(v);                                   \
32
0
        if (nullptr == ptr) {                                              \
33
0
            return false;                                                  \
34
0
        }                                                                  \
35
0
        return read<ty>(db.dna[#ty], ptr, cnt, db);                        \
36
0
    }
Unexecuted instantiation: Assimp::Blender::readMVert(Assimp::Blender::ElemBase*, unsigned long, Assimp::Blender::FileDatabase const&)
Unexecuted instantiation: Assimp::Blender::readMEdge(Assimp::Blender::ElemBase*, unsigned long, Assimp::Blender::FileDatabase const&)
Unexecuted instantiation: Assimp::Blender::readMFace(Assimp::Blender::ElemBase*, unsigned long, Assimp::Blender::FileDatabase const&)
Unexecuted instantiation: Assimp::Blender::readMTFace(Assimp::Blender::ElemBase*, unsigned long, Assimp::Blender::FileDatabase const&)
Unexecuted instantiation: Assimp::Blender::readMTexPoly(Assimp::Blender::ElemBase*, unsigned long, Assimp::Blender::FileDatabase const&)
Unexecuted instantiation: Assimp::Blender::readMLoopUV(Assimp::Blender::ElemBase*, unsigned long, Assimp::Blender::FileDatabase const&)
Unexecuted instantiation: Assimp::Blender::readMLoopCol(Assimp::Blender::ElemBase*, unsigned long, Assimp::Blender::FileDatabase const&)
Unexecuted instantiation: Assimp::Blender::readMPoly(Assimp::Blender::ElemBase*, unsigned long, Assimp::Blender::FileDatabase const&)
Unexecuted instantiation: Assimp::Blender::readMLoop(Assimp::Blender::ElemBase*, unsigned long, Assimp::Blender::FileDatabase const&)
37
38
#define IMPL_STRUCT_CREATE(ty)               \
39
0
    ElemBase *create##ty(const size_t cnt) { \
40
0
        return new ty[cnt];                  \
41
0
    }
Unexecuted instantiation: Assimp::Blender::createMVert(unsigned long)
Unexecuted instantiation: Assimp::Blender::createMEdge(unsigned long)
Unexecuted instantiation: Assimp::Blender::createMFace(unsigned long)
Unexecuted instantiation: Assimp::Blender::createMTFace(unsigned long)
Unexecuted instantiation: Assimp::Blender::createMTexPoly(unsigned long)
Unexecuted instantiation: Assimp::Blender::createMLoopUV(unsigned long)
Unexecuted instantiation: Assimp::Blender::createMLoopCol(unsigned long)
Unexecuted instantiation: Assimp::Blender::createMPoly(unsigned long)
Unexecuted instantiation: Assimp::Blender::createMLoop(unsigned long)
42
43
#define IMPL_STRUCT_DESTROY(ty)         \
44
0
    void destroy##ty(ElemBase *pE) {    \
45
0
        ty *p = dynamic_cast<ty *>(pE); \
46
0
        delete[] p;                     \
47
0
    }
Unexecuted instantiation: Assimp::Blender::destroyMVert(Assimp::Blender::ElemBase*)
Unexecuted instantiation: Assimp::Blender::destroyMEdge(Assimp::Blender::ElemBase*)
Unexecuted instantiation: Assimp::Blender::destroyMFace(Assimp::Blender::ElemBase*)
Unexecuted instantiation: Assimp::Blender::destroyMTFace(Assimp::Blender::ElemBase*)
Unexecuted instantiation: Assimp::Blender::destroyMTexPoly(Assimp::Blender::ElemBase*)
Unexecuted instantiation: Assimp::Blender::destroyMLoopUV(Assimp::Blender::ElemBase*)
Unexecuted instantiation: Assimp::Blender::destroyMLoopCol(Assimp::Blender::ElemBase*)
Unexecuted instantiation: Assimp::Blender::destroyMPoly(Assimp::Blender::ElemBase*)
Unexecuted instantiation: Assimp::Blender::destroyMLoop(Assimp::Blender::ElemBase*)
48
49
/**
50
        *   @brief  helper macro to define Structure functions
51
        */
52
#define IMPL_STRUCT(ty)    \
53
    IMPL_STRUCT_READ(ty)   \
54
    IMPL_STRUCT_CREATE(ty) \
55
    IMPL_STRUCT_DESTROY(ty)
56
57
// supported structures for CustomData
58
IMPL_STRUCT(MVert)
59
IMPL_STRUCT(MEdge)
60
IMPL_STRUCT(MFace)
61
IMPL_STRUCT(MTFace)
62
IMPL_STRUCT(MTexPoly)
63
IMPL_STRUCT(MLoopUV)
64
IMPL_STRUCT(MLoopCol)
65
IMPL_STRUCT(MPoly)
66
IMPL_STRUCT(MLoop)
67
68
/**
69
        *   @brief  describes the size of data and the read function to be used for single CustomerData.type
70
        */
71
struct CustomDataTypeDescription {
72
    PRead Read; ///< function to read one CustomData type element
73
    PCreate Create; ///< function to allocate n type elements
74
    PDestroy Destroy;
75
76
    CustomDataTypeDescription(PRead read, PCreate create, PDestroy destroy) :
77
84
            Read(read), Create(create), Destroy(destroy) {}
78
};
79
80
/**
81
        *   @brief  helper macro to define Structure type specific CustomDataTypeDescription
82
        *   @note   IMPL_STRUCT_READ for same ty must be used earlier to implement the typespecific read function
83
        */
84
#define DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(ty) \
85
    CustomDataTypeDescription { &read##ty, &create##ty, &destroy##ty }
86
87
/**
88
        *   @brief  helper macro to define CustomDataTypeDescription for UNSUPPORTED type
89
        */
90
#define DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION \
91
    CustomDataTypeDescription { nullptr, nullptr, nullptr }
92
93
/**
94
        *   @brief  descriptors for data pointed to from CustomDataLayer.data
95
        *   @note   some of the CustomData uses already well defined Structures
96
        *           other (like CD_ORCO, ...) uses arrays of rawtypes or even arrays of Structures
97
        *           use a special readfunction for that cases
98
        */
99
static std::array<CustomDataTypeDescription, CD_NUMTYPES> customDataTypeDescriptions = { {
100
        DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MVert),
101
        DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
102
        DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
103
        DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MEdge),
104
        DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MFace),
105
        DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MTFace),
106
        DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
107
        DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
108
        DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
109
        DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
110
111
        DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
112
        DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
113
        DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
114
        DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
115
        DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
116
        DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MTexPoly),
117
        DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MLoopUV),
118
        DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MLoopCol),
119
        DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
120
        DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
121
122
        DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
123
        DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
124
        DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
125
        DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
126
        DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
127
        DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MPoly),
128
        DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MLoop),
129
        DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
130
        DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
131
        DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
132
133
        DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
134
        DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
135
        DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
136
        DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
137
        DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
138
        DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
139
        DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
140
        DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
141
        DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
142
        DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
143
144
        DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
145
        DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION } };
146
147
0
bool isValidCustomDataType(const int cdtype) {
148
0
    return cdtype >= 0 && cdtype < CD_NUMTYPES;
149
0
}
150
151
0
bool readCustomData(std::shared_ptr<ElemBase> &out, const int cdtype, const size_t cnt, const FileDatabase &db) {
152
0
    if (!isValidCustomDataType(cdtype)) {
153
0
        throw Error("CustomData.type ", cdtype, " out of index");
154
0
    }
155
156
0
    const CustomDataTypeDescription cdtd = customDataTypeDescriptions[cdtype];
157
0
    if (cdtd.Read && cdtd.Create && cdtd.Destroy && cnt > 0) {
158
        // allocate cnt elements and parse them from file
159
0
        out.reset(cdtd.Create(cnt), cdtd.Destroy);
160
0
        return cdtd.Read(out.get(), cnt, db);
161
0
    }
162
0
    return false;
163
0
}
164
165
0
std::shared_ptr<CustomDataLayer> getCustomDataLayer(const CustomData &customdata, const CustomDataType cdtype, const std::string &name) {
166
0
    for (auto it = customdata.layers.begin(); it != customdata.layers.end(); ++it) {
167
0
        if (it->get()->type == cdtype && name == it->get()->name) {
168
0
            return *it;
169
0
        }
170
0
    }
171
0
    return nullptr;
172
0
}
173
174
0
const ElemBase *getCustomDataLayerData(const CustomData &customdata, const CustomDataType cdtype, const std::string &name) {
175
0
    const std::shared_ptr<CustomDataLayer> pLayer = getCustomDataLayer(customdata, cdtype, name);
176
0
    if (pLayer && pLayer->data) {
177
0
        return pLayer->data.get();
178
0
    }
179
0
    return nullptr;
180
0
}
181
} // namespace Blender
182
} // namespace Assimp