diff --git a/.gitignore b/.gitignore index 12cd76a87..2a3b68a50 100644 --- a/.gitignore +++ b/.gitignore @@ -60,6 +60,7 @@ test/gtest/src/gtest-stamp/Debug/gtest-build *.lib test/gtest/src/gtest-stamp/Debug/ tools/assimp_view/assimp_viewer.vcxproj.user +*.pyc # Unix editor backups *~ diff --git a/CMakeLists.txt b/CMakeLists.txt index dd2317cca..f7ebed370 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -103,6 +103,7 @@ OPTION ( BUILD_DOCS OFF ) +# Use subset of Windows.h if (WIN32) ADD_DEFINITIONS( -DWIN32_LEAN_AND_MEAN ) endif() @@ -203,7 +204,6 @@ IF( UNIX ) INCLUDE(GNUInstallDirs) ENDIF( UNIX ) - # Grouped compiler settings IF ((CMAKE_C_COMPILER_ID MATCHES "GNU") AND NOT CMAKE_COMPILER_IS_MINGW) # hide all not-exported symbols diff --git a/Readme.md b/Readme.md index 1f6c4118f..ca6c9ba4d 100644 --- a/Readme.md +++ b/Readme.md @@ -43,7 +43,7 @@ __Importers__: - AMJ - ASE - ASK -- B3D; +- B3D - BLEND (Blender) - BVH - COB diff --git a/code/CMakeLists.txt b/code/CMakeLists.txt index c463c55c7..13417f36f 100644 --- a/code/CMakeLists.txt +++ b/code/CMakeLists.txt @@ -524,6 +524,8 @@ SET( PostProcessing_SRCS ComputeUVMappingProcess.h ConvertToLHProcess.cpp ConvertToLHProcess.h + EmbedTexturesProcess.cpp + EmbedTexturesProcess.h FindDegenerates.cpp FindDegenerates.h FindInstancesProcess.cpp @@ -940,13 +942,13 @@ if (APPLE) # PUBLIC_HEADER option does not support directory structure creation # add ./Compiler/*.h to assimp.framework via copy command - ADD_CUSTOM_COMMAND(TARGET assimp POST_BUILD - COMMAND "${CMAKE_COMMAND}" -E copy_directory + ADD_CUSTOM_COMMAND(TARGET assimp POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy_directory "../${HEADER_PATH}/Compiler" assimp.framework/Headers/Compiler COMMENT "Copying public ./Compiler/ header files to framework bundle's Headers/Compiler/") - endif(BUILD_FRAMEWORK) -endif(APPLE) + ENDIF(BUILD_FRAMEWORK) +ENDIF(APPLE) # Build against external unzip, or add ../contrib/unzip so # assimp can #include "unzip.h" @@ -975,7 +977,7 @@ if (ASSIMP_ANDROID_JNIIOSYSTEM) INSTALL(FILES ${HEADER_PATH}/${ASSIMP_ANDROID_JNIIOSYSTEM_PATH}/AndroidJNIIOSystem.h DESTINATION ${ASSIMP_INCLUDE_INSTALL_DIR} COMPONENT assimp-dev) -endif(ASSIMP_ANDROID_JNIIOSYSTEM) +ENDIF(ASSIMP_ANDROID_JNIIOSYSTEM) if(MSVC AND ASSIMP_INSTALL_PDB) IF(CMAKE_GENERATOR MATCHES "^Visual Studio") @@ -997,7 +999,7 @@ if(MSVC AND ASSIMP_INSTALL_PDB) CONFIGURATIONS RelWithDebInfo ) ENDIF() -endif () +ENDIF () if (ASSIMP_COVERALLS) include(Coveralls) @@ -1009,4 +1011,4 @@ if (ASSIMP_COVERALLS) "${COVERAGE_SRCS}" # The source files. ON # If we should upload. "${PROJECT_SOURCE_DIR}/cmake-modules/") # (Optional) Alternate project cmake module path. -endif() +ENDIF() diff --git a/code/EmbedTexturesProcess.cpp b/code/EmbedTexturesProcess.cpp new file mode 100644 index 000000000..5d40ec16e --- /dev/null +++ b/code/EmbedTexturesProcess.cpp @@ -0,0 +1,147 @@ +/* +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. + +---------------------------------------------------------------------- +*/ + +#include "EmbedTexturesProcess.h" +#include "ParsingUtils.h" +#include "ProcessHelper.h" + +#include + +using namespace Assimp; + +EmbedTexturesProcess::EmbedTexturesProcess() +: BaseProcess() { +} + +EmbedTexturesProcess::~EmbedTexturesProcess() { +} + +bool EmbedTexturesProcess::IsActive(unsigned int pFlags) const { + return (pFlags & aiProcess_EmbedTextures) != 0; +} + +void EmbedTexturesProcess::SetupProperties(const Importer* pImp) { + mRootPath = pImp->GetPropertyString("sourceFilePath"); + mRootPath = mRootPath.substr(0, mRootPath.find_last_of("\\/") + 1u); +} + +void EmbedTexturesProcess::Execute(aiScene* pScene) { + if (pScene == nullptr || pScene->mRootNode == nullptr) return; + + aiString path; + + uint32_t embeddedTexturesCount = 0u; + + for (auto matId = 0u; matId < pScene->mNumMaterials; ++matId) { + auto material = pScene->mMaterials[matId]; + + for (auto ttId = 1u; ttId < AI_TEXTURE_TYPE_MAX; ++ttId) { + auto tt = static_cast(ttId); + auto texturesCount = material->GetTextureCount(tt); + + for (auto texId = 0u; texId < texturesCount; ++texId) { + material->GetTexture(tt, texId, &path); + if (path.data[0] == '*') continue; // Already embedded + + // Indeed embed + if (addTexture(pScene, path.data)) { + auto embeddedTextureId = pScene->mNumTextures - 1u; + ::ai_snprintf(path.data, 1024, "*%u", embeddedTextureId); + material->AddProperty(&path, AI_MATKEY_TEXTURE(tt, texId)); + embeddedTexturesCount++; + } + } + } + } + + char stringBuffer[128]; + ::ai_snprintf(stringBuffer, 128, "EmbedTexturesProcess finished. Embedded %u textures.", embeddedTexturesCount); + DefaultLogger::get()->info(stringBuffer); +} + +bool EmbedTexturesProcess::addTexture(aiScene* pScene, std::string path) const { + uint32_t imageSize = 0; + std::string imagePath = path; + + // Test path directly + std::ifstream file(imagePath, std::ios::binary | std::ios::ate); + if ((imageSize = file.tellg()) == -1u) { + DefaultLogger::get()->warn("EmbedTexturesProcess: Cannot find image: " + imagePath + ". Will try to find it in root folder."); + + // Test path in root path + imagePath = mRootPath + path; + file.open(imagePath, std::ios::binary | std::ios::ate); + if ((imageSize = file.tellg()) == -1u) { + // Test path basename in root path + imagePath = mRootPath + path.substr(path.find_last_of("\\/") + 1u); + file.open(imagePath, std::ios::binary | std::ios::ate); + if ((imageSize = file.tellg()) == -1u) { + DefaultLogger::get()->error("EmbedTexturesProcess: Unable to embed texture: " + path + "."); + return false; + } + } + } + + aiTexel* imageContent = new aiTexel[1u + imageSize / sizeof(aiTexel)]; + file.seekg(0, std::ios::beg); + file.read(reinterpret_cast(imageContent), imageSize); + + // Enlarging the textures table + auto textureId = pScene->mNumTextures++; + auto oldTextures = pScene->mTextures; + pScene->mTextures = new aiTexture*[pScene->mNumTextures]; + memmove(pScene->mTextures, oldTextures, sizeof(aiTexture*) * (pScene->mNumTextures - 1u)); + + // Add the new texture + auto pTexture = new aiTexture(); + pTexture->mHeight = 0; // Means that this is still compressed + pTexture->mWidth = imageSize; + pTexture->pcData = imageContent; + + auto extension = path.substr(path.find_last_of('.') + 1u); + std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower); + if (extension == "jpeg") extension = "jpg"; + strcpy(pTexture->achFormatHint, extension.c_str()); + + pScene->mTextures[textureId] = pTexture; + + return true; +} diff --git a/code/EmbedTexturesProcess.h b/code/EmbedTexturesProcess.h new file mode 100644 index 000000000..5a472f644 --- /dev/null +++ b/code/EmbedTexturesProcess.h @@ -0,0 +1,84 @@ +/* +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. + +---------------------------------------------------------------------- +*/ + +#pragma once + +#include "BaseProcess.h" + +#include + +struct aiNode; + +namespace Assimp { + +/** + * Force embedding of textures (using the path = "*1" convention). + * If a texture's file does not exist at the specified path + * (due, for instance, to an absolute path generated on another system), + * it will check if a file with the same name exists at the root folder + * of the imported model. And if so, it uses that. + */ +class ASSIMP_API EmbedTexturesProcess : public BaseProcess { +public: + /// The default class constructor. + EmbedTexturesProcess(); + + /// The class destructor. + virtual ~EmbedTexturesProcess(); + + /// Overwritten, @see BaseProcess + virtual bool IsActive(unsigned int pFlags) const; + + /// Overwritten, @see BaseProcess + virtual void SetupProperties(const Importer* pImp); + + /// Overwritten, @see BaseProcess + virtual void Execute(aiScene* pScene); + +private: + // Resolve the path and add the file content to the scene as a texture. + bool addTexture(aiScene* pScene, std::string path) const; + +private: + std::string mRootPath; +}; + +} // namespace Assimp diff --git a/code/FBXBinaryTokenizer.cpp b/code/FBXBinaryTokenizer.cpp index cc2e734fc..5884125a2 100644 --- a/code/FBXBinaryTokenizer.cpp +++ b/code/FBXBinaryTokenizer.cpp @@ -129,30 +129,26 @@ AI_WONT_RETURN void TokenizeError(const std::string& message, unsigned int offse // ------------------------------------------------------------------------------------------------ -uint32_t Offset(const char* begin, const char* cursor) -{ +uint32_t Offset(const char* begin, const char* cursor) { ai_assert(begin <= cursor); + return static_cast(cursor - begin); } - // ------------------------------------------------------------------------------------------------ -void TokenizeError(const std::string& message, const char* begin, const char* cursor) -{ +void TokenizeError(const std::string& message, const char* begin, const char* cursor) { TokenizeError(message, Offset(begin, cursor)); } - // ------------------------------------------------------------------------------------------------ -uint32_t ReadWord(const char* input, const char*& cursor, const char* end) -{ +uint32_t ReadWord(const char* input, const char*& cursor, const char* end) { const size_t k_to_read = sizeof( uint32_t ); if(Offset(cursor, end) < k_to_read ) { TokenizeError("cannot ReadWord, out of bounds",input, cursor); } uint32_t word; - memcpy(&word, cursor, 4); + ::memcpy(&word, cursor, 4); AI_SWAP4(word); cursor += k_to_read; @@ -167,7 +163,8 @@ uint64_t ReadDoubleWord(const char* input, const char*& cursor, const char* end) TokenizeError("cannot ReadDoubleWord, out of bounds",input, cursor); } - uint64_t dword = *reinterpret_cast(cursor); + uint64_t dword /*= *reinterpret_cast(cursor)*/; + ::memcpy( &dword, cursor, sizeof( uint64_t ) ); AI_SWAP8(dword); cursor += k_to_read; @@ -176,24 +173,21 @@ uint64_t ReadDoubleWord(const char* input, const char*& cursor, const char* end) } // ------------------------------------------------------------------------------------------------ -uint8_t ReadByte(const char* input, const char*& cursor, const char* end) -{ +uint8_t ReadByte(const char* input, const char*& cursor, const char* end) { if(Offset(cursor, end) < sizeof( uint8_t ) ) { TokenizeError("cannot ReadByte, out of bounds",input, cursor); } - uint8_t word = *reinterpret_cast(cursor); + uint8_t word;/* = *reinterpret_cast< const uint8_t* >( cursor )*/ + ::memcpy( &word, cursor, sizeof( uint8_t ) ); ++cursor; return word; } - // ------------------------------------------------------------------------------------------------ -unsigned int ReadString(const char*& sbegin_out, const char*& send_out, const char* input, const char*& cursor, const char* end, - bool long_length = false, - bool allow_null = false) -{ +unsigned int ReadString(const char*& sbegin_out, const char*& send_out, const char* input, + const char*& cursor, const char* end, bool long_length = false, bool allow_null = false) { const uint32_t len_len = long_length ? 4 : 1; if(Offset(cursor, end) < len_len) { TokenizeError("cannot ReadString, out of bounds reading length",input, cursor); @@ -222,8 +216,7 @@ unsigned int ReadString(const char*& sbegin_out, const char*& send_out, const ch } // ------------------------------------------------------------------------------------------------ -void ReadData(const char*& sbegin_out, const char*& send_out, const char* input, const char*& cursor, const char* end) -{ +void ReadData(const char*& sbegin_out, const char*& send_out, const char* input, const char*& cursor, const char* end) { if(Offset(cursor, end) < 1) { TokenizeError("cannot ReadData, out of bounds reading length",input, cursor); } @@ -422,7 +415,7 @@ bool ReadScope(TokenList& output_tokens, const char* input, const char*& cursor, return true; } -} +} // anonymous namespace // ------------------------------------------------------------------------------------------------ // TODO: Test FBX Binary files newer than the 7500 version to check if the 64 bits address behaviour is consistent diff --git a/code/Importer.cpp b/code/Importer.cpp index c6c6f0edd..bde937b44 100644 --- a/code/Importer.cpp +++ b/code/Importer.cpp @@ -677,6 +677,8 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) profiler->EndRegion("import"); } + SetPropertyString("sourceFilePath", pFile); + // If successful, apply all active post processing steps to the imported data if( pimpl->mScene) { diff --git a/code/PostStepRegistry.cpp b/code/PostStepRegistry.cpp index c80c373e5..eaae1447b 100644 --- a/code/PostStepRegistry.cpp +++ b/code/PostStepRegistry.cpp @@ -91,6 +91,9 @@ corresponding preprocessor flag to selectively disable steps. #ifndef ASSIMP_BUILD_NO_REMOVE_REDUNDANTMATERIALS_PROCESS # include "RemoveRedundantMaterials.h" #endif +#if (!defined ASSIMP_BUILD_NO_EMBEDTEXTURES_PROCESS) +# include "EmbedTexturesProcess.h" +#endif #ifndef ASSIMP_BUILD_NO_FINDINVALIDDATA_PROCESS # include "FindInvalidDataProcess.h" #endif @@ -132,7 +135,7 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out) // of sequence it is executed. Steps that are added here are not // validated - as RegisterPPStep() does - all dependencies must be given. // ---------------------------------------------------------------------------- - out.reserve(25); + out.reserve(30); #if (!defined ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS) out.push_back( new MakeLeftHandedProcess()); #endif @@ -148,6 +151,9 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out) #if (!defined ASSIMP_BUILD_NO_REMOVE_REDUNDANTMATERIALS_PROCESS) out.push_back( new RemoveRedundantMatsProcess()); #endif +#if (!defined ASSIMP_BUILD_NO_EMBEDTEXTURES_PROCESS) + out.push_back( new EmbedTexturesProcess()); +#endif #if (!defined ASSIMP_BUILD_NO_FINDINSTANCES_PROCESS) out.push_back( new FindInstancesProcess()); #endif diff --git a/code/Version.cpp b/code/Version.cpp index fe9a2fdaa..eb4cab417 100644 --- a/code/Version.cpp +++ b/code/Version.cpp @@ -111,6 +111,10 @@ ASSIMP_API unsigned int aiGetVersionRevision() { return GitVersion; } +ASSIMP_API const char *aiGetBranchName() { + return GitBranch; +} + // ------------------------------------------------------------------------------------------------ ASSIMP_API aiScene::aiScene() : mFlags(0) diff --git a/code/glTF2Asset.h b/code/glTF2Asset.h index cece307d9..4aa56e9ef 100644 --- a/code/glTF2Asset.h +++ b/code/glTF2Asset.h @@ -181,13 +181,17 @@ namespace glTF2 #define _AI_MATKEY_GLTF_MAPPINGID_BASE "$tex.mappingid" #define _AI_MATKEY_GLTF_MAPPINGFILTER_MAG_BASE "$tex.mappingfiltermag" #define _AI_MATKEY_GLTF_MAPPINGFILTER_MIN_BASE "$tex.mappingfiltermin" + #define _AI_MATKEY_GLTF_SCALE_BASE "$tex.scale" + #define _AI_MATKEY_GLTF_STRENGTH_BASE "$tex.strength" #define AI_MATKEY_GLTF_TEXTURE_TEXCOORD _AI_MATKEY_GLTF_TEXTURE_TEXCOORD_BASE, type, N #define AI_MATKEY_GLTF_MAPPINGNAME(type, N) _AI_MATKEY_GLTF_MAPPINGNAME_BASE, type, N #define AI_MATKEY_GLTF_MAPPINGID(type, N) _AI_MATKEY_GLTF_MAPPINGID_BASE, type, N #define AI_MATKEY_GLTF_MAPPINGFILTER_MAG(type, N) _AI_MATKEY_GLTF_MAPPINGFILTER_MAG_BASE, type, N #define AI_MATKEY_GLTF_MAPPINGFILTER_MIN(type, N) _AI_MATKEY_GLTF_MAPPINGFILTER_MIN_BASE, type, N - + #define AI_MATKEY_GLTF_TEXTURE_SCALE(type, N) _AI_MATKEY_GLTF_SCALE_BASE, type, N + #define AI_MATKEY_GLTF_TEXTURE_STRENGTH(type, N) _AI_MATKEY_GLTF_STRENGTH_BASE, type, N + #ifdef ASSIMP_API #include "./../include/assimp/Compiler/pushpack1.h" #endif diff --git a/code/glTF2AssetWriter.inl b/code/glTF2AssetWriter.inl index 6b1a50887..3c465d2d2 100644 --- a/code/glTF2AssetWriter.inl +++ b/code/glTF2AssetWriter.inl @@ -156,7 +156,10 @@ namespace glTF2 { inline void Write(Value& obj, Buffer& b, AssetWriter& w) { obj.AddMember("byteLength", static_cast(b.byteLength), w.mAl); - obj.AddMember("uri", Value(b.GetURI(), w.mAl).Move(), w.mAl); + + const auto uri = b.GetURI(); + const auto relativeUri = uri.substr(uri.find_last_of("/\\") + 1u); + obj.AddMember("uri", Value(relativeUri, w.mAl).Move(), w.mAl); } inline void Write(Value& obj, BufferView& bv, AssetWriter& w) @@ -167,7 +170,9 @@ namespace glTF2 { if (bv.byteStride != 0) { obj.AddMember("byteStride", bv.byteStride, w.mAl); } - obj.AddMember("target", int(bv.target), w.mAl); + if (bv.target != 0) { + obj.AddMember("target", int(bv.target), w.mAl); + } } inline void Write(Value& /*obj*/, Camera& /*c*/, AssetWriter& /*w*/) @@ -177,17 +182,23 @@ namespace glTF2 { inline void Write(Value& obj, Image& img, AssetWriter& w) { - std::string uri; - if (img.HasData()) { - uri = "data:" + (img.mimeType.empty() ? "application/octet-stream" : img.mimeType); - uri += ";base64,"; - Util::EncodeBase64(img.GetData(), img.GetDataLength(), uri); + if (img.bufferView) { + obj.AddMember("bufferView", img.bufferView->index, w.mAl); + obj.AddMember("mimeType", Value(img.mimeType, w.mAl).Move(), w.mAl); } else { - uri = img.uri; - } + std::string uri; + if (img.HasData()) { + uri = "data:" + (img.mimeType.empty() ? "application/octet-stream" : img.mimeType); + uri += ";base64,"; + Util::EncodeBase64(img.GetData(), img.GetDataLength(), uri); + } + else { + uri = img.uri; + } - obj.AddMember("uri", Value(uri, w.mAl).Move(), w.mAl); + obj.AddMember("uri", Value(uri, w.mAl).Move(), w.mAl); + } } namespace { @@ -569,13 +580,17 @@ namespace glTF2 { throw DeadlyExportError("Could not open output file: " + std::string(path)); } + Ref bodyBuffer = mAsset.GetBodyBuffer(); + if (bodyBuffer->byteLength > 0) { + rapidjson::Value glbBodyBuffer; + glbBodyBuffer.SetObject(); + glbBodyBuffer.AddMember("byteLength", static_cast(bodyBuffer->byteLength), mAl); + mDoc["buffers"].PushBack(glbBodyBuffer, mAl); + } + // Padding with spaces as required by the spec uint32_t padding = 0x20202020; - // Adapt JSON so that it is not pointing to an external file, - // as this is required by the GLB spec'. - mDoc["buffers"][0].RemoveMember("uri"); - // // JSON chunk // @@ -608,28 +623,25 @@ namespace glTF2 { // uint32_t binaryChunkLength = 0; - if (mAsset.buffers.Size() > 0) { - Ref b = mAsset.buffers.Get(0u); - if (b->byteLength > 0) { - binaryChunkLength = (b->byteLength + 3) & ~3; // Round up to next multiple of 4 - auto paddingLength = binaryChunkLength - b->byteLength; + if (bodyBuffer->byteLength > 0) { + binaryChunkLength = (bodyBuffer->byteLength + 3) & ~3; // Round up to next multiple of 4 + auto paddingLength = binaryChunkLength - bodyBuffer->byteLength; - GLB_Chunk binaryChunk; - binaryChunk.chunkLength = binaryChunkLength; - binaryChunk.chunkType = ChunkType_BIN; - AI_SWAP4(binaryChunk.chunkLength); + GLB_Chunk binaryChunk; + binaryChunk.chunkLength = binaryChunkLength; + binaryChunk.chunkType = ChunkType_BIN; + AI_SWAP4(binaryChunk.chunkLength); - size_t bodyOffset = sizeof(GLB_Header) + sizeof(GLB_Chunk) + jsonChunk.chunkLength; - outfile->Seek(bodyOffset, aiOrigin_SET); - if (outfile->Write(&binaryChunk, 1, sizeof(GLB_Chunk)) != sizeof(GLB_Chunk)) { - throw DeadlyExportError("Failed to write body data header!"); - } - if (outfile->Write(b->GetPointer(), 1, b->byteLength) != b->byteLength) { - throw DeadlyExportError("Failed to write body data!"); - } - if (paddingLength && outfile->Write(&padding, 1, paddingLength) != paddingLength) { - throw DeadlyExportError("Failed to write body data padding!"); - } + size_t bodyOffset = sizeof(GLB_Header) + sizeof(GLB_Chunk) + jsonChunk.chunkLength; + outfile->Seek(bodyOffset, aiOrigin_SET); + if (outfile->Write(&binaryChunk, 1, sizeof(GLB_Chunk)) != sizeof(GLB_Chunk)) { + throw DeadlyExportError("Failed to write body data header!"); + } + if (outfile->Write(bodyBuffer->GetPointer(), 1, bodyBuffer->byteLength) != bodyBuffer->byteLength) { + throw DeadlyExportError("Failed to write body data!"); + } + if (paddingLength && outfile->Write(&padding, 1, paddingLength) != paddingLength) { + throw DeadlyExportError("Failed to write body data padding!"); } } diff --git a/code/glTF2Exporter.cpp b/code/glTF2Exporter.cpp index 22ceb57d2..221a3bf9f 100644 --- a/code/glTF2Exporter.cpp +++ b/code/glTF2Exporter.cpp @@ -109,6 +109,10 @@ glTF2Exporter::glTF2Exporter(const char* filename, IOSystem* pIOSystem, const ai mAsset.reset( new Asset( pIOSystem ) ); + if (isBinary) { + mAsset->SetAsBinary(); + } + ExportMetadata(); ExportMaterials(); diff --git a/code/glTF2Importer.cpp b/code/glTF2Importer.cpp index 94e5ca3f1..40917f441 100644 --- a/code/glTF2Importer.cpp +++ b/code/glTF2Importer.cpp @@ -99,14 +99,14 @@ const aiImporterDesc* glTF2Importer::GetInfo() const return &desc; } -bool glTF2Importer::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const +bool glTF2Importer::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool /* checkSig */) const { const std::string &extension = GetExtension(pFile); if (extension != "gltf" && extension != "glb") return false; - if (checkSig && pIOHandler) { + if (pIOHandler) { glTF2::Asset asset(pIOHandler); try { asset.Load(pFile, extension == "glb"); @@ -211,63 +211,90 @@ inline void SetMaterialTextureProperty(std::vector& embeddedTexIdxs, Asset& } } +inline void SetMaterialTextureProperty(std::vector& embeddedTexIdxs, Asset& r, glTF2::NormalTextureInfo& prop, aiMaterial* mat, aiTextureType texType, unsigned int texSlot = 0) +{ + SetMaterialTextureProperty( embeddedTexIdxs, r, (glTF2::TextureInfo) prop, mat, texType, texSlot ); + + if (prop.texture && prop.texture->source) { + mat->AddProperty(&prop.scale, 1, AI_MATKEY_GLTF_TEXTURE_SCALE(texType, texSlot)); + } +} + +inline void SetMaterialTextureProperty(std::vector& embeddedTexIdxs, Asset& r, glTF2::OcclusionTextureInfo& prop, aiMaterial* mat, aiTextureType texType, unsigned int texSlot = 0) +{ + SetMaterialTextureProperty( embeddedTexIdxs, r, (glTF2::TextureInfo) prop, mat, texType, texSlot ); + + if (prop.texture && prop.texture->source) { + mat->AddProperty(&prop.strength, 1, AI_MATKEY_GLTF_TEXTURE_STRENGTH(texType, texSlot)); + } +} + +static aiMaterial* ImportMaterial(std::vector& embeddedTexIdxs, Asset& r, Material& mat) +{ + aiMaterial* aimat = new aiMaterial(); + + if (!mat.name.empty()) { + aiString str(mat.name); + + aimat->AddProperty(&str, AI_MATKEY_NAME); + } + + SetMaterialColorProperty(r, mat.pbrMetallicRoughness.baseColorFactor, aimat, AI_MATKEY_COLOR_DIFFUSE); + SetMaterialColorProperty(r, mat.pbrMetallicRoughness.baseColorFactor, aimat, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_FACTOR); + + SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.baseColorTexture, aimat, aiTextureType_DIFFUSE); + SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.baseColorTexture, aimat, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_TEXTURE); + + SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.metallicRoughnessTexture, aimat, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE); + + aimat->AddProperty(&mat.pbrMetallicRoughness.metallicFactor, 1, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLIC_FACTOR); + aimat->AddProperty(&mat.pbrMetallicRoughness.roughnessFactor, 1, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_ROUGHNESS_FACTOR); + + float roughnessAsShininess = (1 - mat.pbrMetallicRoughness.roughnessFactor) * 1000; + aimat->AddProperty(&roughnessAsShininess, 1, AI_MATKEY_SHININESS); + + SetMaterialTextureProperty(embeddedTexIdxs, r, mat.normalTexture, aimat, aiTextureType_NORMALS); + SetMaterialTextureProperty(embeddedTexIdxs, r, mat.occlusionTexture, aimat, aiTextureType_LIGHTMAP); + SetMaterialTextureProperty(embeddedTexIdxs, r, mat.emissiveTexture, aimat, aiTextureType_EMISSIVE); + SetMaterialColorProperty(r, mat.emissiveFactor, aimat, AI_MATKEY_COLOR_EMISSIVE); + + aimat->AddProperty(&mat.doubleSided, 1, AI_MATKEY_TWOSIDED); + + aiString alphaMode(mat.alphaMode); + aimat->AddProperty(&alphaMode, AI_MATKEY_GLTF_ALPHAMODE); + aimat->AddProperty(&mat.alphaCutoff, 1, AI_MATKEY_GLTF_ALPHACUTOFF); + + //pbrSpecularGlossiness + if (mat.pbrSpecularGlossiness.isPresent) { + PbrSpecularGlossiness &pbrSG = mat.pbrSpecularGlossiness.value; + + aimat->AddProperty(&mat.pbrSpecularGlossiness.isPresent, 1, AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS); + SetMaterialColorProperty(r, pbrSG.diffuseFactor, aimat, AI_MATKEY_COLOR_DIFFUSE); + SetMaterialColorProperty(r, pbrSG.specularFactor, aimat, AI_MATKEY_COLOR_SPECULAR); + + float glossinessAsShininess = pbrSG.glossinessFactor * 1000.0f; + aimat->AddProperty(&glossinessAsShininess, 1, AI_MATKEY_SHININESS); + aimat->AddProperty(&pbrSG.glossinessFactor, 1, AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_GLOSSINESS_FACTOR); + + SetMaterialTextureProperty(embeddedTexIdxs, r, pbrSG.diffuseTexture, aimat, aiTextureType_DIFFUSE); + + SetMaterialTextureProperty(embeddedTexIdxs, r, pbrSG.specularGlossinessTexture, aimat, aiTextureType_SPECULAR); + } + + return aimat; +} + void glTF2Importer::ImportMaterials(glTF2::Asset& r) { - mScene->mNumMaterials = unsigned(r.materials.Size()); + const unsigned int numImportedMaterials = unsigned(r.materials.Size()); + Material defaultMaterial; + + mScene->mNumMaterials = numImportedMaterials + 1; mScene->mMaterials = new aiMaterial*[mScene->mNumMaterials]; + mScene->mMaterials[numImportedMaterials] = ImportMaterial(embeddedTexIdxs, r, defaultMaterial); - for (unsigned int i = 0; i < mScene->mNumMaterials; ++i) { - aiMaterial* aimat = mScene->mMaterials[i] = new aiMaterial(); - - Material& mat = r.materials[i]; - - if (!mat.name.empty()) { - aiString str(mat.name); - - aimat->AddProperty(&str, AI_MATKEY_NAME); - } - - SetMaterialColorProperty(r, mat.pbrMetallicRoughness.baseColorFactor, aimat, AI_MATKEY_COLOR_DIFFUSE); - SetMaterialColorProperty(r, mat.pbrMetallicRoughness.baseColorFactor, aimat, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_FACTOR); - - SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.baseColorTexture, aimat, aiTextureType_DIFFUSE); - SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.baseColorTexture, aimat, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_TEXTURE); - - SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.metallicRoughnessTexture, aimat, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE); - - aimat->AddProperty(&mat.pbrMetallicRoughness.metallicFactor, 1, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLIC_FACTOR); - aimat->AddProperty(&mat.pbrMetallicRoughness.roughnessFactor, 1, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_ROUGHNESS_FACTOR); - - float roughnessAsShininess = (1 - mat.pbrMetallicRoughness.roughnessFactor) * 1000; - aimat->AddProperty(&roughnessAsShininess, 1, AI_MATKEY_SHININESS); - - SetMaterialTextureProperty(embeddedTexIdxs, r, mat.normalTexture, aimat, aiTextureType_NORMALS); - SetMaterialTextureProperty(embeddedTexIdxs, r, mat.occlusionTexture, aimat, aiTextureType_LIGHTMAP); - SetMaterialTextureProperty(embeddedTexIdxs, r, mat.emissiveTexture, aimat, aiTextureType_EMISSIVE); - SetMaterialColorProperty(r, mat.emissiveFactor, aimat, AI_MATKEY_COLOR_EMISSIVE); - - aimat->AddProperty(&mat.doubleSided, 1, AI_MATKEY_TWOSIDED); - - aiString alphaMode(mat.alphaMode); - aimat->AddProperty(&alphaMode, AI_MATKEY_GLTF_ALPHAMODE); - aimat->AddProperty(&mat.alphaCutoff, 1, AI_MATKEY_GLTF_ALPHACUTOFF); - - //pbrSpecularGlossiness - if (mat.pbrSpecularGlossiness.isPresent) { - PbrSpecularGlossiness &pbrSG = mat.pbrSpecularGlossiness.value; - - aimat->AddProperty(&mat.pbrSpecularGlossiness.isPresent, 1, AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS); - SetMaterialColorProperty(r, pbrSG.diffuseFactor, aimat, AI_MATKEY_COLOR_DIFFUSE); - SetMaterialColorProperty(r, pbrSG.specularFactor, aimat, AI_MATKEY_COLOR_SPECULAR); - - float glossinessAsShininess = pbrSG.glossinessFactor * 1000.0f; - aimat->AddProperty(&glossinessAsShininess, 1, AI_MATKEY_SHININESS); - aimat->AddProperty(&pbrSG.glossinessFactor, 1, AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_GLOSSINESS_FACTOR); - - SetMaterialTextureProperty(embeddedTexIdxs, r, pbrSG.diffuseTexture, aimat, aiTextureType_DIFFUSE); - - SetMaterialTextureProperty(embeddedTexIdxs, r, pbrSG.specularGlossinessTexture, aimat, aiTextureType_SPECULAR); - } + for (unsigned int i = 0; i < numImportedMaterials; ++i) { + mScene->mMaterials[i] = ImportMaterial(embeddedTexIdxs, r, r.materials[i]); } } @@ -479,6 +506,10 @@ void glTF2Importer::ImportMeshes(glTF2::Asset& r) if (prim.material) { aim->mMaterialIndex = prim.material.GetIndex(); } + else { + aim->mMaterialIndex = mScene->mNumMaterials - 1; + } + } } @@ -499,6 +530,9 @@ void glTF2Importer::ImportCameras(glTF2::Asset& r) aiCamera* aicam = mScene->mCameras[i] = new aiCamera(); + // cameras point in -Z by default, rest is specified in node transform + aicam->mLookAt = aiVector3D(0.f,0.f,-1.f); + if (cam.type == Camera::Perspective) { aicam->mAspect = cam.cameraProperties.perspective.aspectRatio; diff --git a/code/glTFImporter.cpp b/code/glTFImporter.cpp index 381e459fd..e5a1ae883 100644 --- a/code/glTFImporter.cpp +++ b/code/glTFImporter.cpp @@ -98,14 +98,14 @@ const aiImporterDesc* glTFImporter::GetInfo() const return &desc; } -bool glTFImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const +bool glTFImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool /* checkSig */) const { const std::string &extension = GetExtension(pFile); if (extension != "gltf" && extension != "glb") return false; - if (checkSig && pIOHandler) { + if (pIOHandler) { glTF::Asset asset(pIOHandler); try { asset.Load(pFile, extension == "glb"); diff --git a/doc/dox.h b/doc/dox.h index 2672adcb5..3215016ab 100644 --- a/doc/dox.h +++ b/doc/dox.h @@ -533,8 +533,9 @@ assimp::Importer::ReadFile(), aiImportFile() or aiImportFileEx() - see the @link for further information on how to use the library. By default, all 3D data is provided in a right-handed coordinate system such as OpenGL uses. In -this coordinate system, +X points to the right, -Z points away from the viewer into the screen and -+Y points upwards. Several modeling packages such as 3D Studio Max use this coordinate system as well (or a rotated variant of it). +this coordinate system, +X points to the right, +Y points upwards and +Z points out of the screen +towards the viewer. Several modeling packages such as 3D Studio Max use this coordinate system as well +(or a rotated variant of it). By contrast, some other environments use left-handed coordinate systems, a prominent example being DirectX. If you need the imported data to be in a left-handed coordinate system, supply the #aiProcess_MakeLeftHanded flag to the ReadFile() function call. @@ -552,7 +553,7 @@ although our built-in triangulation (#aiProcess_Triangulate postprocessing step) The output UV coordinate system has its origin in the lower-left corner: @code -0y|1y ---------- 1x|1y +0x|1y ---------- 1x|1y | | | | | | @@ -560,18 +561,27 @@ The output UV coordinate system has its origin in the lower-left corner: @endcode Use the #aiProcess_FlipUVs flag to get UV coordinates with the upper-left corner als origin. -All matrices in the library are row-major. That means that the matrices are stored row by row in memory, -which is similar to the OpenGL matrix layout. A typical 4x4 matrix including a translational part looks like this: +A typical 4x4 matrix including a translational part looks like this: @code X1 Y1 Z1 T1 X2 Y2 Z2 T2 X3 Y3 Z3 T3 -0 0 0 1 + 0 0 0 1 @endcode +with (X1, X2, X3) being the local X base vector, (Y1, Y2, Y3) being the local +Y base vector, (Z1, Z2, Z3) being the local Z base vector and (T1, T2, T3) being the +offset of the local origin (the translational part). +All matrices in the library use row-major storage order. That means that the matrix elements are +stored row-by-row, i.e. they end up like this in memory: +[X1, Y1, Z1, T1, X2, Y2, Z2, T2, X3, Y3, Z3, T3, 0, 0, 0, 1]. -... with (X1, X2, X3) being the X base vector, (Y1, Y2, Y3) being the Y base vector, (Z1, Z2, Z3) -being the Z base vector and (T1, T2, T3) being the translation part. If you want to use these matrices -in DirectX functions, you have to transpose them. +Note that this is neither the OpenGL format nor the DirectX format, because both of them specify the +matrix layout such that the translational part occupies three consecutive addresses in memory (so those +matrices end with [..., T1, T2, T3, 1]), whereas the translation in an Assimp matrix is found at +the offsets 3, 7 and 11 (spread across the matrix). You can transpose an Assimp matrix to end up with +the format that OpenGL and DirectX mandate. To be very precise: The transposition has nothing +to do with a left-handed or right-handed coordinate system but 'converts' between row-major and +column-major storage format.
@@ -664,7 +674,7 @@ See the @link materials Material System Page. @endlink @section bones Bones -A mesh may have a set of bones in the form of aiBone structures.. Bones are a means to deform a mesh +A mesh may have a set of bones in the form of aiBone objects. Bones are a means to deform a mesh according to the movement of a skeleton. Each bone has a name and a set of vertices on which it has influence. Its offset matrix declares the transformation needed to transform from mesh space to the local space of this bone. diff --git a/include/assimp/defs.h b/include/assimp/defs.h index 20b234f90..0adea90e8 100644 --- a/include/assimp/defs.h +++ b/include/assimp/defs.h @@ -112,6 +112,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * TRANSFORMTEXCOORDS * GENUVCOORDS * ENTITYMESHBUILDER + * EMBEDTEXTURES * MAKELEFTHANDED * FLIPUVS * FLIPWINDINGORDER diff --git a/include/assimp/postprocess.h b/include/assimp/postprocess.h index 970df8e8a..dfb26d5ed 100644 --- a/include/assimp/postprocess.h +++ b/include/assimp/postprocess.h @@ -535,7 +535,18 @@ enum aiPostProcessSteps * * Use #AI_CONFIG_GLOBAL_SCALE_FACTOR_KEY to control this. */ - aiProcess_GlobalScale = 0x8000000 + aiProcess_GlobalScale = 0x8000000, + + // ------------------------------------------------------------------------- + /**
A postprocessing step to embed of textures. + * + * This will remove external data dependencies for textures. + * If a texture's file does not exist at the specified path + * (due, for instance, to an absolute path generated on another system), + * it will check if a file with the same name exists at the root folder + * of the imported model. And if so, it uses that. + */ + aiProcess_EmbedTextures = 0x10000000, // aiProcess_GenEntityMeshes = 0x100000, // aiProcess_OptimizeAnimations = 0x200000 diff --git a/include/assimp/types.h b/include/assimp/types.h index 0012a0bba..e7bec2f85 100644 --- a/include/assimp/types.h +++ b/include/assimp/types.h @@ -110,8 +110,7 @@ extern "C" { /** Maximum dimension for strings, ASSIMP strings are zero terminated. */ #ifdef __cplusplus -static -const size_t MAXLEN = 1024; + static const size_t MAXLEN = 1024; #else # define MAXLEN 1024 #endif diff --git a/include/assimp/version.h b/include/assimp/version.h index d1821fa2b..20ece7fa0 100644 --- a/include/assimp/version.h +++ b/include/assimp/version.h @@ -82,6 +82,12 @@ ASSIMP_API unsigned int aiGetVersionMajor (void); */ ASSIMP_API unsigned int aiGetVersionRevision (void); +// --------------------------------------------------------------------------- +/** @brief Returns the branchname of the Assimp runtime. + * @return The current branch name. + */ +ASSIMP_API const char *aiGetBranchName(); + //! Assimp was compiled as a shared object (Windows: DLL) #define ASSIMP_CFLAGS_SHARED 0x1 //! Assimp was compiled against STLport diff --git a/port/PyAssimp/gen/materialgen.py b/port/PyAssimp/gen/materialgen.py new file mode 100644 index 000000000..d60bf4bc2 --- /dev/null +++ b/port/PyAssimp/gen/materialgen.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python +# -*- Coding: UTF-8 -*- + +# --------------------------------------------------------------------------- +# Open Asset Import Library (ASSIMP) +# --------------------------------------------------------------------------- +# +# Copyright (c) 2006-2010, ASSIMP Development 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 Development 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. +# --------------------------------------------------------------------------- + +"""Update PyAssimp's texture type constants C/C++ headers. + +This script is meant to be executed in the source tree, directly from +port/PyAssimp/gen +""" + +import os +import re + +REenumTextureType = re.compile(r'' + r'enum\saiTextureType' # enum aiTextureType + r'[^{]*?\{' # { + r'(?P.*?)' # code + r'\};' # }; + , re.IGNORECASE + re.DOTALL + re.MULTILINE) + +# Replace comments +RErpcom = re.compile(r'' + r'\s*(/\*+\s|\*+/|\B\*\s?|///?!?)' # /** + r'(?P.*?)' # * line + , re.IGNORECASE + re.DOTALL) + +# Remove trailing commas +RErmtrailcom = re.compile(r',$', re.IGNORECASE + re.DOTALL) + +# Remove #ifdef __cplusplus +RErmifdef = re.compile(r'' + r'#ifndef SWIG' # #ifndef SWIG + r'(?P.*)' # code + r'#endif(\s*//\s*!?\s*SWIG)*' # #endif + , re.IGNORECASE + re.DOTALL) + +path = '../../../include/assimp' + +files = os.listdir (path) +enumText = '' +for fileName in files: + if fileName.endswith('.h'): + text = open(os.path.join(path, fileName)).read() + for enum in REenumTextureType.findall(text): + enumText = enum + +text = '' +for line in enumText.split('\n'): + line = line.lstrip().rstrip() + line = RErmtrailcom.sub('', line) + text += RErpcom.sub('# \g', line) + '\n' +text = RErmifdef.sub('', text) + +file = open('material.py', 'w') +file.write(text) +file.close() + +print("Generation done. You can now review the file 'material.py' and merge it.") diff --git a/port/PyAssimp/pyassimp/helper.py b/port/PyAssimp/pyassimp/helper.py index 85bb53add..7d9282745 100644 --- a/port/PyAssimp/pyassimp/helper.py +++ b/port/PyAssimp/pyassimp/helper.py @@ -51,11 +51,8 @@ if os.name=='posix': elif os.name=='nt': ext_whitelist.append('.dll') path_dirs = os.environ['PATH'].split(';') - for dir_candidate in path_dirs: - if 'assimp' in dir_candidate.lower(): - additional_dirs.append(dir_candidate) + additional_dirs.extend(path_dirs) -#print(additional_dirs) def vec2tuple(x): """ Converts a VECTOR3D to a Tuple """ return (x.x, x.y, x.z) diff --git a/port/PyAssimp/pyassimp/material.py b/port/PyAssimp/pyassimp/material.py index 97b143a62..a36e50a17 100644 --- a/port/PyAssimp/pyassimp/material.py +++ b/port/PyAssimp/pyassimp/material.py @@ -1,89 +1,89 @@ -##
Dummy value. +# Dummy value. # -# No texture, but the value to be used as 'texture semantic' -# (#aiMaterialProperty::mSemantic) for all material properties -# *not* related to textures. +# No texture, but the value to be used as 'texture semantic' +# (#aiMaterialProperty::mSemantic) for all material properties +# # not* related to textures. # aiTextureType_NONE = 0x0 -##
The texture is combined with the result of the diffuse -# lighting equation. +# The texture is combined with the result of the diffuse +# lighting equation. # aiTextureType_DIFFUSE = 0x1 -##
The texture is combined with the result of the specular -# lighting equation. +# The texture is combined with the result of the specular +# lighting equation. # aiTextureType_SPECULAR = 0x2 -##
The texture is combined with the result of the ambient -# lighting equation. +# The texture is combined with the result of the ambient +# lighting equation. # aiTextureType_AMBIENT = 0x3 -##
The texture is added to the result of the lighting -# calculation. It isn't influenced by incoming light. +# The texture is added to the result of the lighting +# calculation. It isn't influenced by incoming light. # aiTextureType_EMISSIVE = 0x4 -##
The texture is a height map. +# The texture is a height map. # -# By convention, higher gray-scale values stand for -# higher elevations from the base height. +# By convention, higher gray-scale values stand for +# higher elevations from the base height. # aiTextureType_HEIGHT = 0x5 -##
The texture is a (tangent space) normal-map. +# The texture is a (tangent space) normal-map. # -# Again, there are several conventions for tangent-space -# normal maps. Assimp does (intentionally) not -# distinguish here. +# Again, there are several conventions for tangent-space +# normal maps. Assimp does (intentionally) not +# distinguish here. # aiTextureType_NORMALS = 0x6 -##
The texture defines the glossiness of the material. +# The texture defines the glossiness of the material. # -# The glossiness is in fact the exponent of the specular -# (phong) lighting equation. Usually there is a conversion -# function defined to map the linear color values in the -# texture to a suitable exponent. Have fun. +# The glossiness is in fact the exponent of the specular +# (phong) lighting equation. Usually there is a conversion +# function defined to map the linear color values in the +# texture to a suitable exponent. Have fun. # aiTextureType_SHININESS = 0x7 -##
The texture defines per-pixel opacity. +# The texture defines per-pixel opacity. # -# Usually 'white' means opaque and 'black' means -# 'transparency'. Or quite the opposite. Have fun. +# Usually 'white' means opaque and 'black' means +# 'transparency'. Or quite the opposite. Have fun. # aiTextureType_OPACITY = 0x8 -##
Displacement texture +# Displacement texture # -# The exact purpose and format is application-dependent. -# Higher color values stand for higher vertex displacements. +# The exact purpose and format is application-dependent. +# Higher color values stand for higher vertex displacements. # aiTextureType_DISPLACEMENT = 0x9 -##
Lightmap texture (aka Ambient Occlusion) +# Lightmap texture (aka Ambient Occlusion) # -# Both 'Lightmaps' and dedicated 'ambient occlusion maps' are -# covered by this material property. The texture contains a -# scaling value for the final color value of a pixel. Its -# intensity is not affected by incoming light. +# Both 'Lightmaps' and dedicated 'ambient occlusion maps' are +# covered by this material property. The texture contains a +# scaling value for the final color value of a pixel. Its +# intensity is not affected by incoming light. # aiTextureType_LIGHTMAP = 0xA -##
Reflection texture +# Reflection texture # -#Contains the color of a perfect mirror reflection. -#Rarely used, almost never for real-time applications. +# Contains the color of a perfect mirror reflection. +# Rarely used, almost never for real-time applications. # aiTextureType_REFLECTION = 0xB -##
Unknown texture +# Unknown texture # -# A texture reference that does not match any of the definitions -# above is considered to be 'unknown'. It is still imported -# but is excluded from any further postprocessing. +# A texture reference that does not match any of the definitions +# above is considered to be 'unknown'. It is still imported +# but is excluded from any further postprocessing. # aiTextureType_UNKNOWN = 0xC diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 741da9534..a1bb5fd35 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -38,9 +38,6 @@ #---------------------------------------------------------------------- cmake_minimum_required( VERSION 2.6 ) -include( CTest ) -enable_testing() - INCLUDE_DIRECTORIES( ../contrib/gtest/include ../contrib/gtest/ diff --git a/test/unit/utVersion.cpp b/test/unit/utVersion.cpp index a424a27cf..af16211a1 100644 --- a/test/unit/utVersion.cpp +++ b/test/unit/utVersion.cpp @@ -69,3 +69,8 @@ TEST_F( utVersion, aiGetVersionRevisionTest ) { EXPECT_NE( aiGetVersionRevision(), 0U ); } +TEST_F( utVersion, aiGetBranchNameTest ) { + EXPECT_NE( nullptr, aiGetBranchName() ); +} + +