summaryrefslogtreecommitdiff
path: root/src/mesh/assimp-master/code/AssetLib/Blender/BlenderCustomData.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mesh/assimp-master/code/AssetLib/Blender/BlenderCustomData.cpp')
-rw-r--r--src/mesh/assimp-master/code/AssetLib/Blender/BlenderCustomData.cpp181
1 files changed, 181 insertions, 0 deletions
diff --git a/src/mesh/assimp-master/code/AssetLib/Blender/BlenderCustomData.cpp b/src/mesh/assimp-master/code/AssetLib/Blender/BlenderCustomData.cpp
new file mode 100644
index 0000000..c74a6bb
--- /dev/null
+++ b/src/mesh/assimp-master/code/AssetLib/Blender/BlenderCustomData.cpp
@@ -0,0 +1,181 @@
+#include "BlenderCustomData.h"
+#include "BlenderDNA.h"
+#include <array>
+#include <functional>
+
+namespace Assimp {
+namespace Blender {
+/**
+ * @brief read/convert of Structure array to memory
+ */
+template <typename T>
+bool read(const Structure &s, T *p, const size_t cnt, const FileDatabase &db) {
+ for (size_t i = 0; i < cnt; ++i) {
+ T read;
+ s.Convert(read, db);
+ *p = read;
+ p++;
+ }
+ return true;
+}
+
+/**
+ * @brief pointer to function read memory for n CustomData types
+ */
+typedef bool (*PRead)(ElemBase *pOut, const size_t cnt, const FileDatabase &db);
+typedef ElemBase *(*PCreate)(const size_t cnt);
+typedef void (*PDestroy)(ElemBase *);
+
+#define IMPL_STRUCT_READ(ty) \
+ bool read##ty(ElemBase *v, const size_t cnt, const FileDatabase &db) { \
+ ty *ptr = dynamic_cast<ty *>(v); \
+ if (nullptr == ptr) { \
+ return false; \
+ } \
+ return read<ty>(db.dna[#ty], ptr, cnt, db); \
+ }
+
+#define IMPL_STRUCT_CREATE(ty) \
+ ElemBase *create##ty(const size_t cnt) { \
+ return new ty[cnt]; \
+ }
+
+#define IMPL_STRUCT_DESTROY(ty) \
+ void destroy##ty(ElemBase *pE) { \
+ ty *p = dynamic_cast<ty *>(pE); \
+ delete[] p; \
+ }
+
+/**
+ * @brief helper macro to define Structure functions
+ */
+#define IMPL_STRUCT(ty) \
+ IMPL_STRUCT_READ(ty) \
+ IMPL_STRUCT_CREATE(ty) \
+ IMPL_STRUCT_DESTROY(ty)
+
+// supported structures for CustomData
+IMPL_STRUCT(MVert)
+IMPL_STRUCT(MEdge)
+IMPL_STRUCT(MFace)
+IMPL_STRUCT(MTFace)
+IMPL_STRUCT(MTexPoly)
+IMPL_STRUCT(MLoopUV)
+IMPL_STRUCT(MLoopCol)
+IMPL_STRUCT(MPoly)
+IMPL_STRUCT(MLoop)
+
+/**
+ * @brief describes the size of data and the read function to be used for single CustomerData.type
+ */
+struct CustomDataTypeDescription {
+ PRead Read; ///< function to read one CustomData type element
+ PCreate Create; ///< function to allocate n type elements
+ PDestroy Destroy;
+
+ CustomDataTypeDescription(PRead read, PCreate create, PDestroy destroy) :
+ Read(read), Create(create), Destroy(destroy) {}
+};
+
+/**
+ * @brief helper macro to define Structure type specific CustomDataTypeDescription
+ * @note IMPL_STRUCT_READ for same ty must be used earlier to implement the typespecific read function
+ */
+#define DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(ty) \
+ CustomDataTypeDescription { &read##ty, &create##ty, &destroy##ty }
+
+/**
+ * @brief helper macro to define CustomDataTypeDescription for UNSUPPORTED type
+ */
+#define DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION \
+ CustomDataTypeDescription { nullptr, nullptr, nullptr }
+
+/**
+ * @brief descriptors for data pointed to from CustomDataLayer.data
+ * @note some of the CustomData uses already well defined Structures
+ * other (like CD_ORCO, ...) uses arrays of rawtypes or even arrays of Structures
+ * use a special readfunction for that cases
+ */
+std::array<CustomDataTypeDescription, CD_NUMTYPES> customDataTypeDescriptions = { { DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MVert),
+ DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+ DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+ DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MEdge),
+ DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MFace),
+ DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MTFace),
+ DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+ DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+ DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+ DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+
+ DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+ DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+ DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+ DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+ DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+ DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MTexPoly),
+ DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MLoopUV),
+ DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MLoopCol),
+ DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+ DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+
+ DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+ DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+ DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+ DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+ DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+ DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MPoly),
+ DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MLoop),
+ DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+ DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+ DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+
+ DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+ DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+ DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+ DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+ DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+ DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+ DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+ DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+ DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+ DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+
+ DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
+ DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION } };
+
+bool isValidCustomDataType(const int cdtype) {
+ return cdtype >= 0 && cdtype < CD_NUMTYPES;
+}
+
+bool readCustomData(std::shared_ptr<ElemBase> &out, const int cdtype, const size_t cnt, const FileDatabase &db) {
+ if (!isValidCustomDataType(cdtype)) {
+ throw Error("CustomData.type ", cdtype, " out of index");
+ }
+
+ const CustomDataTypeDescription cdtd = customDataTypeDescriptions[cdtype];
+ if (cdtd.Read && cdtd.Create && cdtd.Destroy && cnt > 0) {
+ // allocate cnt elements and parse them from file
+ out.reset(cdtd.Create(cnt), cdtd.Destroy);
+ return cdtd.Read(out.get(), cnt, db);
+ }
+ return false;
+}
+
+std::shared_ptr<CustomDataLayer> getCustomDataLayer(const CustomData &customdata, const CustomDataType cdtype, const std::string &name) {
+ for (auto it = customdata.layers.begin(); it != customdata.layers.end(); ++it) {
+ if (it->get()->type == cdtype && name == it->get()->name) {
+ return *it;
+ }
+ }
+ return nullptr;
+}
+
+const ElemBase *getCustomDataLayerData(const CustomData &customdata, const CustomDataType cdtype, const std::string &name) {
+ const std::shared_ptr<CustomDataLayer> pLayer = getCustomDataLayer(customdata, cdtype, name);
+ if (pLayer && pLayer->data) {
+ return pLayer->data.get();
+ }
+ return nullptr;
+}
+} // namespace Blender
+} // namespace Assimp