| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- #pragma once
- #include "BlenderCustomData.h"
- #include <array>
- 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)(void *pOut, const size_t cnt, const FileDatabase &db);
- /**
- * @brief pointer to function read memory for cnt CustomData types
- */
- typedef void *(*PAlloc)(const size_t cnt);
- /**
- * @brief helper macro to define Structure specific read function
- * for ex: when used like
- *
- * IMPL_STRUCT_READ(MLoop)
- *
- * following function is implemented
- *
- * bool readMLoop(void *v, const size_t cnt, const FileDatabase &db) {
- * return read<MLoop>(db.dna["MLoop"], static_cast<MLoop *>(v), cnt, db);
- * }
- */
- #define IMPL_STRUCT_READ(ty) \
- bool read##ty(void *v, const size_t cnt, const FileDatabase &db) { \
- return read<ty>(db.dna[#ty], static_cast<ty *>(v), cnt, db); \
- }
- /**
- * @brief helper macro to define Structure specific alloc function
- * for ex: when used like
- *
- * IMPL_STRUCT_ALLOC(MLoop)
- *
- * following function is implemented
- *
- * void * allocMLoop(const size_t cnt) {
- * return new uint8_t[cnt * sizeof MLoop];
- * }
- */
- #define IMPL_STRUCT_ALLOC(ty) \
- void *alloc##ty(const size_t cnt) { \
- return new uint8_t[cnt * sizeof ty]; \
- }
- /**
- * @brief helper macro to define Structure functions
- */
- #define IMPL_STRUCT(ty) \
- IMPL_STRUCT_ALLOC(ty) \
- IMPL_STRUCT_READ(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
- PAlloc Alloc; ///< function to allocate n type elements
- };
- /**
- * @brief shortcut for array of CustomDataTypeDescription
- */
- typedef std::array<CustomDataTypeDescription, CD_NUMTYPES> CustomDataTypeDescriptions;
- /**
- * @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, &alloc##ty }
- /**
- * @brief helper macro to define CustomDataTypeDescription for UNSUPPORTED type
- */
- #define DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION \
- CustomDataTypeDescription{ 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
- */
- CustomDataTypeDescriptions 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<void> &out, const int cdtype, const size_t cnt, const FileDatabase &db) {
- if (!isValidCustomDataType(cdtype)) {
- throw Error((Formatter::format(), "CustomData.type ", cdtype, " out of index"));
- }
- const CustomDataTypeDescription cdtd = customDataTypeDescriptions[cdtype];
- if (cdtd.Read && cdtd.Alloc) {
- // allocate cnt elements and parse them from file
- out.reset(cdtd.Alloc(cnt));
- 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 void * 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;
- }
- }
- }
|