blender loader now loads material assignments.
blender loader no longer produces randomized output in some scenarious. nice side effect of less asthetic diversity: less segfaults. assimpview is no longer topmost. git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@732 67173fc5-114c-0410-ac8e-9d2fd5bffc1fpull/1/head
parent
c29e985f12
commit
3cf20b605d
|
@ -111,6 +111,27 @@ struct Pointer
|
||||||
uint64_t val;
|
uint64_t val;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// -------------------------------------------------------------------------------
|
||||||
|
/** Dummy derivate of std::vector to be able to use it in templates simultaenously
|
||||||
|
* with boost::shared_ptr, which takes only one template argument
|
||||||
|
* while std::vector takes three. Also we need to provide some special member
|
||||||
|
* functions of shared_ptr */
|
||||||
|
// -------------------------------------------------------------------------------
|
||||||
|
template <typename T>
|
||||||
|
class vector : public std::vector<T>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
using std::vector<T>::resize;
|
||||||
|
using std::vector<T>::empty;
|
||||||
|
|
||||||
|
void reset() {
|
||||||
|
resize(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
operator bool () const {
|
||||||
|
return !empty();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
/** Mixed flags for use in #Field */
|
/** Mixed flags for use in #Field */
|
||||||
|
@ -181,7 +202,7 @@ public:
|
||||||
|
|
||||||
// publicly accessible members
|
// publicly accessible members
|
||||||
std::string name;
|
std::string name;
|
||||||
std::vector< Field > fields;
|
vector< Field > fields;
|
||||||
std::map<std::string, size_t> indices;
|
std::map<std::string, size_t> indices;
|
||||||
|
|
||||||
size_t size;
|
size_t size;
|
||||||
|
@ -255,6 +276,11 @@ private:
|
||||||
void ResolvePointer(TOUT<T>& out, const Pointer & ptrval,
|
void ResolvePointer(TOUT<T>& out, const Pointer & ptrval,
|
||||||
const FileDatabase& db, const Field& f) const;
|
const FileDatabase& db, const Field& f) const;
|
||||||
|
|
||||||
|
// --------------------------------------------------------
|
||||||
|
template <template <typename> class TOUT, typename T>
|
||||||
|
void ResolvePointer(vector< TOUT<T> >& out, const Pointer & ptrval,
|
||||||
|
const FileDatabase& db, const Field& f) const;
|
||||||
|
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
inline const FileBlockHead* LocateFileBlockForAddress(
|
inline const FileBlockHead* LocateFileBlockForAddress(
|
||||||
const Pointer & ptrval,
|
const Pointer & ptrval,
|
||||||
|
@ -263,13 +289,15 @@ private:
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
template <typename T> void _allocate(boost::shared_ptr<T>& out, size_t& s) const {
|
template <typename T> T* _allocate(boost::shared_ptr<T>& out, size_t& s) const {
|
||||||
out = boost::shared_ptr<T>(new T());
|
out = boost::shared_ptr<T>(new T());
|
||||||
s = 1;
|
s = 1;
|
||||||
|
return out.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> void _allocate(boost::shared_array<T>& out, size_t& s) const {
|
template <typename T> T* _allocate(vector<T>& out, size_t& s) const {
|
||||||
out = boost::shared_array<T>(new T[s]);
|
out.resize(s);
|
||||||
|
return s ? &out.front() : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------
|
// --------------------------------------------------------
|
||||||
|
@ -346,7 +374,7 @@ public:
|
||||||
typedef boost::shared_ptr<ElemBase> (Structure::*ConvertProcPtr) (const FileDatabase& ) const;
|
typedef boost::shared_ptr<ElemBase> (Structure::*ConvertProcPtr) (const FileDatabase& ) const;
|
||||||
|
|
||||||
std::map<std::string, ConvertProcPtr> converters;
|
std::map<std::string, ConvertProcPtr> converters;
|
||||||
std::vector<Structure > structures;
|
vector<Structure > structures;
|
||||||
std::map<std::string, size_t> indices;
|
std::map<std::string, size_t> indices;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -585,19 +613,20 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
mutable std::vector<StructureCache> caches;
|
mutable vector<StructureCache> caches;
|
||||||
const FileDatabase& db;
|
const FileDatabase& db;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
template <> class ObjectCache<boost::shared_array>
|
// -------------------------------------------------------------------------------
|
||||||
|
template <> class ObjectCache<Blender::vector>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ObjectCache(const FileDatabase&) {}
|
ObjectCache(const FileDatabase&) {}
|
||||||
|
|
||||||
template <typename T> void get(const Structure&, boost::shared_array<T>&t, const Pointer&) {}
|
template <typename T> void get(const Structure&, vector<T>&t, const Pointer&) {}
|
||||||
template <typename T> void set(const Structure&, const boost::shared_array<T>&, const Pointer&) {}
|
template <typename T> void set(const Structure&, const vector<T>&, const Pointer&) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
@ -629,7 +658,7 @@ public:
|
||||||
|
|
||||||
DNA dna;
|
DNA dna;
|
||||||
boost::shared_ptr< StreamReaderAny > reader;
|
boost::shared_ptr< StreamReaderAny > reader;
|
||||||
std::vector< FileBlockHead > entries;
|
vector< FileBlockHead > entries;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -637,7 +666,7 @@ public:
|
||||||
return _stats;
|
return _stats;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For all our templates to work on both shared_ptr's and shared_array's
|
// For all our templates to work on both shared_ptr's and vector's
|
||||||
// using the same code, a dummy cache for arrays is provided. Actually,
|
// using the same code, a dummy cache for arrays is provided. Actually,
|
||||||
// arrays of objects are never cached because we can't easily
|
// arrays of objects are never cached because we can't easily
|
||||||
// ensure their proper destruction.
|
// ensure their proper destruction.
|
||||||
|
@ -647,7 +676,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
ObjectCache<boost::shared_array>& cache(boost::shared_array<T>& in) const {
|
ObjectCache<vector>& cache(vector<T>& in) const {
|
||||||
return _cacheArrays;
|
return _cacheArrays;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -658,7 +687,7 @@ private:
|
||||||
mutable Statistics _stats;
|
mutable Statistics _stats;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
mutable ObjectCache<boost::shared_array> _cacheArrays;
|
mutable ObjectCache<vector> _cacheArrays;
|
||||||
mutable ObjectCache<boost::shared_ptr> _cache;
|
mutable ObjectCache<boost::shared_ptr> _cache;
|
||||||
|
|
||||||
mutable size_t next_cache_idx;
|
mutable size_t next_cache_idx;
|
||||||
|
|
|
@ -242,48 +242,80 @@ template <template <typename> class TOUT, typename T>
|
||||||
void Structure :: ResolvePointer(TOUT<T>& out, const Pointer & ptrval, const FileDatabase& db, const Field& f) const
|
void Structure :: ResolvePointer(TOUT<T>& out, const Pointer & ptrval, const FileDatabase& db, const Field& f) const
|
||||||
{
|
{
|
||||||
out.reset();
|
out.reset();
|
||||||
if (ptrval.val) {
|
if (!ptrval.val) {
|
||||||
const Structure& s = db.dna[f.type];
|
return;
|
||||||
|
|
||||||
// find the file block the pointer is pointing to
|
|
||||||
const FileBlockHead* block = LocateFileBlockForAddress(ptrval,db);
|
|
||||||
|
|
||||||
// also determine the target type from the block header
|
|
||||||
// and check if it matches the type which we expect.
|
|
||||||
const Structure& ss = db.dna[block->dna_index];
|
|
||||||
if (ss != s) {
|
|
||||||
throw Error((Formatter::format(),"Expected target to be of type `",s.name,
|
|
||||||
"` but seemingly it is a `",ss.name,"` instead"
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
// try to retrieve the object from the cache
|
|
||||||
db.cache(out).get(s,out,ptrval);
|
|
||||||
if (out) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// seek to this location, but save the previous stream pointer.
|
|
||||||
const StreamReaderAny::pos pold = db.reader->GetCurrentPos();
|
|
||||||
db.reader->SetCurrentPos(block->start+ static_cast<size_t>((ptrval.val - block->address.val) ));
|
|
||||||
// FIXME: basically, this could cause problems with 64 bit pointers on 32 bit systems.
|
|
||||||
// I really ought to improve StreamReader to work with 64 bit indices exclusively.
|
|
||||||
|
|
||||||
// continue conversion after allocating the required storage
|
|
||||||
size_t num = block->size / ss.size;
|
|
||||||
_allocate(out,num);
|
|
||||||
|
|
||||||
// cache the object before we convert it to avoid
|
|
||||||
// cyclic recursion.
|
|
||||||
db.cache(out).set(s,out,ptrval);
|
|
||||||
|
|
||||||
T* o = out.get();
|
|
||||||
for (size_t i = 0; i < num; ++i,++o) {
|
|
||||||
s.Convert(*o,db);
|
|
||||||
}
|
|
||||||
|
|
||||||
db.reader->SetCurrentPos(pold);
|
|
||||||
}
|
}
|
||||||
|
const Structure& s = db.dna[f.type];
|
||||||
|
// find the file block the pointer is pointing to
|
||||||
|
const FileBlockHead* block = LocateFileBlockForAddress(ptrval,db);
|
||||||
|
|
||||||
|
// also determine the target type from the block header
|
||||||
|
// and check if it matches the type which we expect.
|
||||||
|
const Structure& ss = db.dna[block->dna_index];
|
||||||
|
if (ss != s) {
|
||||||
|
throw Error((Formatter::format(),"Expected target to be of type `",s.name,
|
||||||
|
"` but seemingly it is a `",ss.name,"` instead"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to retrieve the object from the cache
|
||||||
|
db.cache(out).get(s,out,ptrval);
|
||||||
|
if (out) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// seek to this location, but save the previous stream pointer.
|
||||||
|
const StreamReaderAny::pos pold = db.reader->GetCurrentPos();
|
||||||
|
db.reader->SetCurrentPos(block->start+ static_cast<size_t>((ptrval.val - block->address.val) ));
|
||||||
|
// FIXME: basically, this could cause problems with 64 bit pointers on 32 bit systems.
|
||||||
|
// I really ought to improve StreamReader to work with 64 bit indices exclusively.
|
||||||
|
|
||||||
|
// continue conversion after allocating the required storage
|
||||||
|
size_t num = block->size / ss.size;
|
||||||
|
T* o = _allocate(out,num);
|
||||||
|
|
||||||
|
// cache the object before we convert it to avoid cyclic recursion.
|
||||||
|
db.cache(out).set(s,out,ptrval);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < num; ++i,++o) {
|
||||||
|
s.Convert(*o,db);
|
||||||
|
}
|
||||||
|
|
||||||
|
db.reader->SetCurrentPos(pold);
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------------------
|
||||||
|
template <template <typename> class TOUT, typename T>
|
||||||
|
void Structure :: ResolvePointer(vector< TOUT<T> >& out, const Pointer & ptrval, const FileDatabase& db, const Field& f) const
|
||||||
|
{
|
||||||
|
// This is a function overload, not a template specialization. According to
|
||||||
|
// the partial ordering rules, it should be selected by the compiler
|
||||||
|
// for array-of-pointer inputs, i.e. Object::mats.
|
||||||
|
|
||||||
|
out.reset();
|
||||||
|
if (!ptrval.val) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// find the file block the pointer is pointing to
|
||||||
|
const FileBlockHead* block = LocateFileBlockForAddress(ptrval,db);
|
||||||
|
const size_t num = block->size / (db.i64bit?8:4);
|
||||||
|
|
||||||
|
// keep the old stream position
|
||||||
|
const StreamReaderAny::pos pold = db.reader->GetCurrentPos();
|
||||||
|
db.reader->SetCurrentPos(block->start+ static_cast<size_t>((ptrval.val - block->address.val) ));
|
||||||
|
|
||||||
|
// allocate raw storage for the array
|
||||||
|
out.resize(num);
|
||||||
|
for (size_t i = 0; i< num; ++i) {
|
||||||
|
Pointer val;
|
||||||
|
Convert(val,db);
|
||||||
|
|
||||||
|
// and resolve the pointees
|
||||||
|
ResolvePointer(out[i],val,db,f);
|
||||||
|
}
|
||||||
|
|
||||||
|
db.reader->SetCurrentPos(pold);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -297,47 +329,49 @@ template <> void Structure :: ResolvePointer<boost::shared_ptr,ElemBase>(boost::
|
||||||
// Less secure than in the `strongly-typed` case.
|
// Less secure than in the `strongly-typed` case.
|
||||||
|
|
||||||
out.reset();
|
out.reset();
|
||||||
if (ptrval.val) {
|
if (!ptrval.val) {
|
||||||
// find the file block the pointer is pointing to
|
return;
|
||||||
const FileBlockHead* block = LocateFileBlockForAddress(ptrval,db);
|
|
||||||
|
|
||||||
// determine the target type from the block header
|
|
||||||
const Structure& s = db.dna[block->dna_index];
|
|
||||||
|
|
||||||
// try to retrieve the object from the cache
|
|
||||||
db.cache(out).get(s,out,ptrval);
|
|
||||||
if (out) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// seek to this location, but save the previous stream pointer.
|
|
||||||
const StreamReaderAny::pos pold = db.reader->GetCurrentPos();
|
|
||||||
db.reader->SetCurrentPos(block->start+ static_cast<size_t>((ptrval.val - block->address.val) ));
|
|
||||||
// FIXME: basically, this could cause problems with 64 bit pointers on 32 bit systems.
|
|
||||||
// I really ought to improve StreamReader to work with 64 bit indices exclusively.
|
|
||||||
|
|
||||||
// continue conversion after allocating the required storage
|
|
||||||
out = db.dna.ConvertBlobToStructure(s,db);
|
|
||||||
db.reader->SetCurrentPos(pold);
|
|
||||||
if (!out) {
|
|
||||||
// this might happen if DNA::RegisterConverters hasn't been called so far
|
|
||||||
// or if the target type is not contained in `our` DNA.
|
|
||||||
out.reset();
|
|
||||||
DefaultLogger::get()->warn((Formatter::format(),
|
|
||||||
"Failed to find a converter for the `",s.name,"` structure"
|
|
||||||
));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// store a pointer to the name string of the actual type
|
|
||||||
// in the object itself. This allows the conversion code
|
|
||||||
// to perform additional type checking.
|
|
||||||
out->dna_type = s.name.c_str();
|
|
||||||
|
|
||||||
// cache the object now that construction is complete
|
|
||||||
// FIXME we need to do this in ConvertBlobToStructure
|
|
||||||
db.cache(out).set(s,out,ptrval);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// find the file block the pointer is pointing to
|
||||||
|
const FileBlockHead* block = LocateFileBlockForAddress(ptrval,db);
|
||||||
|
|
||||||
|
// determine the target type from the block header
|
||||||
|
const Structure& s = db.dna[block->dna_index];
|
||||||
|
|
||||||
|
// try to retrieve the object from the cache
|
||||||
|
db.cache(out).get(s,out,ptrval);
|
||||||
|
if (out) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// seek to this location, but save the previous stream pointer.
|
||||||
|
const StreamReaderAny::pos pold = db.reader->GetCurrentPos();
|
||||||
|
db.reader->SetCurrentPos(block->start+ static_cast<size_t>((ptrval.val - block->address.val) ));
|
||||||
|
// FIXME: basically, this could cause problems with 64 bit pointers on 32 bit systems.
|
||||||
|
// I really ought to improve StreamReader to work with 64 bit indices exclusively.
|
||||||
|
|
||||||
|
// continue conversion after allocating the required storage
|
||||||
|
out = db.dna.ConvertBlobToStructure(s,db);
|
||||||
|
db.reader->SetCurrentPos(pold);
|
||||||
|
if (!out) {
|
||||||
|
// this might happen if DNA::RegisterConverters hasn't been called so far
|
||||||
|
// or if the target type is not contained in `our` DNA.
|
||||||
|
out.reset();
|
||||||
|
DefaultLogger::get()->warn((Formatter::format(),
|
||||||
|
"Failed to find a converter for the `",s.name,"` structure"
|
||||||
|
));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// store a pointer to the name string of the actual type
|
||||||
|
// in the object itself. This allows the conversion code
|
||||||
|
// to perform additional type checking.
|
||||||
|
out->dna_type = s.name.c_str();
|
||||||
|
|
||||||
|
// cache the object now that construction is complete
|
||||||
|
// FIXME we need to do this in ConvertBlobToStructure
|
||||||
|
db.cache(out).set(s,out,ptrval);
|
||||||
}
|
}
|
||||||
|
|
||||||
//--------------------------------------------------------------------------------
|
//--------------------------------------------------------------------------------
|
||||||
|
@ -352,7 +386,7 @@ const FileBlockHead* Structure :: LocateFileBlockForAddress(const Pointer & ptrv
|
||||||
// which are only used for structures starting with an ID.
|
// which are only used for structures starting with an ID.
|
||||||
// We don't need to make this distinction, our algorithm
|
// We don't need to make this distinction, our algorithm
|
||||||
// works regardless where the data is stored.
|
// works regardless where the data is stored.
|
||||||
std::vector<FileBlockHead>::const_iterator it = std::lower_bound(db.entries.begin(),db.entries.end(),ptrval);
|
vector<FileBlockHead>::const_iterator it = std::lower_bound(db.entries.begin(),db.entries.end(),ptrval);
|
||||||
if (it == db.entries.end()) {
|
if (it == db.entries.end()) {
|
||||||
// this is crucial, pointers may not be invalid.
|
// this is crucial, pointers may not be invalid.
|
||||||
// this is either a corrupted file or an attempted attack.
|
// this is either a corrupted file or an attempted attack.
|
||||||
|
|
|
@ -58,7 +58,7 @@ using namespace Assimp;
|
||||||
using namespace Assimp::Blender;
|
using namespace Assimp::Blender;
|
||||||
using namespace Assimp::Formatter;
|
using namespace Assimp::Formatter;
|
||||||
|
|
||||||
#define for_each BOOST_FOREACH
|
#define for_each(x,y) BOOST_FOREACH(x,y)
|
||||||
|
|
||||||
static const aiLoaderDesc blenderDesc = {
|
static const aiLoaderDesc blenderDesc = {
|
||||||
"Blender 3D Importer \nhttp://www.blender3d.org",
|
"Blender 3D Importer \nhttp://www.blender3d.org",
|
||||||
|
@ -75,9 +75,13 @@ static const aiLoaderDesc blenderDesc = {
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
namespace Blender {
|
namespace Blender {
|
||||||
|
|
||||||
/** Mini smart-array to avoid pulling in even more boost stuff */
|
/** Mini smart-array to avoid pulling in even more boost stuff. usable with vector and deque */
|
||||||
template <template <typename,typename> class TCLASS, typename T>
|
template <template <typename,typename> class TCLASS, typename T>
|
||||||
struct TempArray {
|
struct TempArray {
|
||||||
|
|
||||||
|
TempArray() {
|
||||||
|
}
|
||||||
|
|
||||||
~TempArray () {
|
~TempArray () {
|
||||||
for_each(T* elem, arr) {
|
for_each(T* elem, arr) {
|
||||||
delete elem;
|
delete elem;
|
||||||
|
@ -96,6 +100,26 @@ namespace Blender {
|
||||||
return arr;
|
return arr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TCLASS< T*,std::allocator<T*> >& get () {
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const TCLASS< T*,std::allocator<T*> >& get () const {
|
||||||
|
return arr;
|
||||||
|
}
|
||||||
|
|
||||||
|
T* operator[] (size_t idx) const {
|
||||||
|
return arr[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// no copy semantics
|
||||||
|
void operator= (const TempArray&) {
|
||||||
|
}
|
||||||
|
|
||||||
|
TempArray(const TempArray& arr) {
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TCLASS< T*,std::allocator<T*> > arr;
|
TCLASS< T*,std::allocator<T*> > arr;
|
||||||
};
|
};
|
||||||
|
@ -109,6 +133,9 @@ namespace Blender {
|
||||||
TempArray <std::vector, aiCamera> cameras;
|
TempArray <std::vector, aiCamera> cameras;
|
||||||
TempArray <std::vector, aiLight> lights;
|
TempArray <std::vector, aiLight> lights;
|
||||||
TempArray <std::vector, aiMaterial> materials;
|
TempArray <std::vector, aiMaterial> materials;
|
||||||
|
|
||||||
|
// set of all materials referenced by at least one mesh in the scene
|
||||||
|
std::deque< boost::shared_ptr< Material > > materials_raw;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -304,6 +331,8 @@ void BlenderImporter::ConvertBlendFile(aiScene* out, const Scene& in)
|
||||||
root->mChildren[i]->mParent = root;
|
root->mChildren[i]->mParent = root;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BuildMaterials(conv);
|
||||||
|
|
||||||
if (conv.meshes->size()) {
|
if (conv.meshes->size()) {
|
||||||
out->mMeshes = new aiMesh*[out->mNumMeshes = static_cast<unsigned int>( conv.meshes->size() )];
|
out->mMeshes = new aiMesh*[out->mNumMeshes = static_cast<unsigned int>( conv.meshes->size() )];
|
||||||
std::copy(conv.meshes->begin(),conv.meshes->end(),out->mMeshes);
|
std::copy(conv.meshes->begin(),conv.meshes->end(),out->mMeshes);
|
||||||
|
@ -332,12 +361,67 @@ void BlenderImporter::ConvertBlendFile(aiScene* out, const Scene& in)
|
||||||
// acknowledge that the scene might come out incomplete
|
// acknowledge that the scene might come out incomplete
|
||||||
// by Assimps definition of `complete`: blender scenes
|
// by Assimps definition of `complete`: blender scenes
|
||||||
// can consist of thousands of cameras or lights with
|
// can consist of thousands of cameras or lights with
|
||||||
// not a single mesh in them.
|
// not a single mesh between them.
|
||||||
if (!out->mNumMeshes) {
|
if (!out->mNumMeshes) {
|
||||||
out->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
|
out->mFlags |= AI_SCENE_FLAGS_INCOMPLETE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void BlenderImporter::BuildMaterials(ConversionData& conv_data)
|
||||||
|
{
|
||||||
|
conv_data.materials->reserve(conv_data.materials_raw.size());
|
||||||
|
|
||||||
|
// add a default material if necessary
|
||||||
|
unsigned int index = static_cast<unsigned int>( -1 );
|
||||||
|
for_each( aiMesh* mesh, conv_data.meshes.get() ) {
|
||||||
|
if (mesh->mMaterialIndex == static_cast<unsigned int>( -1 )) {
|
||||||
|
|
||||||
|
if (index == static_cast<unsigned int>( -1 )) {
|
||||||
|
|
||||||
|
// ok, we need to add a dedicated default material for some poor material-less meshes
|
||||||
|
boost::shared_ptr<Material> p(new Material());
|
||||||
|
strcpy( p->id.name, "$AssimpDefault" );
|
||||||
|
|
||||||
|
p->r = p->g = p->b = 0.6f;
|
||||||
|
p->specr = p->specg = p->specb = 0.6f;
|
||||||
|
p->ambir = p->ambig = p->ambib = 0.0f;
|
||||||
|
p->emit = 0.f;
|
||||||
|
p->alpha = 0.f;
|
||||||
|
|
||||||
|
// XXX add more / or add default c'tor to Material
|
||||||
|
|
||||||
|
index = static_cast<unsigned int>( conv_data.materials_raw.size() );
|
||||||
|
conv_data.materials_raw.push_back(p);
|
||||||
|
|
||||||
|
LogInfo("Adding default material ...");
|
||||||
|
}
|
||||||
|
mesh->mMaterialIndex = index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for_each(boost::shared_ptr<Material> mat, conv_data.materials_raw) {
|
||||||
|
|
||||||
|
MaterialHelper* mout = new MaterialHelper();
|
||||||
|
conv_data.materials->push_back(mout);
|
||||||
|
|
||||||
|
// set material name
|
||||||
|
aiString name = aiString(mat->id.name);
|
||||||
|
mout->AddProperty(&name,AI_MATKEY_NAME);
|
||||||
|
|
||||||
|
|
||||||
|
// basic material colors
|
||||||
|
aiColor3D col(mat->r,mat->g,mat->b);
|
||||||
|
mout->AddProperty(&col,1,AI_MATKEY_COLOR_DIFFUSE);
|
||||||
|
|
||||||
|
col = aiColor3D(mat->specr,mat->specg,mat->specb);
|
||||||
|
mout->AddProperty(&col,1,AI_MATKEY_COLOR_SPECULAR);
|
||||||
|
|
||||||
|
col = aiColor3D(mat->ambir,mat->ambig,mat->ambib);
|
||||||
|
mout->AddProperty(&col,1,AI_MATKEY_COLOR_AMBIENT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void BlenderImporter::CheckActualType(const ElemBase* dt, const char* check)
|
void BlenderImporter::CheckActualType(const ElemBase* dt, const char* check)
|
||||||
{
|
{
|
||||||
|
@ -357,25 +441,93 @@ void BlenderImporter::NotSupportedObjectType(const Object* obj, const char* type
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
aiMesh* BlenderImporter::ConvertMesh(const Scene& in, const Object* obj, const Mesh* mesh, ConversionData& conv_data)
|
void BlenderImporter::ConvertMesh(const Scene& in, const Object* obj, const Mesh* mesh,
|
||||||
|
ConversionData& conv_data, TempArray<std::vector,aiMesh>& temp
|
||||||
|
)
|
||||||
{
|
{
|
||||||
|
typedef std::pair<const int,size_t> MyPair;
|
||||||
if (!mesh->totface || !mesh->totvert) {
|
if (!mesh->totface || !mesh->totvert) {
|
||||||
return NULL;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScopeGuard<aiMesh> out(new aiMesh());
|
// some sanity checks
|
||||||
|
if (mesh->totface > mesh->mface.size() ){
|
||||||
|
ThrowException("Number of faces is larger than the corresponding array");
|
||||||
|
}
|
||||||
|
|
||||||
aiVector3D* vo = out->mVertices = new aiVector3D[mesh->totface*4];
|
if (mesh->totvert > mesh->mvert.size()) {
|
||||||
aiVector3D* vn = out->mNormals = new aiVector3D[mesh->totface*4];
|
ThrowException("Number of vertices is larger than the corresponding array");
|
||||||
|
}
|
||||||
|
|
||||||
out->mNumFaces = mesh->totface;
|
// collect per-submesh numbers
|
||||||
out->mFaces = new aiFace[out->mNumFaces]();
|
std::map<int,size_t> per_mat;
|
||||||
|
for (int i = 0; i < mesh->totface; ++i) {
|
||||||
for (unsigned int i = 0; i < out->mNumFaces; ++i) {
|
|
||||||
aiFace& f = out->mFaces[i];
|
|
||||||
|
|
||||||
const MFace& mf = mesh->mface[i];
|
const MFace& mf = mesh->mface[i];
|
||||||
|
per_mat[ mf.mat_nr ]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ... and allocate the corresponding meshes
|
||||||
|
const size_t old = temp->size();
|
||||||
|
temp->reserve(temp->size() + per_mat.size());
|
||||||
|
|
||||||
|
std::map<size_t,size_t> mat_num_to_mesh_idx;
|
||||||
|
for_each(MyPair& it, per_mat) {
|
||||||
|
|
||||||
|
mat_num_to_mesh_idx[it.first] = temp->size();
|
||||||
|
temp->push_back(new aiMesh());
|
||||||
|
|
||||||
|
aiMesh* out = temp->back();
|
||||||
|
out->mVertices = new aiVector3D[it.second*4];
|
||||||
|
out->mNormals = new aiVector3D[it.second*4];
|
||||||
|
|
||||||
|
//out->mNumFaces = 0
|
||||||
|
//out->mNumVertices = 0
|
||||||
|
out->mFaces = new aiFace[it.second]();
|
||||||
|
|
||||||
|
// all submeshes created from this mesh are named equally. this allows
|
||||||
|
// curious users to recover the original adjacency.
|
||||||
|
out->mName = aiString(mesh->id.name);
|
||||||
|
|
||||||
|
// resolve the material reference and add this material to the set of
|
||||||
|
// output materials. The (temporary) material index is the index
|
||||||
|
// of the material entry within the list of resolved materials.
|
||||||
|
if (mesh->mat) {
|
||||||
|
|
||||||
|
if (it.first >= mesh->mat.size() ) {
|
||||||
|
ThrowException("Material index is out of range");
|
||||||
|
}
|
||||||
|
|
||||||
|
boost::shared_ptr<Material> mat = mesh->mat[it.first];
|
||||||
|
const std::deque< boost::shared_ptr<Material> >::iterator has = std::find(
|
||||||
|
conv_data.materials_raw.begin(),
|
||||||
|
conv_data.materials_raw.end(),mat
|
||||||
|
);
|
||||||
|
|
||||||
|
if (has != conv_data.materials_raw.end()) {
|
||||||
|
out->mMaterialIndex = static_cast<unsigned int>( std::distance(conv_data.materials_raw.begin(),has));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
out->mMaterialIndex = static_cast<unsigned int>( conv_data.materials_raw.size() );
|
||||||
|
conv_data.materials_raw.push_back(mat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else out->mMaterialIndex = static_cast<unsigned int>( -1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < mesh->totface; ++i) {
|
||||||
|
|
||||||
|
const MFace& mf = mesh->mface[i];
|
||||||
|
|
||||||
|
aiMesh* const out = temp[ mat_num_to_mesh_idx[ mf.mat_nr ] ];
|
||||||
|
aiFace& f = out->mFaces[out->mNumFaces++];
|
||||||
|
|
||||||
f.mIndices = new unsigned int[ f.mNumIndices = mf.v4?4:3 ];
|
f.mIndices = new unsigned int[ f.mNumIndices = mf.v4?4:3 ];
|
||||||
|
aiVector3D* vo = out->mVertices + out->mNumVertices;
|
||||||
|
aiVector3D* vn = out->mNormals + out->mNumVertices;
|
||||||
|
|
||||||
|
// XXX we can't fold this easily, because we are restricted
|
||||||
|
// to the member names from the BLEND file (v1,v2,v3,v4) ..
|
||||||
|
|
||||||
if (mf.v1 >= mesh->totvert) {
|
if (mf.v1 >= mesh->totvert) {
|
||||||
ThrowException("Vertex index v1 out of range");
|
ThrowException("Vertex index v1 out of range");
|
||||||
|
@ -426,56 +578,97 @@ aiMesh* BlenderImporter::ConvertMesh(const Scene& in, const Object* obj, const M
|
||||||
}
|
}
|
||||||
// if (f.mNumIndices >= 4) {
|
// if (f.mNumIndices >= 4) {
|
||||||
if (mf.v4) {
|
if (mf.v4) {
|
||||||
v = &mesh->mvert[mf.v4];
|
v = &mesh->mvert[mf.v4];
|
||||||
vo->x = v->co[0];
|
vo->x = v->co[0];
|
||||||
vo->y = v->co[1];
|
vo->y = v->co[1];
|
||||||
vo->z = v->co[2];
|
vo->z = v->co[2];
|
||||||
vn->x = v->no[0];
|
vn->x = v->no[0];
|
||||||
vn->y = v->no[1];
|
vn->y = v->no[1];
|
||||||
vn->z = v->no[2];
|
vn->z = v->no[2];
|
||||||
f.mIndices[3] = out->mNumVertices++;
|
f.mIndices[3] = out->mNumVertices++;
|
||||||
++vo;
|
++vo;
|
||||||
++vn;
|
++vn;
|
||||||
|
|
||||||
|
out->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
|
||||||
}
|
}
|
||||||
|
else out->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
|
||||||
|
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// collect texture coordinates, they're stored in a separate per-face buffer
|
||||||
if (mesh->mtface) {
|
if (mesh->mtface) {
|
||||||
vo = out->mTextureCoords[0] = new aiVector3D[out->mNumVertices];
|
if (mesh->totface > mesh->mtface.size()) {
|
||||||
|
ThrowException("Number of UV faces is larger than the corresponding UV face array (#1)");
|
||||||
|
}
|
||||||
|
for (std::vector<aiMesh*>::iterator it = temp->begin()+old; it != temp->end(); ++it) {
|
||||||
|
ai_assert((*it)->mNumVertices && (*it)->mNumFaces);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < out->mNumFaces; ++i) {
|
(*it)->mTextureCoords[0] = new aiVector3D[(*it)->mNumVertices];
|
||||||
const aiFace& f = out->mFaces[i];
|
(*it)->mNumFaces = (*it)->mNumVertices = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < mesh->totface; ++i) {
|
||||||
const MTFace* v = &mesh->mtface[i];
|
const MTFace* v = &mesh->mtface[i];
|
||||||
for (unsigned int i = 0; i < f.mNumIndices; ++i,++vo) {
|
|
||||||
vo->x = v->uv[i][0];
|
|
||||||
vo->y = v->uv[i][1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mesh->tface) {
|
aiMesh* const out = temp[ mat_num_to_mesh_idx[ mesh->mface[i].mat_nr ] ];
|
||||||
vo = out->mTextureCoords[0] = new aiVector3D[out->mNumVertices];
|
const aiFace& f = out->mFaces[out->mNumFaces++];
|
||||||
|
|
||||||
for (unsigned int i = 0; i < out->mNumFaces; ++i) {
|
|
||||||
const aiFace& f = out->mFaces[i];
|
|
||||||
|
|
||||||
const TFace* v = &mesh->tface[i];
|
|
||||||
for (unsigned int i = 0; i < f.mNumIndices; ++i,++vo) {
|
|
||||||
vo->x = v->uv[i][0];
|
|
||||||
vo->y = v->uv[i][1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mesh->mcol) {
|
|
||||||
aiColor4D* vo = out->mColors[0] = new aiColor4D[out->mNumVertices];
|
|
||||||
for (unsigned int i = 0; i < out->mNumFaces; ++i) {
|
|
||||||
|
|
||||||
for (unsigned int n = 0; n < 4; ++n, ++vo) {
|
aiVector3D* vo = &out->mTextureCoords[0][out->mNumVertices];
|
||||||
|
for (unsigned int i = 0; i < f.mNumIndices; ++i,++vo,++out->mNumVertices) {
|
||||||
|
vo->x = v->uv[i][0];
|
||||||
|
vo->y = v->uv[i][1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// collect texture coordinates, old-style (marked as deprecated in current blender sources)
|
||||||
|
if (mesh->tface) {
|
||||||
|
if (mesh->totface > mesh->mtface.size()) {
|
||||||
|
ThrowException("Number of faces is larger than the corresponding UV face array (#2)");
|
||||||
|
}
|
||||||
|
for (std::vector<aiMesh*>::iterator it = temp->begin()+old; it != temp->end(); ++it) {
|
||||||
|
ai_assert((*it)->mNumVertices && (*it)->mNumFaces);
|
||||||
|
|
||||||
|
(*it)->mTextureCoords[0] = new aiVector3D[(*it)->mNumVertices];
|
||||||
|
(*it)->mNumFaces = (*it)->mNumVertices = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < mesh->totface; ++i) {
|
||||||
|
const TFace* v = &mesh->tface[i];
|
||||||
|
|
||||||
|
aiMesh* const out = temp[ mat_num_to_mesh_idx[ mesh->mface[i].mat_nr ] ];
|
||||||
|
const aiFace& f = out->mFaces[out->mNumFaces++];
|
||||||
|
|
||||||
|
aiVector3D* vo = &out->mTextureCoords[0][out->mNumVertices];
|
||||||
|
for (unsigned int i = 0; i < f.mNumIndices; ++i,++vo,++out->mNumVertices) {
|
||||||
|
vo->x = v->uv[i][0];
|
||||||
|
vo->y = v->uv[i][1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// collect vertex colors, stored separately as well
|
||||||
|
if (mesh->mcol) {
|
||||||
|
if (mesh->totface > (mesh->mcol.size()/4)) {
|
||||||
|
ThrowException("Number of faces is larger than the corresponding color face array");
|
||||||
|
}
|
||||||
|
for (std::vector<aiMesh*>::iterator it = temp->begin()+old; it != temp->end(); ++it) {
|
||||||
|
ai_assert((*it)->mNumVertices && (*it)->mNumFaces);
|
||||||
|
|
||||||
|
(*it)->mColors[0] = new aiColor4D[(*it)->mNumVertices];
|
||||||
|
(*it)->mNumFaces = (*it)->mNumVertices = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < mesh->totface; ++i) {
|
||||||
|
|
||||||
|
aiMesh* const out = temp[ mat_num_to_mesh_idx[ mesh->mface[i].mat_nr ] ];
|
||||||
|
const aiFace& f = out->mFaces[out->mNumFaces++];
|
||||||
|
|
||||||
|
aiColor4D* vo = &out->mColors[0][out->mNumVertices];
|
||||||
|
for (unsigned int n = 0; n < f.mNumIndices; ++n, ++vo,++out->mNumVertices) {
|
||||||
const MCol* col = &mesh->mcol[(i<<2)+n];
|
const MCol* col = &mesh->mcol[(i<<2)+n];
|
||||||
|
|
||||||
vo->r = col->r;
|
vo->r = col->r;
|
||||||
|
@ -483,10 +676,11 @@ aiMesh* BlenderImporter::ConvertMesh(const Scene& in, const Object* obj, const M
|
||||||
vo->b = col->b;
|
vo->b = col->b;
|
||||||
vo->a = col->a;
|
vo->a = col->a;
|
||||||
}
|
}
|
||||||
|
for (unsigned int n = f.mNumIndices; n < 4; ++n);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return out.dismiss();
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
@ -509,15 +703,15 @@ aiLight* BlenderImporter::ConvertLight(const Scene& in, const Object* obj, const
|
||||||
aiNode* BlenderImporter::ConvertNode(const Scene& in, const Object* obj, ConversionData& conv_data)
|
aiNode* BlenderImporter::ConvertNode(const Scene& in, const Object* obj, ConversionData& conv_data)
|
||||||
{
|
{
|
||||||
std::deque<const Object*> children;
|
std::deque<const Object*> children;
|
||||||
for(std::set<const Object*>::iterator it = conv_data.objects.begin(); it != conv_data.objects.end() ;++it) {
|
for(std::set<const Object*>::iterator it = conv_data.objects.begin(); it != conv_data.objects.end() ;) {
|
||||||
const Object* object = *it;
|
const Object* object = *it;
|
||||||
if (object->parent.get() == obj) {
|
if (object->parent.get() == obj) {
|
||||||
children.push_back(object);
|
children.push_back(object);
|
||||||
|
|
||||||
conv_data.objects.erase(it++);
|
conv_data.objects.erase(it++);
|
||||||
if(it == conv_data.objects.end()) {
|
continue;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
++it;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScopeGuard<aiNode> node(new aiNode(obj->id.name));
|
ScopeGuard<aiNode> node(new aiNode(obj->id.name));
|
||||||
|
@ -530,15 +724,16 @@ aiNode* BlenderImporter::ConvertNode(const Scene& in, const Object* obj, Convers
|
||||||
|
|
||||||
// supported object types
|
// supported object types
|
||||||
case Object :: Type_MESH: {
|
case Object :: Type_MESH: {
|
||||||
|
const size_t old = conv_data.meshes->size();
|
||||||
|
|
||||||
CheckActualType(obj->data.get(),"Mesh");
|
CheckActualType(obj->data.get(),"Mesh");
|
||||||
aiMesh* mesh = ConvertMesh(in,obj,static_cast<const Mesh*>(
|
ConvertMesh(in,obj,static_cast<const Mesh*>(obj->data.get()),conv_data,conv_data.meshes);
|
||||||
obj->data.get()),conv_data);
|
|
||||||
|
|
||||||
if (mesh) {
|
if (conv_data.meshes->size() > old) {
|
||||||
node->mMeshes = new unsigned int[node->mNumMeshes = 1u];
|
node->mMeshes = new unsigned int[node->mNumMeshes = static_cast<unsigned int>(conv_data.meshes->size()-old)];
|
||||||
node->mMeshes[0] = conv_data.meshes->size();
|
for (unsigned int i = 0; i < node->mNumMeshes; ++i) {
|
||||||
|
node->mMeshes[i] = i + old;
|
||||||
conv_data.meshes->push_back(mesh);
|
}
|
||||||
}}
|
}}
|
||||||
break;
|
break;
|
||||||
case Object :: Type_LAMP: {
|
case Object :: Type_LAMP: {
|
||||||
|
|
|
@ -71,6 +71,7 @@ namespace Assimp {
|
||||||
// BlenderLoader.cpp
|
// BlenderLoader.cpp
|
||||||
namespace Blender {
|
namespace Blender {
|
||||||
struct ConversionData;
|
struct ConversionData;
|
||||||
|
template <template <typename,typename> class TCLASS, typename T> struct TempArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -168,10 +169,11 @@ private:
|
||||||
);
|
);
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
aiMesh* ConvertMesh(const Blender::Scene& in,
|
void ConvertMesh(const Blender::Scene& in,
|
||||||
const Blender::Object* obj,
|
const Blender::Object* obj,
|
||||||
const Blender::Mesh* mesh,
|
const Blender::Mesh* mesh,
|
||||||
Blender::ConversionData& conv_data
|
Blender::ConversionData& conv_data,
|
||||||
|
Blender::TempArray<std::vector,aiMesh>& temp
|
||||||
);
|
);
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
|
@ -188,6 +190,9 @@ private:
|
||||||
Blender::ConversionData& conv_data
|
Blender::ConversionData& conv_data
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// --------------------
|
||||||
|
void BuildMaterials(Blender::ConversionData& conv_data) ;
|
||||||
|
|
||||||
private: // static stuff, mostly logging and error reporting.
|
private: // static stuff, mostly logging and error reporting.
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
|
|
|
@ -58,18 +58,18 @@ template <> void Structure :: Convert<Object> (
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
|
|
||||||
ReadField<ErrorPolicy_Igno>(dest.id,"id",db);
|
ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
|
||||||
ReadField<ErrorPolicy_Igno>((int&)dest.type,"type",db);
|
ReadField<ErrorPolicy_Fail>((int&)dest.type,"type",db);
|
||||||
ReadFieldArray2<ErrorPolicy_Igno>(dest.obmat,"obmat",db);
|
ReadFieldArray2<ErrorPolicy_Warn>(dest.obmat,"obmat",db);
|
||||||
ReadFieldArray2<ErrorPolicy_Igno>(dest.parentinv,"parentinv",db);
|
ReadFieldArray2<ErrorPolicy_Warn>(dest.parentinv,"parentinv",db);
|
||||||
ReadFieldArray<ErrorPolicy_Igno>(dest.parsubstr,"parsubstr",db);
|
ReadFieldArray<ErrorPolicy_Warn>(dest.parsubstr,"parsubstr",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.parent,"*parent",db);
|
ReadFieldPtr<ErrorPolicy_Warn>(dest.parent,"*parent",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.track,"*track",db);
|
ReadFieldPtr<ErrorPolicy_Warn>(dest.track,"*track",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.proxy,"*proxy",db);
|
ReadFieldPtr<ErrorPolicy_Warn>(dest.proxy,"*proxy",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.proxy_from,"*proxy_from",db);
|
ReadFieldPtr<ErrorPolicy_Warn>(dest.proxy_from,"*proxy_from",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.proxy_group,"*proxy_group",db);
|
ReadFieldPtr<ErrorPolicy_Warn>(dest.proxy_group,"*proxy_group",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.dup_group,"*dup_group",db);
|
ReadFieldPtr<ErrorPolicy_Warn>(dest.dup_group,"*dup_group",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.data,"*data",db);
|
ReadFieldPtr<ErrorPolicy_Fail>(dest.data,"*data",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ template <> void Structure :: Convert<Group> (
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
|
|
||||||
ReadField<ErrorPolicy_Igno>(dest.id,"id",db);
|
ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.layer,"layer",db);
|
ReadField<ErrorPolicy_Igno>(dest.layer,"layer",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.gobject,"*gobject",db);
|
ReadFieldPtr<ErrorPolicy_Igno>(dest.gobject,"*gobject",db);
|
||||||
|
|
||||||
|
@ -110,10 +110,10 @@ template <> void Structure :: Convert<MTex> (
|
||||||
ReadField<ErrorPolicy_Igno>(dest.colormodel,"colormodel",db);
|
ReadField<ErrorPolicy_Igno>(dest.colormodel,"colormodel",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.pmapto,"pmapto",db);
|
ReadField<ErrorPolicy_Igno>(dest.pmapto,"pmapto",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.pmaptoneg,"pmaptoneg",db);
|
ReadField<ErrorPolicy_Igno>(dest.pmaptoneg,"pmaptoneg",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.r,"r",db);
|
ReadField<ErrorPolicy_Warn>(dest.r,"r",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.g,"g",db);
|
ReadField<ErrorPolicy_Warn>(dest.g,"g",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.b,"b",db);
|
ReadField<ErrorPolicy_Warn>(dest.b,"b",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.k,"k",db);
|
ReadField<ErrorPolicy_Warn>(dest.k,"k",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.colspecfac,"colspecfac",db);
|
ReadField<ErrorPolicy_Igno>(dest.colspecfac,"colspecfac",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.mirrfac,"mirrfac",db);
|
ReadField<ErrorPolicy_Igno>(dest.mirrfac,"mirrfac",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.alphafac,"alphafac",db);
|
ReadField<ErrorPolicy_Igno>(dest.alphafac,"alphafac",db);
|
||||||
|
@ -132,8 +132,8 @@ template <> void Structure :: Convert<TFace> (
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
|
|
||||||
ReadFieldArray2<ErrorPolicy_Igno>(dest.uv,"uv",db);
|
ReadFieldArray2<ErrorPolicy_Fail>(dest.uv,"uv",db);
|
||||||
ReadFieldArray<ErrorPolicy_Igno>(dest.col,"col",db);
|
ReadFieldArray<ErrorPolicy_Fail>(dest.col,"col",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
|
ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.mode,"mode",db);
|
ReadField<ErrorPolicy_Igno>(dest.mode,"mode",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.tile,"tile",db);
|
ReadField<ErrorPolicy_Igno>(dest.tile,"tile",db);
|
||||||
|
@ -149,11 +149,11 @@ template <> void Structure :: Convert<MFace> (
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
|
|
||||||
ReadField<ErrorPolicy_Igno>(dest.v1,"v1",db);
|
ReadField<ErrorPolicy_Fail>(dest.v1,"v1",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.v2,"v2",db);
|
ReadField<ErrorPolicy_Fail>(dest.v2,"v2",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.v3,"v3",db);
|
ReadField<ErrorPolicy_Fail>(dest.v3,"v3",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.v4,"v4",db);
|
ReadField<ErrorPolicy_Fail>(dest.v4,"v4",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.mat_nr,"mat_nr",db);
|
ReadField<ErrorPolicy_Fail>(dest.mat_nr,"mat_nr",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
|
ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
|
@ -166,15 +166,15 @@ template <> void Structure :: Convert<Lamp> (
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
|
|
||||||
ReadField<ErrorPolicy_Igno>(dest.id,"id",db);
|
ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
|
||||||
ReadField<ErrorPolicy_Igno>((int&)dest.type,"type",db);
|
ReadField<ErrorPolicy_Fail>((int&)dest.type,"type",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.flags,"flags",db);
|
ReadField<ErrorPolicy_Igno>(dest.flags,"flags",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.colormodel,"colormodel",db);
|
ReadField<ErrorPolicy_Igno>(dest.colormodel,"colormodel",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.totex,"totex",db);
|
ReadField<ErrorPolicy_Igno>(dest.totex,"totex",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.r,"r",db);
|
ReadField<ErrorPolicy_Warn>(dest.r,"r",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.g,"g",db);
|
ReadField<ErrorPolicy_Warn>(dest.g,"g",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.b,"b",db);
|
ReadField<ErrorPolicy_Warn>(dest.b,"b",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.k,"k",db);
|
ReadField<ErrorPolicy_Warn>(dest.k,"k",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.energy,"energy",db);
|
ReadField<ErrorPolicy_Igno>(dest.energy,"energy",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.dist,"dist",db);
|
ReadField<ErrorPolicy_Igno>(dest.dist,"dist",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.spotsize,"spotsize",db);
|
ReadField<ErrorPolicy_Igno>(dest.spotsize,"spotsize",db);
|
||||||
|
@ -194,8 +194,8 @@ template <> void Structure :: Convert<MDeformWeight> (
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
|
|
||||||
ReadField<ErrorPolicy_Igno>(dest.def_nr,"def_nr",db);
|
ReadField<ErrorPolicy_Fail>(dest.def_nr,"def_nr",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.weight,"weight",db);
|
ReadField<ErrorPolicy_Fail>(dest.weight,"weight",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
@ -218,9 +218,9 @@ template <> void Structure :: Convert<Base> (
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
|
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.prev,"*prev",db);
|
ReadFieldPtr<ErrorPolicy_Warn>(dest.prev,"*prev",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.next,"*next",db);
|
ReadFieldPtr<ErrorPolicy_Warn>(dest.next,"*next",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.object,"*object",db);
|
ReadFieldPtr<ErrorPolicy_Warn>(dest.object,"*object",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
@ -232,7 +232,7 @@ template <> void Structure :: Convert<MTFace> (
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
|
|
||||||
ReadFieldArray2<ErrorPolicy_Igno>(dest.uv,"uv",db);
|
ReadFieldArray2<ErrorPolicy_Fail>(dest.uv,"uv",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
|
ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.mode,"mode",db);
|
ReadField<ErrorPolicy_Igno>(dest.mode,"mode",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.tile,"tile",db);
|
ReadField<ErrorPolicy_Igno>(dest.tile,"tile",db);
|
||||||
|
@ -248,29 +248,29 @@ template <> void Structure :: Convert<Material> (
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
|
|
||||||
ReadField<ErrorPolicy_Igno>(dest.id,"id",db);
|
ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.r,"r",db);
|
ReadField<ErrorPolicy_Warn>(dest.r,"r",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.g,"g",db);
|
ReadField<ErrorPolicy_Warn>(dest.g,"g",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.b,"b",db);
|
ReadField<ErrorPolicy_Warn>(dest.b,"b",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.specr,"specr",db);
|
ReadField<ErrorPolicy_Warn>(dest.specr,"specr",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.specg,"specg",db);
|
ReadField<ErrorPolicy_Warn>(dest.specg,"specg",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.specb,"specb",db);
|
ReadField<ErrorPolicy_Warn>(dest.specb,"specb",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.ambir,"ambir",db);
|
ReadField<ErrorPolicy_Warn>(dest.ambir,"ambir",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.ambig,"ambig",db);
|
ReadField<ErrorPolicy_Warn>(dest.ambig,"ambig",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.ambib,"ambib",db);
|
ReadField<ErrorPolicy_Warn>(dest.ambib,"ambib",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.mirr,"mirr",db);
|
ReadField<ErrorPolicy_Igno>(dest.mirr,"mirr",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.mirg,"mirg",db);
|
ReadField<ErrorPolicy_Igno>(dest.mirg,"mirg",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.mirb,"mirb",db);
|
ReadField<ErrorPolicy_Igno>(dest.mirb,"mirb",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.emit,"emit",db);
|
ReadField<ErrorPolicy_Warn>(dest.emit,"emit",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.alpha,"alpha",db);
|
ReadField<ErrorPolicy_Warn>(dest.alpha,"alpha",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.ref,"ref",db);
|
ReadField<ErrorPolicy_Igno>(dest.ref,"ref",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.translucency,"translucency",db);
|
ReadField<ErrorPolicy_Igno>(dest.translucency,"translucency",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.roughness,"roughness",db);
|
ReadField<ErrorPolicy_Igno>(dest.roughness,"roughness",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.darkness,"darkness",db);
|
ReadField<ErrorPolicy_Igno>(dest.darkness,"darkness",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.refrac,"refrac",db);
|
ReadField<ErrorPolicy_Igno>(dest.refrac,"refrac",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.group,"*group",db);
|
ReadFieldPtr<ErrorPolicy_Igno>(dest.group,"*group",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.diff_shader,"diff_shader",db);
|
ReadField<ErrorPolicy_Warn>(dest.diff_shader,"diff_shader",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.spec_shader,"spec_shader",db);
|
ReadField<ErrorPolicy_Warn>(dest.spec_shader,"spec_shader",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
@ -282,21 +282,22 @@ template <> void Structure :: Convert<Mesh> (
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
|
|
||||||
ReadField<ErrorPolicy_Igno>(dest.id,"id",db);
|
ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.totface,"totface",db);
|
ReadField<ErrorPolicy_Fail>(dest.totface,"totface",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.totedge,"totedge",db);
|
ReadField<ErrorPolicy_Fail>(dest.totedge,"totedge",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.totvert,"totvert",db);
|
ReadField<ErrorPolicy_Fail>(dest.totvert,"totvert",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.subdiv,"subdiv",db);
|
ReadField<ErrorPolicy_Igno>(dest.subdiv,"subdiv",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.subdivr,"subdivr",db);
|
ReadField<ErrorPolicy_Igno>(dest.subdivr,"subdivr",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.subsurftype,"subsurftype",db);
|
ReadField<ErrorPolicy_Igno>(dest.subsurftype,"subsurftype",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.smoothresh,"smoothresh",db);
|
ReadField<ErrorPolicy_Igno>(dest.smoothresh,"smoothresh",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.mface,"*mface",db);
|
ReadFieldPtr<ErrorPolicy_Fail>(dest.mface,"*mface",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.mtface,"*mtface",db);
|
ReadFieldPtr<ErrorPolicy_Igno>(dest.mtface,"*mtface",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.tface,"*tface",db);
|
ReadFieldPtr<ErrorPolicy_Igno>(dest.tface,"*tface",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.mvert,"*mvert",db);
|
ReadFieldPtr<ErrorPolicy_Fail>(dest.mvert,"*mvert",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.medge,"*medge",db);
|
ReadFieldPtr<ErrorPolicy_Warn>(dest.medge,"*medge",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.dvert,"*dvert",db);
|
ReadFieldPtr<ErrorPolicy_Igno>(dest.dvert,"*dvert",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.mcol,"*mcol",db);
|
ReadFieldPtr<ErrorPolicy_Igno>(dest.mcol,"*mcol",db);
|
||||||
|
ReadFieldPtr<ErrorPolicy_Fail>(dest.mat,"**mat",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
@ -308,7 +309,7 @@ template <> void Structure :: Convert<MDeformVert> (
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
|
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.dw,"*dw",db);
|
ReadFieldPtr<ErrorPolicy_Warn>(dest.dw,"*dw",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.totweight,"totweight",db);
|
ReadField<ErrorPolicy_Igno>(dest.totweight,"totweight",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
|
@ -321,7 +322,7 @@ template <> void Structure :: Convert<World> (
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
|
|
||||||
ReadField<ErrorPolicy_Igno>(dest.id,"id",db);
|
ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
@ -333,11 +334,11 @@ template <> void Structure :: Convert<MVert> (
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
|
|
||||||
ReadFieldArray<ErrorPolicy_Igno>(dest.co,"co",db);
|
ReadFieldArray<ErrorPolicy_Fail>(dest.co,"co",db);
|
||||||
ReadFieldArray<ErrorPolicy_Igno>(dest.no,"no",db);
|
ReadFieldArray<ErrorPolicy_Fail>(dest.no,"no",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
|
ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.mat_nr,"mat_nr",db);
|
ReadField<ErrorPolicy_Warn>(dest.mat_nr,"mat_nr",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.bweight,"bweight",db);
|
ReadField<ErrorPolicy_Fail>(dest.bweight,"bweight",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
@ -349,8 +350,8 @@ template <> void Structure :: Convert<MEdge> (
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
|
|
||||||
ReadField<ErrorPolicy_Igno>(dest.v1,"v1",db);
|
ReadField<ErrorPolicy_Fail>(dest.v1,"v1",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.v2,"v2",db);
|
ReadField<ErrorPolicy_Fail>(dest.v2,"v2",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.crease,"crease",db);
|
ReadField<ErrorPolicy_Igno>(dest.crease,"crease",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.bweight,"bweight",db);
|
ReadField<ErrorPolicy_Igno>(dest.bweight,"bweight",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
|
ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
|
||||||
|
@ -365,8 +366,8 @@ template <> void Structure :: Convert<GroupObject> (
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
|
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.prev,"*prev",db);
|
ReadFieldPtr<ErrorPolicy_Fail>(dest.prev,"*prev",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.next,"*next",db);
|
ReadFieldPtr<ErrorPolicy_Fail>(dest.next,"*next",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.ob,"*ob",db);
|
ReadFieldPtr<ErrorPolicy_Igno>(dest.ob,"*ob",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
|
@ -392,7 +393,7 @@ template <> void Structure :: Convert<ID> (
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
|
|
||||||
ReadFieldArray<ErrorPolicy_Igno>(dest.name,"name",db);
|
ReadFieldArray<ErrorPolicy_Warn>(dest.name,"name",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
|
ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
|
@ -405,10 +406,10 @@ template <> void Structure :: Convert<MCol> (
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
|
|
||||||
ReadField<ErrorPolicy_Igno>(dest.r,"r",db);
|
ReadField<ErrorPolicy_Fail>(dest.r,"r",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.g,"g",db);
|
ReadField<ErrorPolicy_Fail>(dest.g,"g",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.b,"b",db);
|
ReadField<ErrorPolicy_Fail>(dest.b,"b",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.a,"a",db);
|
ReadField<ErrorPolicy_Fail>(dest.a,"a",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
@ -420,8 +421,8 @@ template <> void Structure :: Convert<Image> (
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
|
|
||||||
ReadField<ErrorPolicy_Igno>(dest.id,"id",db);
|
ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
|
||||||
ReadFieldArray<ErrorPolicy_Igno>(dest.name,"name",db);
|
ReadFieldArray<ErrorPolicy_Warn>(dest.name,"name",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.ok,"ok",db);
|
ReadField<ErrorPolicy_Igno>(dest.ok,"ok",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
|
ReadField<ErrorPolicy_Igno>(dest.flag,"flag",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.source,"source",db);
|
ReadField<ErrorPolicy_Igno>(dest.source,"source",db);
|
||||||
|
@ -453,10 +454,10 @@ template <> void Structure :: Convert<Scene> (
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
|
|
||||||
ReadField<ErrorPolicy_Igno>(dest.id,"id",db);
|
ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.camera,"*camera",db);
|
ReadFieldPtr<ErrorPolicy_Warn>(dest.camera,"*camera",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.world,"*world",db);
|
ReadFieldPtr<ErrorPolicy_Warn>(dest.world,"*world",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.basact,"*basact",db);
|
ReadFieldPtr<ErrorPolicy_Warn>(dest.basact,"*basact",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.base,"base",db);
|
ReadField<ErrorPolicy_Igno>(dest.base,"base",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
|
@ -469,10 +470,10 @@ template <> void Structure :: Convert<Library> (
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
|
|
||||||
ReadField<ErrorPolicy_Igno>(dest.id,"id",db);
|
ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
|
||||||
ReadFieldArray<ErrorPolicy_Igno>(dest.name,"name",db);
|
ReadFieldArray<ErrorPolicy_Warn>(dest.name,"name",db);
|
||||||
ReadFieldArray<ErrorPolicy_Igno>(dest.filename,"filename",db);
|
ReadFieldArray<ErrorPolicy_Fail>(dest.filename,"filename",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.parent,"*parent",db);
|
ReadFieldPtr<ErrorPolicy_Warn>(dest.parent,"*parent",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
@ -484,8 +485,8 @@ template <> void Structure :: Convert<Tex> (
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
|
|
||||||
ReadField<ErrorPolicy_Igno>((int&)dest.type,"type",db);
|
ReadField<ErrorPolicy_Fail>((int&)dest.type,"type",db);
|
||||||
ReadFieldPtr<ErrorPolicy_Igno>(dest.ima,"*ima",db);
|
ReadFieldPtr<ErrorPolicy_Warn>(dest.ima,"*ima",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
@ -497,10 +498,10 @@ template <> void Structure :: Convert<Camera> (
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
|
|
||||||
ReadField<ErrorPolicy_Igno>(dest.id,"id",db);
|
ReadField<ErrorPolicy_Fail>(dest.id,"id",db);
|
||||||
ReadField<ErrorPolicy_Igno>((int&)dest.type,"type",db);
|
ReadField<ErrorPolicy_Warn>((int&)dest.type,"type",db);
|
||||||
ReadField<ErrorPolicy_Igno>((int&)dest.flag,"flag",db);
|
ReadField<ErrorPolicy_Warn>((int&)dest.flag,"flag",db);
|
||||||
ReadField<ErrorPolicy_Igno>(dest.angle,"angle",db);
|
ReadField<ErrorPolicy_Warn>(dest.angle,"angle",db);
|
||||||
|
|
||||||
db.reader->IncPtr(size);
|
db.reader->IncPtr(size);
|
||||||
}
|
}
|
||||||
|
|
|
@ -197,7 +197,7 @@ struct MDeformWeight : ElemBase {
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
struct MDeformVert : ElemBase {
|
struct MDeformVert : ElemBase {
|
||||||
|
|
||||||
boost::shared_array<MDeformWeight> dw WARN;
|
vector<MDeformWeight> dw WARN;
|
||||||
int totweight;
|
int totweight;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -238,13 +238,15 @@ struct Mesh : ElemBase {
|
||||||
short subsurftype;
|
short subsurftype;
|
||||||
short smoothresh;
|
short smoothresh;
|
||||||
|
|
||||||
boost::shared_array<MFace> mface FAIL;
|
vector<MFace> mface FAIL;
|
||||||
boost::shared_array<MTFace> mtface;
|
vector<MTFace> mtface;
|
||||||
boost::shared_array<TFace> tface;
|
vector<TFace> tface;
|
||||||
boost::shared_array<MVert> mvert FAIL;
|
vector<MVert> mvert FAIL;
|
||||||
boost::shared_array<MEdge> medge WARN;
|
vector<MEdge> medge WARN;
|
||||||
boost::shared_array<MDeformVert> dvert;
|
vector<MDeformVert> dvert;
|
||||||
boost::shared_array<MCol> mcol;
|
vector<MCol> mcol;
|
||||||
|
|
||||||
|
vector< boost::shared_ptr<Material> > mat FAIL;
|
||||||
};
|
};
|
||||||
|
|
||||||
// -------------------------------------------------------------------------------
|
// -------------------------------------------------------------------------------
|
||||||
|
|
|
@ -101,10 +101,13 @@ def main():
|
||||||
flags = re.ASCII|re.DOTALL|re.MULTILINE
|
flags = re.ASCII|re.DOTALL|re.MULTILINE
|
||||||
#stripcoms = re.compile(r"/\*(.*?)*\/",flags)
|
#stripcoms = re.compile(r"/\*(.*?)*\/",flags)
|
||||||
getstruct = re.compile(r"struct\s+(\w+?)\s*(:\s*ElemBase)?\s*\{(.*?)^\}\s*;",flags)
|
getstruct = re.compile(r"struct\s+(\w+?)\s*(:\s*ElemBase)?\s*\{(.*?)^\}\s*;",flags)
|
||||||
|
getsmartx = re.compile(r"(std\s*::\s*)?(vector)\s*<\s*(boost\s*::\s*)?shared_(ptr)\s*<\s*(\w+)\s*>\s*>\s*",flags)
|
||||||
getsmartp = re.compile(r"(boost\s*::\s*)?shared_(ptr)\s*<\s*(\w+)\s*>\s*",flags)
|
getsmartp = re.compile(r"(boost\s*::\s*)?shared_(ptr)\s*<\s*(\w+)\s*>\s*",flags)
|
||||||
getsmarta = re.compile(r"(boost\s*::\s*)?shared_(array)\s*<\s*(\w+)\s*>\s*",flags)
|
getsmarta = re.compile(r"(std\s*::\s*)?(vector)\s*<\s*(\w+)\s*>\s*",flags)
|
||||||
getpolicy = re.compile(r"\s*(WARN|FAIL|IGNO|)",flags)
|
getpolicy = re.compile(r"\s*(WARN|FAIL|IGNO)",flags)
|
||||||
stripenum = re.compile(r"enum\s+(\w+)\s*{.*?\}\s*;",flags)
|
stripenum = re.compile(r"enum\s+(\w+)\s*{.*?\}\s*;",flags)
|
||||||
|
|
||||||
|
assert getsmartx and getsmartp and getsmarta and getpolicy and stripenum
|
||||||
|
|
||||||
enums = set()
|
enums = set()
|
||||||
#re.sub(stripcoms," ",input)
|
#re.sub(stripcoms," ",input)
|
||||||
|
@ -136,28 +139,27 @@ def main():
|
||||||
for k,v in hits.items():
|
for k,v in hits.items():
|
||||||
out = []
|
out = []
|
||||||
for line in v:
|
for line in v:
|
||||||
tok = line.split(None,1)
|
|
||||||
if len(tok) <= 1:
|
policy = "IGNO"
|
||||||
continue
|
py = re.search(getpolicy,line)
|
||||||
|
if not py is None:
|
||||||
|
policy = py.groups()[0]
|
||||||
|
line = re.sub(getpolicy,"",line)
|
||||||
|
|
||||||
#print(tok)
|
ty = re.match(getsmartx,line) or re.match(getsmartp,line) or re.match(getsmarta,line)
|
||||||
|
if ty is None:
|
||||||
ty = re.match(getsmartp,tok[0]) or re.match(getsmarta,tok[0]) or tok[0]
|
ty = line.split(None,1)[0]
|
||||||
if not isinstance(ty,str):
|
else:
|
||||||
if ty.groups()[1] == "ptr":
|
if ty.groups()[1] == "ptr":
|
||||||
ty = ty.groups()[2] + "*"
|
ty = ty.groups()[2] + "*"
|
||||||
elif ty.groups()[1] == "array":
|
elif ty.groups()[1] == "vector":
|
||||||
ty = ty.groups()[2] + "*"
|
ty = ty.groups()[-1] + ("*" if len(ty.groups()) == 3 else "**")
|
||||||
|
|
||||||
policy = "IGNO"
|
#print(line)
|
||||||
py = re.search(getpolicy,tok[1]) or tok[1]
|
sp = line.split(',')
|
||||||
if not isinstance(py,str):
|
out.append((ty,sp[0].split(None)[-1].strip(),policy))
|
||||||
policy = py.groups()[0]
|
for m in sp[1:]:
|
||||||
py = re.sub(getpolicy,"",tok[1])
|
out.append((ty,m.strip(),policy))
|
||||||
|
|
||||||
#print(py)
|
|
||||||
for m in py.split(','):
|
|
||||||
out.append((ty,m,policy))
|
|
||||||
|
|
||||||
v[:] = out
|
v[:] = out
|
||||||
print("Structure {0}".format(k))
|
print("Structure {0}".format(k))
|
||||||
|
|
Binary file not shown.
|
@ -55,7 +55,7 @@ END
|
||||||
|
|
||||||
IDD_DIALOGMAIN DIALOGEX 0, 0, 615, 485
|
IDD_DIALOGMAIN DIALOGEX 0, 0, 615, 485
|
||||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||||
EXSTYLE WS_EX_TOPMOST | WS_EX_ACCEPTFILES | WS_EX_WINDOWEDGE
|
EXSTYLE WS_EX_ACCEPTFILES | WS_EX_WINDOWEDGE
|
||||||
CAPTION "Open Asset Import Library - ModelViewer "
|
CAPTION "Open Asset Import Library - ModelViewer "
|
||||||
MENU IDR_MENU1
|
MENU IDR_MENU1
|
||||||
FONT 8, "Microsoft Sans Serif", 400, 0, 0x0
|
FONT 8, "Microsoft Sans Serif", 400, 0, 0x0
|
||||||
|
|
Loading…
Reference in New Issue