/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 |