Marco Di Benedetto 2019-03-29 11:55:21 +01:00
commit faf12c6f5f
45 changed files with 6197 additions and 3088 deletions

View File

@ -157,7 +157,7 @@ SET (PROJECT_VERSION "${ASSIMP_VERSION}")
SET( ASSIMP_PACKAGE_VERSION "0" CACHE STRING "the package-specific version used for uploading the sources" )
# Enable C++1 globally
# Enable C++11 support globally
set_property( GLOBAL PROPERTY CXX_STANDARD 11 )
IF(NOT IGNORE_GIT_HASH)
@ -351,6 +351,15 @@ IF( NOT ZLIB_FOUND )
INCLUDE(CheckIncludeFile)
INCLUDE(CheckTypeSize)
INCLUDE(CheckFunctionExists)
# Explicitly turn off ASM686 and AMD64 cmake options.
# The AMD64 option causes a build failure on MSVC and the ASM builds seem to have problems:
# https://github.com/madler/zlib/issues/41#issuecomment-125848075
# Also prevents these options from "polluting" the cmake options if assimp is being
# included as a submodule.
set( ASM686 FALSE CACHE INTERNAL "Override ZLIB flag to turn off assembly" FORCE )
set( AMD64 FALSE CACHE INTERNAL "Override ZLIB flag to turn off assembly" FORCE )
# compile from sources
ADD_SUBDIRECTORY(contrib/zlib)
SET(ZLIB_FOUND 1)

11
INSTALL
View File

@ -35,13 +35,16 @@ http://www.cmake.org/.
For Unix:
1. cmake CMakeLists.txt -G 'Unix Makefiles'
2. make
1. mkdir build && cd build
2. cmake .. -G 'Unix Makefiles'
3. make -j4
For Windows:
1. Open a command prompt
2. cmake CMakeLists.txt
2. Open your default IDE and build it
2. mkdir build
3. cd build
4. cmake ..
5. cmake --build .
For iOS:
Just check the following project, which deploys a compiler toolchain for different iOS-versions: https://github.com/assimp/assimp/tree/master/port/iOS

View File

@ -128,6 +128,7 @@ Take a look into the https://github.com/assimp/assimp/blob/master/Build.md file.
* [Javascript (Alpha)](https://github.com/makc/assimp2json)
* [Unity 3d Plugin](https://www.assetstore.unity3d.com/en/#!/content/91777)
* [JVM](https://github.com/kotlin-graphics/assimp) Full jvm port (current [status](https://github.com/kotlin-graphics/assimp/wiki/Status))
* [HAXE-Port](https://github.com/longde123/assimp-haxe) The Assimp-HAXE-port.
### Other tools ###
[open3mod](https://github.com/acgessler/open3mod) is a powerful 3D model viewer based on Assimp's import and export abilities.

View File

@ -15,8 +15,8 @@ matrix:
image:
- Visual Studio 2013
# - Visual Studio 2015
# - Visual Studio 2017
- Previous Visual Studio 2015
- Previous Visual Studio 2017
platform:
- Win32
@ -28,8 +28,8 @@ install:
- set PATH=C:\Ruby24-x64\bin;%PATH%
- set CMAKE_DEFINES -DASSIMP_WERROR=ON
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2013" set CMAKE_GENERATOR_NAME=Visual Studio 12 2013
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2015" set CMAKE_GENERATOR_NAME=Visual Studio 14 2015
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Visual Studio 2017" set CMAKE_GENERATOR_NAME=Visual Studio 15 2017
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Previous Visual Studio 2015" set CMAKE_GENERATOR_NAME=Visual Studio 14 2015
- if "%APPVEYOR_BUILD_WORKER_IMAGE%"=="Previous Visual Studio 2017" set CMAKE_GENERATOR_NAME=Visual Studio 15 2017
- if "%platform%"=="x64" set CMAKE_GENERATOR_NAME=%CMAKE_GENERATOR_NAME% Win64
- cmake %CMAKE_DEFINES% -G "%CMAKE_GENERATOR_NAME%"
- set PATH=%PATH%;"C:\\Program Files (x86)\\Inno Setup 5"

View File

@ -708,7 +708,7 @@ void AssbinImporter::InternReadFile( const std::string& pFile, aiScene* pScene,
unsigned char * uncompressedData = new unsigned char[ uncompressedSize ];
int res = uncompress( uncompressedData, &uncompressedSize, compressedData, len );
int res = uncompress( uncompressedData, &uncompressedSize, compressedData, (uLong) len );
if(res != Z_OK)
{
delete [] uncompressedData;

View File

@ -216,7 +216,7 @@ ENDIF ( ASSIMP_BUILD_NONFREE_C4D_IMPORTER )
# ASSIMP_BUILD_XXX_IMPORTER to FALSE for each importer
# if this variable is set to FALSE, the user can manually enable importers by setting
# ASSIMP_BUILD_XXX_IMPORTER to TRUE for each importer
OPTION(ASSIMP_BUILD_ALL_IMPORTERS_BY_DEFAULT "default value of all ASSIMP_BUILD_XXX_IMPORTER value" TRUE)
OPTION(ASSIMP_BUILD_ALL_IMPORTERS_BY_DEFAULT "default value of all ASSIMP_BUILD_XXX_IMPORTER values" TRUE)
# macro to add the CMake Option ADD_ASSIMP_IMPORTER_<name> which enables compile of loader
# this way selective loaders can be compiled (reduces filesize + compile time)
@ -232,19 +232,51 @@ MACRO(ADD_ASSIMP_IMPORTER name)
IF (ASSIMP_IMPORTER_ENABLED)
LIST(APPEND ASSIMP_LOADER_SRCS ${ARGN})
SET(ASSIMP_IMPORTERS_ENABLED "${ASSIMP_IMPORTERS_ENABLED} ${name}")
SET(${name}_SRCS ${ARGN})
SOURCE_GROUP(${name} FILES ${ARGN})
ELSE()
SET(${name}_SRC "")
SET(ASSIMP_IMPORTERS_DISABLED "${ASSIMP_IMPORTERS_DISABLED} ${name}")
add_definitions(-DASSIMP_BUILD_NO_${name}_IMPORTER)
ENDIF()
ENDMACRO()
# if this variable is set to TRUE, the user can manually disable exporters by setting
# ASSIMP_BUILD_XXX_EXPORTER to FALSE for each exporter
# if this variable is set to FALSE, the user can manually enable exporters by setting
# ASSIMP_BUILD_XXX_EXPORTER to TRUE for each exporter
OPTION(ASSIMP_BUILD_ALL_EXPORTERS_BY_DEFAULT "default value of all ASSIMP_BUILD_XXX_EXPORTER values" TRUE)
# macro to add the CMake Option ADD_ASSIMP_IMPORTER_<name> which enables compile of loader
# this way selective loaders can be compiled (reduces filesize + compile time)
MACRO(ADD_ASSIMP_EXPORTER name)
IF (ASSIMP_NO_EXPORT)
set(ASSIMP_EXPORTER_ENABLED FALSE)
ELSEIF (ASSIMP_BUILD_ALL_EXPORTERS_BY_DEFAULT)
set(ASSIMP_EXPORTER_ENABLED TRUE)
IF (DEFINED ASSIMP_BUILD_${name}_EXPORTER AND NOT ASSIMP_BUILD_${name}_EXPORTER)
set(ASSIMP_EXPORTER_ENABLED FALSE)
ENDIF ()
ELSE ()
set(ASSIMP_EXPORTER_ENABLED ${ASSIMP_BUILD_${name}_EXPORTER})
ENDIF ()
IF (ASSIMP_EXPORTER_ENABLED)
SET(ASSIMP_EXPORTERS_ENABLED "${ASSIMP_EXPORTERS_ENABLED} ${name}")
LIST(APPEND ASSIMP_EXPORTER_SRCS ${ARGN})
SOURCE_GROUP(${name}_EXPORTER FILES ${ARGN})
ELSE()
SET(ASSIMP_EXPORTERS_DISABLED "${ASSIMP_EXPORTERS_DISABLED} ${name}")
add_definitions(-DASSIMP_BUILD_NO_${name}_EXPORTER)
ENDIF()
ENDMACRO()
SET(ASSIMP_LOADER_SRCS "")
SET(ASSIMP_IMPORTERS_ENABLED "") # list of enabled importers
SET(ASSIMP_IMPORTERS_DISABLED "") # disabled list (used to print)
SET(ASSIMP_IMPORTERS_DISABLED "") # disabled importers list (used to print)
SET(ASSIMP_EXPORTER_SRCS "")
SET(ASSIMP_EXPORTERS_ENABLED "") # list of enabled exporters
SET(ASSIMP_EXPORTERS_DISABLED "") # disabled exporters list (used to print)
ADD_ASSIMP_IMPORTER( AMF
AMFImporter.hpp
@ -261,6 +293,9 @@ ADD_ASSIMP_IMPORTER( 3DS
3DSHelper.h
3DSLoader.cpp
3DSLoader.h
)
ADD_ASSIMP_EXPORTER( 3DS
3DSExporter.h
3DSExporter.cpp
)
@ -278,12 +313,15 @@ ADD_ASSIMP_IMPORTER( ASE
)
ADD_ASSIMP_IMPORTER( ASSBIN
AssbinExporter.h
AssbinExporter.cpp
AssbinLoader.h
AssbinLoader.cpp
)
ADD_ASSIMP_EXPORTER( ASSBIN
AssbinExporter.h
AssbinExporter.cpp
)
ADD_ASSIMP_IMPORTER( ASSXML
AssxmlExporter.h
AssxmlExporter.cpp
@ -305,6 +343,9 @@ ADD_ASSIMP_IMPORTER( COLLADA
ColladaLoader.h
ColladaParser.cpp
ColladaParser.h
)
ADD_ASSIMP_EXPORTER( COLLADA
ColladaExporter.h
ColladaExporter.cpp
)
@ -421,6 +462,9 @@ ADD_ASSIMP_IMPORTER( OBJ
ObjFileParser.cpp
ObjFileParser.h
ObjTools.h
)
ADD_ASSIMP_EXPORTER( OBJ
ObjExporter.h
ObjExporter.cpp
)
@ -439,18 +483,24 @@ ADD_ASSIMP_IMPORTER( OGRE
)
ADD_ASSIMP_IMPORTER( OPENGEX
OpenGEXExporter.cpp
OpenGEXExporter.h
OpenGEXImporter.cpp
OpenGEXImporter.h
OpenGEXStructs.h
)
ADD_ASSIMP_EXPORTER( OPENGEX
OpenGEXExporter.cpp
OpenGEXExporter.h
)
ADD_ASSIMP_IMPORTER( PLY
PlyLoader.cpp
PlyLoader.h
PlyParser.cpp
PlyParser.h
)
ADD_ASSIMP_EXPORTER( PLY
PlyExporter.cpp
PlyExporter.h
)
@ -541,13 +591,16 @@ ADD_ASSIMP_IMPORTER( FBX
FBXDeformer.cpp
FBXBinaryTokenizer.cpp
FBXDocumentUtil.cpp
FBXCommon.h
)
ADD_ASSIMP_EXPORTER( FBX
FBXExporter.h
FBXExporter.cpp
FBXExportNode.h
FBXExportNode.cpp
FBXExportProperty.h
FBXExportProperty.cpp
FBXCommon.h
)
SET( PostProcessing_SRCS
@ -647,6 +700,9 @@ ADD_ASSIMP_IMPORTER( SMD
ADD_ASSIMP_IMPORTER( STL
STLLoader.cpp
STLLoader.h
)
ADD_ASSIMP_EXPORTER( STL
STLExporter.h
STLExporter.cpp
)
@ -667,13 +723,14 @@ ADD_ASSIMP_IMPORTER( X
XFileImporter.h
XFileParser.cpp
XFileParser.h
)
ADD_ASSIMP_EXPORTER( X
XFileExporter.h
XFileExporter.cpp
)
ADD_ASSIMP_IMPORTER( X3D
X3DExporter.cpp
X3DExporter.hpp
X3DImporter.cpp
X3DImporter.hpp
X3DImporter_Geometry2D.cpp
@ -693,6 +750,11 @@ ADD_ASSIMP_IMPORTER( X3D
X3DVocabulary.cpp
)
ADD_ASSIMP_EXPORTER( X3D
X3DExporter.cpp
X3DExporter.hpp
)
ADD_ASSIMP_IMPORTER( GLTF
glTFAsset.h
glTFAsset.inl
@ -700,28 +762,34 @@ ADD_ASSIMP_IMPORTER( GLTF
glTFAssetWriter.inl
glTFImporter.cpp
glTFImporter.h
glTFExporter.h
glTFExporter.cpp
glTF2Asset.h
glTF2Asset.inl
glTF2AssetWriter.h
glTF2AssetWriter.inl
glTF2Importer.cpp
glTF2Importer.h
)
ADD_ASSIMP_EXPORTER( GLTF
glTFExporter.h
glTFExporter.cpp
glTF2Exporter.h
glTF2Exporter.cpp
)
ADD_ASSIMP_IMPORTER( 3MF
D3MFImporter.h
D3MFImporter.h
D3MFImporter.cpp
D3MFExporter.h
D3MFExporter.cpp
D3MFOpcPackage.h
D3MFOpcPackage.h
D3MFOpcPackage.cpp
3MFXmlTags.h
)
ADD_ASSIMP_EXPORTER( 3MF
D3MFExporter.h
D3MFExporter.cpp
)
ADD_ASSIMP_IMPORTER( MMD
MMDCpp14.h
MMDImporter.cpp
@ -740,16 +808,21 @@ ADD_ASSIMP_IMPORTER( STEP
Importer/StepFile/StepFileGen2.cpp
Importer/StepFile/StepFileGen3.cpp
Importer/StepFile/StepReaderGen.h
)
ADD_ASSIMP_EXPORTER( STEP
StepExporter.h
StepExporter.cpp
)
SET( Exporter_SRCS
Exporter.cpp
AssimpCExport.cpp
${HEADER_PATH}/BlobIOSystem.h
)
SOURCE_GROUP( Exporter FILES ${Exporter_SRCS})
if ((NOT ASSIMP_NO_EXPORT) OR (NOT ASSIMP_EXPORTERS_ENABLED STREQUAL ""))
SET( Exporter_SRCS
Exporter.cpp
AssimpCExport.cpp
${HEADER_PATH}/BlobIOSystem.h
)
SOURCE_GROUP( Exporter FILES ${Exporter_SRCS})
endif()
SET( Extra_SRCS
MD4FileData.h
@ -793,6 +866,13 @@ SET( ziplib_SRCS
../contrib/zip/src/zip.h
)
# TODO if cmake required version has been updated to >3.12.0, collapse this to the second case only
if(${CMAKE_VERSION} VERSION_LESS "3.12.0")
add_definitions(-DMINIZ_USE_UNALIGNED_LOADS_AND_STORES=0)
else()
add_compile_definitions(MINIZ_USE_UNALIGNED_LOADS_AND_STORES=0)
endif()
SOURCE_GROUP( ziplib FILES ${ziplib_SRCS} )
SET ( openddl_parser_SRCS
@ -883,8 +963,11 @@ else (UNZIP_FOUND)
INCLUDE_DIRECTORIES( "../contrib/unzip/" )
endif (UNZIP_FOUND)
MESSAGE(STATUS "Enabled formats:${ASSIMP_IMPORTERS_ENABLED}")
MESSAGE(STATUS "Disabled formats:${ASSIMP_IMPORTERS_DISABLED}")
MESSAGE(STATUS "Enabled importer formats:${ASSIMP_IMPORTERS_ENABLED}")
MESSAGE(STATUS "Disabled importer formats:${ASSIMP_IMPORTERS_DISABLED}")
MESSAGE(STATUS "Enabled exporter formats:${ASSIMP_EXPORTERS_ENABLED}")
MESSAGE(STATUS "Disabled exporter formats:${ASSIMP_EXPORTERS_DISABLED}")
SET( assimp_src
# Assimp Files
@ -899,6 +982,7 @@ SET( assimp_src
# Model Support
${ASSIMP_LOADER_SRCS}
${ASSIMP_EXPORTER_SRCS}
# Third-party libraries
${IrrXML_SRCS}
@ -912,7 +996,6 @@ SET( assimp_src
${PUBLIC_HEADERS}
${COMPILER_HEADERS}
)
ADD_DEFINITIONS( -DOPENDDLPARSER_BUILD )

View File

@ -964,7 +964,7 @@ namespace Assimp {
{
if (indices[i] < 0) epcount++;
}
unsigned int pcount = indices.size();
unsigned int pcount = static_cast<unsigned int>( indices.size() );
unsigned int scount = out_mesh->mNumFaces = pcount - epcount;
aiFace* fac = out_mesh->mFaces = new aiFace[scount]();

View File

@ -178,30 +178,30 @@ void FindInstancesProcess::Execute( aiScene* pScene)
// use a constant epsilon for colors and UV coordinates
static const float uvEpsilon = 10e-4f;
{
unsigned int i, end = orig->GetNumUVChannels();
for(i = 0; i < end; ++i) {
if (!orig->mTextureCoords[i]) {
unsigned int j, end = orig->GetNumUVChannels();
for(j = 0; j < end; ++j) {
if (!orig->mTextureCoords[j]) {
continue;
}
if(!CompareArrays(orig->mTextureCoords[i],inst->mTextureCoords[i],orig->mNumVertices,uvEpsilon)) {
if(!CompareArrays(orig->mTextureCoords[j],inst->mTextureCoords[j],orig->mNumVertices,uvEpsilon)) {
break;
}
}
if (i != end) {
if (j != end) {
continue;
}
}
{
unsigned int i, end = orig->GetNumColorChannels();
for(i = 0; i < end; ++i) {
if (!orig->mColors[i]) {
unsigned int j, end = orig->GetNumColorChannels();
for(j = 0; j < end; ++j) {
if (!orig->mColors[j]) {
continue;
}
if(!CompareArrays(orig->mColors[i],inst->mColors[i],orig->mNumVertices,uvEpsilon)) {
if(!CompareArrays(orig->mColors[j],inst->mColors[j],orig->mNumVertices,uvEpsilon)) {
break;
}
}
if (i != end) {
if (j != end) {
continue;
}
}

View File

@ -112,7 +112,9 @@ void ImproveCacheLocalityProcess::Execute( aiScene* pScene)
}
}
if (!DefaultLogger::isNullLogger()) {
ASSIMP_LOG_INFO_F("Cache relevant are ", numm, " meshes (", numf," faces). Average output ACMR is ", out / numf );
if (numf > 0) {
ASSIMP_LOG_INFO_F("Cache relevant are ", numm, " meshes (", numf, " faces). Average output ACMR is ", out / numf);
}
ASSIMP_LOG_DEBUG("ImproveCacheLocalityProcess finished. ");
}
}

View File

@ -320,13 +320,10 @@ void LWOImporter::ConvertMaterial(const LWO::Surface& surf,aiMaterial* pcMat)
// opacity ... either additive or default-blended, please
if (0.0 != surf.mAdditiveTransparency) {
const int add = aiBlendMode_Additive;
pcMat->AddProperty(&surf.mAdditiveTransparency,1,AI_MATKEY_OPACITY);
pcMat->AddProperty(&add,1,AI_MATKEY_BLEND_FUNC);
}
else if (10e10f != surf.mTransparency) {
} else if (10e10f != surf.mTransparency) {
const int def = aiBlendMode_Default;
const float f = 1.0f-surf.mTransparency;
pcMat->AddProperty(&f,1,AI_MATKEY_OPACITY);

View File

@ -59,7 +59,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/Compiler/pushpack1.h>
namespace Assimp {
namespace Assimp {
namespace MD3 {
// to make it easier for us, we test the magic word against both "endianesses"
@ -303,12 +303,12 @@ inline void Vec3NormalToLatLng( const aiVector3D& p_vIn, uint16_t& p_iOut )
b = int(57.2957795f * ( std::acos( p_vIn[2] ) ) * ( 255.0f / 360.0f ));
b &= 0xff;
((unsigned char*)&p_iOut)[0] = b; // longitude
((unsigned char*)&p_iOut)[1] = a; // latitude
((unsigned char*)&p_iOut)[0] = (unsigned char) b; // longitude
((unsigned char*)&p_iOut)[1] = (unsigned char) a; // latitude
}
}
}
}
} // Namespace MD3
} // Namespace Assimp
#endif // !! AI_MD3FILEHELPER_H_INC

View File

@ -258,10 +258,10 @@ bool Q3Shader::LoadSkin(SkinData& fill, const std::string& pFile,IOSystem* io)
continue;
fill.textures.push_back(SkinData::TextureEntry());
SkinData::TextureEntry& s = fill.textures.back();
SkinData::TextureEntry &entry = fill.textures.back();
s.first = ss;
s.second = GetNextToken(buff);
entry.first = ss;
entry.second = GetNextToken(buff);
}
return true;
}
@ -718,9 +718,7 @@ void MD3Importer::ConvertPath(const char* texture_name, const char* header_name,
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
void MD3Importer::InternReadFile( const std::string& pFile,
aiScene* pScene, IOSystem* pIOHandler)
{
void MD3Importer::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) {
mFile = pFile;
mScene = pScene;
mIOHandler = pIOHandler;
@ -730,11 +728,13 @@ void MD3Importer::InternReadFile( const std::string& pFile,
std::string::size_type s = mFile.find_last_of("/\\");
if (s == std::string::npos) {
s = 0;
} else {
++s;
}
filename = mFile.substr(s), path = mFile.substr(0, s);
for (std::string::iterator it = filename.begin(); it != filename.end(); ++it) {
*it = static_cast<char>( tolower(*it) );
}
else ++s;
filename = mFile.substr(s), path = mFile.substr(0,s);
for( std::string::iterator it = filename .begin(); it != filename.end(); ++it)
*it = tolower( *it);
// Load multi-part model file, if necessary
if (configHandleMP) {
@ -905,15 +905,15 @@ void MD3Importer::InternReadFile( const std::string& pFile,
// Now search the current shader for a record with this name (
// excluding texture file extension)
if (!shaders.blocks.empty()) {
std::string::size_type sh = convertedPath.find_last_of('.');
if (sh == std::string::npos) {
sh = convertedPath.length();
}
std::string::size_type s = convertedPath.find_last_of('.');
if (s == std::string::npos)
s = convertedPath.length();
const std::string without_ext = convertedPath.substr(0,s);
const std::string without_ext = convertedPath.substr(0,sh);
std::list< Q3Shader::ShaderDataBlock >::const_iterator dit = std::find(shaders.blocks.begin(),shaders.blocks.end(),without_ext);
if (dit != shaders.blocks.end()) {
// Hurra, wir haben einen. Tolle Sache.
// We made it!
shader = &*dit;
ASSIMP_LOG_INFO("Found shader record for " +without_ext );
} else {
@ -945,8 +945,7 @@ void MD3Importer::InternReadFile( const std::string& pFile,
aiString szString;
if (convertedPath.length()) {
szString.Set(convertedPath);
}
else {
} else {
ASSIMP_LOG_WARN("Texture file name has zero length. Using default name");
szString.Set("dummy_texture.bmp");
}
@ -955,8 +954,7 @@ void MD3Importer::InternReadFile( const std::string& pFile,
// prevent transparency by default
int no_alpha = aiTextureFlags_IgnoreAlpha;
pcHelper->AddProperty(&no_alpha,1,AI_MATKEY_TEXFLAGS_DIFFUSE(0));
}
else {
} else {
Q3Shader::ConvertShaderToMaterial(pcHelper,*shader);
}
@ -1026,7 +1024,7 @@ void MD3Importer::InternReadFile( const std::string& pFile,
if (!shader || shader->cull == Q3Shader::CULL_CW) {
std::swap(pcMesh->mFaces[i].mIndices[2],pcMesh->mFaces[i].mIndices[1]);
}
pcTriangles++;
++pcTriangles;
}
// Go to the next surface
@ -1042,8 +1040,9 @@ void MD3Importer::InternReadFile( const std::string& pFile,
}
}
if (!pScene->mNumMeshes)
if (!pScene->mNumMeshes) {
throw DeadlyImportError( "MD3: File contains no valid mesh");
}
pScene->mNumMaterials = iNumMaterials;
// Now we need to generate an empty node graph
@ -1057,7 +1056,6 @@ void MD3Importer::InternReadFile( const std::string& pFile,
pScene->mRootNode->mChildren = new aiNode*[pcHeader->NUM_TAGS];
for (unsigned int i = 0; i < pcHeader->NUM_TAGS; ++i, ++pcTags) {
aiNode* nd = pScene->mRootNode->mChildren[i] = new aiNode();
nd->mName.Set((const char*)pcTags->NAME);
nd->mParent = pScene->mRootNode;
@ -1085,8 +1083,12 @@ void MD3Importer::InternReadFile( const std::string& pFile,
pScene->mRootNode->mMeshes[i] = i;
// Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system
pScene->mRootNode->mTransformation = aiMatrix4x4(1.f,0.f,0.f,0.f,
0.f,0.f,1.f,0.f,0.f,-1.f,0.f,0.f,0.f,0.f,0.f,1.f);
pScene->mRootNode->mTransformation = aiMatrix4x4(
1.f,0.f,0.f,0.f,
0.f,0.f,1.f,0.f,
0.f,-1.f,0.f,0.f,
0.f,0.f,0.f,1.f
);
}
#endif // !! ASSIMP_BUILD_NO_MD3_IMPORTER

View File

@ -281,6 +281,8 @@ struct Model {
std::string m_strActiveGroup;
//! Vector with generated texture coordinates
std::vector<aiVector3D> m_TextureCoord;
//! Maximum dimension of texture coordinates
unsigned int m_TextureCoordDim;
//! Current mesh instance
Mesh *m_pCurrentMesh;
//! Vector with stored meshes
@ -296,6 +298,7 @@ struct Model {
m_pDefaultMaterial(NULL),
m_pGroupFaceIDs(NULL),
m_strActiveGroup(""),
m_TextureCoordDim(0),
m_pCurrentMesh(NULL)
{
// empty

View File

@ -442,7 +442,7 @@ void ObjFileImporter::createVertexArray(const ObjFile::Model* pModel,
// Allocate buffer for texture coordinates
if ( !pModel->m_TextureCoord.empty() && pObjMesh->m_uiUVCoordinates[0] )
{
pMesh->mNumUVComponents[ 0 ] = 2;
pMesh->mNumUVComponents[ 0 ] = pModel->m_TextureCoordDim;
pMesh->mTextureCoords[ 0 ] = new aiVector3D[ pMesh->mNumVertices ];
}

View File

@ -151,7 +151,8 @@ void ObjFileParser::parseFile( IOStreamBuffer<char> &streamBuffer ) {
} else if (*m_DataIt == 't') {
// read in texture coordinate ( 2D or 3D )
++m_DataIt;
getVector( m_pModel->m_TextureCoord );
size_t dim = getVector(m_pModel->m_TextureCoord);
m_pModel->m_TextureCoordDim = std::max(m_pModel->m_TextureCoordDim, (unsigned int)dim);
} else if (*m_DataIt == 'n') {
// Read in normal vector definition
++m_DataIt;
@ -296,7 +297,7 @@ size_t ObjFileParser::getNumComponentsInDataDefinition() {
return numComponents;
}
void ObjFileParser::getVector( std::vector<aiVector3D> &point3d_array ) {
size_t ObjFileParser::getVector( std::vector<aiVector3D> &point3d_array ) {
size_t numComponents = getNumComponentsInDataDefinition();
ai_real x, y, z;
if( 2 == numComponents ) {
@ -320,6 +321,7 @@ void ObjFileParser::getVector( std::vector<aiVector3D> &point3d_array ) {
}
point3d_array.push_back( aiVector3D( x, y, z ) );
m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
return numComponents;
}
void ObjFileParser::getVector3( std::vector<aiVector3D> &point3d_array ) {

View File

@ -96,7 +96,7 @@ protected:
/// Get the number of components in a line.
size_t getNumComponentsInDataDefinition();
/// Stores the vector
void getVector( std::vector<aiVector3D> &point3d_array );
size_t getVector( std::vector<aiVector3D> &point3d_array );
/// Stores the following 3d vector.
void getVector3( std::vector<aiVector3D> &point3d_array );
/// Stores the following homogeneous vector as a 3D vector

View File

@ -173,6 +173,9 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out)
#ifndef ASSIMP_BUILD_NO_TRANSFORMTEXCOORDS_PROCESS
out.push_back( new TextureTransformStep());
#endif
#if (!defined ASSIMP_BUILD_NO_GLOBALSCALE_PROCESS)
out.push_back( new ScaleProcess());
#endif
#if (!defined ASSIMP_BUILD_NO_PRETRANSFORMVERTICES_PROCESS)
out.push_back( new PretransformVertices());
#endif
@ -208,9 +211,6 @@ void GetPostProcessingStepInstanceList(std::vector< BaseProcess* >& out)
#endif
#if (!defined ASSIMP_BUILD_NO_GENFACENORMALS_PROCESS)
out.push_back( new GenFaceNormalsProcess());
#endif
#if (!defined ASSIMP_BUILD_NO_GLOBALSCALE_PROCESS)
out.push_back( new ScaleProcess());
#endif
// .........................................................................
// DON'T change the order of these five ..

View File

@ -486,7 +486,7 @@ void SMDImporter::CreateOutputAnimations(const std::string &pFile, IOSystem* pIO
if (bLoadAnimationList) {
GetAnimationFileList(pFile, pIOHandler, animFileList);
}
int animCount = animFileList.size() + 1;
int animCount = static_cast<int>( animFileList.size() + 1u );
pScene->mNumAnimations = 1;
pScene->mAnimations = new aiAnimation*[animCount];
memset(pScene->mAnimations, 0, sizeof(aiAnimation*)*animCount);
@ -510,7 +510,7 @@ void SMDImporter::CreateOutputAnimation(int index, const std::string &name) {
anim->mName.Set(name.c_str());
}
anim->mDuration = dLengthOfAnim;
anim->mNumChannels = asBones.size();
anim->mNumChannels = static_cast<unsigned int>( asBones.size() );
anim->mTicksPerSecond = 25.0; // FIXME: is this correct?
aiNodeAnim** pp = anim->mChannels = new aiNodeAnim*[anim->mNumChannels];

View File

@ -228,36 +228,37 @@ void SortByPTypeProcess::Execute( aiScene* pScene) {
out->mNumVertices = (3 == real ? numPolyVerts : out->mNumFaces * (real+1));
aiVector3D *vert(NULL), *nor(NULL), *tan(NULL), *bit(NULL);
aiVector3D *vert(nullptr), *nor(nullptr), *tan(nullptr), *bit(nullptr);
aiVector3D *uv [AI_MAX_NUMBER_OF_TEXTURECOORDS];
aiColor4D *cols [AI_MAX_NUMBER_OF_COLOR_SETS];
if (mesh->mVertices)
if (mesh->mVertices) {
vert = out->mVertices = new aiVector3D[out->mNumVertices];
}
if (mesh->mNormals)
nor = out->mNormals = new aiVector3D[out->mNumVertices];
if (mesh->mNormals) {
nor = out->mNormals = new aiVector3D[out->mNumVertices];
}
if (mesh->mTangents)
{
if (mesh->mTangents) {
tan = out->mTangents = new aiVector3D[out->mNumVertices];
bit = out->mBitangents = new aiVector3D[out->mNumVertices];
}
for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS;++i)
{
if (mesh->mTextureCoords[i])
uv[i] = out->mTextureCoords[i] = new aiVector3D[out->mNumVertices];
else uv[i] = NULL;
for (unsigned int j = 0; j < AI_MAX_NUMBER_OF_TEXTURECOORDS;++j) {
uv[j] = nullptr;
if (mesh->mTextureCoords[j]) {
uv[j] = out->mTextureCoords[j] = new aiVector3D[out->mNumVertices];
}
out->mNumUVComponents[i] = mesh->mNumUVComponents[i];
out->mNumUVComponents[j] = mesh->mNumUVComponents[j];
}
for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_COLOR_SETS;++i)
{
if (mesh->mColors[i])
cols[i] = out->mColors[i] = new aiColor4D[out->mNumVertices];
else cols[i] = NULL;
for (unsigned int j = 0; j < AI_MAX_NUMBER_OF_COLOR_SETS;++j) {
cols[j] = nullptr;
if (mesh->mColors[j]) {
cols[j] = out->mColors[j] = new aiColor4D[out->mNumVertices];
}
}
typedef std::vector< aiVertexWeight > TempBoneInfo;
@ -323,7 +324,7 @@ void SortByPTypeProcess::Execute( aiScene* pScene) {
in.mIndices[q] = outIdx++;
}
in.mIndices = NULL;
in.mIndices = nullptr;
++outFaces;
}
ai_assert(outFaces == out->mFaces + out->mNumFaces);

View File

@ -127,35 +127,35 @@ aiMesh* StandardShapes::MakeMesh(const std::vector<aiVector3D>& positions,
// Determine which kinds of primitives the mesh consists of
aiMesh* out = new aiMesh();
switch (numIndices)
{
case 1:
out->mPrimitiveTypes = aiPrimitiveType_POINT;
break;
case 2:
out->mPrimitiveTypes = aiPrimitiveType_LINE;
break;
case 3:
out->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
break;
default:
out->mPrimitiveTypes = aiPrimitiveType_POLYGON;
break;
switch (numIndices) {
case 1:
out->mPrimitiveTypes = aiPrimitiveType_POINT;
break;
case 2:
out->mPrimitiveTypes = aiPrimitiveType_LINE;
break;
case 3:
out->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
break;
default:
out->mPrimitiveTypes = aiPrimitiveType_POLYGON;
break;
};
out->mNumFaces = (unsigned int)positions.size() / numIndices;
out->mFaces = new aiFace[out->mNumFaces];
for (unsigned int i = 0, a = 0; i < out->mNumFaces;++i)
{
for (unsigned int i = 0, a = 0; i < out->mNumFaces;++i) {
aiFace& f = out->mFaces[i];
f.mNumIndices = numIndices;
f.mIndices = new unsigned int[numIndices];
for (unsigned int i = 0; i < numIndices;++i,++a)
f.mIndices[i] = a;
for (unsigned int j = 0; i < numIndices; ++i, ++a) {
f.mIndices[j] = a;
}
}
out->mNumVertices = (unsigned int)positions.size();
out->mVertices = new aiVector3D[out->mNumVertices];
::memcpy(out->mVertices,&positions[0],out->mNumVertices*sizeof(aiVector3D));
return out;
}
@ -466,8 +466,8 @@ void StandardShapes::MakeCone(ai_real height,ai_real radius1,
// Need to flip face order?
if ( SIZE_MAX != old ) {
for (size_t s = old; s < positions.size();s += 3) {
std::swap(positions[s],positions[s+1]);
for (size_t p = old; p < positions.size();p += 3) {
std::swap(positions[p],positions[p+1]);
}
}
}

View File

@ -160,7 +160,7 @@ inline void ValidateDSProcess::DoValidationEx(T** parray, unsigned int size,
{
if (!parray[i])
{
ReportError("aiScene::%s[%i] is NULL (aiScene::%s is %i)",
ReportError("aiScene::%s[%u] is NULL (aiScene::%s is %u)",
firstName,i,secondName,size);
}
Validate(parray[i]);
@ -170,8 +170,8 @@ inline void ValidateDSProcess::DoValidationEx(T** parray, unsigned int size,
{
if (parray[i]->mName == parray[a]->mName)
{
this->ReportError("aiScene::%s[%i] has the same name as "
"aiScene::%s[%i]",firstName, i,secondName, a);
ReportError("aiScene::%s[%u] has the same name as "
"aiScene::%s[%u]",firstName, i,secondName, a);
}
}
}
@ -330,6 +330,7 @@ void ValidateDSProcess::Validate( const aiMesh* pMesh)
{
case 0:
ReportError("aiMesh::mFaces[%i].mNumIndices is 0",i);
break;
case 1:
if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_POINT))
{
@ -422,7 +423,9 @@ void ValidateDSProcess::Validate( const aiMesh* pMesh)
if (!abRefList[i])b = true;
}
abRefList.clear();
if (b)ReportWarning("There are unreferenced vertices");
if (b) {
ReportWarning("There are unreferenced vertices");
}
// texture channel 2 may not be set if channel 1 is zero ...
{
@ -557,7 +560,9 @@ void ValidateDSProcess::Validate( const aiAnimation* pAnimation)
Validate(pAnimation, pAnimation->mChannels[i]);
}
}
else ReportError("aiAnimation::mNumChannels is 0. At least one node animation channel must be there.");
else {
ReportError("aiAnimation::mNumChannels is 0. At least one node animation channel must be there.");
}
// Animation duration is allowed to be zero in cases where the anim contains only a single key frame.
// if (!pAnimation->mDuration)this->ReportError("aiAnimation::mDuration is zero");
@ -577,15 +582,16 @@ void ValidateDSProcess::SearchForInvalidTextures(const aiMaterial* pMaterial,
int iNumIndices = 0;
int iIndex = -1;
for (unsigned int i = 0; i < pMaterial->mNumProperties;++i)
{
aiMaterialProperty* prop = pMaterial->mProperties[i];
if (!::strcmp(prop->mKey.data,"$tex.file") && prop->mSemantic == type) {
for (unsigned int i = 0; i < pMaterial->mNumProperties;++i) {
aiMaterialProperty* prop = pMaterial->mProperties[ i ];
ai_assert(nullptr != prop);
if ( !::strcmp(prop->mKey.data,"$tex.file") && prop->mSemantic == static_cast<unsigned int>(type)) {
iIndex = std::max(iIndex, (int) prop->mIndex);
++iNumIndices;
if (aiPTI_String != prop->mType)
ReportError("Material property %s is expected to be a string",prop->mKey.data);
if (aiPTI_String != prop->mType) {
ReportError("Material property %s is expected to be a string", prop->mKey.data);
}
}
}
if (iIndex +1 != iNumIndices) {
@ -773,8 +779,10 @@ void ValidateDSProcess::Validate( const aiTexture* pTexture)
}
if (pTexture->mHeight)
{
if (!pTexture->mWidth)ReportError("aiTexture::mWidth is zero "
"(aiTexture::mHeight is %i, uncompressed texture)",pTexture->mHeight);
if (!pTexture->mWidth){
ReportError("aiTexture::mWidth is zero (aiTexture::mHeight is %i, uncompressed texture)",
pTexture->mHeight);
}
}
else
{
@ -805,15 +813,15 @@ void ValidateDSProcess::Validate( const aiAnimation* pAnimation,
{
Validate(&pNodeAnim->mNodeName);
if (!pNodeAnim->mNumPositionKeys && !pNodeAnim->mScalingKeys && !pNodeAnim->mNumRotationKeys)
if (!pNodeAnim->mNumPositionKeys && !pNodeAnim->mScalingKeys && !pNodeAnim->mNumRotationKeys) {
ReportError("Empty node animation channel");
}
// otherwise check whether one of the keys exceeds the total duration of the animation
if (pNodeAnim->mNumPositionKeys)
{
if (!pNodeAnim->mPositionKeys)
{
this->ReportError("aiNodeAnim::mPositionKeys is NULL (aiNodeAnim::mNumPositionKeys is %i)",
ReportError("aiNodeAnim::mPositionKeys is NULL (aiNodeAnim::mNumPositionKeys is %i)",
pNodeAnim->mNumPositionKeys);
}
double dLast = -10e10;
@ -844,7 +852,7 @@ void ValidateDSProcess::Validate( const aiAnimation* pAnimation,
{
if (!pNodeAnim->mRotationKeys)
{
this->ReportError("aiNodeAnim::mRotationKeys is NULL (aiNodeAnim::mNumRotationKeys is %i)",
ReportError("aiNodeAnim::mRotationKeys is NULL (aiNodeAnim::mNumRotationKeys is %i)",
pNodeAnim->mNumRotationKeys);
}
double dLast = -10e10;
@ -905,19 +913,23 @@ void ValidateDSProcess::Validate( const aiAnimation* pAnimation,
// ------------------------------------------------------------------------------------------------
void ValidateDSProcess::Validate( const aiNode* pNode)
{
if (!pNode)ReportError("A node of the scenegraph is NULL");
if (pNode != mScene->mRootNode && !pNode->mParent)
this->ReportError("A node has no valid parent (aiNode::mParent is NULL)");
if (!pNode) {
ReportError("A node of the scenegraph is NULL");
}
// Validate node name string first so that it's safe to use in below expressions
this->Validate(&pNode->mName);
const char* nodeName = (&pNode->mName)->C_Str();
if (pNode != mScene->mRootNode && !pNode->mParent){
ReportError("Non-root node %s lacks a valid parent (aiNode::mParent is NULL) ", nodeName);
}
// validate all meshes
if (pNode->mNumMeshes)
{
if (!pNode->mMeshes)
{
ReportError("aiNode::mMeshes is NULL (aiNode::mNumMeshes is %i)",
pNode->mNumMeshes);
ReportError("aiNode::mMeshes is NULL for node %s (aiNode::mNumMeshes is %i)",
nodeName, pNode->mNumMeshes);
}
std::vector<bool> abHadMesh;
abHadMesh.resize(mScene->mNumMeshes,false);
@ -925,13 +937,13 @@ void ValidateDSProcess::Validate( const aiNode* pNode)
{
if (pNode->mMeshes[i] >= mScene->mNumMeshes)
{
ReportError("aiNode::mMeshes[%i] is out of range (maximum is %i)",
pNode->mMeshes[i],mScene->mNumMeshes-1);
ReportError("aiNode::mMeshes[%i] is out of range for node %s (maximum is %i)",
pNode->mMeshes[i], nodeName, mScene->mNumMeshes-1);
}
if (abHadMesh[pNode->mMeshes[i]])
{
ReportError("aiNode::mMeshes[%i] is already referenced by this node (value: %i)",
i,pNode->mMeshes[i]);
ReportError("aiNode::mMeshes[%i] is already referenced by this node %s (value: %i)",
i, nodeName, pNode->mMeshes[i]);
}
abHadMesh[pNode->mMeshes[i]] = true;
}
@ -939,8 +951,8 @@ void ValidateDSProcess::Validate( const aiNode* pNode)
if (pNode->mNumChildren)
{
if (!pNode->mChildren) {
ReportError("aiNode::mChildren is NULL (aiNode::mNumChildren is %i)",
pNode->mNumChildren);
ReportError("aiNode::mChildren is NULL for node %s (aiNode::mNumChildren is %i)",
nodeName, pNode->mNumChildren);
}
for (unsigned int i = 0; i < pNode->mNumChildren;++i) {
Validate(pNode->mChildren[i]);
@ -953,7 +965,7 @@ void ValidateDSProcess::Validate( const aiString* pString)
{
if (pString->length > MAXLEN)
{
this->ReportError("aiString::length is too large (%i, maximum is %lu)",
ReportError("aiString::length is too large (%lu, maximum is %lu)",
pString->length,MAXLEN);
}
const char* sz = pString->data;
@ -961,12 +973,14 @@ void ValidateDSProcess::Validate( const aiString* pString)
{
if ('\0' == *sz)
{
if (pString->length != (unsigned int)(sz-pString->data))
if (pString->length != (unsigned int)(sz-pString->data)) {
ReportError("aiString::data is invalid: the terminal zero is at a wrong offset");
}
break;
}
else if (sz >= &pString->data[MAXLEN])
else if (sz >= &pString->data[MAXLEN]) {
ReportError("aiString::data is invalid. There is no terminal character");
}
++sz;
}
}

View File

@ -36,3 +36,21 @@
# Temporary
*.swp
.DS_Store
# CMake
CMakeScripts
*.cmake
# Xcode
*.build
*.xcodeproj
zip.sln
zip.vcxproj.filters
zip.vcxproj
ALL_BUILD.vcxproj.filters
ALL_BUILD.vcxproj
CMakeFiles/
zip.dir/
test/test.exe.vcxproj.filters
test/test.exe.vcxproj
test/test.exe.dir/

View File

@ -0,0 +1,18 @@
#!/bin/bash
#
# Build script for travis-ci.org builds.
#
if [ $ANALYZE = "true" ] && [ "$CC" = "clang" ]; then
# scan-build -h
scan-build cmake -G "Unix Makefiles"
scan-build -enable-checker security.FloatLoopCounter \
-enable-checker security.insecureAPI.UncheckedReturn \
--status-bugs -v \
make -j 8 \
make -j 8 test
else
cmake -DCMAKE_BUILD_TYPE=Debug -DSANITIZE_ADDRESS=On -DCMAKE_INSTALL_PREFIX=_install
make -j 8
make install
ASAN_OPTIONS=detect_leaks=0 LSAN_OPTIONS=verbosity=1:log_threads=1 ctest -V
fi

View File

@ -1,10 +1,22 @@
language: c
addons:
apt:
packages: &1
- lcov
# Compiler selection
compiler:
- clang
- gcc
env:
- ANALYZE=false
- ANALYZE=true
# Build steps
script:
- mkdir build
- cd build
- cmake -DCMAKE_BUILD_TYPE=Debug .. && make && make test
- ./.travis.sh
after_success:
# Creating report
- cmake -DENABLE_COVERAGE=ON
- make
- make test
# Uploading report to CodeCov
- bash <(curl -s https://codecov.io/bash)

View File

@ -1,18 +1,47 @@
cmake_minimum_required(VERSION 2.8)
project(zip)
enable_language(C)
set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
if (MSVC)
# Use secure functions by defaualt and suppress warnings about "deprecated" functions
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT=1")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_NONSTDC_NO_WARNINGS=1 /D _CRT_SECURE_NO_WARNINGS=1")
# Use secure functions by defaualt and suppress warnings about "deprecated" functions
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES=1")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES_COUNT=1")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /D _CRT_NONSTDC_NO_WARNINGS=1 /D _CRT_SECURE_NO_WARNINGS=1")
elseif ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR
"${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR
"${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99 -Wall -Wextra -Werror -pedantic")
endif (MSVC)
# zip
set(SRC src/miniz.h src/zip.h src/zip.c)
add_library(${CMAKE_PROJECT_NAME} ${SRC})
add_library(${PROJECT_NAME} ${SRC})
target_include_directories(${PROJECT_NAME} INTERFACE src)
# test
enable_testing()
add_subdirectory(test)
if (NOT CMAKE_DISABLE_TESTING)
enable_testing()
add_subdirectory(test)
find_package(Sanitizers)
add_sanitizers(${PROJECT_NAME} test.exe)
add_sanitizers(${PROJECT_NAME} test_miniz.exe)
endif()
install(TARGETS ${PROJECT_NAME}
RUNTIME DESTINATION bin
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
COMPONENT library)
install(FILES ${PROJECT_SOURCE_DIR}/src/zip.h DESTINATION include)
# uninstall target (https://gitlab.kitware.com/cmake/community/wikis/FAQ#can-i-do-make-uninstall-with-cmake)
if(NOT TARGET uninstall)
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake"
IMMEDIATE @ONLY)
add_custom_target(uninstall
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake)
endif()

View File

@ -1,12 +1,11 @@
### A portable (OSX/Linux/Windows), simple zip library written in C
This is done by hacking awesome [miniz](https://code.google.com/p/miniz) library and layering functions on top of the miniz v1.15 API.
[![Windows][win-badge]][win-link] [![OS X][osx-linux-badge]][osx-linux-link]
[![Windows](https://ci.appveyor.com/api/projects/status/bph8dr3jacgmjv32/branch/master?svg=true&label=windows)](https://ci.appveyor.com/project/kuba--/zip)
[![Linux](https://travis-ci.org/kuba--/zip.svg?branch=master&label=linux%2fosx)](https://travis-ci.org/kuba--/zip)
[![Version](https://badge.fury.io/gh/kuba--%2Fzip.svg)](https://github.com/kuba--/zip/releases)
[![Codecov](https://codecov.io/gh/kuba--/zip/branch/master/graph/badge.svg)](https://codecov.io/gh/kuba--/zip)
[win-badge]: https://img.shields.io/appveyor/ci/kuba--/zip/master.svg?label=windows "AppVeyor build status"
[win-link]: https://ci.appveyor.com/project/kuba--/zip "AppVeyor build status"
[osx-linux-badge]: https://img.shields.io/travis/kuba--/zip/master.svg?label=linux/osx "Travis CI build status"
[osx-linux-link]: https://travis-ci.org/kuba--/zip "Travis CI build status"
# The Idea
<img src="zip.png" name="zip" />
@ -23,117 +22,288 @@ It was the reason, why I decided to write zip module on top of the miniz. It req
* Create a new zip archive with default compression level.
```c
struct zip_t *zip = zip_open("foo.zip", ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
struct zip_t *zip = zip_open("foo.zip", ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
{
zip_entry_open(zip, "foo-1.txt");
{
zip_entry_open(zip, "foo-1.txt");
{
char *buf = "Some data here...";
zip_entry_write(zip, buf, strlen(buf));
}
zip_entry_close(zip);
zip_entry_open(zip, "foo-2.txt");
{
// merge 3 files into one entry and compress them on-the-fly.
zip_entry_fwrite(zip, "foo-2.1.txt");
zip_entry_fwrite(zip, "foo-2.2.txt");
zip_entry_fwrite(zip, "foo-2.3.txt");
}
zip_entry_close(zip);
const char *buf = "Some data here...\0";
zip_entry_write(zip, buf, strlen(buf));
}
zip_close(zip);
zip_entry_close(zip);
zip_entry_open(zip, "foo-2.txt");
{
// merge 3 files into one entry and compress them on-the-fly.
zip_entry_fwrite(zip, "foo-2.1.txt");
zip_entry_fwrite(zip, "foo-2.2.txt");
zip_entry_fwrite(zip, "foo-2.3.txt");
}
zip_entry_close(zip);
}
zip_close(zip);
```
* Append to the existing zip archive.
```c
struct zip_t *zip = zip_open("foo.zip", ZIP_DEFAULT_COMPRESSION_LEVEL, 'a');
struct zip_t *zip = zip_open("foo.zip", ZIP_DEFAULT_COMPRESSION_LEVEL, 'a');
{
zip_entry_open(zip, "foo-3.txt");
{
zip_entry_open(zip, "foo-3.txt");
{
char *buf = "Append some data here...";
zip_entry_write(zip, buf, strlen(buf));
}
zip_entry_close(zip);
const char *buf = "Append some data here...\0";
zip_entry_write(zip, buf, strlen(buf));
}
zip_close(zip);
zip_entry_close(zip);
}
zip_close(zip);
```
* Extract a zip archive into a folder.
```c
int on_extract_entry(const char *filename, void *arg) {
static int i = 0;
int n = *(int *)arg;
printf("Extracted: %s (%d of %d)\n", filename, ++i, n);
int on_extract_entry(const char *filename, void *arg) {
static int i = 0;
int n = *(int *)arg;
printf("Extracted: %s (%d of %d)\n", filename, ++i, n);
return 0;
}
return 0;
}
int arg = 2;
zip_extract("foo.zip", "/tmp", on_extract_entry, &arg);
int arg = 2;
zip_extract("foo.zip", "/tmp", on_extract_entry, &arg);
```
* Extract a zip entry into memory.
* Extract a zip entry into memory.
```c
void *buf = NULL;
size_t bufsize;
void *buf = NULL;
size_t bufsize;
struct zip_t *zip = zip_open("foo.zip", 0, 'r');
struct zip_t *zip = zip_open("foo.zip", 0, 'r');
{
zip_entry_open(zip, "foo-1.txt");
{
zip_entry_open(zip, "foo-1.txt");
{
zip_entry_read(zip, &buf, &bufsize);
}
zip_entry_close(zip);
zip_entry_read(zip, &buf, &bufsize);
}
zip_close(zip);
zip_entry_close(zip);
}
zip_close(zip);
free(buf);
free(buf);
```
* Extract a zip entry into memory using callback.
* Extract a zip entry into memory (no internal allocation).
```c
struct buffer_t {
char *data;
size_t size;
};
unsigned char *buf;
size_t bufsize;
static size_t on_extract(void *arg, unsigned long long offset, const void *data, size_t size) {
struct buffer_t *buf = (struct buffer_t *)arg;
buf->data = realloc(buf->data, buf->size + size + 1);
assert(NULL != buf->data);
memcpy(&(buf->data[buf->size]), data, size);
buf->size += size;
buf->data[buf->size] = 0;
return size;
}
struct buffer_t buf = {0};
struct zip_t *zip = zip_open("foo.zip", 0, 'r');
struct zip_t *zip = zip_open("foo.zip", 0, 'r');
{
zip_entry_open(zip, "foo-1.txt");
{
zip_entry_open(zip, "foo-1.txt");
{
zip_entry_extract(zip, on_extract, &buf);
}
zip_entry_close(zip);
}
zip_close(zip);
bufsize = zip_entry_size(zip);
buf = calloc(sizeof(unsigned char), bufsize);
free(buf.data);
zip_entry_noallocread(zip, (void *)buf, bufsize);
}
zip_entry_close(zip);
}
zip_close(zip);
free(buf);
```
* Extract a zip entry into a file.
* Extract a zip entry into memory using callback.
```c
struct zip_t *zip = zip_open("foo.zip", 0, 'r');
struct buffer_t {
char *data;
size_t size;
};
static size_t on_extract(void *arg, unsigned long long offset, const void *data, size_t size) {
struct buffer_t *buf = (struct buffer_t *)arg;
buf->data = realloc(buf->data, buf->size + size + 1);
assert(NULL != buf->data);
memcpy(&(buf->data[buf->size]), data, size);
buf->size += size;
buf->data[buf->size] = 0;
return size;
}
struct buffer_t buf = {0};
struct zip_t *zip = zip_open("foo.zip", 0, 'r');
{
zip_entry_open(zip, "foo-1.txt");
{
zip_entry_open(zip, "foo-2.txt");
{
zip_entry_fread(zip, "foo-2.txt");
}
zip_entry_close(zip);
zip_entry_extract(zip, on_extract, &buf);
}
zip_close(zip);
zip_entry_close(zip);
}
zip_close(zip);
free(buf.data);
```
* Extract a zip entry into a file.
```c
struct zip_t *zip = zip_open("foo.zip", 0, 'r');
{
zip_entry_open(zip, "foo-2.txt");
{
zip_entry_fread(zip, "foo-2.txt");
}
zip_entry_close(zip);
}
zip_close(zip);
```
* List of all zip entries
```c
struct zip_t *zip = zip_open("foo.zip", 0, 'r');
int i, n = zip_total_entries(zip);
for (i = 0; i < n; ++i) {
zip_entry_openbyindex(zip, i);
{
const char *name = zip_entry_name(zip);
int isdir = zip_entry_isdir(zip);
unsigned long long size = zip_entry_size(zip);
unsigned int crc32 = zip_entry_crc32(zip);
}
zip_entry_close(zip);
}
zip_close(zip);
```
## Bindings
Compile zip library as a dynamic library.
```shell
$ mkdir build
$ cd build
$ cmake -DBUILD_SHARED_LIBS=true ..
$ make
```
### Go (cgo)
```go
package main
/*
#cgo CFLAGS: -I../src
#cgo LDFLAGS: -L. -lzip
#include <zip.h>
*/
import "C"
import "unsafe"
func main() {
path := C.CString("/tmp/go.zip")
zip := C.zip_open(path, 6, 'w')
entryname := C.CString("test")
C.zip_entry_open(zip, entryname)
content := "test content"
buf := unsafe.Pointer(C.CString(content))
bufsize := C.size_t(len(content))
C.zip_entry_write(zip, buf, bufsize)
C.zip_entry_close(zip)
C.zip_close(zip)
}
```
### Ruby (ffi)
Install _ffi_ gem.
```shell
$ gem install ffi
```
Bind in your module.
```ruby
require 'ffi'
module Zip
extend FFI::Library
ffi_lib "./libzip.#{::FFI::Platform::LIBSUFFIX}"
attach_function :zip_open, [:string, :int, :char], :pointer
attach_function :zip_close, [:pointer], :void
attach_function :zip_entry_open, [:pointer, :string], :int
attach_function :zip_entry_close, [:pointer], :void
attach_function :zip_entry_write, [:pointer, :string, :int], :int
end
ptr = Zip.zip_open("/tmp/ruby.zip", 6, "w".bytes()[0])
status = Zip.zip_entry_open(ptr, "test")
content = "test content"
status = Zip.zip_entry_write(ptr, content, content.size())
Zip.zip_entry_close(ptr)
Zip.zip_close(ptr)
```
### Python (cffi)
Install _cffi_ package
```shell
$ pip install cffi
```
Bind in your package.
```python
import ctypes.util
from cffi import FFI
ffi = FFI()
ffi.cdef("""
struct zip_t *zip_open(const char *zipname, int level, char mode);
void zip_close(struct zip_t *zip);
int zip_entry_open(struct zip_t *zip, const char *entryname);
int zip_entry_close(struct zip_t *zip);
int zip_entry_write(struct zip_t *zip, const void *buf, size_t bufsize);
""")
Zip = ffi.dlopen(ctypes.util.find_library("zip"))
ptr = Zip.zip_open("/tmp/python.zip", 6, 'w')
status = Zip.zip_entry_open(ptr, "test")
content = "test content"
status = Zip.zip_entry_write(ptr, content, len(content))
Zip.zip_entry_close(ptr)
Zip.zip_close(ptr)
```
### Ring
The language comes with RingZip based on this library
```ring
load "ziplib.ring"
new Zip {
setFileName("myfile.zip")
open("w")
newEntry() {
open("test.c")
writefile("test.c")
close()
}
close()
}
```
# Contribution Rules/Coding Standards
No need to throw away your coding style, just do your best to follow default clang-format style.
Apply `clang-format` to the source files before commit:
```sh
for file in $(git ls-files | \grep -E '\.(c|h)$' | \grep -v -- '#')
do
clang-format -i $file
done
```

View File

@ -1,4 +1,4 @@
version: 1.0.{build}
version: zip-0.1.9.{build}
build_script:
- cmd: >-
cd c:\projects\zip

View File

@ -0,0 +1,55 @@
#!/bin/sh
# The MIT License (MIT)
#
# Copyright (c)
# 2013 Matthew Arsenault
# 2015-2016 RWTH Aachen University, Federal Republic of Germany
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# 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 AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
# This script is a wrapper for AddressSanitizer. In some special cases you need
# to preload AddressSanitizer to avoid error messages - e.g. if you're
# preloading another library to your application. At the moment this script will
# only do something, if we're running on a Linux platform. OSX might not be
# affected.
# Exit immediately, if platform is not Linux.
if [ "$(uname)" != "Linux" ]
then
exec $@
fi
# Get the used libasan of the application ($1). If a libasan was found, it will
# be prepended to LD_PRELOAD.
libasan=$(ldd $1 | grep libasan | sed "s/^[[:space:]]//" | cut -d' ' -f1)
if [ -n "$libasan" ]
then
if [ -n "$LD_PRELOAD" ]
then
export LD_PRELOAD="$libasan:$LD_PRELOAD"
else
export LD_PRELOAD="$libasan"
fi
fi
# Execute the application.
exec $@

View File

@ -0,0 +1,23 @@
# copied from https://gitlab.kitware.com/cmake/community/wikis/FAQ#can-i-do-make-uninstall-with-cmake
if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt")
endif(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files)
string(REGEX REPLACE "\n" ";" files "${files}")
foreach(file ${files})
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
exec_program(
"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
OUTPUT_VARIABLE rm_out
RETURN_VALUE rm_retval
)
if(NOT "${rm_retval}" STREQUAL 0)
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
endif(NOT "${rm_retval}" STREQUAL 0)
else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
endforeach(file)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -13,11 +13,24 @@
#define ZIP_H
#include <string.h>
#include <sys/types.h>
#ifdef __cplusplus
extern "C" {
#endif
#if !defined(_SSIZE_T_DEFINED) && !defined(_SSIZE_T_DEFINED_) && \
!defined(_SSIZE_T) && !defined(_SSIZE_T_) && !defined(__ssize_t_defined)
#define _SSIZE_T
// 64-bit Windows is the only mainstream platform
// where sizeof(long) != sizeof(void*)
#ifdef _WIN64
typedef long long ssize_t; /* byte count or error */
#else
typedef long ssize_t; /* byte count or error */
#endif
#endif
#ifndef MAX_PATH
#define MAX_PATH 32767 /* # chars in a path name including NULL */
#endif
@ -47,7 +60,7 @@ struct zip_t;
extern struct zip_t *zip_open(const char *zipname, int level, char mode);
/*
Closes zip archive, releases resources - always finalize.
Closes the zip archive, releases resources - always finalize.
Args:
zip: zip archive handler.
@ -55,7 +68,10 @@ extern struct zip_t *zip_open(const char *zipname, int level, char mode);
extern void zip_close(struct zip_t *zip);
/*
Opens a new entry for writing in a zip archive.
Opens an entry by name in the zip archive.
For zip archive opened in 'w' or 'a' mode the function will append
a new entry. In readonly mode the function tries to locate the entry
in global dictionary.
Args:
zip: zip archive handler.
@ -66,6 +82,19 @@ extern void zip_close(struct zip_t *zip);
*/
extern int zip_entry_open(struct zip_t *zip, const char *entryname);
/*
Opens a new entry by index in the zip archive.
This function is only valid if zip archive was opened in 'r' (readonly) mode.
Args:
zip: zip archive handler.
index: index in local dictionary.
Returns:
The return code - 0 on success, negative number (< 0) on error.
*/
extern int zip_entry_openbyindex(struct zip_t *zip, int index);
/*
Closes a zip entry, flushes buffer and releases resources.
@ -77,6 +106,67 @@ extern int zip_entry_open(struct zip_t *zip, const char *entryname);
*/
extern int zip_entry_close(struct zip_t *zip);
/*
Returns a local name of the current zip entry.
The main difference between user's entry name and local entry name
is optional relative path.
Following .ZIP File Format Specification - the path stored MUST not contain
a drive or device letter, or a leading slash.
All slashes MUST be forward slashes '/' as opposed to backwards slashes '\'
for compatibility with Amiga and UNIX file systems etc.
Args:
zip: zip archive handler.
Returns:
The pointer to the current zip entry name, or NULL on error.
*/
extern const char *zip_entry_name(struct zip_t *zip);
/*
Returns an index of the current zip entry.
Args:
zip: zip archive handler.
Returns:
The index on success, negative number (< 0) on error.
*/
extern int zip_entry_index(struct zip_t *zip);
/*
Determines if the current zip entry is a directory entry.
Args:
zip: zip archive handler.
Returns:
The return code - 1 (true), 0 (false), negative number (< 0) on error.
*/
extern int zip_entry_isdir(struct zip_t *zip);
/*
Returns an uncompressed size of the current zip entry.
Args:
zip: zip archive handler.
Returns:
The uncompressed size in bytes.
*/
extern unsigned long long zip_entry_size(struct zip_t *zip);
/*
Returns CRC-32 checksum of the current zip entry.
Args:
zip: zip archive handler.
Returns:
The CRC-32 checksum.
*/
extern unsigned int zip_entry_crc32(struct zip_t *zip);
/*
Compresses an input buffer for the current zip entry.
@ -116,9 +206,31 @@ extern int zip_entry_fwrite(struct zip_t *zip, const char *filename);
- for large entries, please take a look at zip_entry_extract function.
Returns:
The return code - 0 on success, negative number (< 0) on error.
The return code - the number of bytes actually read on success.
Otherwise a -1 on error.
*/
extern int zip_entry_read(struct zip_t *zip, void **buf, size_t *bufsize);
extern ssize_t zip_entry_read(struct zip_t *zip, void **buf, size_t *bufsize);
/*
Extracts the current zip entry into a memory buffer using no memory
allocation.
Args:
zip: zip archive handler.
buf: preallocated output buffer.
bufsize: output buffer size (in bytes).
Note:
- ensure supplied output buffer is large enough.
- zip_entry_size function (returns uncompressed size for the current entry)
can be handy to estimate how big buffer is needed.
- for large entries, please take a look at zip_entry_extract function.
Returns:
The return code - the number of bytes actually read on success.
Otherwise a -1 on error (e.g. bufsize is not large enough).
*/
extern ssize_t zip_entry_noallocread(struct zip_t *zip, void *buf, size_t bufsize);
/*
Extracts the current zip entry into output file.
@ -133,9 +245,9 @@ extern int zip_entry_read(struct zip_t *zip, void **buf, size_t *bufsize);
extern int zip_entry_fread(struct zip_t *zip, const char *filename);
/*
Extract the current zip entry using a callback function (on_extract).
Extracts the current zip entry using a callback function (on_extract).
Args:
Args:
zip: zip archive handler.
on_extract: callback function.
arg: opaque pointer (optional argument,
@ -144,12 +256,23 @@ extern int zip_entry_fread(struct zip_t *zip, const char *filename);
Returns:
The return code - 0 on success, negative number (< 0) on error.
*/
extern int zip_entry_extract(struct zip_t *zip,
size_t (*on_extract)(void *arg,
unsigned long long offset,
const void *data,
size_t size),
void *arg);
extern int
zip_entry_extract(struct zip_t *zip,
size_t (*on_extract)(void *arg, unsigned long long offset,
const void *data, size_t size),
void *arg);
/*
Returns the number of all entries (files and directories) in the zip archive.
Args:
zip: zip archive handler.
Returns:
The return code - the number of entries on success,
negative number (< 0) on error.
*/
extern int zip_total_entries(struct zip_t *zip);
/*
Creates a new archive and puts files into a single zip archive.

View File

@ -1,7 +1,19 @@
cmake_minimum_required(VERSION 2.8)
if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_C_COMPILER_ID}" STREQUAL "AppleClang")
if(ENABLE_COVERAGE)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -g ")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ftest-coverage")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage")
endif()
endif ()
# test
include_directories(../src)
add_executable(test.exe test.c ../src/zip.c)
add_executable(test_miniz.exe test_miniz.c)
add_test(NAME test COMMAND test.exe)
add_test(NAME test_miniz COMMAND test_miniz.exe)

View File

@ -4,102 +4,456 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#define ZIPNAME "test.zip"
#if defined(_MSC_VER) || defined(__MINGW64__) || defined(__MINGW32__)
#define MZ_FILE_STAT_STRUCT _stat
#define MZ_FILE_STAT _stat
#else
#define MZ_FILE_STAT_STRUCT stat
#define MZ_FILE_STAT stat
#endif
#define ZIPNAME "test.zip\0"
#define TESTDATA1 "Some test data 1...\0"
#define CRC32DATA1 2220805626
#define TESTDATA2 "Some test data 2...\0"
#define CRC32DATA2 2532008468
#define RFILE "4.txt\0"
#define RMODE 0100444
#define WFILE "6.txt\0"
#define WMODE 0100666
#define XFILE "7.txt\0"
#define XMODE 0100777
#define UNUSED(x) (void)x
static int total_entries = 0;
static void test_write(void) {
struct zip_t *zip = zip_open(ZIPNAME, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
assert(zip != NULL);
struct zip_t *zip = zip_open(ZIPNAME, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
assert(zip != NULL);
assert(0 == zip_entry_open(zip, "test/test-1.txt"));
assert(0 == zip_entry_write(zip, TESTDATA1, strlen(TESTDATA1)));
assert(0 == zip_entry_close(zip));
assert(0 == zip_entry_open(zip, "test/test-1.txt"));
assert(0 == zip_entry_write(zip, TESTDATA1, strlen(TESTDATA1)));
assert(0 == strcmp(zip_entry_name(zip), "test/test-1.txt"));
assert(total_entries == zip_entry_index(zip));
assert(strlen(TESTDATA1) == zip_entry_size(zip));
assert(CRC32DATA1 == zip_entry_crc32(zip));
++total_entries;
assert(0 == zip_entry_close(zip));
zip_close(zip);
zip_close(zip);
}
static void test_append(void) {
struct zip_t *zip = zip_open(ZIPNAME, ZIP_DEFAULT_COMPRESSION_LEVEL, 'a');
assert(zip != NULL);
struct zip_t *zip = zip_open(ZIPNAME, ZIP_DEFAULT_COMPRESSION_LEVEL, 'a');
assert(zip != NULL);
assert(0 == zip_entry_open(zip, "test\\test-2.txt"));
assert(0 == zip_entry_write(zip, TESTDATA2, strlen(TESTDATA2)));
assert(0 == zip_entry_close(zip));
assert(0 == zip_entry_open(zip, "test\\test-2.txt"));
assert(0 == strcmp(zip_entry_name(zip), "test/test-2.txt"));
assert(total_entries == zip_entry_index(zip));
assert(0 == zip_entry_write(zip, TESTDATA2, strlen(TESTDATA2)));
assert(strlen(TESTDATA2) == zip_entry_size(zip));
assert(CRC32DATA2 == zip_entry_crc32(zip));
zip_close(zip);
++total_entries;
assert(0 == zip_entry_close(zip));
assert(0 == zip_entry_open(zip, "test\\empty/"));
assert(0 == strcmp(zip_entry_name(zip), "test/empty/"));
assert(0 == zip_entry_size(zip));
assert(0 == zip_entry_crc32(zip));
assert(total_entries == zip_entry_index(zip));
++total_entries;
assert(0 == zip_entry_close(zip));
assert(0 == zip_entry_open(zip, "empty/"));
assert(0 == strcmp(zip_entry_name(zip), "empty/"));
assert(0 == zip_entry_size(zip));
assert(0 == zip_entry_crc32(zip));
assert(total_entries == zip_entry_index(zip));
++total_entries;
assert(0 == zip_entry_close(zip));
zip_close(zip);
}
static void test_read(void) {
char *buf = NULL;
size_t bufsize;
struct zip_t *zip = zip_open(ZIPNAME, 0, 'r');
assert(zip != NULL);
char *buf = NULL;
ssize_t bufsize;
size_t buftmp;
struct zip_t *zip = zip_open(ZIPNAME, 0, 'r');
assert(zip != NULL);
assert(0 == zip_entry_open(zip, "test\\test-1.txt"));
assert(0 == zip_entry_read(zip, (void **)&buf, &bufsize));
assert(bufsize == strlen(TESTDATA1));
assert(0 == strncmp(buf, TESTDATA1, bufsize));
assert(0 == zip_entry_close(zip));
free(buf);
buf = NULL;
bufsize = 0;
assert(0 == zip_entry_open(zip, "test\\test-1.txt"));
assert(strlen(TESTDATA1) == zip_entry_size(zip));
assert(CRC32DATA1 == zip_entry_crc32(zip));
assert(0 == zip_entry_open(zip, "test/test-2.txt"));
assert(0 == zip_entry_read(zip, (void **)&buf, &bufsize));
assert(bufsize == strlen(TESTDATA2));
assert(0 == strncmp(buf, TESTDATA2, bufsize));
assert(0 == zip_entry_close(zip));
free(buf);
buf = NULL;
bufsize = 0;
bufsize = zip_entry_read(zip, (void **)&buf, &buftmp);
assert(bufsize == strlen(TESTDATA1));
assert((size_t)bufsize == buftmp);
assert(0 == strncmp(buf, TESTDATA1, bufsize));
assert(0 == zip_entry_close(zip));
free(buf);
buf = NULL;
assert(0 == zip_entry_open(zip, "test/test-2.txt"));
assert(strlen(TESTDATA2) == zip_entry_size(zip));
assert(CRC32DATA2 == zip_entry_crc32(zip));
zip_close(zip);
bufsize = zip_entry_read(zip, (void **)&buf, NULL);
assert((size_t)bufsize == strlen(TESTDATA2));
assert(0 == strncmp(buf, TESTDATA2, (size_t)bufsize));
assert(0 == zip_entry_close(zip));
free(buf);
buf = NULL;
bufsize = 0;
assert(0 == zip_entry_open(zip, "test\\empty/"));
assert(0 == strcmp(zip_entry_name(zip), "test/empty/"));
assert(0 == zip_entry_size(zip));
assert(0 == zip_entry_crc32(zip));
assert(0 == zip_entry_close(zip));
buftmp = strlen(TESTDATA2);
buf = calloc(buftmp, sizeof(char));
assert(0 == zip_entry_open(zip, "test/test-2.txt"));
bufsize = zip_entry_noallocread(zip, (void *)buf, buftmp);
assert(buftmp == (size_t)bufsize);
assert(0 == strncmp(buf, TESTDATA2, buftmp));
assert(0 == zip_entry_close(zip));
free(buf);
buf = NULL;
buftmp = strlen(TESTDATA1);
buf = calloc(buftmp, sizeof(char));
assert(0 == zip_entry_open(zip, "test/test-1.txt"));
bufsize = zip_entry_noallocread(zip, (void *)buf, buftmp);
assert(buftmp == (size_t)bufsize);
assert(0 == strncmp(buf, TESTDATA1, buftmp));
assert(0 == zip_entry_close(zip));
free(buf);
buf = NULL;
bufsize = 0;
zip_close(zip);
}
struct buffer_t {
char *data;
size_t size;
char *data;
size_t size;
};
static size_t on_extract(void *arg, unsigned long long offset, const void *data,
size_t size) {
struct buffer_t *buf = (struct buffer_t *)arg;
buf->data = realloc(buf->data, buf->size + size + 1);
assert(NULL != buf->data);
UNUSED(offset);
memcpy(&(buf->data[buf->size]), data, size);
buf->size += size;
buf->data[buf->size] = 0;
struct buffer_t *buf = (struct buffer_t *)arg;
buf->data = realloc(buf->data, buf->size + size + 1);
assert(NULL != buf->data);
return size;
memcpy(&(buf->data[buf->size]), data, size);
buf->size += size;
buf->data[buf->size] = 0;
return size;
}
static void test_extract(void) {
struct buffer_t buf = {0};
struct buffer_t buf;
struct zip_t *zip = zip_open(ZIPNAME, 0, 'r');
assert(zip != NULL);
struct zip_t *zip = zip_open(ZIPNAME, 0, 'r');
assert(zip != NULL);
memset((void *)&buf, 0, sizeof(struct buffer_t));
assert(0 == zip_entry_open(zip, "test/test-1.txt"));
assert(0 == zip_entry_extract(zip, on_extract, &buf));
assert(0 == zip_entry_open(zip, "test/test-1.txt"));
assert(0 == zip_entry_extract(zip, on_extract, &buf));
assert(buf.size == strlen(TESTDATA1));
assert(0 == strncmp(buf.data, TESTDATA1, buf.size));
assert(buf.size == strlen(TESTDATA1));
assert(0 == strncmp(buf.data, TESTDATA1, buf.size));
assert(0 == zip_entry_close(zip));
free(buf.data);
buf.data = NULL;
buf.size = 0;
zip_close(zip);
}
static void test_total_entries(void) {
struct zip_t *zip = zip_open(ZIPNAME, 0, 'r');
assert(zip != NULL);
int n = zip_total_entries(zip);
zip_close(zip);
assert(n == total_entries);
}
static void test_entry_name(void) {
struct zip_t *zip = zip_open(ZIPNAME, 0, 'r');
assert(zip != NULL);
assert(zip_entry_name(zip) == NULL);
assert(0 == zip_entry_open(zip, "test\\test-1.txt"));
assert(NULL != zip_entry_name(zip));
assert(0 == strcmp(zip_entry_name(zip), "test/test-1.txt"));
assert(strlen(TESTDATA1) == zip_entry_size(zip));
assert(CRC32DATA1 == zip_entry_crc32(zip));
assert(0 == zip_entry_index(zip));
assert(0 == zip_entry_close(zip));
assert(0 == zip_entry_open(zip, "test/test-2.txt"));
assert(NULL != zip_entry_name(zip));
assert(0 == strcmp(zip_entry_name(zip), "test/test-2.txt"));
assert(strlen(TESTDATA2) == zip_entry_size(zip));
assert(CRC32DATA2 == zip_entry_crc32(zip));
assert(1 == zip_entry_index(zip));
assert(0 == zip_entry_close(zip));
zip_close(zip);
}
static void test_entry_index(void) {
struct zip_t *zip = zip_open(ZIPNAME, 0, 'r');
assert(zip != NULL);
assert(0 == zip_entry_open(zip, "test\\test-1.txt"));
assert(0 == zip_entry_index(zip));
assert(0 == strcmp(zip_entry_name(zip), "test/test-1.txt"));
assert(strlen(TESTDATA1) == zip_entry_size(zip));
assert(CRC32DATA1 == zip_entry_crc32(zip));
assert(0 == zip_entry_close(zip));
assert(0 == zip_entry_open(zip, "test/test-2.txt"));
assert(1 == zip_entry_index(zip));
assert(0 == strcmp(zip_entry_name(zip), "test/test-2.txt"));
assert(strlen(TESTDATA2) == zip_entry_size(zip));
assert(CRC32DATA2 == zip_entry_crc32(zip));
assert(0 == zip_entry_close(zip));
zip_close(zip);
}
static void test_entry_openbyindex(void) {
struct zip_t *zip = zip_open(ZIPNAME, 0, 'r');
assert(zip != NULL);
assert(0 == zip_entry_openbyindex(zip, 1));
assert(1 == zip_entry_index(zip));
assert(strlen(TESTDATA2) == zip_entry_size(zip));
assert(CRC32DATA2 == zip_entry_crc32(zip));
assert(0 == strcmp(zip_entry_name(zip), "test/test-2.txt"));
assert(0 == zip_entry_close(zip));
assert(0 == zip_entry_openbyindex(zip, 0));
assert(0 == zip_entry_index(zip));
assert(strlen(TESTDATA1) == zip_entry_size(zip));
assert(CRC32DATA1 == zip_entry_crc32(zip));
assert(0 == strcmp(zip_entry_name(zip), "test/test-1.txt"));
assert(0 == zip_entry_close(zip));
zip_close(zip);
}
static void test_list_entries(void) {
struct zip_t *zip = zip_open(ZIPNAME, 0, 'r');
assert(zip != NULL);
int i = 0, n = zip_total_entries(zip);
for (; i < n; ++i) {
assert(0 == zip_entry_openbyindex(zip, i));
fprintf(stdout, "[%d]: %s", i, zip_entry_name(zip));
if (zip_entry_isdir(zip)) {
fprintf(stdout, " (DIR)");
}
fprintf(stdout, "\n");
assert(0 == zip_entry_close(zip));
free(buf.data);
buf.data = NULL;
buf.size = 0;
}
zip_close(zip);
zip_close(zip);
}
static void test_fwrite(void) {
const char *filename = WFILE;
FILE *stream = NULL;
struct zip_t *zip = NULL;
#if defined(_MSC_VER)
if (0 != fopen_s(&stream, filename, "w+"))
#else
if (!(stream = fopen(filename, "w+")))
#endif
{
// Cannot open filename
fprintf(stdout, "Cannot open filename\n");
assert(0 == -1);
}
fwrite(TESTDATA1, sizeof(char), strlen(TESTDATA1), stream);
assert(0 == fclose(stream));
zip = zip_open(ZIPNAME, 9, 'w');
assert(zip != NULL);
assert(0 == zip_entry_open(zip, WFILE));
assert(0 == zip_entry_fwrite(zip, WFILE));
assert(0 == zip_entry_close(zip));
zip_close(zip);
remove(WFILE);
remove(ZIPNAME);
}
static void test_exe_permissions(void) {
#if defined(_WIN32) || defined(__WIN32__)
#else
struct MZ_FILE_STAT_STRUCT file_stats;
const char *filenames[] = {XFILE};
FILE *f = fopen(XFILE, "w");
fclose(f);
chmod(XFILE, XMODE);
remove(ZIPNAME);
assert(0 == zip_create(ZIPNAME, filenames, 1));
remove(XFILE);
assert(0 == zip_extract(ZIPNAME, ".", NULL, NULL));
assert(0 == MZ_FILE_STAT(XFILE, &file_stats));
assert(XMODE == file_stats.st_mode);
remove(XFILE);
remove(ZIPNAME);
#endif
}
static void test_read_permissions(void) {
#if defined(_MSC_VER)
#else
struct MZ_FILE_STAT_STRUCT file_stats;
const char *filenames[] = {RFILE};
FILE *f = fopen(RFILE, "w");
fclose(f);
chmod(RFILE, RMODE);
remove(ZIPNAME);
assert(0 == zip_create(ZIPNAME, filenames, 1));
// chmod from 444 to 666 to be able delete the file on windows
chmod(RFILE, WMODE);
remove(RFILE);
assert(0 == zip_extract(ZIPNAME, ".", NULL, NULL));
assert(0 == MZ_FILE_STAT(RFILE, &file_stats));
assert(RMODE == file_stats.st_mode);
chmod(RFILE, WMODE);
remove(RFILE);
remove(ZIPNAME);
#endif
}
static void test_write_permissions(void) {
#if defined(_MSC_VER)
#else
struct MZ_FILE_STAT_STRUCT file_stats;
const char *filenames[] = {WFILE};
FILE *f = fopen(WFILE, "w");
fclose(f);
chmod(WFILE, WMODE);
remove(ZIPNAME);
assert(0 == zip_create(ZIPNAME, filenames, 1));
remove(WFILE);
assert(0 == zip_extract(ZIPNAME, ".", NULL, NULL));
assert(0 == MZ_FILE_STAT(WFILE, &file_stats));
assert(WMODE == file_stats.st_mode);
remove(WFILE);
remove(ZIPNAME);
#endif
}
static void test_mtime(void) {
struct MZ_FILE_STAT_STRUCT file_stat1, file_stat2;
const char *filename = WFILE;
FILE *stream = NULL;
struct zip_t *zip = NULL;
#if defined(_MSC_VER)
if (0 != fopen_s(&stream, filename, "w+"))
#else
if (!(stream = fopen(filename, "w+")))
#endif
{
// Cannot open filename
fprintf(stdout, "Cannot open filename\n");
assert(0 == -1);
}
fwrite(TESTDATA1, sizeof(char), strlen(TESTDATA1), stream);
assert(0 == fclose(stream));
memset(&file_stat1, 0, sizeof(file_stat1));
memset(&file_stat2, 0, sizeof(file_stat2));
zip = zip_open(ZIPNAME, ZIP_DEFAULT_COMPRESSION_LEVEL, 'w');
assert(zip != NULL);
assert(0 == zip_entry_open(zip, filename));
assert(0 == zip_entry_fwrite(zip, filename));
assert(0 == zip_entry_close(zip));
zip_close(zip);
assert(0 == MZ_FILE_STAT(filename, &file_stat1));
remove(filename);
assert(0 == zip_extract(ZIPNAME, ".", NULL, NULL));
assert(0 == MZ_FILE_STAT(filename, &file_stat2));
fprintf(stdout, "file_stat1.st_mtime: %lu\n", file_stat1.st_mtime);
fprintf(stdout, "file_stat2.st_mtime: %lu\n", file_stat2.st_mtime);
assert(labs(file_stat1.st_mtime - file_stat2.st_mtime) <= 1);
remove(filename);
remove(ZIPNAME);
}
int main(int argc, char *argv[]) {
test_write();
test_append();
test_read();
test_extract();
UNUSED(argc);
UNUSED(argv);
return remove(ZIPNAME);
remove(ZIPNAME);
test_write();
test_append();
test_read();
test_extract();
test_total_entries();
test_entry_name();
test_entry_index();
test_entry_openbyindex();
test_list_entries();
test_fwrite();
test_read_permissions();
test_write_permissions();
test_exe_permissions();
test_mtime();
remove(ZIPNAME);
return 0;
}

View File

@ -0,0 +1,104 @@
// Demonstrates miniz.c's compress() and uncompress() functions
// (same as zlib's). Public domain, May 15 2011, Rich Geldreich,
// richgel99@gmail.com. See "unlicense" statement at the end of tinfl.c.
#include <miniz.h>
#include <stdio.h>
typedef unsigned char uint8;
typedef unsigned short uint16;
typedef unsigned int uint;
// The string to compress.
static const char *s_pStr =
"Good morning Dr. Chandra. This is Hal. I am ready for my first lesson."
"Good morning Dr. Chandra. This is Hal. I am ready for my first lesson."
"Good morning Dr. Chandra. This is Hal. I am ready for my first lesson."
"Good morning Dr. Chandra. This is Hal. I am ready for my first lesson."
"Good morning Dr. Chandra. This is Hal. I am ready for my first lesson."
"Good morning Dr. Chandra. This is Hal. I am ready for my first lesson."
"Good morning Dr. Chandra. This is Hal. I am ready for my first lesson.";
int main(int argc, char *argv[]) {
uint step = 0;
int cmp_status;
uLong src_len = (uLong)strlen(s_pStr);
uLong cmp_len = compressBound(src_len);
uLong uncomp_len = src_len;
uint8 *pCmp, *pUncomp;
uint total_succeeded = 0;
(void)argc, (void)argv;
printf("miniz.c version: %s\n", MZ_VERSION);
do {
// Allocate buffers to hold compressed and uncompressed data.
pCmp = (mz_uint8 *)malloc((size_t)cmp_len);
pUncomp = (mz_uint8 *)malloc((size_t)src_len);
if ((!pCmp) || (!pUncomp)) {
printf("Out of memory!\n");
return EXIT_FAILURE;
}
// Compress the string.
cmp_status =
compress(pCmp, &cmp_len, (const unsigned char *)s_pStr, src_len);
if (cmp_status != Z_OK) {
printf("compress() failed!\n");
free(pCmp);
free(pUncomp);
return EXIT_FAILURE;
}
printf("Compressed from %u to %u bytes\n", (mz_uint32)src_len,
(mz_uint32)cmp_len);
if (step) {
// Purposely corrupt the compressed data if fuzzy testing (this is a
// very crude fuzzy test).
uint n = 1 + (rand() % 3);
while (n--) {
uint i = rand() % cmp_len;
pCmp[i] ^= (rand() & 0xFF);
}
}
// Decompress.
cmp_status = uncompress(pUncomp, &uncomp_len, pCmp, cmp_len);
total_succeeded += (cmp_status == Z_OK);
if (step) {
printf("Simple fuzzy test: step %u total_succeeded: %u\n", step,
total_succeeded);
} else {
if (cmp_status != Z_OK) {
printf("uncompress failed!\n");
free(pCmp);
free(pUncomp);
return EXIT_FAILURE;
}
printf("Decompressed from %u to %u bytes\n", (mz_uint32)cmp_len,
(mz_uint32)uncomp_len);
// Ensure uncompress() returned the expected data.
if ((uncomp_len != src_len) ||
(memcmp(pUncomp, s_pStr, (size_t)src_len))) {
printf("Decompression failed!\n");
free(pCmp);
free(pUncomp);
return EXIT_FAILURE;
}
}
free(pCmp);
free(pUncomp);
step++;
// Keep on fuzzy testing if there's a non-empty command line.
} while (argc >= 2);
printf("Success.\n");
return EXIT_SUCCESS;
}

View File

@ -1173,6 +1173,18 @@ float4 PimpMyPixel (float4 prev)
@endcode
@section shdacc How to access shader-code from a texture (AI_MATKEY_GLOBAL_SHADERLANG and AI_MATKEY_SHADER_VERTEX, ...)
You can get assigned shader sources by using the following material keys:
<li>AI_MATKEY_GLOBAL_SHADERLANG</li>To get the used shader language.
<li>AI_MATKEY_SHADER_VERTEX</li> Assigned vertex shader code stored as a string.
<li>AI_MATKEY_SHADER_FRAGMENT</li> Assigned fragment shader code stored as a string.
<li>AI_MATKEY_SHADER_GEO</li> Assigned geometry shader code stored as a string.
<li>AI_MATKEY_SHADER_TESSELATION</li> Assigned tesselation shader code stored as a string.
<li>AI_MATKEY_SHADER_PRIMITIVE</li> Assigned primitive shader code stored as a string.
<li>AI_MATKEY_SHADER_COMPUTE</li> Assigned compute shader code stored as a string.
*/

View File

@ -198,8 +198,6 @@ enum aiTextureType
*/
aiTextureType_NONE = 0x0,
/** The texture is combined with the result of the diffuse
* lighting equation.
*/
@ -278,7 +276,7 @@ enum aiTextureType
*
* 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.
* but is excluded from any further post-processing.
*/
aiTextureType_UNKNOWN = 0xC,
@ -375,7 +373,7 @@ enum aiShadingMode
*/
enum aiTextureFlags
{
/** The texture's color values have to be inverted (componentwise 1-n)
/** The texture's color values have to be inverted (component-wise 1-n)
*/
aiTextureFlags_Invert = 0x1,
@ -914,6 +912,13 @@ extern "C" {
#define AI_MATKEY_COLOR_TRANSPARENT "$clr.transparent",0,0
#define AI_MATKEY_COLOR_REFLECTIVE "$clr.reflective",0,0
#define AI_MATKEY_GLOBAL_BACKGROUND_IMAGE "?bg.global",0,0
#define AI_MATKEY_GLOBAL_SHADERLANG "?sh.lang",0,0
#define AI_MATKEY_SHADER_VERTEX "?sh.vs",0,0
#define AI_MATKEY_SHADER_FRAGMENT "?sh.fs",0,0
#define AI_MATKEY_SHADER_GEO "?sh.gs",0,0
#define AI_MATKEY_SHADER_TESSELATION "?sh.ts",0,0
#define AI_MATKEY_SHADER_PRIMITIVE "?sh.ps",0,0
#define AI_MATKEY_SHADER_COMPUTE "?sh.cs",0,0
// ---------------------------------------------------------------------------
// Pure key names for all texture-related properties
@ -1457,8 +1462,6 @@ inline aiReturn aiGetMaterialInteger(const C_STRUCT aiMaterial* pMat,
#endif //!__cplusplus
// ---------------------------------------------------------------------------
/** @brief Retrieve a color value from the material property table
*

View File

@ -52,8 +52,8 @@ use_ifc_template = False
input_step_template_h = 'StepReaderGen.h.template'
input_step_template_cpp = 'StepReaderGen.cpp.template'
input_ifc_template_h = 'IFCReaderGen.h.template'
input_ifc_template_cpp = 'IFCReaderGen.cpp.template'
input_ifc_template_h = 'IFCReaderGen.h.template'
input_ifc_template_cpp = 'IFCReaderGen.cpp.template'
cpp_keywords = "class"
@ -87,7 +87,7 @@ template_type = r"""
template_stub_decl = '\tDECL_CONV_STUB({type});\n'
template_schema = '\t\tSchemaEntry("{normalized_name}",&STEP::ObjectHelper<{type},{argcnt}>::Construct )\n'
template_schema_type = '\t\tSchemaEntry("{normalized_name}",NULL )\n'
template_schema_type = '\t\tSchemaEntry("{normalized_name}",nullptr )\n'
template_converter = r"""
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<{type}>(const DB& db, const LIST& params, {type}* in)
@ -99,7 +99,7 @@ template_converter_prologue_a = '\tsize_t base = GenericFill(db,params,static_ca
template_converter_prologue_b = '\tsize_t base = 0;\n'
template_converter_check_argcnt = '\tif (params.GetSize() < {max_arg}) {{ throw STEP::TypeError("expected {max_arg} arguments to {name}"); }}'
template_converter_code_per_field = r""" do {{ // convert the '{fieldname}' argument
boost::shared_ptr<const DataType> arg = params[base++];{handle_unset}{convert}
std::shared_ptr<const DataType> arg = params[base++];{handle_unset}{convert}
}} while(0);
"""
template_allow_optional = r"""

View File

@ -2,7 +2,7 @@
Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------
Copyright (c) 2006-2018, ASSIMP Development Team
Copyright (c) 2006-2019, ASSIMP Development Team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -66,7 +66,7 @@ namespace STEP {
// -----------------------------------------------------------------------------------------------------------
template <> size_t GenericFill<NotImplemented>(const STEP::DB& db, const LIST& params, NotImplemented* in)
{
return 0;
return 0u;
}

View File

@ -2,7 +2,7 @@
Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------
Copyright (c) 2006-2018, ASSIMP Development Team
Copyright (c) 2006-2019, ASSIMP Development Team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -47,25 +47,23 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp {
namespace StepFile {
using namespace STEP;
using namespace STEP::EXPRESS;
struct NotImplemented : public ObjectHelper<NotImplemented,0> {
};
// ******************************************************************************
// StepFile Custom data types
// ******************************************************************************
using namespace STEP;
using namespace STEP::EXPRESS;
struct NotImplemented : public ObjectHelper<NotImplemented,0> {
};
// ******************************************************************************
// StepFile Custom data types
// ******************************************************************************
{types}
// ******************************************************************************
// StepFile Entities
// ******************************************************************************
// ******************************************************************************
// StepFile Entities
// ******************************************************************************
{predefs}
{entities}
@ -73,11 +71,12 @@ namespace StepFile {
void GetSchema(EXPRESS::ConversionSchema& out);
} //! StepFile
namespace STEP {
// ******************************************************************************
// Converter stubs
// ******************************************************************************
// ******************************************************************************
// Converter stubs
// ******************************************************************************
#define DECL_CONV_STUB(type) template <> size_t GenericFill<IFC::type>(const STEP::DB& db, const EXPRESS::LIST& params, IFC::type* in)

View File

@ -152,10 +152,10 @@ TEST_F(utSTLImporterExporter, test_export_pointclouds) {
auto pMesh = scene.mMeshes[0];
long numValidPoints = points.size();
size_t numValidPoints = points.size();
pMesh->mVertices = new aiVector3D[numValidPoints];
pMesh->mNumVertices = numValidPoints;
pMesh->mNumVertices = static_cast<unsigned int>( numValidPoints );
int i = 0;
for (XYZ &p : points) {

View File

@ -0,0 +1,199 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2019, 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 "UnitTestPCH.h"
#include <assimp/mesh.h>
#include <assimp/scene.h>
#include <ValidateDataStructure.h>
using namespace std;
using namespace Assimp;
class ValidateDataStructureTest : public ::testing::Test
{
public:
virtual void SetUp();
virtual void TearDown();
protected:
ValidateDSProcess* vds;
aiScene* scene;
};
// ------------------------------------------------------------------------------------------------
void ValidateDataStructureTest::SetUp()
{
// setup a dummy scene with a single node
scene = new aiScene();
scene->mRootNode = new aiNode();
scene->mRootNode->mName.Set("<test>");
// add some translation
scene->mRootNode->mTransformation.a4 = 1.f;
scene->mRootNode->mTransformation.b4 = 2.f;
scene->mRootNode->mTransformation.c4 = 3.f;
// and allocate a ScenePreprocessor to operate on the scene
vds = new ValidateDSProcess();
}
// ------------------------------------------------------------------------------------------------
void ValidateDataStructureTest::TearDown()
{
delete vds;
delete scene;
}
// ------------------------------------------------------------------------------------------------
//Template
//TEST_F(ScenePreprocessorTest, test)
//{
//}
// TODO Conditions not yet checked:
//132: ReportError("aiScene::%s is NULL (aiScene::%s is %i)",
//139: ReportError("aiScene::%s[%i] is NULL (aiScene::%s is %i)",
//156: ReportError("aiScene::%s is NULL (aiScene::%s is %i)",
//163: ReportError("aiScene::%s[%i] is NULL (aiScene::%s is %i)",
//173: ReportError("aiScene::%s[%i] has the same name as "
//192: ReportError("aiScene::%s[%i] has no corresponding node in the scene graph (%s)",
//196: ReportError("aiScene::%s[%i]: there are more than one nodes with %s as name",
//217: ReportError("aiScene::mNumMeshes is 0. At least one mesh must be there");
//220: ReportError("aiScene::mMeshes is non-null although there are no meshes");
//229: ReportError("aiScene::mAnimations is non-null although there are no animations");
//238: ReportError("aiScene::mCameras is non-null although there are no cameras");
//247: ReportError("aiScene::mLights is non-null although there are no lights");
//256: ReportError("aiScene::mTextures is non-null although there are no textures");
//266: ReportError("aiScene::mNumMaterials is 0. At least one material must be there");
//270: ReportError("aiScene::mMaterials is non-null although there are no materials");
//281: ReportWarning("aiLight::mType is aiLightSource_UNDEFINED");
//286: ReportWarning("aiLight::mAttenuationXXX - all are zero");
//290: ReportError("aiLight::mAngleInnerCone is larger than aiLight::mAngleOuterCone");
//295: ReportWarning("aiLight::mColorXXX - all are black and won't have any influence");
//303: ReportError("aiCamera::mClipPlaneFar must be >= aiCamera::mClipPlaneNear");
//308: ReportWarning("%f is not a valid value for aiCamera::mHorizontalFOV",pCamera->mHorizontalFOV);
//317: ReportError("aiMesh::mMaterialIndex is invalid (value: %i maximum: %i)",
//332: ReportError("aiMesh::mFaces[%i].mNumIndices is 0",i);
//336: ReportError("aiMesh::mFaces[%i] is a POINT but aiMesh::mPrimitiveTypes "
//337: "does not report the POINT flag",i);
//343: ReportError("aiMesh::mFaces[%i] is a LINE but aiMesh::mPrimitiveTypes "
//344: "does not report the LINE flag",i);
//350: ReportError("aiMesh::mFaces[%i] is a TRIANGLE but aiMesh::mPrimitiveTypes "
//351: "does not report the TRIANGLE flag",i);
//357: this->ReportError("aiMesh::mFaces[%i] is a POLYGON but aiMesh::mPrimitiveTypes "
//358: "does not report the POLYGON flag",i);
//365: ReportError("aiMesh::mFaces[%i].mIndices is NULL",i);
//370: ReportError("The mesh %s contains no vertices", pMesh->mName.C_Str());
//374: ReportError("Mesh has too many vertices: %u, but the limit is %u",pMesh->mNumVertices,AI_MAX_VERTICES);
//377: ReportError("Mesh has too many faces: %u, but the limit is %u",pMesh->mNumFaces,AI_MAX_FACES);
//382: ReportError("If there are tangents, bitangent vectors must be present as well");
//387: ReportError("Mesh %s contains no faces", pMesh->mName.C_Str());
//398: ReportError("Face %u has too many faces: %u, but the limit is %u",i,face.mNumIndices,AI_MAX_FACE_INDICES);
//404: ReportError("aiMesh::mFaces[%i]::mIndices[%i] is out of range",i,a);
//412: ReportError("aiMesh::mVertices[%i] is referenced twice - second "
//426: ReportWarning("There are unreferenced vertices");
//439: ReportError("Texture coordinate channel %i exists "
//453: ReportError("Vertex color channel %i is exists "
//464: ReportError("aiMesh::mBones is NULL (aiMesh::mNumBones is %i)",
//480: ReportError("Bone %u has too many weights: %u, but the limit is %u",i,bone->mNumWeights,AI_MAX_BONE_WEIGHTS);
//485: ReportError("aiMesh::mBones[%i] is NULL (aiMesh::mNumBones is %i)",
//498: ReportError("aiMesh::mBones[%i], name = \"%s\" has the same name as "
//507: ReportWarning("aiMesh::mVertices[%i]: bone weight sum != 1.0 (sum is %f)",i,afSum[i]);
//513: ReportError("aiMesh::mBones is non-null although there are no bones");
//524: ReportError("aiBone::mNumWeights is zero");
//531: ReportError("aiBone::mWeights[%i].mVertexId is out of range",i);
//534: ReportWarning("aiBone::mWeights[%i].mWeight has an invalid value",i);
//549: ReportError("aiAnimation::mChannels is NULL (aiAnimation::mNumChannels is %i)",
//556: ReportError("aiAnimation::mChannels[%i] is NULL (aiAnimation::mNumChannels is %i)",
//563: ReportError("aiAnimation::mNumChannels is 0. At least one node animation channel must be there.");
//567: // if (!pAnimation->mDuration)this->ReportError("aiAnimation::mDuration is zero");
//592: ReportError("Material property %s is expected to be a string",prop->mKey.data);
//596: ReportError("%s #%i is set, but there are only %i %s textures",
//611: ReportError("Found texture property with index %i, although there "
//619: ReportError("Material property %s%i is expected to be an integer (size is %i)",
//627: ReportError("Material property %s%i is expected to be 5 floats large (size is %i)",
//635: ReportError("Material property %s%i is expected to be an integer (size is %i)",
//656: ReportWarning("Invalid UV index: %i (key %s). Mesh %i has only %i UV channels",
//676: ReportWarning("UV-mapped texture, but there are no UV coords");
//690: ReportError("aiMaterial::mProperties[%i] is NULL (aiMaterial::mNumProperties is %i)",
//694: ReportError("aiMaterial::mProperties[%i].mDataLength or "
//702: ReportError("aiMaterial::mProperties[%i].mDataLength is "
//707: ReportError("Missing null-terminator in string material property");
//713: ReportError("aiMaterial::mProperties[%i].mDataLength is "
//720: ReportError("aiMaterial::mProperties[%i].mDataLength is "
//739: ReportWarning("A specular shading model is specified but there is no "
//743: ReportWarning("A specular shading model is specified but the value of the "
//752: ReportWarning("Invalid opacity value (must be 0 < opacity < 1.0)");
//776: ReportError("aiTexture::pcData is NULL");
//781: ReportError("aiTexture::mWidth is zero (aiTexture::mHeight is %i, uncompressed texture)",
//788: ReportError("aiTexture::mWidth is zero (compressed texture)");
//791: ReportWarning("aiTexture::achFormatHint must be zero-terminated");
//794: ReportWarning("aiTexture::achFormatHint should contain a file extension "
//804: ReportError("aiTexture::achFormatHint contains non-lowercase letters");
//815: ReportError("Empty node animation channel");
//822: ReportError("aiNodeAnim::mPositionKeys is NULL (aiNodeAnim::mNumPositionKeys is %i)",
//833: ReportError("aiNodeAnim::mPositionKeys[%i].mTime (%.5f) is larger "
//840: ReportWarning("aiNodeAnim::mPositionKeys[%i].mTime (%.5f) is smaller "
//853: ReportError("aiNodeAnim::mRotationKeys is NULL (aiNodeAnim::mNumRotationKeys is %i)",
//861: ReportError("aiNodeAnim::mRotationKeys[%i].mTime (%.5f) is larger "
//868: ReportWarning("aiNodeAnim::mRotationKeys[%i].mTime (%.5f) is smaller "
//880: ReportError("aiNodeAnim::mScalingKeys is NULL (aiNodeAnim::mNumScalingKeys is %i)",
//888: ReportError("aiNodeAnim::mScalingKeys[%i].mTime (%.5f) is larger "
//895: ReportWarning("aiNodeAnim::mScalingKeys[%i].mTime (%.5f) is smaller "
//907: ReportError("A node animation channel must have at least one subtrack");
//915: ReportError("A node of the scenegraph is NULL");
//920: ReportError("Non-root node %s lacks a valid parent (aiNode::mParent is NULL) ",pNode->mName);
//928: ReportError("aiNode::mMeshes is NULL for node %s (aiNode::mNumMeshes is %i)",
//937: ReportError("aiNode::mMeshes[%i] is out of range for node %s (maximum is %i)",
//942: ReportError("aiNode::mMeshes[%i] is already referenced by this node %s (value: %i)",
//951: ReportError("aiNode::mChildren is NULL for node %s (aiNode::mNumChildren is %i)",
//965: ReportError("aiString::length is too large (%i, maximum is %lu)",
//974: ReportError("aiString::data is invalid: the terminal zero is at a wrong offset");
//979: ReportError("aiString::data is invalid. There is no terminal character");
}

View File

@ -51,27 +51,26 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string>
const char* AICMD_MSG_INFO_HELP_E =
"assimp info <file> [-r] [-v]\n"
"\tPrint basic structure of a 3D model\n"
"\t-r,--raw: No postprocessing, do a raw import\n"
"\t-v,--verbose: Print verbose info such as node transform data\n"
"\t-s, --silent: Print only minimal info\n";
"assimp info <file> [-r] [-v]\n"
"\tPrint basic structure of a 3D model\n"
"\t-r,--raw: No postprocessing, do a raw import\n"
"\t-v,--verbose: Print verbose info such as node transform data\n"
"\t-s, --silent: Print only minimal info\n";
const std::string TREE_BRANCH_ASCII = "|-";
const std::string TREE_BRANCH_UTF8 = "\xe2\x94\x9c\xe2\x95\xb4";
const std::string TREE_STOP_ASCII = "'-";
const std::string TREE_STOP_UTF8 = "\xe2\x94\x94\xe2\x95\xb4";
const std::string TREE_CONTINUE_ASCII = "| ";
const std::string TREE_CONTINUE_UTF8 = "\xe2\x94\x82 ";
const char *TREE_BRANCH_ASCII = "|-";
const char *TREE_BRANCH_UTF8 = "\xe2\x94\x9c\xe2\x95\xb4";
const char *TREE_STOP_ASCII = "'-";
const char *TREE_STOP_UTF8 = "\xe2\x94\x94\xe2\x95\xb4";
const char *TREE_CONTINUE_ASCII = "| ";
const char *TREE_CONTINUE_UTF8 = "\xe2\x94\x82 ";
// note: by default this is outputing utf-8 text.
// note: by default this is using utf-8 text.
// this is well supported on pretty much any linux terminal.
// if this causes problems on some platform,
// put an #ifdef to use the ascii version for that platform.
const std::string TREE_BRANCH = TREE_BRANCH_UTF8;
const std::string TREE_STOP = TREE_STOP_UTF8;
const std::string TREE_CONTINUE = TREE_CONTINUE_UTF8;
const char *TREE_BRANCH = TREE_BRANCH_UTF8;
const char *TREE_STOP = TREE_STOP_UTF8;
const char *TREE_CONTINUE = TREE_CONTINUE_UTF8;
// -----------------------------------------------------------------------------------
unsigned int CountNodes(const aiNode* root)
@ -280,14 +279,7 @@ void PrintHierarchy(
// -----------------------------------------------------------------------------------
// 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;
}
int Assimp_Info (const char* const* params, unsigned int num) {
// --help
if (!strcmp( params[0],"-h")||!strcmp( params[0],"--help")||!strcmp( params[0],"-?") ) {
printf("%s",AICMD_MSG_INFO_HELP_E);

View File

@ -276,9 +276,12 @@ inline uint32_t WriteBounds(const T* in, unsigned int size)
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);
int retCode;
retCode = fseek(out, ofs, SEEK_SET);
ai_assert(0 == retCode);
fwrite(&n, 4, 1, out);
retCode = fseek(out, cur, SEEK_SET);
ai_assert(0 == retCode);
}
// -----------------------------------------------------------------------------------
@ -1333,10 +1336,6 @@ 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], "-?") ) {

View File

@ -90,7 +90,7 @@ void SceneAnimator::SetAnimIndex( size_t pAnimIndex) {
delete mAnimEvaluator; mAnimEvaluator = nullptr;
mNodesByName.clear();
mCurrentAnimIndex = pAnimIndex;
mCurrentAnimIndex = static_cast<int>( pAnimIndex );
// create the internal node tree. Do this even in case of invalid animation index
// so that the transformation matrices are properly set up to mimic the current scene