diff options
| author | Marijn Tamis <[email protected]> | 2018-05-03 18:22:48 +0200 |
|---|---|---|
| committer | Marijn Tamis <[email protected]> | 2018-05-03 18:22:48 +0200 |
| commit | ca32c59a58d37c1822e185a2d5f3d0d3e8943593 (patch) | |
| tree | b06b9eec03f34344ef8fc31aa147b2714d3962ee /NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd | |
| parent | Forced rename of platform folders in cmake dir. Git didn't pick this up before. (diff) | |
| download | nvcloth-ca32c59a58d37c1822e185a2d5f3d0d3e8943593.tar.xz nvcloth-ca32c59a58d37c1822e185a2d5f3d0d3e8943593.zip | |
NvCloth 1.1.4 Release. (24070740)
Diffstat (limited to 'NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd')
11 files changed, 4251 insertions, 0 deletions
diff --git a/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/CMakeLists.txt b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/CMakeLists.txt new file mode 100644 index 0000000..cb78942 --- /dev/null +++ b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/CMakeLists.txt @@ -0,0 +1,76 @@ +# Open Asset Import Library (assimp) +# ---------------------------------------------------------------------- +# +# Copyright (c) 2006-2017, assimp team + +# All rights reserved. +# +# Redistribution and use of this software in source and binary forms, +# with or without modification, are permitted provided that the +# following conditions are met: +# +# * Redistributions of source code must retain the above +# copyright notice, this list of conditions and the +# following disclaimer. +# +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the +# following disclaimer in the documentation and/or other +# materials provided with the distribution. +# +# * Neither the name of the assimp team, nor the names of its +# contributors may be used to endorse or promote products +# derived from this software without specific prior +# written permission of the assimp team. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# +#---------------------------------------------------------------------- +cmake_minimum_required( VERSION 2.6 ) + +INCLUDE_DIRECTORIES( + ${Assimp_SOURCE_DIR}/include + ${Assimp_SOURCE_DIR}/code +) + +LINK_DIRECTORIES( ${Assimp_BINARY_DIR} ${Assimp_BINARY_DIR}/lib ) + +ADD_EXECUTABLE( assimp_cmd + assimp_cmd.rc + CompareDump.cpp + ImageExtractor.cpp + Main.cpp + Main.h + resource.h + WriteDumb.cpp + Info.cpp + Export.cpp +) + +SET_PROPERTY(TARGET assimp_cmd PROPERTY DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX}) + +IF( WIN32 ) + ADD_CUSTOM_COMMAND(TARGET assimp_cmd + PRE_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:assimp> $<TARGET_FILE_DIR:assimp_cmd> + MAIN_DEPENDENCY assimp) +ENDIF( WIN32 ) + +TARGET_LINK_LIBRARIES( assimp_cmd assimp ${ZLIB_LIBRARIES} ) +SET_TARGET_PROPERTIES( assimp_cmd PROPERTIES + OUTPUT_NAME assimp +) + +INSTALL( TARGETS assimp_cmd + DESTINATION "${ASSIMP_BIN_INSTALL_DIR}" COMPONENT assimp-bin +) diff --git a/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/CompareDump.cpp b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/CompareDump.cpp new file mode 100644 index 0000000..2db11ef --- /dev/null +++ b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/CompareDump.cpp @@ -0,0 +1,951 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2017, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +/** @file CompareDump.cpp + * @brief Implementation of the 'assimp cmpdmp', which compares + * two model dumps for equality. It plays an important role + * in the regression test suite. + */ + +#include "Main.h" +const char* AICMD_MSG_CMPDUMP_HELP = +"assimp cmpdump <actual> <expected>\n" +"\tCompare two short dumps produced with \'assimp dump <..> -s\' for equality.\n" +; + +#include "../../code/assbin_chunks.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +#include "generic_inserter.hpp" +#include <map> +#include <deque> +#include <stack> +#include <sstream> +#include <iostream> +#include "../../include/assimp/ai_assert.h" + +// get << for aiString +template <typename char_t, typename traits_t> +void mysprint(std::basic_ostream<char_t, traits_t>& os, const aiString& vec) { + os << "[length: \'" << std::dec << vec.length << "\' content: \'" << vec.data << "\']"; +} + +template <typename char_t, typename traits_t> +std::basic_ostream<char_t, traits_t>& operator<< (std::basic_ostream<char_t, traits_t>& os, const aiString& vec) { + return generic_inserter(mysprint<char_t,traits_t>, os, vec); +} + +class sliced_chunk_iterator; +//////////////////////////////////////////////////////////////////////////////////////////////////// +/// @class compare_fails_exception +/// +/// @brief Sentinel exception to return quickly from deeply nested control paths +//////////////////////////////////////////////////////////////////////////////////////////////////// +class compare_fails_exception : public virtual std::exception { +public: + + enum {MAX_ERR_LEN = 4096}; + + /* public c'tors */ + compare_fails_exception(const char* msg) { + strncpy(mywhat,msg,MAX_ERR_LEN-1); + strcat(mywhat,"\n"); + } + + /* public member functions */ + const char* what() const throw() { + return mywhat; + } + +private: + + char mywhat[MAX_ERR_LEN+1]; +}; + + +#define MY_FLT_EPSILON 1e-1f +#define MY_DBL_EPSILON 1e-1 +//////////////////////////////////////////////////////////////////////////////////////////////////// +/// @class comparer_context +/// +/// @brief Record our way through the files to be compared and dump useful information if we fail. +//////////////////////////////////////////////////////////////////////////////////////////////////// +class comparer_context { + friend class sliced_chunk_iterator; + +public: + + /* construct given two file handles to compare */ + comparer_context(FILE* actual,FILE* expect) + : actual(actual) + , expect(expect) + , cnt_chunks(0) + { + ai_assert(actual); + ai_assert(expect); + + fseek(actual,0,SEEK_END); + lengths.push(std::make_pair(static_cast<uint32_t>(ftell(actual)),0)); + fseek(actual,0,SEEK_SET); + + history.push_back(HistoryEntry("---",PerChunkCounter())); + } + +public: + + + /* set new scope */ + void push_elem(const char* msg) { + const std::string s = msg; + + PerChunkCounter::const_iterator it = history.back().second.find(s); + if(it != history.back().second.end()) { + ++history.back().second[s]; + } + else history.back().second[s] = 0; + + history.push_back(HistoryEntry(s,PerChunkCounter())); + debug_trace.push_back("PUSH " + s); + } + + /* leave current scope */ + void pop_elem() { + ai_assert(history.size()); + debug_trace.push_back("POP "+ history.back().first); + history.pop_back(); + } + + + /* push current chunk length and start offset on top of stack */ + void push_length(uint32_t nl, uint32_t start) { + lengths.push(std::make_pair(nl,start)); + ++cnt_chunks; + } + + /* pop the chunk length stack */ + void pop_length() { + ai_assert(lengths.size()); + lengths.pop(); + } + + /* access the current chunk length */ + uint32_t get_latest_chunk_length() { + ai_assert(lengths.size()); + return lengths.top().first; + } + + /* access the current chunk start offset */ + uint32_t get_latest_chunk_start() { + ai_assert(lengths.size()); + return lengths.top().second; + } + + /* total number of chunk headers passed so far*/ + uint32_t get_num_chunks() { + return cnt_chunks; + } + + + /* get ACTUAL file desc. != NULL */ + FILE* get_actual() const { + return actual; + } + + /* get EXPECT file desc. != NULL */ + FILE* get_expect() const { + return expect; + } + + + /* compare next T from both streams, name occurs in error messages */ + template<typename T> T cmp(const std::string& name) { + T a,e; + read(a,e); + + if(a != e) { + std::stringstream ss; + failure((ss<< "Expected " << e << ", but actual is " << a, + ss.str()),name); + } + // std::cout << name << " " << std::hex << a << std::endl; + return a; + } + + /* compare next num T's from both streams, name occurs in error messages */ + template<typename T> void cmp(size_t num,const std::string& name) { + for(size_t n = 0; n < num; ++n) { + std::stringstream ss; + cmp<T>((ss<<name<<"["<<n<<"]",ss.str())); + // std::cout << name << " " << std::hex << a << std::endl; + } + } + + /* Bounds of an aiVector3D array (separate function + * because partial specializations of member functions are illegal--)*/ + template<typename T> void cmp_bounds(const std::string& name) { + cmp<T> (name+".<minimum-value>"); + cmp<T> (name+".<maximum-value>"); + } + +private: + + /* Report failure */ + AI_WONT_RETURN void failure(const std::string& err, const std::string& name) AI_WONT_RETURN_SUFFIX { + std::stringstream ss; + throw compare_fails_exception((ss + << "Files are different at " + << history.back().first + << "." + << name + << ".\nError is: " + << err + << ".\nCurrent position in scene hierarchy is " + << print_hierarchy(),ss.str().c_str() + )); + } + + /** print our 'stack' */ + std::string print_hierarchy() { + std::stringstream ss; + ss << "\n"; + + const char* last = history.back().first.c_str(); + std::string pad; + + for(ChunkHistory::reverse_iterator rev = history.rbegin(), + end = history.rend(); rev != end; ++rev, pad += " ") + { + ss << pad << (*rev).first << "(Index: " << (*rev).second[last] << ")" << "\n"; + last = (*rev).first.c_str(); + } + + ss << std::endl << "Debug trace: "<< "\n"; + for (std::vector<std::string>::const_iterator it = debug_trace.begin(); it != debug_trace.end(); ++it) { + ss << *it << "\n"; + } + ss << std::flush; + + return ss.str(); + } + + + /* read from both streams at the same time */ + template <typename T> void read(T& filla,T& fille) { + if(1 != fread(&filla,sizeof(T),1,actual)) { + EOFActual(); + } + if(1 != fread(&fille,sizeof(T),1,expect)) { + EOFExpect(); + } + } + +private: + + void EOFActual() { + std::stringstream ss; + throw compare_fails_exception((ss + << "Unexpected EOF reading ACTUAL.\nCurrent position in scene hierarchy is " + << print_hierarchy(),ss.str().c_str() + )); + } + + void EOFExpect() { + std::stringstream ss; + throw compare_fails_exception((ss + << "Unexpected EOF reading EXPECT.\nCurrent position in scene hierarchy is " + << print_hierarchy(),ss.str().c_str() + )); + } + + + FILE *const actual, *const expect; + + typedef std::map<std::string,unsigned int> PerChunkCounter; + typedef std::pair<std::string,PerChunkCounter> HistoryEntry; + + typedef std::deque<HistoryEntry> ChunkHistory; + ChunkHistory history; + + std::vector<std::string> debug_trace; + + typedef std::stack<std::pair<uint32_t,uint32_t> > LengthStack; + LengthStack lengths; + + uint32_t cnt_chunks; +}; + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +/* specialization for aiString (it needs separate handling because its on-disk representation + * differs from its binary representation in memory and can't be treated as an array of n T's.*/ +template <> void comparer_context :: read<aiString>(aiString& filla,aiString& fille) { + uint32_t lena,lene; + read(lena,lene); + + if(lena && 1 != fread(&filla.data,lena,1,actual)) { + EOFActual(); + } + if(lene && 1 != fread(&fille.data,lene,1,expect)) { + EOFExpect(); + } + + fille.data[fille.length=static_cast<unsigned int>(lene)] = '\0'; + filla.data[filla.length=static_cast<unsigned int>(lena)] = '\0'; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +/* Specialization for float, uses epsilon for comparisons*/ +template<> float comparer_context :: cmp<float>(const std::string& name) +{ + float a,e,t; + read(a,e); + + if((t=fabs(a-e)) > MY_FLT_EPSILON) { + std::stringstream ss; + failure((ss<< "Expected " << e << ", but actual is " + << a << " (delta is " << t << ")", ss.str()),name); + } + return a; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +/* Specialization for double, uses epsilon for comparisons*/ +template<> double comparer_context :: cmp<double>(const std::string& name) +{ + double a,e,t; + read(a,e); + + if((t=fabs(a-e)) > MY_DBL_EPSILON) { + std::stringstream ss; + failure((ss<< "Expected " << e << ", but actual is " + << a << " (delta is " << t << ")", ss.str()),name); + } + return a; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +/* Specialization for aiVector3D */ +template<> aiVector3D comparer_context :: cmp<aiVector3D >(const std::string& name) +{ + const float x = cmp<float>(name+".x"); + const float y = cmp<float>(name+".y"); + const float z = cmp<float>(name+".z"); + + return aiVector3D(x,y,z); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +/* Specialization for aiColor4D */ +template<> aiColor4D comparer_context :: cmp<aiColor4D >(const std::string& name) +{ + const float r = cmp<float>(name+".r"); + const float g = cmp<float>(name+".g"); + const float b = cmp<float>(name+".b"); + const float a = cmp<float>(name+".a"); + + return aiColor4D(r,g,b,a); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +/* Specialization for aiQuaternion */ +template<> aiQuaternion comparer_context :: cmp<aiQuaternion >(const std::string& name) +{ + const float w = cmp<float>(name+".w"); + const float x = cmp<float>(name+".x"); + const float y = cmp<float>(name+".y"); + const float z = cmp<float>(name+".z"); + + return aiQuaternion(w,x,y,z); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +/* Specialization for aiQuatKey */ +template<> aiQuatKey comparer_context :: cmp<aiQuatKey >(const std::string& name) +{ + const double mTime = cmp<double>(name+".mTime"); + const aiQuaternion mValue = cmp<aiQuaternion>(name+".mValue"); + + return aiQuatKey(mTime,mValue); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +/* Specialization for aiVectorKey */ +template<> aiVectorKey comparer_context :: cmp<aiVectorKey >(const std::string& name) +{ + const double mTime = cmp<double>(name+".mTime"); + const aiVector3D mValue = cmp<aiVector3D>(name+".mValue"); + + return aiVectorKey(mTime,mValue); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +/* Specialization for aiMatrix4x4 */ +template<> aiMatrix4x4 comparer_context :: cmp<aiMatrix4x4 >(const std::string& name) +{ + aiMatrix4x4 res; + for(unsigned int i = 0; i < 4; ++i) { + for(unsigned int j = 0; j < 4; ++j) { + std::stringstream ss; + res[i][j] = cmp<float>(name+(ss<<".m"<<i<<j,ss.str())); + } + } + + return res; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +/* Specialization for aiVertexWeight */ +template<> aiVertexWeight comparer_context :: cmp<aiVertexWeight >(const std::string& name) +{ + const unsigned int mVertexId = cmp<unsigned int>(name+".mVertexId"); + const float mWeight = cmp<float>(name+".mWeight"); + + return aiVertexWeight(mVertexId,mWeight); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +/// @class sliced_chunk_iterator +/// +/// @brief Helper to iterate easily through corresponding chunks of two dumps simultaneously. +/// +/// Not a *real* iterator, doesn't fully conform to the isocpp iterator spec +//////////////////////////////////////////////////////////////////////////////////////////////////// +class sliced_chunk_iterator { + + friend class sliced_chunk_reader; + sliced_chunk_iterator(comparer_context& ctx, long end) + : ctx(ctx) + , endit(false) + , next(std::numeric_limits<long>::max()) + , end(end) + { + load_next(); + } + +public: + + ~sliced_chunk_iterator() { + fseek(ctx.get_actual(),end,SEEK_SET); + fseek(ctx.get_expect(),end,SEEK_SET); + } + +public: + + /* get current chunk head */ + typedef std::pair<uint32_t,uint32_t> Chunk; + const Chunk& operator*() { + return current; + } + + /* get to next chunk head */ + const sliced_chunk_iterator& operator++() { + cleanup(); + load_next(); + return *this; + } + + /* */ + bool is_end() const { + return endit; + } + +private: + + /* get to the end of *this* chunk */ + void cleanup() { + if(next != std::numeric_limits<long>::max()) { + fseek(ctx.get_actual(),next,SEEK_SET); + fseek(ctx.get_expect(),next,SEEK_SET); + + ctx.pop_length(); + } + } + + /* advance to the next chunk */ + void load_next() { + + Chunk actual; + size_t res=0; + + const long cur = ftell(ctx.get_expect()); + if(end-cur<8) { + current = std::make_pair(0u,0u); + endit = true; + return; + } + + res|=fread(¤t.first,4,1,ctx.get_expect()); + res|=fread(¤t.second,4,1,ctx.get_expect()) <<1u; + res|=fread(&actual.first,4,1,ctx.get_actual()) <<2u; + res|=fread(&actual.second,4,1,ctx.get_actual()) <<3u; + + if(res!=0xf) { + ctx.failure("IO Error reading chunk head, dumps are malformed","<ChunkHead>"); + } + + if (current.first != actual.first) { + std::stringstream ss; + ctx.failure((ss + <<"Chunk headers do not match. EXPECT: " + << std::hex << current.first + <<" ACTUAL: " + << /*std::hex */actual.first, + ss.str()), + "<ChunkHead>"); + } + + if (current.first != actual.first) { + std::stringstream ss; + ctx.failure((ss + <<"Chunk lengths do not match. EXPECT: " + <<current.second + <<" ACTUAL: " + << actual.second, + ss.str()), + "<ChunkHead>"); + } + + next = cur+current.second+8; + ctx.push_length(current.second,cur+8); + } + + comparer_context& ctx; + Chunk current; + bool endit; + long next,end; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +/// @class sliced_chunk_reader +/// +/// @brief Helper to iterate easily through corresponding chunks of two dumps simultaneously. +//////////////////////////////////////////////////////////////////////////////////////////////////// +class sliced_chunk_reader { +public: + + // + sliced_chunk_reader(comparer_context& ctx) + : ctx(ctx) + {} + + // + ~sliced_chunk_reader() { + } + +public: + + sliced_chunk_iterator begin() const { + return sliced_chunk_iterator(ctx,ctx.get_latest_chunk_length()+ + ctx.get_latest_chunk_start()); + } + +private: + + comparer_context& ctx; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +/// @class scoped_chunk +/// +/// @brief Utility to simplify usage of comparer_context.push_elem/pop_elem +//////////////////////////////////////////////////////////////////////////////////////////////////// +class scoped_chunk { +public: + + // + scoped_chunk(comparer_context& ctx,const char* msg) + : ctx(ctx) + { + ctx.push_elem(msg); + } + + // + ~scoped_chunk() + { + ctx.pop_elem(); + } + +private: + + comparer_context& ctx; +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +void CompareOnTheFlyMaterialProperty(comparer_context& comp) { + scoped_chunk chunk(comp,"aiMaterialProperty"); + + comp.cmp<aiString>("mKey"); + comp.cmp<uint32_t>("mSemantic"); + comp.cmp<uint32_t>("mIndex"); + const uint32_t length = comp.cmp<uint32_t>("mDataLength"); + const aiPropertyTypeInfo type = static_cast<aiPropertyTypeInfo>( + comp.cmp<uint32_t>("mType")); + + switch (type) + { + case aiPTI_Float: + comp.cmp<float>(length/4,"mData"); + break; + + case aiPTI_String: + comp.cmp<aiString>("mData"); + break; + + case aiPTI_Integer: + comp.cmp<uint32_t>(length/4,"mData"); + break; + + case aiPTI_Buffer: + comp.cmp<uint8_t>(length,"mData"); + break; + + default: + break; + }; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +void CompareOnTheFlyMaterial(comparer_context& comp) { + scoped_chunk chunk(comp,"aiMaterial"); + + comp.cmp<uint32_t>("aiMaterial::mNumProperties"); + sliced_chunk_reader reader(comp); + for(sliced_chunk_iterator it = reader.begin(); !it.is_end(); ++it) { + if ((*it).first == ASSBIN_CHUNK_AIMATERIALPROPERTY) { + CompareOnTheFlyMaterialProperty(comp); + } + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +void CompareOnTheFlyBone(comparer_context& comp) { + scoped_chunk chunk(comp,"aiBone"); + comp.cmp<aiString>("mName"); + comp.cmp<uint32_t>("mNumWeights"); + comp.cmp<aiMatrix4x4>("mOffsetMatrix"); + + comp.cmp_bounds<aiVertexWeight>("mWeights"); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +void CompareOnTheFlyNodeAnim(comparer_context& comp) { + scoped_chunk chunk(comp,"aiNodeAnim"); + + comp.cmp<aiString>("mNodeName"); + comp.cmp<uint32_t>("mNumPositionKeys"); + comp.cmp<uint32_t>("mNumRotationKeys"); + comp.cmp<uint32_t>("mNumScalingKeys"); + comp.cmp<uint32_t>("mPreState"); + comp.cmp<uint32_t>("mPostState"); + + comp.cmp_bounds<aiVectorKey>("mPositionKeys"); + comp.cmp_bounds<aiQuatKey>("mRotationKeys"); + comp.cmp_bounds<aiVectorKey>("mScalingKeys"); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +void CompareOnTheFlyMesh(comparer_context& comp) { + scoped_chunk chunk(comp,"aiMesh"); + + comp.cmp<uint32_t>("mPrimitiveTypes"); + comp.cmp<uint32_t>("mNumVertices"); + const uint32_t nf = comp.cmp<uint32_t>("mNumFaces"); + comp.cmp<uint32_t>("mNumBones"); + comp.cmp<uint32_t>("mMaterialIndex"); + + const uint32_t present = comp.cmp<uint32_t>("<vertex-components-present>"); + if(present & ASSBIN_MESH_HAS_POSITIONS) { + comp.cmp_bounds<aiVector3D>("mVertices"); + } + + if(present & ASSBIN_MESH_HAS_NORMALS) { + comp.cmp_bounds<aiVector3D>("mNormals"); + } + + if(present & ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS) { + comp.cmp_bounds<aiVector3D>("mTangents"); + comp.cmp_bounds<aiVector3D>("mBitangents"); + } + + for(unsigned int i = 0; present & ASSBIN_MESH_HAS_COLOR(i); ++i) { + std::stringstream ss; + comp.cmp_bounds<aiColor4D>((ss<<"mColors["<<i<<"]",ss.str())); + } + + for(unsigned int i = 0; present & ASSBIN_MESH_HAS_TEXCOORD(i); ++i) { + std::stringstream ss; + comp.cmp<uint32_t>((ss<<"mNumUVComponents["<<i<<"]",ss.str())); + comp.cmp_bounds<aiVector3D>((ss.clear(),ss<<"mTextureCoords["<<i<<"]",ss.str())); + } + + for(unsigned int i = 0; i< ((nf+511)/512); ++i) { + std::stringstream ss; + comp.cmp<uint32_t>((ss<<"mFaces["<<i*512<<"-"<<std::min(static_cast< + uint32_t>((i+1)*512),nf)<<"]",ss.str())); + } + + sliced_chunk_reader reader(comp); + for(sliced_chunk_iterator it = reader.begin(); !it.is_end(); ++it) { + if ((*it).first == ASSBIN_CHUNK_AIBONE) { + CompareOnTheFlyBone(comp); + } + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +void CompareOnTheFlyCamera(comparer_context& comp) { + scoped_chunk chunk(comp,"aiCamera"); + + comp.cmp<aiString>("mName"); + + comp.cmp<aiVector3D>("mPosition"); + comp.cmp<aiVector3D>("mLookAt"); + comp.cmp<aiVector3D>("mUp"); + + comp.cmp<float>("mHorizontalFOV"); + comp.cmp<float>("mClipPlaneNear"); + comp.cmp<float>("mClipPlaneFar"); + comp.cmp<float>("mAspect"); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +void CompareOnTheFlyLight(comparer_context& comp) { + scoped_chunk chunk(comp,"aiLight"); + + comp.cmp<aiString>("mName"); + const aiLightSourceType type = static_cast<aiLightSourceType>( + comp.cmp<uint32_t>("mType")); + + if(type!=aiLightSource_DIRECTIONAL) { + comp.cmp<float>("mAttenuationConstant"); + comp.cmp<float>("mAttenuationLinear"); + comp.cmp<float>("mAttenuationQuadratic"); + } + + comp.cmp<aiVector3D>("mColorDiffuse"); + comp.cmp<aiVector3D>("mColorSpecular"); + comp.cmp<aiVector3D>("mColorAmbient"); + + if(type==aiLightSource_SPOT) { + comp.cmp<float>("mAngleInnerCone"); + comp.cmp<float>("mAngleOuterCone"); + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +void CompareOnTheFlyAnimation(comparer_context& comp) { + scoped_chunk chunk(comp,"aiAnimation"); + + comp.cmp<aiString>("mName"); + comp.cmp<double>("mDuration"); + comp.cmp<double>("mTicksPerSecond"); + comp.cmp<uint32_t>("mNumChannels"); + + sliced_chunk_reader reader(comp); + for(sliced_chunk_iterator it = reader.begin(); !it.is_end(); ++it) { + if ((*it).first == ASSBIN_CHUNK_AINODEANIM) { + CompareOnTheFlyNodeAnim(comp); + } + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +void CompareOnTheFlyTexture(comparer_context& comp) { + scoped_chunk chunk(comp,"aiTexture"); + + const uint32_t w = comp.cmp<uint32_t>("mWidth"); + const uint32_t h = comp.cmp<uint32_t>("mHeight"); + (void)w; (void)h; + comp.cmp<char>("achFormatHint[0]"); + comp.cmp<char>("achFormatHint[1]"); + comp.cmp<char>("achFormatHint[2]"); + comp.cmp<char>("achFormatHint[3]"); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +void CompareOnTheFlyNode(comparer_context& comp) { + scoped_chunk chunk(comp,"aiNode"); + comp.cmp<aiString>("mName"); + comp.cmp<aiMatrix4x4>("mTransformation"); + comp.cmp<uint32_t>("mNumChildren"); + comp.cmp<uint32_t>(comp.cmp<uint32_t>("mNumMeshes"),"mMeshes"); + + sliced_chunk_reader reader(comp); + for(sliced_chunk_iterator it = reader.begin(); !it.is_end(); ++it) { + if ((*it).first == ASSBIN_CHUNK_AINODE) { + CompareOnTheFlyNode(comp); + } + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +void CompareOnTheFlyScene(comparer_context& comp) { + scoped_chunk chunk(comp,"aiScene"); + + comp.cmp<uint32_t>("mFlags"); + comp.cmp<uint32_t>("mNumMeshes"); + comp.cmp<uint32_t>("mNumMaterials"); + comp.cmp<uint32_t>("mNumAnimations"); + comp.cmp<uint32_t>("mNumTextures"); + comp.cmp<uint32_t>("mNumLights"); + comp.cmp<uint32_t>("mNumCameras"); + + sliced_chunk_reader reader(comp); + for(sliced_chunk_iterator it = reader.begin(); !it.is_end(); ++it) { + if ((*it).first == ASSBIN_CHUNK_AIMATERIAL) { + CompareOnTheFlyMaterial(comp); + } + else if ((*it).first == ASSBIN_CHUNK_AITEXTURE) { + CompareOnTheFlyTexture(comp); + } + else if ((*it).first == ASSBIN_CHUNK_AIMESH) { + CompareOnTheFlyMesh(comp); + } + else if ((*it).first == ASSBIN_CHUNK_AIANIMATION) { + CompareOnTheFlyAnimation(comp); + } + else if ((*it).first == ASSBIN_CHUNK_AICAMERA) { + CompareOnTheFlyCamera(comp); + } + else if ((*it).first == ASSBIN_CHUNK_AILIGHT) { + CompareOnTheFlyLight(comp); + } + else if ((*it).first == ASSBIN_CHUNK_AINODE) { + CompareOnTheFlyNode(comp); + } + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +void CompareOnTheFly(comparer_context& comp) +{ + sliced_chunk_reader reader(comp); + for(sliced_chunk_iterator it = reader.begin(); !it.is_end(); ++it) { + if ((*it).first == ASSBIN_CHUNK_AISCENE) { + CompareOnTheFlyScene(comp); + break; + } + } +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +void CheckHeader(comparer_context& comp) +{ + fseek(comp.get_actual(),ASSBIN_HEADER_LENGTH,SEEK_CUR); + fseek(comp.get_expect(),ASSBIN_HEADER_LENGTH,SEEK_CUR); +} + +//////////////////////////////////////////////////////////////////////////////////////////////////// +int Assimp_CompareDump (const char* const* params, unsigned int num) +{ + // --help + if ((num == 1 && !strcmp( params[0], "-h")) || !strcmp( params[0], "--help") || !strcmp( params[0], "-?") ) { + printf("%s",AICMD_MSG_CMPDUMP_HELP); + return 0; + } + + // assimp cmpdump actual expected + if (num < 2) { + std::cout << "assimp cmpdump: Invalid number of arguments. " + "See \'assimp cmpdump --help\'\r\n" << std::endl; + return 1; + } + + if(!strcmp(params[0],params[1])) { + std::cout << "assimp cmpdump: same file, same content." << std::endl; + return 0; + } + + class file_ptr + { + public: + file_ptr(FILE *p) + : m_file(p) + {} + ~file_ptr() + { + if (m_file) + { + fclose(m_file); + m_file = NULL; + } + } + + operator FILE *() { return m_file; } + + private: + FILE *m_file; + }; + file_ptr actual(fopen(params[0],"rb")); + if (!actual) { + std::cout << "assimp cmpdump: Failure reading ACTUAL data from " << + params[0] << std::endl; + return -5; + } + file_ptr expected(fopen(params[1],"rb")); + if (!expected) { + std::cout << "assimp cmpdump: Failure reading EXPECT data from " << + params[1] << std::endl; + return -6; + } + + comparer_context comp(actual,expected); + try { + CheckHeader(comp); + CompareOnTheFly(comp); + } + catch(const compare_fails_exception& ex) { + printf("%s",ex.what()); + return -1; + } + catch(...) { + // we don't bother checking too rigourously here, so + // we might end up here ... + std::cout << "Unknown failure, are the input files well-defined?"; + return -3; + } + + std::cout << "Success (totally " << std::dec << comp.get_num_chunks() << + " chunks)" << std::endl; + + return 0; +} diff --git a/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/Export.cpp b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/Export.cpp new file mode 100644 index 0000000..3752db5 --- /dev/null +++ b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/Export.cpp @@ -0,0 +1,172 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2017, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +/** @file Export.cpp + * @brief Implementation of the 'assimp export' utility + */ + +#include "Main.h" + +#ifndef ASSIMP_BUILD_NO_EXPORT + +const char* AICMD_MSG_EXPORT_HELP_E = +"assimp export <model> [<out>] [-f<h>] [common parameters]\n" +"\t -f<h> Specify the file format. If omitted, the output format is \n" +"\t\tderived from the file extension of the given output file \n" +"\t[See the assimp_cmd docs for a full list of all common parameters] \n" +; + + +// ----------------------------------------------------------------------------------- +size_t GetMatchingFormat(const std::string& outf,bool byext=false) +{ + for(size_t i = 0, end = globalExporter->GetExportFormatCount(); i < end; ++i) { + const aiExportFormatDesc* const e = globalExporter->GetExportFormatDescription(i); + if (outf == (byext ? e->fileExtension : e->id)) { + return i; + } + } + return SIZE_MAX; +} + + +// ----------------------------------------------------------------------------------- +int Assimp_Export(const char* const* params, unsigned int num) +{ + const char* const invalid = "assimp export: Invalid number of arguments. See \'assimp export --help\'\n"; + if (num < 1) { + printf(invalid); + return 1; + } + + // --help + if (!strcmp( params[0], "-h") || !strcmp( params[0], "--help") || !strcmp( params[0], "-?") ) { + printf("%s",AICMD_MSG_EXPORT_HELP_E); + return 0; + } + + std::string in = std::string(params[0]); + std::string out = (num > 1 ? std::string(params[1]) : "-"), outext; + + // + const std::string::size_type s = out.find_last_of('.'); + if (s != std::string::npos) { + outext = out.substr(s+1); + out = out.substr(0,s); + } + + // get import flags + ImportData import; + ProcessStandardArguments(import,params+1,num-1); + + // process other flags + std::string outf = ""; + for (unsigned int i = (out[0] == '-' ? 1 : 2); i < num;++i) { + if (!params[i]) { + continue; + } + if (!strncmp( params[i], "-f",2)) { + outf = std::string(params[i]+2); + } + else if ( !strncmp( params[i], "--format=",9)) { + outf = std::string(params[i]+9); + } + } + + std::transform(outf.begin(),outf.end(),outf.begin(),::tolower); + + // convert the output format to a format id + size_t outfi = GetMatchingFormat(outf); + if (outfi == SIZE_MAX) { + if (outf.length()) { + printf("assimp export: warning, format id \'%s\' is unknown\n",outf.c_str()); + } + + // retry to see if we know it as file extension + outfi = GetMatchingFormat(outf,true); + if (outfi == SIZE_MAX) { + // retry to see if we know the file extension of the output file + outfi = GetMatchingFormat(outext,true); + + if (outfi == SIZE_MAX) { + // still no match -> failure + printf("assimp export: no output format specified and I failed to guess it\n"); + return -23; + } + } + else { + outext = outf; + } + } + + // if no output file is specified, take the file name from input file + if (out[0] == '-') { + std::string::size_type s = in.find_last_of('.'); + if (s == std::string::npos) { + s = in.length(); + } + + out = in.substr(0,s); + } + + const aiExportFormatDesc* const e = globalExporter->GetExportFormatDescription(outfi); + printf("assimp export: select file format: \'%s\' (%s)\n",e->id,e->description); + + // import the model + const aiScene* scene = ImportModel(import,in); + if (!scene) { + return -39; + } + + // derive the final file name + out += "."+outext; + + // and call the export routine + if(!ExportModel(scene, import, out,e->id)) { + return -25; + } + printf("assimp export: wrote output file: %s\n",out.c_str()); + return 0; +} + +#endif // no export + diff --git a/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/ImageExtractor.cpp b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/ImageExtractor.cpp new file mode 100644 index 0000000..691f629 --- /dev/null +++ b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/ImageExtractor.cpp @@ -0,0 +1,378 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2017, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +/** @file ImageExtractor.cpp + * @brief Implementation of the 'assimp extract' utility + */ + +#include "Main.h" +#include <../code/fast_atof.h> +#include <../code/StringComparison.h> + +const char* AICMD_MSG_DUMP_HELP_E = +"assimp extract <model> [<out>] [-t<n>] [-f<fmt>] [-ba] [-s] [common parameters]\n" +"\t -ba Writes BMP's with alpha channel\n" +"\t -t<n> Zero-based index of the texture to be extracted \n" +"\t -f<f> Specify the file format if <out> is omitted \n" +"\t[See the assimp_cmd docs for a full list of all common parameters] \n" +"\t -cfast Fast post processing preset, runs just a few important steps \n" +"\t -cdefault Default post processing: runs all recommended steps\n" +"\t -cfull Fires almost all post processing steps \n" +; + +#define AI_EXTRACT_WRITE_BMP_ALPHA 0x1 +#include <assimp/Compiler/pushpack1.h> + +// ----------------------------------------------------------------------------------- +// Data structure for the first header of a BMP +struct BITMAPFILEHEADER +{ + uint16_t bfType ; + uint32_t bfSize; + uint16_t bfReserved1 ; + uint16_t bfReserved2; + uint32_t bfOffBits; +} PACK_STRUCT; + +// ----------------------------------------------------------------------------------- +// Data structure for the second header of a BMP +struct BITMAPINFOHEADER +{ + int32_t biSize; + int32_t biWidth; + int32_t biHeight; + int16_t biPlanes; + int16_t biBitCount; + uint32_t biCompression; + int32_t biSizeImage; + int32_t biXPelsPerMeter; + int32_t biYPelsPerMeter; + int32_t biClrUsed; + int32_t biClrImportant; + + // pixel data follows header +} PACK_STRUCT; + +// ----------------------------------------------------------------------------------- +// Data structure for the header of a TGA +struct TGA_HEADER +{ + uint8_t identsize; // size of ID field that follows 18 byte header (0 usually) + uint8_t colourmaptype; // type of colour map 0=none, 1=has palette + uint8_t imagetype; // type of image 0=none,1=indexed,2=rgb,3=grey,+8=rle packed + + uint16_t colourmapstart; // first colour map entry in palette + uint16_t colourmaplength; // number of colours in palette + uint8_t colourmapbits; // number of bits per palette entry 15,16,24,32 + + uint16_t xstart; // image x origin + uint16_t ystart; // image y origin + uint16_t width; // image width in pixels + uint16_t height; // image height in pixels + uint8_t bits; // image bits per pixel 8,16,24,32 + uint8_t descriptor; // image descriptor bits (vh flip bits) + + // pixel data follows header +} PACK_STRUCT; + + +#include <assimp/Compiler/poppack1.h> + +// ----------------------------------------------------------------------------------- +// Save a texture as bitmap +int SaveAsBMP (FILE* file, const aiTexel* data, unsigned int width, unsigned int height, bool SaveAlpha = false) +{ + if (!file || !data) { + return 1; + } + + const unsigned int numc = (SaveAlpha ? 4 : 3); + unsigned char* buffer = new unsigned char[width*height*numc]; + + for (unsigned int y = 0; y < height; ++y) { + for (unsigned int x = 0; x < width; ++x) { + + unsigned char* s = &buffer[(y*width+x) * numc]; + const aiTexel* t = &data [ y*width+x]; + s[0] = t->b; + s[1] = t->g; + s[2] = t->r; + if (4 == numc) + s[3] = t->a; + } + } + + BITMAPFILEHEADER header; + header.bfType = 'B' | (int('M') << 8u); + header.bfOffBits = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER); + header.bfSize = header.bfOffBits+width*height*numc; + header.bfReserved1 = header.bfReserved2 = 0; + + fwrite(&header,sizeof(BITMAPFILEHEADER),1,file); + + BITMAPINFOHEADER info; + info.biSize = 40; + info.biWidth = width; + info.biHeight = height; + info.biPlanes = 1; + info.biBitCount = numc<<3; + info.biCompression = 0; + info.biSizeImage = width*height*numc; + info.biXPelsPerMeter = 1; // dummy + info.biYPelsPerMeter = 1; // dummy + info.biClrUsed = 0; + info.biClrImportant = 0; + + fwrite(&info,sizeof(BITMAPINFOHEADER),1,file); + + unsigned char* temp = buffer+info.biSizeImage; + const unsigned int row = width*numc; + + for (int y = 0; temp -= row,y < info.biHeight;++y) { + fwrite(temp,row,1,file); + } + + // delete the buffer + delete[] buffer; + return 0; +} + +// ----------------------------------------------------------------------------------- +// Save a texture as tga +int SaveAsTGA (FILE* file, const aiTexel* data, unsigned int width, unsigned int height) +{ + if (!file || !data) { + return 1; + } + + TGA_HEADER head; + memset(&head, 0, sizeof(head)); + head.bits = 32; + head.height = (uint16_t)height; + head.width = (uint16_t)width; + head.descriptor |= (1u<<5); + + head.imagetype = 2; // actually it's RGBA + fwrite(&head,sizeof(TGA_HEADER),1,file); + + for (unsigned int y = 0; y < height; ++y) { + for (unsigned int x = 0; x < width; ++x) { + fwrite(data + y*width+x,4,1,file); + } + } + + return 0; +} + +// ----------------------------------------------------------------------------------- +// Do the texture import for a given aiTexture +int DoExport(const aiTexture* tx, FILE* p, const std::string& extension, + unsigned int flags) +{ + // export the image to the appropriate decoder + if (extension == "bmp") { + SaveAsBMP(p,tx->pcData,tx->mWidth,tx->mHeight, + (0 != (flags & AI_EXTRACT_WRITE_BMP_ALPHA))); + } + else if (extension == "tga") { + SaveAsTGA(p,tx->pcData,tx->mWidth,tx->mHeight); + } + else { + printf("assimp extract: No available texture encoder found for %s\n", extension.c_str()); + return 1; + } + return 0; +} + +// ----------------------------------------------------------------------------------- +// Implementation of the assimp extract utility +int Assimp_Extract (const char* const* params, unsigned int num) +{ + const char* const invalid = "assimp extract: Invalid number of arguments. See \'assimp extract --help\'\n"; + if (num < 1) { + printf(invalid); + return 1; + } + + // --help + if (!strcmp( params[0], "-h") || !strcmp( params[0], "--help") || !strcmp( params[0], "-?") ) { + printf("%s",AICMD_MSG_DUMP_HELP_E); + return 0; + } + + // asssimp extract in out [options] + if (num < 1) { + printf(invalid); + return 1; + } + + std::string in = std::string(params[0]); + std::string out = (num > 1 ? std::string(params[1]) : "-"); + + // get import flags + ImportData import; + ProcessStandardArguments(import,params+1,num-1); + + bool nosuffix = false; + unsigned int texIdx = 0xffffffff, flags = 0; + + // process other flags + std::string extension = "bmp"; + for (unsigned int i = (out[0] == '-' ? 1 : 2); i < num;++i) { + if (!params[i]) { + continue; + } + + if (!strncmp( params[i], "-f",2)) { + extension = std::string(params[i]+2); + } + else if ( !strncmp( params[i], "--format=",9)) { + extension = std::string(params[i]+9); + } + else if ( !strcmp( params[i], "--nosuffix") || !strcmp(params[i],"-s")) { + nosuffix = true; + } + else if ( !strncmp( params[i], "--texture=",10)) { + texIdx = Assimp::strtoul10(params[i]+10); + } + else if ( !strncmp( params[i], "-t",2)) { + texIdx = Assimp::strtoul10(params[i]+2); + } + else if ( !strcmp( params[i], "-ba") || !strcmp( params[i], "--bmp-with-alpha")) { + flags |= AI_EXTRACT_WRITE_BMP_ALPHA; + } +#if 0 + else { + printf("Unknown parameter: %s\n",params[i]); + return 10; + } +#endif + } + + std::transform(extension.begin(),extension.end(),extension.begin(),::tolower); + + if (out[0] == '-') { + // take file name from input file + std::string::size_type s = in.find_last_of('.'); + if (s == std::string::npos) + s = in.length(); + + out = in.substr(0,s); + } + + // take file extension from file name, if given + std::string::size_type s = out.find_last_of('.'); + if (s != std::string::npos) { + extension = out.substr(s+1,in.length()-(s+1)); + out = out.substr(0,s); + } + + // import the main model + const aiScene* scene = ImportModel(import,in); + if (!scene) { + printf("assimp extract: Unable to load input file %s\n",in.c_str()); + return 5; + } + + // get the texture(s) to be exported + if (texIdx != 0xffffffff) { + + // check whether the requested texture is existing + if (texIdx >= scene->mNumTextures) { + ::printf("assimp extract: Texture %i requested, but there are just %i textures\n", + texIdx, scene->mNumTextures); + return 6; + } + } + else { + ::printf("assimp extract: Exporting %i textures\n",scene->mNumTextures); + } + + // now write all output textures + for (unsigned int i = 0; i < scene->mNumTextures;++i) { + if (texIdx != 0xffffffff && texIdx != i) { + continue; + } + + const aiTexture* tex = scene->mTextures[i]; + std::string out_cpy = out, out_ext = extension; + + // append suffix if necessary - always if all textures are exported + if (!nosuffix || (texIdx == 0xffffffff)) { + out_cpy.append ("_img"); + char tmp[10]; + Assimp::ASSIMP_itoa10(tmp,i); + + out_cpy.append(std::string(tmp)); + } + + // if the texture is a compressed one, we'll export + // it to its native file format + if (!tex->mHeight) { + printf("assimp extract: Texture %i is compressed (%s). Writing native file format.\n", + i,tex->achFormatHint); + + // modify file extension + out_ext = std::string(tex->achFormatHint); + } + out_cpy.append("."+out_ext); + + // open output file + FILE* p = ::fopen(out_cpy.c_str(),"wb"); + if (!p) { + printf("assimp extract: Unable to open output file %s\n",out_cpy.c_str()); + return 7; + } + int m; + + if (!tex->mHeight) { + m = (1 != fwrite(tex->pcData,tex->mWidth,1,p)); + } + else m = DoExport(tex,p,extension,flags); + ::fclose(p); + + printf("assimp extract: Wrote texture %i to %s\n",i, out_cpy.c_str()); + if (texIdx != 0xffffffff) + return m; + } + return 0; +} diff --git a/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/Info.cpp b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/Info.cpp new file mode 100644 index 0000000..d116f04 --- /dev/null +++ b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/Info.cpp @@ -0,0 +1,352 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2017, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +/** @file Info.cpp + * @brief Implementation of the 'assimp info' utility */ + +#include "Main.h" + +const char* AICMD_MSG_INFO_HELP_E = +"assimp info <file> [-r]\n" +"\tPrint basic structure of a 3D model\n" +"\t-r,--raw: No postprocessing, do a raw import\n"; + + +// ----------------------------------------------------------------------------------- +unsigned int CountNodes(const aiNode* root) +{ + unsigned int i = 0; + for (unsigned int a = 0; a < root->mNumChildren; ++a ) { + i += CountNodes(root->mChildren[a]); + } + return 1+i; +} + +// ----------------------------------------------------------------------------------- +unsigned int GetMaxDepth(const aiNode* root) +{ + unsigned int cnt = 0; + for (unsigned int i = 0; i < root->mNumChildren; ++i ) { + cnt = std::max(cnt,GetMaxDepth(root->mChildren[i])); + } + return cnt+1; +} + +// ----------------------------------------------------------------------------------- +unsigned int CountVertices(const aiScene* scene) +{ + unsigned int cnt = 0; + for(unsigned int i = 0; i < scene->mNumMeshes; ++i) { + cnt += scene->mMeshes[i]->mNumVertices; + } + return cnt; +} + +// ----------------------------------------------------------------------------------- +unsigned int CountFaces(const aiScene* scene) +{ + unsigned int cnt = 0; + for(unsigned int i = 0; i < scene->mNumMeshes; ++i) { + cnt += scene->mMeshes[i]->mNumFaces; + } + return cnt; +} + +// ----------------------------------------------------------------------------------- +unsigned int CountBones(const aiScene* scene) +{ + unsigned int cnt = 0; + for(unsigned int i = 0; i < scene->mNumMeshes; ++i) { + cnt += scene->mMeshes[i]->mNumBones; + } + return cnt; +} + +// ----------------------------------------------------------------------------------- +unsigned int CountAnimChannels(const aiScene* scene) +{ + unsigned int cnt = 0; + for(unsigned int i = 0; i < scene->mNumAnimations; ++i) { + cnt += scene->mAnimations[i]->mNumChannels; + } + return cnt; +} + +// ----------------------------------------------------------------------------------- +unsigned int GetAvgFacePerMesh(const aiScene* scene) { + return (scene->mNumMeshes != 0) ? static_cast<unsigned int>(CountFaces(scene)/scene->mNumMeshes) : 0; +} + +// ----------------------------------------------------------------------------------- +unsigned int GetAvgVertsPerMesh(const aiScene* scene) { + return (scene->mNumMeshes != 0) ? static_cast<unsigned int>(CountVertices(scene)/scene->mNumMeshes) : 0; +} + +// ----------------------------------------------------------------------------------- +void FindSpecialPoints(const aiScene* scene,const aiNode* root,aiVector3D special_points[3],const aiMatrix4x4& mat=aiMatrix4x4()) +{ + // XXX that could be greatly simplified by using code from code/ProcessHelper.h + // XXX I just don't want to include it here. + const aiMatrix4x4 trafo = root->mTransformation*mat; + for(unsigned int i = 0; i < root->mNumMeshes; ++i) { + const aiMesh* mesh = scene->mMeshes[root->mMeshes[i]]; + + for(unsigned int a = 0; a < mesh->mNumVertices; ++a) { + aiVector3D v = trafo*mesh->mVertices[a]; + + special_points[0].x = std::min(special_points[0].x,v.x); + special_points[0].y = std::min(special_points[0].y,v.y); + special_points[0].z = std::min(special_points[0].z,v.z); + + special_points[1].x = std::max(special_points[1].x,v.x); + special_points[1].y = std::max(special_points[1].y,v.y); + special_points[1].z = std::max(special_points[1].z,v.z); + } + } + + for(unsigned int i = 0; i < root->mNumChildren; ++i) { + FindSpecialPoints(scene,root->mChildren[i],special_points,trafo); + } +} + +// ----------------------------------------------------------------------------------- +void FindSpecialPoints(const aiScene* scene,aiVector3D special_points[3]) +{ + special_points[0] = aiVector3D(1e10,1e10,1e10); + special_points[1] = aiVector3D(-1e10,-1e10,-1e10); + + FindSpecialPoints(scene,scene->mRootNode,special_points); + special_points[2] = (special_points[0]+special_points[1])*(ai_real)0.5; +} + +// ----------------------------------------------------------------------------------- +std::string FindPTypes(const aiScene* scene) +{ + bool haveit[4] = {0}; + for(unsigned int i = 0; i < scene->mNumMeshes; ++i) { + const unsigned int pt = scene->mMeshes[i]->mPrimitiveTypes; + if (pt & aiPrimitiveType_POINT) { + haveit[0]=true; + } + if (pt & aiPrimitiveType_LINE) { + haveit[1]=true; + } + if (pt & aiPrimitiveType_TRIANGLE) { + haveit[2]=true; + } + if (pt & aiPrimitiveType_POLYGON) { + haveit[3]=true; + } + } + return (haveit[0]?std::string("points"):"")+(haveit[1]?"lines":"")+ + (haveit[2]?"triangles":"")+(haveit[3]?"n-polygons":""); +} + +// ----------------------------------------------------------------------------------- +void PrintHierarchy(const aiNode* root, unsigned int maxnest, unsigned int maxline, + unsigned int cline, unsigned int cnest=0) +{ + if (cline++ >= maxline || cnest >= maxnest) { + return; + } + + for(unsigned int i = 0; i < cnest; ++i) { + printf("-- "); + } + printf("\'%s\', meshes: %u\n",root->mName.data,root->mNumMeshes); + for (unsigned int i = 0; i < root->mNumChildren; ++i ) { + PrintHierarchy(root->mChildren[i],maxnest,maxline,cline,cnest+1); + if(i == root->mNumChildren-1) { + for(unsigned int i = 0; i < cnest; ++i) { + printf(" "); + } + printf("<--\n"); + } + } +} + +// ----------------------------------------------------------------------------------- +// Implementation of the assimp info utility to print basic file info +int Assimp_Info (const char* const* params, unsigned int num) +{ + if (num < 1) { + printf("assimp info: Invalid number of arguments. " + "See \'assimp info --help\'\n"); + return 1; + } + + // --help + if (!strcmp( params[0],"-h")||!strcmp( params[0],"--help")||!strcmp( params[0],"-?") ) { + printf("%s",AICMD_MSG_INFO_HELP_E); + return 0; + } + + // asssimp info <file> [-r] + if (num < 1) { + printf("assimp info: Invalid number of arguments. " + "See \'assimp info --help\'\n"); + return 1; + } + + const std::string in = std::string(params[0]); + + // do maximum post-processing unless -r was specified + ImportData import; + import.ppFlags = num>1&&(!strcmp(params[1],"--raw")||!strcmp(params[1],"-r")) ? 0 + : aiProcessPreset_TargetRealtime_MaxQuality; + + // import the main model + const aiScene* scene = ImportModel(import,in); + if (!scene) { + printf("assimp info: Unable to load input file %s\n", + in.c_str()); + return 5; + } + + aiMemoryInfo mem; + globalImporter->GetMemoryRequirements(mem); + + + static const char* format_string = + "Memory consumption: %i B\n" + "Nodes: %i\n" + "Maximum depth %i\n" + "Meshes: %i\n" + "Animations: %i\n" + "Textures (embed.): %i\n" + "Materials: %i\n" + "Cameras: %i\n" + "Lights: %i\n" + "Vertices: %i\n" + "Faces: %i\n" + "Bones: %i\n" + "Animation Channels: %i\n" + "Primitive Types: %s\n" + "Average faces/mesh %i\n" + "Average verts/mesh %i\n" + "Minimum point (%f %f %f)\n" + "Maximum point (%f %f %f)\n" + "Center point (%f %f %f)\n" + + ; + + aiVector3D special_points[3]; + FindSpecialPoints(scene,special_points); + printf(format_string, + mem.total, + CountNodes(scene->mRootNode), + GetMaxDepth(scene->mRootNode), + scene->mNumMeshes, + scene->mNumAnimations, + scene->mNumTextures, + scene->mNumMaterials, + scene->mNumCameras, + scene->mNumLights, + CountVertices(scene), + CountFaces(scene), + CountBones(scene), + CountAnimChannels(scene), + FindPTypes(scene).c_str(), + GetAvgFacePerMesh(scene), + GetAvgVertsPerMesh(scene), + special_points[0][0],special_points[0][1],special_points[0][2], + special_points[1][0],special_points[1][1],special_points[1][2], + special_points[2][0],special_points[2][1],special_points[2][2] + ) + ; + unsigned int total=0; + for(unsigned int i = 0;i < scene->mNumMaterials; ++i) { + aiString name; + if (AI_SUCCESS==aiGetMaterialString(scene->mMaterials[i],AI_MATKEY_NAME,&name)) { + printf("%s\n \'%s\'",(total++?"":"\nNamed Materials:" ),name.data); + } + } + if(total) { + printf("\n"); + } + + total=0; + for(unsigned int i = 0;i < scene->mNumMaterials; ++i) { + aiString name; + static const aiTextureType types[] = { + aiTextureType_NONE, + aiTextureType_DIFFUSE, + aiTextureType_SPECULAR, + aiTextureType_AMBIENT, + aiTextureType_EMISSIVE, + aiTextureType_HEIGHT, + aiTextureType_NORMALS, + aiTextureType_SHININESS, + aiTextureType_OPACITY, + aiTextureType_DISPLACEMENT, + aiTextureType_LIGHTMAP, + aiTextureType_REFLECTION, + aiTextureType_UNKNOWN + }; + for(unsigned int type = 0; type < sizeof(types)/sizeof(types[0]); ++type) { + for(unsigned int idx = 0;AI_SUCCESS==aiGetMaterialString(scene->mMaterials[i], + AI_MATKEY_TEXTURE(types[type],idx),&name); ++idx) { + printf("%s\n \'%s\'",(total++?"":"\nTexture Refs:" ),name.data); + } + } + } + if(total) { + printf("\n"); + } + + total=0; + for(unsigned int i = 0;i < scene->mNumAnimations; ++i) { + if (scene->mAnimations[i]->mName.length) { + printf("%s\n \'%s\'",(total++?"":"\nNamed Animations:" ),scene->mAnimations[i]->mName.data); + } + } + if(total) { + printf("\n"); + } + + printf("\nNode hierarchy:\n"); + unsigned int cline=0; + PrintHierarchy(scene->mRootNode,20,1000,cline); + + printf("\n"); + return 0; +} diff --git a/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/Main.cpp b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/Main.cpp new file mode 100644 index 0000000..587e111 --- /dev/null +++ b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/Main.cpp @@ -0,0 +1,514 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2017, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +/** @file Main.cpp + * @brief main() function of assimp_cmd + */ + +#include "Main.h" + +const char* AICMD_MSG_ABOUT = +"------------------------------------------------------ \n" +"Open Asset Import Library (\"Assimp\", https://github.com/assimp/assimp) \n" +" -- Commandline toolchain --\n" +"------------------------------------------------------ \n\n" + +"Version %i.%i %s%s%s%s%s(GIT commit %x)\n\n"; + +const char* AICMD_MSG_HELP = +"assimp <verb> <parameters>\n\n" +" verbs:\n" +" \tinfo - Quick file stats\n" +" \tlistext - List all known file extensions available for import\n" +" \tknowext - Check whether a file extension is recognized by Assimp\n" +#ifndef ASSIMP_BUILD_NO_EXPORT +" \texport - Export a file to one of the supported output formats\n" +" \tlistexport - List all supported export formats\n" +" \texportinfo - Show basic information on a specific export format\n" +#endif +" \textract - Extract embedded texture images\n" +" \tdump - Convert models to a binary or textual dump (ASSBIN/ASSXML)\n" +" \tcmpdump - Compare dumps created using \'assimp dump <file> -s ...\'\n" +" \tversion - Display Assimp version\n" +"\n Use \'assimp <verb> --help\' for detailed help on a command.\n" +; + +/*extern*/ Assimp::Importer* globalImporter = NULL; + +#ifndef ASSIMP_BUILD_NO_EXPORT +/*extern*/ Assimp::Exporter* globalExporter = NULL; +#endif + +// ------------------------------------------------------------------------------ +// Application entry point +int main (int argc, char* argv[]) +{ + if (argc <= 1) { + printf("assimp: No command specified. Use \'assimp help\' for a detailed command list\n"); + return 0; + } + + // assimp version + // Display version information + if (! strcmp(argv[1], "version")) { + const unsigned int flags = aiGetCompileFlags(); + printf(AICMD_MSG_ABOUT, + aiGetVersionMajor(), + aiGetVersionMinor(), + (flags & ASSIMP_CFLAGS_DEBUG ? "-debug " : ""), + (flags & ASSIMP_CFLAGS_NOBOOST ? "-noboost " : ""), + (flags & ASSIMP_CFLAGS_SHARED ? "-shared " : ""), + (flags & ASSIMP_CFLAGS_SINGLETHREADED ? "-st " : ""), + (flags & ASSIMP_CFLAGS_STLPORT ? "-stlport " : ""), + aiGetVersionRevision()); + + return 0; + } + + // assimp help + // Display some basic help (--help and -h work as well + // because people could try them intuitively) + if (!strcmp(argv[1], "help") || !strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")) { + printf("%s",AICMD_MSG_HELP); + return 0; + } + + // assimp cmpdump + // Compare two mini model dumps (regression suite) + if (! strcmp(argv[1], "cmpdump")) { + return Assimp_CompareDump (&argv[2],argc-2); + } + + // construct global importer and exporter instances + Assimp::Importer imp; + imp.SetPropertyBool("GLOB_MEASURE_TIME",true); + globalImporter = &imp; + +#ifndef ASSIMP_BUILD_NO_EXPORT + // + Assimp::Exporter exp; + globalExporter = &exp; +#endif + + // assimp listext + // List all file extensions supported by Assimp + if (! strcmp(argv[1], "listext")) { + aiString s; + imp.GetExtensionList(s); + + printf("%s\n",s.data); + return 0; + } + +#ifndef ASSIMP_BUILD_NO_EXPORT + // assimp listexport + // List all export file formats supported by Assimp (not the file extensions, just the format identifiers!) + if (! strcmp(argv[1], "listexport")) { + aiString s; + + for(size_t i = 0, end = exp.GetExportFormatCount(); i < end; ++i) { + const aiExportFormatDesc* const e = exp.GetExportFormatDescription(i); + s.Append( e->id ); + if (i!=end-1) { + s.Append("\n"); + } + } + + printf("%s\n",s.data); + return 0; + } + + + // assimp exportinfo + // stat an export format + if (! strcmp(argv[1], "exportinfo")) { + aiString s; + + if (argc<3) { + printf("Expected file format id\n"); + return -11; + } + + for(size_t i = 0, end = exp.GetExportFormatCount(); i < end; ++i) { + const aiExportFormatDesc* const e = exp.GetExportFormatDescription(i); + if (!strcmp(e->id,argv[2])) { + printf("%s\n%s\n%s\n",e->id,e->fileExtension,e->description); + return 0; + } + } + + printf("Unknown file format id: \'%s\'\n",argv[2]); + return -12; + } + + // assimp export + // Export a model to a file + if (! strcmp(argv[1], "export")) { + return Assimp_Export (&argv[2],argc-2); + } + +#endif + + // assimp knowext + // Check whether a particular file extension is known by us, return 0 on success + if (! strcmp(argv[1], "knowext")) { + if (argc<3) { + printf("Expected file extension"); + return -10; + } + const bool b = imp.IsExtensionSupported(argv[2]); + printf("File extension \'%s\' is %sknown\n",argv[2],(b?"":"not ")); + return b?0:-1; + } + + // assimp info + // Print basic model statistics + if (! strcmp(argv[1], "info")) { + return Assimp_Info ((const char**)&argv[2],argc-2); + } + + // assimp dump + // Dump a model to a file + if (! strcmp(argv[1], "dump")) { + return Assimp_Dump (&argv[2],argc-2); + } + + // assimp extract + // Extract an embedded texture from a file + if (! strcmp(argv[1], "extract")) { + return Assimp_Extract (&argv[2],argc-2); + } + + // assimp testbatchload + // Used by /test/other/streamload.py to load a list of files + // using the same importer instance to check for incompatible + // importers. + if (! strcmp(argv[1], "testbatchload")) { + return Assimp_TestBatchLoad (&argv[2],argc-2); + } + + printf("Unrecognized command. Use \'assimp help\' for a detailed command list\n"); + return 1; +} + + +// ------------------------------------------------------------------------------ +void SetLogStreams(const ImportData& imp) +{ + printf("\nAttaching log stream ... OK\n"); + + unsigned int flags = 0; + if (imp.logFile.length()) { + flags |= aiDefaultLogStream_FILE; + } + if (imp.showLog) { + flags |= aiDefaultLogStream_STDERR; + } + DefaultLogger::create(imp.logFile.c_str(),imp.verbose ? Logger::VERBOSE : Logger::NORMAL,flags); +} + + +// ------------------------------------------------------------------------------ +void FreeLogStreams() +{ + DefaultLogger::kill(); +} + + +// ------------------------------------------------------------------------------ +void PrintHorBar() +{ + printf("-----------------------------------------------------------------\n"); +} + + +// ------------------------------------------------------------------------------ +// Import a specific file +const aiScene* ImportModel( + const ImportData& imp, + const std::string& path) +{ + // Attach log streams + if (imp.log) { + SetLogStreams(imp); + } + printf("Launching asset import ... OK\n"); + + // Now validate this flag combination + if(!globalImporter->ValidateFlags(imp.ppFlags)) { + printf("ERROR: Unsupported post-processing flags \n"); + return NULL; + } + printf("Validating postprocessing flags ... OK\n"); + if (imp.showLog) { + PrintHorBar(); + } + + + // do the actual import, measure time + const clock_t first = clock(); + const aiScene* scene = globalImporter->ReadFile(path,imp.ppFlags); + + if (imp.showLog) { + PrintHorBar(); + } + if (!scene) { + printf("ERROR: Failed to load file: %s\n", globalImporter->GetErrorString()); + return NULL; + } + + const clock_t second = ::clock(); + const double seconds = static_cast<double>(second-first) / CLOCKS_PER_SEC; + + printf("Importing file ... OK \n import took approx. %.5f seconds\n" + "\n",seconds); + + if (imp.log) { + FreeLogStreams(); + } + return scene; +} + +#ifndef ASSIMP_BUILD_NO_EXPORT +// ------------------------------------------------------------------------------ +bool ExportModel(const aiScene* pOut, + const ImportData& imp, + const std::string& path, + const char* pID) +{ + // Attach log streams + if (imp.log) { + SetLogStreams(imp); + } + printf("Launching asset export ... OK\n"); + + if (imp.showLog) { + PrintHorBar(); + } + + // do the actual export, measure time + const clock_t first = clock(); + const aiReturn res = globalExporter->Export(pOut,pID,path); + + if (imp.showLog) { + PrintHorBar(); + } + if (res != AI_SUCCESS) { + printf("ERROR: Failed to write file\n"); + return false; + } + + const clock_t second = ::clock(); + const double seconds = static_cast<double>(second-first) / CLOCKS_PER_SEC; + + printf("Exporting file ... OK \n export took approx. %.5f seconds\n" + "\n",seconds); + + if (imp.log) { + FreeLogStreams(); + } + + return true; +} +#endif + +// ------------------------------------------------------------------------------ +// Process standard arguments +int ProcessStandardArguments( + ImportData& fill, + const char* const * params, + unsigned int num) +{ + // -ptv --pretransform-vertices + // -gsn --gen-smooth-normals + // -gn --gen-normals + // -cts --calc-tangent-space + // -jiv --join-identical-vertices + // -rrm --remove-redundant-materials + // -fd --find-degenerates + // -slm --split-large-meshes + // -lbw --limit-bone-weights + // -vds --validate-data-structure + // -icl --improve-cache-locality + // -sbpt --sort-by-ptype + // -lh --convert-to-lh + // -fuv --flip-uv + // -fwo --flip-winding-order + // -tuv --transform-uv-coords + // -guv --gen-uvcoords + // -fid --find-invalid-data + // -fixn --fix normals + // -tri --triangulate + // -fi --find-instances + // -og --optimize-graph + // -om --optimize-meshes + // -db --debone + // -sbc --split-by-bone-count + // + // -c<file> --config-file=<file> + + for (unsigned int i = 0; i < num;++i) + { + if (! strcmp(params[i], "-ptv") || ! strcmp(params[i], "--pretransform-vertices")) { + fill.ppFlags |= aiProcess_PreTransformVertices; + } + else if (! strcmp(params[i], "-gsn") || ! strcmp(params[i], "--gen-smooth-normals")) { + fill.ppFlags |= aiProcess_GenSmoothNormals; + } + else if (! strcmp(params[i], "-gn") || ! strcmp(params[i], "--gen-normals")) { + fill.ppFlags |= aiProcess_GenNormals; + } + else if (! strcmp(params[i], "-jiv") || ! strcmp(params[i], "--join-identical-vertices")) { + fill.ppFlags |= aiProcess_JoinIdenticalVertices; + } + else if (! strcmp(params[i], "-rrm") || ! strcmp(params[i], "--remove-redundant-materials")) { + fill.ppFlags |= aiProcess_RemoveRedundantMaterials; + } + else if (! strcmp(params[i], "-fd") || ! strcmp(params[i], "--find-degenerates")) { + fill.ppFlags |= aiProcess_FindDegenerates; + } + else if (! strcmp(params[i], "-slm") || ! strcmp(params[i], "--split-large-meshes")) { + fill.ppFlags |= aiProcess_SplitLargeMeshes; + } + else if (! strcmp(params[i], "-lbw") || ! strcmp(params[i], "--limit-bone-weights")) { + fill.ppFlags |= aiProcess_LimitBoneWeights; + } + else if (! strcmp(params[i], "-vds") || ! strcmp(params[i], "--validate-data-structure")) { + fill.ppFlags |= aiProcess_ValidateDataStructure; + } + else if (! strcmp(params[i], "-icl") || ! strcmp(params[i], "--improve-cache-locality")) { + fill.ppFlags |= aiProcess_ImproveCacheLocality; + } + else if (! strcmp(params[i], "-sbpt") || ! strcmp(params[i], "--sort-by-ptype")) { + fill.ppFlags |= aiProcess_SortByPType; + } + else if (! strcmp(params[i], "-lh") || ! strcmp(params[i], "--left-handed")) { + fill.ppFlags |= aiProcess_ConvertToLeftHanded; + } + else if (! strcmp(params[i], "-fuv") || ! strcmp(params[i], "--flip-uv")) { + fill.ppFlags |= aiProcess_FlipUVs; + } + else if (! strcmp(params[i], "-fwo") || ! strcmp(params[i], "--flip-winding-order")) { + fill.ppFlags |= aiProcess_FlipWindingOrder; + } + else if (! strcmp(params[i], "-tuv") || ! strcmp(params[i], "--transform-uv-coords")) { + fill.ppFlags |= aiProcess_TransformUVCoords; + } + else if (! strcmp(params[i], "-guv") || ! strcmp(params[i], "--gen-uvcoords")) { + fill.ppFlags |= aiProcess_GenUVCoords; + } + else if (! strcmp(params[i], "-fid") || ! strcmp(params[i], "--find-invalid-data")) { + fill.ppFlags |= aiProcess_FindInvalidData; + } + else if (! strcmp(params[i], "-fixn") || ! strcmp(params[i], "--fix-normals")) { + fill.ppFlags |= aiProcess_FixInfacingNormals; + } + else if (! strcmp(params[i], "-tri") || ! strcmp(params[i], "--triangulate")) { + fill.ppFlags |= aiProcess_Triangulate; + } + else if (! strcmp(params[i], "-cts") || ! strcmp(params[i], "--calc-tangent-space")) { + fill.ppFlags |= aiProcess_CalcTangentSpace; + } + else if (! strcmp(params[i], "-fi") || ! strcmp(params[i], "--find-instances")) { + fill.ppFlags |= aiProcess_FindInstances; + } + else if (! strcmp(params[i], "-og") || ! strcmp(params[i], "--optimize-graph")) { + fill.ppFlags |= aiProcess_OptimizeGraph; + } + else if (! strcmp(params[i], "-om") || ! strcmp(params[i], "--optimize-meshes")) { + fill.ppFlags |= aiProcess_OptimizeMeshes; + } + else if (! strcmp(params[i], "-db") || ! strcmp(params[i], "--debone")) { + fill.ppFlags |= aiProcess_Debone; + } + else if (! strcmp(params[i], "-sbc") || ! strcmp(params[i], "--split-by-bone-count")) { + fill.ppFlags |= aiProcess_SplitByBoneCount; + } + + + else if (! strncmp(params[i], "-c",2) || ! strncmp(params[i], "--config=",9)) { + + const unsigned int ofs = (params[i][1] == '-' ? 9 : 2); + + // use default configurations + if (! strncmp(params[i]+ofs,"full",4)) { + fill.ppFlags |= aiProcessPreset_TargetRealtime_MaxQuality; + } + else if (! strncmp(params[i]+ofs,"default",7)) { + fill.ppFlags |= aiProcessPreset_TargetRealtime_Quality; + } + else if (! strncmp(params[i]+ofs,"fast",4)) { + fill.ppFlags |= aiProcessPreset_TargetRealtime_Fast; + } + } + else if (! strcmp(params[i], "-l") || ! strcmp(params[i], "--show-log")) { + fill.showLog = true; + } + else if (! strcmp(params[i], "-v") || ! strcmp(params[i], "--verbose")) { + fill.verbose = true; + } + else if (! strncmp(params[i], "--log-out=",10) || ! strncmp(params[i], "-lo",3)) { + fill.logFile = std::string(params[i]+(params[i][1] == '-' ? 10 : 3)); + if (!fill.logFile.length()) { + fill.logFile = "assimp-log.txt"; + } + } + } + + if (fill.logFile.length() || fill.showLog || fill.verbose) { + fill.log = true; + } + + return 0; +} + +// ------------------------------------------------------------------------------ +int Assimp_TestBatchLoad ( + const char* const* params, + unsigned int num) +{ + for(unsigned int i = 0; i < num; ++i) { + globalImporter->ReadFile(params[i],aiProcessPreset_TargetRealtime_MaxQuality); + // we're totally silent. scene destructs automatically. + } + return 0; +} diff --git a/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/Main.h b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/Main.h new file mode 100644 index 0000000..56b06d5 --- /dev/null +++ b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/Main.h @@ -0,0 +1,208 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2015, assimp team + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +/** @file Main.h + * @brief Utility declarations for assimp_cmd + */ + +#ifndef AICMD_MAIN_INCLUDED +#define AICMD_MAIN_INCLUDED + +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS +#endif + +#include <stdio.h> +#include <string.h> +#include <time.h> +#include <limits> + +#include <assimp/postprocess.h> +#include <assimp/version.h> +#include <assimp/scene.h> +#include <assimp/Importer.hpp> +#include <assimp/DefaultLogger.hpp> + +#ifndef ASSIMP_BUILD_NO_EXPORT +# include <assimp/Exporter.hpp> +#endif + +#ifdef ASSIMP_BUILD_NO_OWN_ZLIB +#include <zlib.h> +#else +#include <../contrib/zlib/zlib.h> +#endif + + +#ifndef SIZE_MAX +# define SIZE_MAX (std::numeric_limits<size_t>::max()) +#endif + + +using namespace Assimp; + + +// Global assimp importer instance +extern Assimp::Importer* globalImporter; + +#ifndef ASSIMP_BUILD_NO_EXPORT +// Global assimp exporter instance +extern Assimp::Exporter* globalExporter; +#endif + +// ------------------------------------------------------------------------------ +/** Defines common import parameters */ +struct ImportData +{ + ImportData() + : ppFlags (0) + , showLog (false) + , verbose (false) + , log (false) + {} + + /** Postprocessing flags + */ + unsigned int ppFlags; + + + // Log to std::err? + bool showLog; + + // Log file + std::string logFile; + + // Verbose log mode? + bool verbose; + + // Need to log? + bool log; +}; + +// ------------------------------------------------------------------------------ +/** Process standard arguments + * + * @param fill Filled by function + * @param params Command line parameters to be processed + * @param num NUmber of params + * @return 0 for success */ +int ProcessStandardArguments(ImportData& fill, + const char* const* params, + unsigned int num); + +// ------------------------------------------------------------------------------ +/** Import a specific model file + * @param imp Import configuration to be used + * @param path Path to the file to be read */ +const aiScene* ImportModel( + const ImportData& imp, + const std::string& path); + +#ifndef ASSIMP_BUILD_NO_EXPORT + +// ------------------------------------------------------------------------------ +/** Export a specific model file + * @param imp Import configuration to be used + * @param path Path to the file to be written + * @param format Format id*/ +bool ExportModel(const aiScene* pOut, + const ImportData& imp, + const std::string& path, + const char* pID); + +#endif + +// ------------------------------------------------------------------------------ +/** assimp_dump utility + * @param params Command line parameters to 'assimp dumb' + * @param Number of params + * @return 0 for success*/ +int Assimp_Dump ( + const char* const* params, + unsigned int num); + +// ------------------------------------------------------------------------------ +/** assimp_export utility + * @param params Command line parameters to 'assimp export' + * @param Number of params + * @return 0 for success*/ +int Assimp_Export ( + const char* const* params, + unsigned int num); + +// ------------------------------------------------------------------------------ +/** assimp_extract utility + * @param params Command line parameters to 'assimp extract' + * @param Number of params + * @return 0 for success*/ +int Assimp_Extract ( + const char* const* params, + unsigned int num); + +// ------------------------------------------------------------------------------ +/** assimp_cmpdump utility + * @param params Command line parameters to 'assimp cmpdump' + * @param Number of params + * @return 0 for success*/ +int Assimp_CompareDump ( + const char* const* params, + unsigned int num); + +// ------------------------------------------------------------------------------ +/** @brief assimp info utility + * @param params Command line parameters to 'assimp info' + * @param Number of params + * @return 0 for success */ +int Assimp_Info ( + const char* const* params, + unsigned int num); + +// ------------------------------------------------------------------------------ +/** @brief assimp testbatchload utility + * @param params Command line parameters to 'assimp testbatchload' + * @param Number of params + * @return 0 for success */ +int Assimp_TestBatchLoad ( + const char* const* params, + unsigned int num); + + +#endif // !! AICMD_MAIN_INCLUDED diff --git a/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/WriteDumb.cpp b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/WriteDumb.cpp new file mode 100644 index 0000000..e1b104d --- /dev/null +++ b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/WriteDumb.cpp @@ -0,0 +1,1415 @@ +/* +--------------------------------------------------------------------------- +Open Asset Import Library (assimp) +--------------------------------------------------------------------------- + +Copyright (c) 2006-2017, assimp team + + +All rights reserved. + +Redistribution and use of this software in source and binary forms, +with or without modification, are permitted provided that the following +conditions are met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of the assimp team, nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of the assimp team. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +--------------------------------------------------------------------------- +*/ + +/** @file WriteTextDumb.cpp + * @brief Implementation of the 'assimp dump' utility + */ + +#include "Main.h" +#include "../code/ProcessHelper.h" + +const char* AICMD_MSG_DUMP_HELP = +"assimp dump <model> [<out>] [-b] [-s] [-z] [common parameters]\n" +"\t -b Binary output \n" +"\t -s Shortened \n" +"\t -z Compressed \n" +"\t[See the assimp_cmd docs for a full list of all common parameters] \n" +"\t -cfast Fast post processing preset, runs just a few important steps \n" +"\t -cdefault Default post processing: runs all recommended steps\n" +"\t -cfull Fires almost all post processing steps \n" +; + +#include "../../code/assbin_chunks.h" + +FILE* out = NULL; +bool shortened = false; + +// ----------------------------------------------------------------------------------- +// Compress a binary dump file (beginning at offset head_size) +void CompressBinaryDump(const char* file, unsigned int head_size) +{ + // for simplicity ... copy the file into memory again and compress it there + FILE* p = fopen(file,"r"); + fseek(p,0,SEEK_END); + const uint32_t size = ftell(p); + fseek(p,0,SEEK_SET); + + if (size<head_size) { + fclose(p); + return; + } + + uint8_t* data = new uint8_t[size]; + fread(data,1,size,p); + + uLongf out_size = (uLongf)((size-head_size) * 1.001 + 12.); + uint8_t* out = new uint8_t[out_size]; + + compress2(out,&out_size,data+head_size,size-head_size,9); + fclose(p); + p = fopen(file,"w"); + + fwrite(data,head_size,1,p); + fwrite(&out_size,4,1,p); // write size of uncompressed data + fwrite(out,out_size,1,p); + + fclose(p); + delete[] data; + delete[] out; +} + +// ----------------------------------------------------------------------------------- +// Write a magic start value for each serialized data structure +inline uint32_t WriteMagic(uint32_t magic) +{ + fwrite(&magic,4,1,out); + fwrite(&magic,4,1,out); + return ftell(out)-4; +} + +// use template specializations rather than regular overloading to be able to +// explicitly select the right 'overload' to leave no doubts on what is called, +// retaining the possibility of letting the compiler select. +template <typename T> uint32_t Write(const T&); + +// ----------------------------------------------------------------------------------- +// Serialize an aiString +template <> +inline uint32_t Write<aiString>(const aiString& s) +{ + const uint32_t s2 = (uint32_t)s.length; + fwrite(&s,4,1,out); + fwrite(s.data,s2,1,out); + return s2+4; +} + +// ----------------------------------------------------------------------------------- +// Serialize an unsigned int as uint32_t +template <> +inline uint32_t Write<unsigned int>(const unsigned int& w) +{ + const uint32_t t = (uint32_t)w; + if (w > t) { + // this shouldn't happen, integers in Assimp data structures never exceed 2^32 + printf("loss of data due to 64 -> 32 bit integer conversion"); + } + + fwrite(&t,4,1,out); + return 4; +} + +// ----------------------------------------------------------------------------------- +// Serialize an unsigned int as uint16_t +template <> +inline uint32_t Write<uint16_t>(const uint16_t& w) +{ + fwrite(&w,2,1,out); + return 2; +} + +// ----------------------------------------------------------------------------------- +// Serialize a float +template <> +inline uint32_t Write<float>(const float& f) +{ + static_assert(sizeof(float)==4, "sizeof(float)==4"); + fwrite(&f,4,1,out); + return 4; +} + +// ----------------------------------------------------------------------------------- +// Serialize a double +template <> +inline uint32_t Write<double>(const double& f) +{ + static_assert(sizeof(double)==8, "sizeof(double)==8"); + fwrite(&f,8,1,out); + return 8; +} + +// ----------------------------------------------------------------------------------- +// Serialize a vec3 +template <> +inline uint32_t Write<aiVector3D>(const aiVector3D& v) +{ + uint32_t t = Write<float>(v.x); + t += Write<float>(v.y); + t += Write<float>(v.z); + return t; +} + +// ----------------------------------------------------------------------------------- +// Serialize a color value +template <> +inline uint32_t Write<aiColor3D>(const aiColor3D& v) +{ + uint32_t t = Write<float>(v.r); + t += Write<float>(v.g); + t += Write<float>(v.b); + return t; +} + +// ----------------------------------------------------------------------------------- +// Serialize a color value +template <> +inline uint32_t Write<aiColor4D>(const aiColor4D& v) +{ + uint32_t t = Write<float>(v.r); + t += Write<float>(v.g); + t += Write<float>(v.b); + t += Write<float>(v.a); + return t; +} + +// ----------------------------------------------------------------------------------- +// Serialize a quaternion +template <> +inline uint32_t Write<aiQuaternion>(const aiQuaternion& v) +{ + uint32_t t = Write<float>(v.w); + t += Write<float>(v.x); + t += Write<float>(v.y); + t += Write<float>(v.z); + ai_assert(t == 16); + return 16; +} + + +// ----------------------------------------------------------------------------------- +// Serialize a vertex weight +template <> +inline uint32_t Write<aiVertexWeight>(const aiVertexWeight& v) +{ + uint32_t t = Write<unsigned int>(v.mVertexId); + return t+Write<float>(v.mWeight); +} + +// ----------------------------------------------------------------------------------- +// Serialize a mat4x4 +template <> +inline uint32_t Write<aiMatrix4x4>(const aiMatrix4x4& m) +{ + for (unsigned int i = 0; i < 4;++i) { + for (unsigned int i2 = 0; i2 < 4;++i2) { + Write<float>(m[i][i2]); + } + } + return 64; +} + +// ----------------------------------------------------------------------------------- +// Serialize an aiVectorKey +template <> +inline uint32_t Write<aiVectorKey>(const aiVectorKey& v) +{ + const uint32_t t = Write<double>(v.mTime); + return t + Write<aiVector3D>(v.mValue); +} + +// ----------------------------------------------------------------------------------- +// Serialize an aiQuatKey +template <> +inline uint32_t Write<aiQuatKey>(const aiQuatKey& v) +{ + const uint32_t t = Write<double>(v.mTime); + return t + Write<aiQuaternion>(v.mValue); +} + +// ----------------------------------------------------------------------------------- +// Write the min/max values of an array of Ts to the file +template <typename T> +inline uint32_t WriteBounds(const T* in, unsigned int size) +{ + T minc,maxc; + Assimp::ArrayBounds(in,size,minc,maxc); + + const uint32_t t = Write<T>(minc); + return t + Write<T>(maxc); +} + + + +// ----------------------------------------------------------------------------------- +void ChangeInteger(uint32_t ofs,uint32_t n) +{ + const uint32_t cur = ftell(out); + fseek(out,ofs,SEEK_SET); + fwrite(&n,4,1,out); + fseek(out,cur,SEEK_SET); +} + +// ----------------------------------------------------------------------------------- +uint32_t WriteBinaryNode(const aiNode* node) +{ + uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AINODE); + len += Write<aiString>(node->mName); + len += Write<aiMatrix4x4>(node->mTransformation); + len += Write<unsigned int>(node->mNumChildren); + len += Write<unsigned int>(node->mNumMeshes); + + for (unsigned int i = 0; i < node->mNumMeshes;++i) { + len += Write<unsigned int>(node->mMeshes[i]); + } + + for (unsigned int i = 0; i < node->mNumChildren;++i) { + len += WriteBinaryNode(node->mChildren[i])+8; + } + + ChangeInteger(old,len); + return len; +} + +// ----------------------------------------------------------------------------------- +uint32_t WriteBinaryTexture(const aiTexture* tex) +{ + uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AITEXTURE); + + len += Write<unsigned int>(tex->mWidth); + len += Write<unsigned int>(tex->mHeight); + len += static_cast<uint32_t>(fwrite(tex->achFormatHint,1,4,out)); + + if(!shortened) { + if (!tex->mHeight) { + len += static_cast<uint32_t>(fwrite(tex->pcData,1,tex->mWidth,out)); + } + else { + len += static_cast<uint32_t>(fwrite(tex->pcData,1,tex->mWidth*tex->mHeight*4,out)); + } + } + + ChangeInteger(old,len); + return len; +} + +// ----------------------------------------------------------------------------------- +uint32_t WriteBinaryBone(const aiBone* b) +{ + uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AIBONE); + + len += Write<aiString>(b->mName); + len += Write<unsigned int>(b->mNumWeights); + len += Write<aiMatrix4x4>(b->mOffsetMatrix); + + // for the moment we write dumb min/max values for the bones, too. + // maybe I'll add a better, hash-like solution later + if (shortened) { + len += WriteBounds(b->mWeights,b->mNumWeights); + } // else write as usual + else len += static_cast<uint32_t>(fwrite(b->mWeights,1,b->mNumWeights*sizeof(aiVertexWeight),out)); + + ChangeInteger(old,len); + return len; +} + +// ----------------------------------------------------------------------------------- +uint32_t WriteBinaryMesh(const aiMesh* mesh) +{ + uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AIMESH); + + len += Write<unsigned int>(mesh->mPrimitiveTypes); + len += Write<unsigned int>(mesh->mNumVertices); + len += Write<unsigned int>(mesh->mNumFaces); + len += Write<unsigned int>(mesh->mNumBones); + len += Write<unsigned int>(mesh->mMaterialIndex); + + // first of all, write bits for all existent vertex components + unsigned int c = 0; + if (mesh->mVertices) { + c |= ASSBIN_MESH_HAS_POSITIONS; + } + if (mesh->mNormals) { + c |= ASSBIN_MESH_HAS_NORMALS; + } + if (mesh->mTangents && mesh->mBitangents) { + c |= ASSBIN_MESH_HAS_TANGENTS_AND_BITANGENTS; + } + for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) { + if (!mesh->mTextureCoords[n]) { + break; + } + c |= ASSBIN_MESH_HAS_TEXCOORD(n); + } + for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) { + if (!mesh->mColors[n]) { + break; + } + c |= ASSBIN_MESH_HAS_COLOR(n); + } + len += Write<unsigned int>(c); + + aiVector3D minVec, maxVec; + if (mesh->mVertices) { + if (shortened) { + len += WriteBounds(mesh->mVertices,mesh->mNumVertices); + } // else write as usual + else len += static_cast<uint32_t>(fwrite(mesh->mVertices,1,12*mesh->mNumVertices,out)); + } + if (mesh->mNormals) { + if (shortened) { + len += WriteBounds(mesh->mNormals,mesh->mNumVertices); + } // else write as usual + else len += static_cast<uint32_t>(fwrite(mesh->mNormals,1,12*mesh->mNumVertices,out)); + } + if (mesh->mTangents && mesh->mBitangents) { + if (shortened) { + len += WriteBounds(mesh->mTangents,mesh->mNumVertices); + len += WriteBounds(mesh->mBitangents,mesh->mNumVertices); + } // else write as usual + else { + len += static_cast<uint32_t>(fwrite(mesh->mTangents,1,12*mesh->mNumVertices,out)); + len += static_cast<uint32_t>(fwrite(mesh->mBitangents,1,12*mesh->mNumVertices,out)); + } + } + for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_COLOR_SETS;++n) { + if (!mesh->mColors[n]) + break; + + if (shortened) { + len += WriteBounds(mesh->mColors[n],mesh->mNumVertices); + } // else write as usual + else len += static_cast<uint32_t>(fwrite(mesh->mColors[n],16*mesh->mNumVertices,1,out)); + } + for (unsigned int n = 0; n < AI_MAX_NUMBER_OF_TEXTURECOORDS;++n) { + if (!mesh->mTextureCoords[n]) + break; + + // write number of UV components + len += Write<unsigned int>(mesh->mNumUVComponents[n]); + + if (shortened) { + len += WriteBounds(mesh->mTextureCoords[n],mesh->mNumVertices); + } // else write as usual + else len += static_cast<uint32_t>(fwrite(mesh->mTextureCoords[n],12*mesh->mNumVertices,1,out)); + } + + // write faces. There are no floating-point calculations involved + // in these, so we can write a simple hash over the face data + // to the dump file. We generate a single 32 Bit hash for 512 faces + // using Assimp's standard hashing function. + if (shortened) { + unsigned int processed = 0; + for (unsigned int job;(job = std::min(mesh->mNumFaces-processed,512u));processed += job) { + + uint32_t hash = 0; + for (unsigned int a = 0; a < job;++a) { + + const aiFace& f = mesh->mFaces[processed+a]; + uint32_t tmp = f.mNumIndices; + hash = SuperFastHash(reinterpret_cast<const char*>(&tmp),sizeof tmp,hash); + for (unsigned int i = 0; i < f.mNumIndices; ++i) { + static_assert(AI_MAX_VERTICES <= 0xffffffff, "AI_MAX_VERTICES <= 0xffffffff"); + tmp = static_cast<uint32_t>( f.mIndices[i] ); + hash = SuperFastHash(reinterpret_cast<const char*>(&tmp),sizeof tmp,hash); + } + } + len += Write<unsigned int>(hash); + } + } + else // else write as usual + { + // if there are less than 2^16 vertices, we can simply use 16 bit integers ... + for (unsigned int i = 0; i < mesh->mNumFaces;++i) { + const aiFace& f = mesh->mFaces[i]; + + static_assert(AI_MAX_FACE_INDICES <= 0xffff, "AI_MAX_FACE_INDICES <= 0xffff"); + len += Write<uint16_t>(f.mNumIndices); + + for (unsigned int a = 0; a < f.mNumIndices;++a) { + if (mesh->mNumVertices < (1u<<16)) { + len += Write<uint16_t>(f.mIndices[a]); + } + else len += Write<unsigned int>(f.mIndices[a]); + } + } + } + + // write bones + if (mesh->mNumBones) { + for (unsigned int a = 0; a < mesh->mNumBones;++a) { + const aiBone* b = mesh->mBones[a]; + len += WriteBinaryBone(b)+8; + } + } + + ChangeInteger(old,len); + return len; +} + +// ----------------------------------------------------------------------------------- +uint32_t WriteBinaryMaterialProperty(const aiMaterialProperty* prop) +{ + uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AIMATERIALPROPERTY); + + len += Write<aiString>(prop->mKey); + len += Write<unsigned int>(prop->mSemantic); + len += Write<unsigned int>(prop->mIndex); + + len += Write<unsigned int>(prop->mDataLength); + len += Write<unsigned int>((unsigned int)prop->mType); + len += static_cast<uint32_t>(fwrite(prop->mData,1,prop->mDataLength,out)); + + ChangeInteger(old,len); + return len; +} + +// ----------------------------------------------------------------------------------- +uint32_t WriteBinaryMaterial(const aiMaterial* mat) +{ + uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AIMATERIAL); + + len += Write<unsigned int>(mat->mNumProperties); + for (unsigned int i = 0; i < mat->mNumProperties;++i) { + len += WriteBinaryMaterialProperty(mat->mProperties[i])+8; + } + + ChangeInteger(old,len); + return len; +} + +// ----------------------------------------------------------------------------------- +uint32_t WriteBinaryNodeAnim(const aiNodeAnim* nd) +{ + uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AINODEANIM); + + len += Write<aiString>(nd->mNodeName); + len += Write<unsigned int>(nd->mNumPositionKeys); + len += Write<unsigned int>(nd->mNumRotationKeys); + len += Write<unsigned int>(nd->mNumScalingKeys); + len += Write<unsigned int>(nd->mPreState); + len += Write<unsigned int>(nd->mPostState); + + if (nd->mPositionKeys) { + if (shortened) { + len += WriteBounds(nd->mPositionKeys,nd->mNumPositionKeys); + + } // else write as usual + else len += static_cast<uint32_t>(fwrite(nd->mPositionKeys,1,nd->mNumPositionKeys*sizeof(aiVectorKey),out)); + } + if (nd->mRotationKeys) { + if (shortened) { + len += WriteBounds(nd->mRotationKeys,nd->mNumRotationKeys); + + } // else write as usual + else len += static_cast<uint32_t>(fwrite(nd->mRotationKeys,1,nd->mNumRotationKeys*sizeof(aiQuatKey),out)); + } + if (nd->mScalingKeys) { + if (shortened) { + len += WriteBounds(nd->mScalingKeys,nd->mNumScalingKeys); + + } // else write as usual + else len += static_cast<uint32_t>(fwrite(nd->mScalingKeys,1,nd->mNumScalingKeys*sizeof(aiVectorKey),out)); + } + + ChangeInteger(old,len); + return len; +} + + +// ----------------------------------------------------------------------------------- +uint32_t WriteBinaryAnim(const aiAnimation* anim) +{ + uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AIANIMATION); + + len += Write<aiString> (anim->mName); + len += Write<double> (anim->mDuration); + len += Write<double> (anim->mTicksPerSecond); + len += Write<unsigned int>(anim->mNumChannels); + + for (unsigned int a = 0; a < anim->mNumChannels;++a) { + const aiNodeAnim* nd = anim->mChannels[a]; + len += WriteBinaryNodeAnim(nd)+8; + } + + ChangeInteger(old,len); + return len; +} + +// ----------------------------------------------------------------------------------- +uint32_t WriteBinaryLight(const aiLight* l) +{ + uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AILIGHT); + + len += Write<aiString>(l->mName); + len += Write<unsigned int>(l->mType); + + if (l->mType != aiLightSource_DIRECTIONAL) { + len += Write<float>(l->mAttenuationConstant); + len += Write<float>(l->mAttenuationLinear); + len += Write<float>(l->mAttenuationQuadratic); + } + + len += Write<aiColor3D>(l->mColorDiffuse); + len += Write<aiColor3D>(l->mColorSpecular); + len += Write<aiColor3D>(l->mColorAmbient); + + if (l->mType == aiLightSource_SPOT) { + len += Write<float>(l->mAngleInnerCone); + len += Write<float>(l->mAngleOuterCone); + } + + ChangeInteger(old,len); + return len; +} + +// ----------------------------------------------------------------------------------- +uint32_t WriteBinaryCamera(const aiCamera* cam) +{ + uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AICAMERA); + + len += Write<aiString>(cam->mName); + len += Write<aiVector3D>(cam->mPosition); + len += Write<aiVector3D>(cam->mLookAt); + len += Write<aiVector3D>(cam->mUp); + len += Write<float>(cam->mHorizontalFOV); + len += Write<float>(cam->mClipPlaneNear); + len += Write<float>(cam->mClipPlaneFar); + len += Write<float>(cam->mAspect); + + ChangeInteger(old,len); + return len; +} + +// ----------------------------------------------------------------------------------- +uint32_t WriteBinaryScene(const aiScene* scene) +{ + uint32_t len = 0, old = WriteMagic(ASSBIN_CHUNK_AISCENE); + + // basic scene information + len += Write<unsigned int>(scene->mFlags); + len += Write<unsigned int>(scene->mNumMeshes); + len += Write<unsigned int>(scene->mNumMaterials); + len += Write<unsigned int>(scene->mNumAnimations); + len += Write<unsigned int>(scene->mNumTextures); + len += Write<unsigned int>(scene->mNumLights); + len += Write<unsigned int>(scene->mNumCameras); + + // write node graph + len += WriteBinaryNode(scene->mRootNode)+8; + + // write all meshes + for (unsigned int i = 0; i < scene->mNumMeshes;++i) { + const aiMesh* mesh = scene->mMeshes[i]; + len += WriteBinaryMesh(mesh)+8; + } + + // write materials + for (unsigned int i = 0; i< scene->mNumMaterials; ++i) { + const aiMaterial* mat = scene->mMaterials[i]; + len += WriteBinaryMaterial(mat)+8; + } + + // write all animations + for (unsigned int i = 0; i < scene->mNumAnimations;++i) { + const aiAnimation* anim = scene->mAnimations[i]; + len += WriteBinaryAnim(anim)+8; + } + + + // write all textures + for (unsigned int i = 0; i < scene->mNumTextures;++i) { + const aiTexture* mesh = scene->mTextures[i]; + len += WriteBinaryTexture(mesh)+8; + } + + // write lights + for (unsigned int i = 0; i < scene->mNumLights;++i) { + const aiLight* l = scene->mLights[i]; + len += WriteBinaryLight(l)+8; + } + + // write cameras + for (unsigned int i = 0; i < scene->mNumCameras;++i) { + const aiCamera* cam = scene->mCameras[i]; + len += WriteBinaryCamera(cam)+8; + } + + ChangeInteger(old,len); + return len; +} + +// ----------------------------------------------------------------------------------- +// Write a binary model dump +void WriteBinaryDump(const aiScene* scene, FILE* _out, const char* src, const char* cmd, + bool _shortened, bool compressed, ImportData& /*imp*/) +{ + out = _out; + shortened = _shortened; + + time_t tt = time(NULL); + tm* p = gmtime(&tt); + + // header + fprintf(out,"ASSIMP.binary-dump.%s",asctime(p)); + // == 44 bytes + + Write<unsigned int>(ASSBIN_VERSION_MAJOR); + Write<unsigned int>(ASSBIN_VERSION_MINOR); + Write<unsigned int>(aiGetVersionRevision()); + Write<unsigned int>(aiGetCompileFlags()); + Write<uint16_t>(shortened); + Write<uint16_t>(compressed); + // == 20 bytes + + { + char buff[256] = { 0 }; + strncpy(buff,src,256); + buff[255] = 0; + fwrite(buff,256,1,out); + } + + { + char buff[128] = { 0 }; + strncpy(buff,cmd,128); + buff[127] = 0; + fwrite(buff,128,1,out); + } + + // leave 64 bytes free for future extensions + { + char buff[64]; + memset(buff,0xcd,64); + fwrite(buff,64,1,out); + } + // == 435 bytes + + // ==== total header size: 512 bytes + ai_assert(ftell(out)==ASSBIN_HEADER_LENGTH); + + // Up to here the data is uncompressed. For compressed files, the rest + // is compressed using standard DEFLATE from zlib. + WriteBinaryScene(scene); +} + +// ----------------------------------------------------------------------------------- +// Convert a name to standard XML format +void ConvertName(aiString& out, const aiString& in) +{ + out.length = 0; + for (unsigned int i = 0; i < in.length; ++i) { + switch (in.data[i]) { + case '<': + out.Append("<");break; + case '>': + out.Append(">");break; + case '&': + out.Append("&");break; + case '\"': + out.Append(""");break; + case '\'': + out.Append("'");break; + default: + out.data[out.length++] = in.data[i]; + } + } + out.data[out.length] = 0; +} + +// ----------------------------------------------------------------------------------- +// Write a single node as text dump +void WriteNode(const aiNode* node, FILE* out, unsigned int depth) +{ + char prefix[512]; + for (unsigned int i = 0; i < depth;++i) + prefix[i] = '\t'; + prefix[depth] = '\0'; + + const aiMatrix4x4& m = node->mTransformation; + + aiString name; + ConvertName(name,node->mName); + fprintf(out,"%s<Node name=\"%s\"> \n" + "%s\t<Matrix4> \n" + "%s\t\t%0 6f %0 6f %0 6f %0 6f\n" + "%s\t\t%0 6f %0 6f %0 6f %0 6f\n" + "%s\t\t%0 6f %0 6f %0 6f %0 6f\n" + "%s\t\t%0 6f %0 6f %0 6f %0 6f\n" + "%s\t</Matrix4> \n", + prefix,name.data,prefix, + prefix,m.a1,m.a2,m.a3,m.a4, + prefix,m.b1,m.b2,m.b3,m.b4, + prefix,m.c1,m.c2,m.c3,m.c4, + prefix,m.d1,m.d2,m.d3,m.d4,prefix); + + if (node->mNumMeshes) { + fprintf(out, "%s\t<MeshRefs num=\"%u\">\n%s\t", + prefix,node->mNumMeshes,prefix); + + for (unsigned int i = 0; i < node->mNumMeshes;++i) { + fprintf(out,"%u ",node->mMeshes[i]); + } + fprintf(out,"\n%s\t</MeshRefs>\n",prefix); + } + + if (node->mNumChildren) { + fprintf(out,"%s\t<NodeList num=\"%u\">\n", + prefix,node->mNumChildren); + + for (unsigned int i = 0; i < node->mNumChildren;++i) { + WriteNode(node->mChildren[i],out,depth+2); + } + fprintf(out,"%s\t</NodeList>\n",prefix); + } + fprintf(out,"%s</Node>\n",prefix); +} + + +// ------------------------------------------------------------------------------- +const char* TextureTypeToString(aiTextureType in) +{ + switch (in) + { + case aiTextureType_NONE: + return "n/a"; + case aiTextureType_DIFFUSE: + return "Diffuse"; + case aiTextureType_SPECULAR: + return "Specular"; + case aiTextureType_AMBIENT: + return "Ambient"; + case aiTextureType_EMISSIVE: + return "Emissive"; + case aiTextureType_OPACITY: + return "Opacity"; + case aiTextureType_NORMALS: + return "Normals"; + case aiTextureType_HEIGHT: + return "Height"; + case aiTextureType_SHININESS: + return "Shininess"; + case aiTextureType_DISPLACEMENT: + return "Displacement"; + case aiTextureType_LIGHTMAP: + return "Lightmap"; + case aiTextureType_REFLECTION: + return "Reflection"; + case aiTextureType_UNKNOWN: + return "Unknown"; + default: + break; + } + ai_assert(false); + return "BUG"; +} + + +// ----------------------------------------------------------------------------------- +// Some chuncks of text will need to be encoded for XML +// http://stackoverflow.com/questions/5665231/most-efficient-way-to-escape-xml-html-in-c-string#5665377 +static std::string encodeXML(const std::string& data) { + std::string buffer; + buffer.reserve(data.size()); + for(size_t pos = 0; pos != data.size(); ++pos) { + switch(data[pos]) { + case '&': buffer.append("&"); break; + case '\"': buffer.append("""); break; + case '\'': buffer.append("'"); break; + case '<': buffer.append("<"); break; + case '>': buffer.append(">"); break; + default: buffer.append(&data[pos], 1); break; + } + } + return buffer; +} + + + +// ----------------------------------------------------------------------------------- +// Write a text model dump +void WriteDump(const aiScene* scene, FILE* out, const char* src, const char* cmd, bool shortened) +{ + time_t tt = ::time(NULL); + tm* p = ::gmtime(&tt); + + std::string c = cmd; + std::string::size_type s; + + // https://sourceforge.net/tracker/?func=detail&aid=3167364&group_id=226462&atid=1067632 + // -- not allowed in XML comments + while((s = c.find("--")) != std::string::npos) { + c[s] = '?'; + } + aiString name; + + // write header + fprintf(out, + "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" + "<ASSIMP format_id=\"1\">\n\n" + + "<!-- XML Model dump produced by assimp dump\n" + " Library version: %u.%u.%u\n" + " Source: %s\n" + " Command line: %s\n" + " %s\n" + "-->" + " \n\n" + "<Scene flags=\"%u\" postprocessing=\"%i\">\n", + + aiGetVersionMajor(),aiGetVersionMinor(),aiGetVersionRevision(),src,c.c_str(),asctime(p), + scene->mFlags, + 0 /*globalImporter->GetEffectivePostProcessing()*/); + + // write the node graph + WriteNode(scene->mRootNode, out, 0); + +#if 0 + // write cameras + for (unsigned int i = 0; i < scene->mNumCameras;++i) { + aiCamera* cam = scene->mCameras[i]; + ConvertName(name,cam->mName); + + // camera header + fprintf(out,"\t<Camera parent=\"%s\">\n" + "\t\t<Vector3 name=\"up\" > %0 8f %0 8f %0 8f </Vector3>\n" + "\t\t<Vector3 name=\"lookat\" > %0 8f %0 8f %0 8f </Vector3>\n" + "\t\t<Vector3 name=\"pos\" > %0 8f %0 8f %0 8f </Vector3>\n" + "\t\t<Float name=\"fov\" > %f </Float>\n" + "\t\t<Float name=\"aspect\" > %f </Float>\n" + "\t\t<Float name=\"near_clip\" > %f </Float>\n" + "\t\t<Float name=\"far_clip\" > %f </Float>\n" + "\t</Camera>\n", + name.data, + cam->mUp.x,cam->mUp.y,cam->mUp.z, + cam->mLookAt.x,cam->mLookAt.y,cam->mLookAt.z, + cam->mPosition.x,cam->mPosition.y,cam->mPosition.z, + cam->mHorizontalFOV,cam->mAspect,cam->mClipPlaneNear,cam->mClipPlaneFar,i); + } + + // write lights + for (unsigned int i = 0; i < scene->mNumLights;++i) { + aiLight* l = scene->mLights[i]; + ConvertName(name,l->mName); + + // light header + fprintf(out,"\t<Light parent=\"%s\"> type=\"%s\"\n" + "\t\t<Vector3 name=\"diffuse\" > %0 8f %0 8f %0 8f </Vector3>\n" + "\t\t<Vector3 name=\"specular\" > %0 8f %0 8f %0 8f </Vector3>\n" + "\t\t<Vector3 name=\"ambient\" > %0 8f %0 8f %0 8f </Vector3>\n", + name.data, + (l->mType == aiLightSource_DIRECTIONAL ? "directional" : + (l->mType == aiLightSource_POINT ? "point" : "spot" )), + l->mColorDiffuse.r, l->mColorDiffuse.g, l->mColorDiffuse.b, + l->mColorSpecular.r,l->mColorSpecular.g,l->mColorSpecular.b, + l->mColorAmbient.r, l->mColorAmbient.g, l->mColorAmbient.b); + + if (l->mType != aiLightSource_DIRECTIONAL) { + fprintf(out, + "\t\t<Vector3 name=\"pos\" > %0 8f %0 8f %0 8f </Vector3>\n" + "\t\t<Float name=\"atten_cst\" > %f </Float>\n" + "\t\t<Float name=\"atten_lin\" > %f </Float>\n" + "\t\t<Float name=\"atten_sqr\" > %f </Float>\n", + l->mPosition.x,l->mPosition.y,l->mPosition.z, + l->mAttenuationConstant,l->mAttenuationLinear,l->mAttenuationQuadratic); + } + + if (l->mType != aiLightSource_POINT) { + fprintf(out, + "\t\t<Vector3 name=\"lookat\" > %0 8f %0 8f %0 8f </Vector3>\n", + l->mDirection.x,l->mDirection.y,l->mDirection.z); + } + + if (l->mType == aiLightSource_SPOT) { + fprintf(out, + "\t\t<Float name=\"cone_out\" > %f </Float>\n" + "\t\t<Float name=\"cone_inn\" > %f </Float>\n", + l->mAngleOuterCone,l->mAngleInnerCone); + } + fprintf(out,"\t</Light>\n"); + } +#endif + + // write textures + if (scene->mNumTextures) { + fprintf(out,"<TextureList num=\"%u\">\n",scene->mNumTextures); + for (unsigned int i = 0; i < scene->mNumTextures;++i) { + aiTexture* tex = scene->mTextures[i]; + bool compressed = (tex->mHeight == 0); + + // mesh header + fprintf(out,"\t<Texture width=\"%i\" height=\"%i\" compressed=\"%s\"> \n", + (compressed ? -1 : tex->mWidth),(compressed ? -1 : tex->mHeight), + (compressed ? "true" : "false")); + + if (compressed) { + fprintf(out,"\t\t<Data length=\"%u\"> \n",tex->mWidth); + + if (!shortened) { + for (unsigned int n = 0; n < tex->mWidth;++n) { + fprintf(out,"\t\t\t%2x",reinterpret_cast<uint8_t*>(tex->pcData)[n]); + if (n && !(n % 50)) { + fprintf(out,"\n"); + } + } + } + } + else if (!shortened){ + fprintf(out,"\t\t<Data length=\"%i\"> \n",tex->mWidth*tex->mHeight*4); + + // const unsigned int width = (unsigned int)log10((double)std::max(tex->mHeight,tex->mWidth))+1; + for (unsigned int y = 0; y < tex->mHeight;++y) { + for (unsigned int x = 0; x < tex->mWidth;++x) { + aiTexel* tx = tex->pcData + y*tex->mWidth+x; + unsigned int r = tx->r,g=tx->g,b=tx->b,a=tx->a; + fprintf(out,"\t\t\t%2x %2x %2x %2x",r,g,b,a); + + // group by four for readibility + if (0 == (x+y*tex->mWidth) % 4) + fprintf(out,"\n"); + } + } + } + fprintf(out,"\t\t</Data>\n\t</Texture>\n"); + } + fprintf(out,"</TextureList>\n"); + } + + // write materials + if (scene->mNumMaterials) { + fprintf(out,"<MaterialList num=\"%u\">\n",scene->mNumMaterials); + for (unsigned int i = 0; i< scene->mNumMaterials; ++i) { + const aiMaterial* mat = scene->mMaterials[i]; + + fprintf(out,"\t<Material>\n"); + fprintf(out,"\t\t<MatPropertyList num=\"%u\">\n",mat->mNumProperties); + for (unsigned int n = 0; n < mat->mNumProperties;++n) { + + const aiMaterialProperty* prop = mat->mProperties[n]; + const char* sz = ""; + if (prop->mType == aiPTI_Float) { + sz = "float"; + } + else if (prop->mType == aiPTI_Integer) { + sz = "integer"; + } + else if (prop->mType == aiPTI_String) { + sz = "string"; + } + else if (prop->mType == aiPTI_Buffer) { + sz = "binary_buffer"; + } + + fprintf(out,"\t\t\t<MatProperty key=\"%s\" \n\t\t\ttype=\"%s\" tex_usage=\"%s\" tex_index=\"%u\"", + prop->mKey.data, sz, + ::TextureTypeToString((aiTextureType)prop->mSemantic),prop->mIndex); + + if (prop->mType == aiPTI_Float) { + fprintf(out," size=\"%i\">\n\t\t\t\t", + static_cast<int>(prop->mDataLength/sizeof(float))); + + for (unsigned int p = 0; p < prop->mDataLength/sizeof(float);++p) { + fprintf(out,"%f ",*((float*)(prop->mData+p*sizeof(float)))); + } + } + else if (prop->mType == aiPTI_Integer) { + fprintf(out," size=\"%i\">\n\t\t\t\t", + static_cast<int>(prop->mDataLength/sizeof(int))); + + for (unsigned int p = 0; p < prop->mDataLength/sizeof(int);++p) { + fprintf(out,"%i ",*((int*)(prop->mData+p*sizeof(int)))); + } + } + else if (prop->mType == aiPTI_Buffer) { + fprintf(out," size=\"%i\">\n\t\t\t\t", + static_cast<int>(prop->mDataLength)); + + for (unsigned int p = 0; p < prop->mDataLength;++p) { + fprintf(out,"%2x ",prop->mData[p]); + if (p && 0 == p%30) { + fprintf(out,"\n\t\t\t\t"); + } + } + } + else if (prop->mType == aiPTI_String) { + fprintf(out,">\n\t\t\t\t\"%s\"",encodeXML(prop->mData+4).c_str() /* skip length */); + } + fprintf(out,"\n\t\t\t</MatProperty>\n"); + } + fprintf(out,"\t\t</MatPropertyList>\n"); + fprintf(out,"\t</Material>\n"); + } + fprintf(out,"</MaterialList>\n"); + } + + // write animations + if (scene->mNumAnimations) { + fprintf(out,"<AnimationList num=\"%u\">\n",scene->mNumAnimations); + for (unsigned int i = 0; i < scene->mNumAnimations;++i) { + aiAnimation* anim = scene->mAnimations[i]; + + // anim header + ConvertName(name,anim->mName); + fprintf(out,"\t<Animation name=\"%s\" duration=\"%e\" tick_cnt=\"%e\">\n", + name.data, anim->mDuration, anim->mTicksPerSecond); + + // write bone animation channels + if (anim->mNumChannels) { + fprintf(out,"\t\t<NodeAnimList num=\"%u\">\n",anim->mNumChannels); + for (unsigned int n = 0; n < anim->mNumChannels;++n) { + aiNodeAnim* nd = anim->mChannels[n]; + + // node anim header + ConvertName(name,nd->mNodeName); + fprintf(out,"\t\t\t<NodeAnim node=\"%s\">\n",name.data); + + if (!shortened) { + // write position keys + if (nd->mNumPositionKeys) { + fprintf(out,"\t\t\t\t<PositionKeyList num=\"%u\">\n",nd->mNumPositionKeys); + for (unsigned int a = 0; a < nd->mNumPositionKeys;++a) { + aiVectorKey* vc = nd->mPositionKeys+a; + fprintf(out,"\t\t\t\t\t<PositionKey time=\"%e\">\n" + "\t\t\t\t\t\t%0 8f %0 8f %0 8f\n\t\t\t\t\t</PositionKey>\n", + vc->mTime,vc->mValue.x,vc->mValue.y,vc->mValue.z); + } + fprintf(out,"\t\t\t\t</PositionKeyList>\n"); + } + + // write scaling keys + if (nd->mNumScalingKeys) { + fprintf(out,"\t\t\t\t<ScalingKeyList num=\"%u\">\n",nd->mNumScalingKeys); + for (unsigned int a = 0; a < nd->mNumScalingKeys;++a) { + aiVectorKey* vc = nd->mScalingKeys+a; + fprintf(out,"\t\t\t\t\t<ScalingKey time=\"%e\">\n" + "\t\t\t\t\t\t%0 8f %0 8f %0 8f\n\t\t\t\t\t</ScalingKey>\n", + vc->mTime,vc->mValue.x,vc->mValue.y,vc->mValue.z); + } + fprintf(out,"\t\t\t\t</ScalingKeyList>\n"); + } + + // write rotation keys + if (nd->mNumRotationKeys) { + fprintf(out,"\t\t\t\t<RotationKeyList num=\"%u\">\n",nd->mNumRotationKeys); + for (unsigned int a = 0; a < nd->mNumRotationKeys;++a) { + aiQuatKey* vc = nd->mRotationKeys+a; + fprintf(out,"\t\t\t\t\t<RotationKey time=\"%e\">\n" + "\t\t\t\t\t\t%0 8f %0 8f %0 8f %0 8f\n\t\t\t\t\t</RotationKey>\n", + vc->mTime,vc->mValue.x,vc->mValue.y,vc->mValue.z,vc->mValue.w); + } + fprintf(out,"\t\t\t\t</RotationKeyList>\n"); + } + } + fprintf(out,"\t\t\t</NodeAnim>\n"); + } + fprintf(out,"\t\t</NodeAnimList>\n"); + } + fprintf(out,"\t</Animation>\n"); + } + fprintf(out,"</AnimationList>\n"); + } + + // write meshes + if (scene->mNumMeshes) { + fprintf(out,"<MeshList num=\"%u\">\n",scene->mNumMeshes); + for (unsigned int i = 0; i < scene->mNumMeshes;++i) { + aiMesh* mesh = scene->mMeshes[i]; + // const unsigned int width = (unsigned int)log10((double)mesh->mNumVertices)+1; + + // mesh header + fprintf(out,"\t<Mesh types=\"%s %s %s %s\" material_index=\"%u\">\n", + (mesh->mPrimitiveTypes & aiPrimitiveType_POINT ? "points" : ""), + (mesh->mPrimitiveTypes & aiPrimitiveType_LINE ? "lines" : ""), + (mesh->mPrimitiveTypes & aiPrimitiveType_TRIANGLE ? "triangles" : ""), + (mesh->mPrimitiveTypes & aiPrimitiveType_POLYGON ? "polygons" : ""), + mesh->mMaterialIndex); + + // bones + if (mesh->mNumBones) { + fprintf(out,"\t\t<BoneList num=\"%u\">\n",mesh->mNumBones); + + for (unsigned int n = 0; n < mesh->mNumBones;++n) { + aiBone* bone = mesh->mBones[n]; + + ConvertName(name,bone->mName); + // bone header + fprintf(out,"\t\t\t<Bone name=\"%s\">\n" + "\t\t\t\t<Matrix4> \n" + "\t\t\t\t\t%0 6f %0 6f %0 6f %0 6f\n" + "\t\t\t\t\t%0 6f %0 6f %0 6f %0 6f\n" + "\t\t\t\t\t%0 6f %0 6f %0 6f %0 6f\n" + "\t\t\t\t\t%0 6f %0 6f %0 6f %0 6f\n" + "\t\t\t\t</Matrix4> \n", + name.data, + bone->mOffsetMatrix.a1,bone->mOffsetMatrix.a2,bone->mOffsetMatrix.a3,bone->mOffsetMatrix.a4, + bone->mOffsetMatrix.b1,bone->mOffsetMatrix.b2,bone->mOffsetMatrix.b3,bone->mOffsetMatrix.b4, + bone->mOffsetMatrix.c1,bone->mOffsetMatrix.c2,bone->mOffsetMatrix.c3,bone->mOffsetMatrix.c4, + bone->mOffsetMatrix.d1,bone->mOffsetMatrix.d2,bone->mOffsetMatrix.d3,bone->mOffsetMatrix.d4); + + if (!shortened && bone->mNumWeights) { + fprintf(out,"\t\t\t\t<WeightList num=\"%u\">\n",bone->mNumWeights); + + // bone weights + for (unsigned int a = 0; a < bone->mNumWeights;++a) { + aiVertexWeight* wght = bone->mWeights+a; + + fprintf(out,"\t\t\t\t\t<Weight index=\"%u\">\n\t\t\t\t\t\t%f\n\t\t\t\t\t</Weight>\n", + wght->mVertexId,wght->mWeight); + } + fprintf(out,"\t\t\t\t</WeightList>\n"); + } + fprintf(out,"\t\t\t</Bone>\n"); + } + fprintf(out,"\t\t</BoneList>\n"); + } + + // faces + if (!shortened && mesh->mNumFaces) { + fprintf(out,"\t\t<FaceList num=\"%u\">\n",mesh->mNumFaces); + for (unsigned int n = 0; n < mesh->mNumFaces; ++n) { + aiFace& f = mesh->mFaces[n]; + fprintf(out,"\t\t\t<Face num=\"%u\">\n" + "\t\t\t\t",f.mNumIndices); + + for (unsigned int j = 0; j < f.mNumIndices;++j) + fprintf(out,"%u ",f.mIndices[j]); + + fprintf(out,"\n\t\t\t</Face>\n"); + } + fprintf(out,"\t\t</FaceList>\n"); + } + + // vertex positions + if (mesh->HasPositions()) { + fprintf(out,"\t\t<Positions num=\"%u\" set=\"0\" num_components=\"3\"> \n",mesh->mNumVertices); + if (!shortened) { + for (unsigned int n = 0; n < mesh->mNumVertices; ++n) { + fprintf(out,"\t\t%0 8f %0 8f %0 8f\n", + mesh->mVertices[n].x, + mesh->mVertices[n].y, + mesh->mVertices[n].z); + } + } + fprintf(out,"\t\t</Positions>\n"); + } + + // vertex normals + if (mesh->HasNormals()) { + fprintf(out,"\t\t<Normals num=\"%u\" set=\"0\" num_components=\"3\"> \n",mesh->mNumVertices); + if (!shortened) { + for (unsigned int n = 0; n < mesh->mNumVertices; ++n) { + fprintf(out,"\t\t%0 8f %0 8f %0 8f\n", + mesh->mNormals[n].x, + mesh->mNormals[n].y, + mesh->mNormals[n].z); + } + } + else { + } + fprintf(out,"\t\t</Normals>\n"); + } + + // vertex tangents and bitangents + if (mesh->HasTangentsAndBitangents()) { + fprintf(out,"\t\t<Tangents num=\"%u\" set=\"0\" num_components=\"3\"> \n",mesh->mNumVertices); + if (!shortened) { + for (unsigned int n = 0; n < mesh->mNumVertices; ++n) { + fprintf(out,"\t\t%0 8f %0 8f %0 8f\n", + mesh->mTangents[n].x, + mesh->mTangents[n].y, + mesh->mTangents[n].z); + } + } + fprintf(out,"\t\t</Tangents>\n"); + + fprintf(out,"\t\t<Bitangents num=\"%u\" set=\"0\" num_components=\"3\"> \n",mesh->mNumVertices); + if (!shortened) { + for (unsigned int n = 0; n < mesh->mNumVertices; ++n) { + fprintf(out,"\t\t%0 8f %0 8f %0 8f\n", + mesh->mBitangents[n].x, + mesh->mBitangents[n].y, + mesh->mBitangents[n].z); + } + } + fprintf(out,"\t\t</Bitangents>\n"); + } + + // texture coordinates + for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) { + if (!mesh->mTextureCoords[a]) + break; + + fprintf(out,"\t\t<TextureCoords num=\"%u\" set=\"%u\" num_components=\"%u\"> \n",mesh->mNumVertices, + a,mesh->mNumUVComponents[a]); + + if (!shortened) { + if (mesh->mNumUVComponents[a] == 3) { + for (unsigned int n = 0; n < mesh->mNumVertices; ++n) { + fprintf(out,"\t\t%0 8f %0 8f %0 8f\n", + mesh->mTextureCoords[a][n].x, + mesh->mTextureCoords[a][n].y, + mesh->mTextureCoords[a][n].z); + } + } + else { + for (unsigned int n = 0; n < mesh->mNumVertices; ++n) { + fprintf(out,"\t\t%0 8f %0 8f\n", + mesh->mTextureCoords[a][n].x, + mesh->mTextureCoords[a][n].y); + } + } + } + fprintf(out,"\t\t</TextureCoords>\n"); + } + + // vertex colors + for (unsigned int a = 0; a < AI_MAX_NUMBER_OF_COLOR_SETS; ++a) { + if (!mesh->mColors[a]) + break; + fprintf(out,"\t\t<Colors num=\"%u\" set=\"%u\" num_components=\"4\"> \n",mesh->mNumVertices,a); + if (!shortened) { + for (unsigned int n = 0; n < mesh->mNumVertices; ++n) { + fprintf(out,"\t\t%0 8f %0 8f %0 8f %0 8f\n", + mesh->mColors[a][n].r, + mesh->mColors[a][n].g, + mesh->mColors[a][n].b, + mesh->mColors[a][n].a); + } + } + fprintf(out,"\t\t</Colors>\n"); + } + fprintf(out,"\t</Mesh>\n"); + } + fprintf(out,"</MeshList>\n"); + } + fprintf(out,"</Scene>\n</ASSIMP>"); +} + + +// ----------------------------------------------------------------------------------- +int Assimp_Dump (const char* const* params, unsigned int num) +{ + const char* fail = "assimp dump: Invalid number of arguments. " + "See \'assimp dump --help\'\r\n"; + if (num < 1) { + printf("%s", fail); + return 1; + } + + // --help + if (!strcmp( params[0], "-h") || !strcmp( params[0], "--help") || !strcmp( params[0], "-?") ) { + printf("%s",AICMD_MSG_DUMP_HELP); + return 0; + } + + // asssimp dump in out [options] + if (num < 1) { + printf("%s", fail); + return 1; + } + + std::string in = std::string(params[0]); + std::string out = (num > 1 ? std::string(params[1]) : std::string("-")); + + // store full command line + std::string cmd; + for (unsigned int i = (out[0] == '-' ? 1 : 2); i < num;++i) { + if (!params[i])continue; + cmd.append(params[i]); + cmd.append(" "); + } + + // get import flags + ImportData import; + ProcessStandardArguments(import,params+1,num-1); + + bool binary = false, shortened = false,compressed=false; + + // process other flags + for (unsigned int i = 1; i < num;++i) { + if (!params[i])continue; + if (!strcmp( params[i], "-b") || !strcmp( params[i], "--binary")) { + binary = true; + } + else if (!strcmp( params[i], "-s") || !strcmp( params[i], "--short")) { + shortened = true; + } + else if (!strcmp( params[i], "-z") || !strcmp( params[i], "--compressed")) { + compressed = true; + } +#if 0 + else if (i > 2 || params[i][0] == '-') { + ::printf("Unknown parameter: %s\n",params[i]); + return 10; + } +#endif + } + + if (out[0] == '-') { + // take file name from input file + std::string::size_type s = in.find_last_of('.'); + if (s == std::string::npos) { + s = in.length(); + } + + out = in.substr(0,s); + out.append((binary ? ".assbin" : ".assxml")); + if (shortened && binary) { + out.append(".regress"); + } + } + + // import the main model + const aiScene* scene = ImportModel(import,in); + if (!scene) { + printf("assimp dump: Unable to load input file %s\n",in.c_str()); + return 5; + } + + // open the output file and build the dump + FILE* o = ::fopen(out.c_str(),(binary ? "wb" : "wt")); + if (!o) { + printf("assimp dump: Unable to open output file %s\n",out.c_str()); + return 12; + } + + if (binary) { + WriteBinaryDump (scene,o,in.c_str(),cmd.c_str(),shortened,compressed,import); + } + else WriteDump (scene,o,in.c_str(),cmd.c_str(),shortened); + fclose(o); + + if (compressed && binary) { + CompressBinaryDump(out.c_str(),ASSBIN_HEADER_LENGTH); + } + + printf("assimp dump: Wrote output dump %s\n",out.c_str()); + return 0; +} + diff --git a/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/assimp_cmd.rc b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/assimp_cmd.rc new file mode 100644 index 0000000..e671006 --- /dev/null +++ b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/assimp_cmd.rc @@ -0,0 +1,51 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" +#include "../../revision.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#define APSTUDIO_HIDDEN_SYMBOLS +#include "windows.h" +#undef APSTUDIO_HIDDEN_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Deutsch (Deutschland) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU) +#ifdef _WIN32 +LANGUAGE LANG_GERMAN, SUBLANG_GERMAN +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDI_ASSIMP_VIEW ICON "../shared/assimp_tools_icon.ico" + + + + + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED +#endif diff --git a/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/generic_inserter.hpp b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/generic_inserter.hpp new file mode 100644 index 0000000..8053219 --- /dev/null +++ b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/generic_inserter.hpp @@ -0,0 +1,113 @@ +/* Boost Software License - Version 1.0 - August 17th, 2003 + * + * Permission is hereby granted, free of charge, to any person or organization + * obtaining a copy of the software and accompanying documentation covered by + * this license (the "Software") to use, reproduce, display, distribute, + * execute, and transmit the Software, and to prepare derivative works of the + * Software, and to permit third-parties to whom the Software is furnished to + * do so, all subject to the following: + * + * The copyright notices in the Software and this entire statement, including + * the above license grant, this restriction and the following disclaimer, + * must be included in all copies of the Software, in whole or in part, and + * all derivative works of the Software, unless such copies or derivative + * works are solely in the form of machine-executable object code generated by + * a source language processor. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE + * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. */ + + +#ifndef HEADER_GENERIC_INSERTER_HPP_INCLUDED +#define HEADER_GENERIC_INSERTER_HPP_INCLUDED + + +#include <ostream> +#include <new> // bad_alloc + + +template <typename char_type, typename traits_type, typename argument_type> +std::basic_ostream<char_type, traits_type>& generic_inserter(void (*print)(std::basic_ostream<char_type, traits_type>& os, argument_type const& arg), std::basic_ostream<char_type, traits_type>& os, argument_type const& arg) +{ + using namespace ::std; + + ios_base::iostate err = ios_base::goodbit; + try + { + typename basic_ostream<char_type, traits_type>::sentry sentry(os); + if (sentry) + { + print(os, arg); + err = os.rdstate(); + os.width(0); // Reset width in case the user didn't do it. + } + } + catch (bad_alloc const&) + { + err |= ios_base::badbit; // bad_alloc is considered fatal + ios_base::iostate const exception_mask = os.exceptions(); + + // Two cases: 1.) badbit is not set; 2.) badbit is set + if (((exception_mask & ios_base::failbit) != 0) && // failbit shall throw + ((exception_mask & ios_base::badbit) == 0)) // badbit shall not throw + { + // Do not throw unless failbit is set. + // If it is set throw ios_base::failure because we don't know what caused the failbit to be set. + os.setstate(err); + } + else if (exception_mask & ios_base::badbit) + { + try + { + // This will set the badbit and throw ios_base::failure. + os.setstate(err); + } + catch (ios_base::failure const&) + { + // Do nothing since we want bad_alloc to be rethrown. + } + throw; + } + // else: no exception must get out! + } + catch (...) + { + err |= ios_base::failbit; // Any other exception is considered "only" as a failure. + ios_base::iostate const exception_mask = os.exceptions(); + + // badbit is considered more important + if (((exception_mask & ios_base::badbit) != 0) && // badbit shall throw + ((err & ios_base::badbit) != 0)) // badbit is set + { + // Throw ios_base::failure because we don't know what caused the badbit to be set. + os.setstate(err); + } + else if ((exception_mask & ios_base::failbit) != 0) + { + try + { + // This will set the failbit and throw the exception ios_base::failure. + os.setstate(err); + } + catch (ios_base::failure const&) + { + // Do nothing since we want the original exception to be rethrown. + } + throw; + } + // else: no exception must get out! + } + + // Needed in the case that no exception has been thrown but the stream state has changed. + if (err) + os.setstate(err); + return os; +} + + +#endif // HEADER_GENERIC_INSERTER_HPP_INCLUDED diff --git a/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/resource.h b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/resource.h new file mode 100644 index 0000000..c516b5e --- /dev/null +++ b/NvCloth/samples/external/assimp-4.1.0/tools/assimp_cmd/resource.h @@ -0,0 +1,21 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by assimp_view.rc +// +#define IDC_MYICON 2 +#define IDD_ASSIMP_VIEW_DIALOG 102 +#define IDD_ABOUTBOX 103 +#define IDI_ASSIMP_VIEW 107 + + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NO_MFC 1 +#define _APS_NEXT_RESOURCE_VALUE 159 +#define _APS_NEXT_COMMAND_VALUE 32831 +#define _APS_NEXT_CONTROL_VALUE 1052 +#define _APS_NEXT_SYMED_VALUE 110 +#endif +#endif |