Merge remote-tracking branch 'official/master' into contrib

pull/546/head
Léo Terziman 2014-12-16 17:48:30 +01:00
commit 3303f97f13
30 changed files with 596 additions and 144 deletions

19
.gitignore vendored
View File

@ -32,3 +32,22 @@ test/results
# Python
__pycache__
*.log
*.vcxproj
*.filters
*.tlog
Assimp.sdf
test/gtest/tmp/gtest-gitupdate.cmake
test/gtest/tmp/gtest-gitclone.cmake
test/gtest/tmp/gtest-cfgcmd.txt.in
test/gtest/tmp/gtest-cfgcmd.txt
test/gtest/src/gtest-stamp/gtest-download.cmake
test/gtest/src/gtest-stamp/gtest-configure.cmake
test/gtest/src/gtest-stamp/gtest-build.cmake
test/gtest/src/gtest-stamp/Debug/gtest-patch
*.cache
test/gtest/src/gtest-stamp/Debug/gtest-build
*.suo
*.lib
test/gtest/src/gtest-stamp/Debug/
tools/assimp_view/assimp_viewer.vcxproj.user

View File

@ -78,21 +78,11 @@ SET( ASSIMP_INCLUDE_INSTALL_DIR "include" CACHE PATH
"Path the header files are installed to." )
SET( ASSIMP_BIN_INSTALL_DIR "bin" CACHE PATH
"Path the tool executables are installed to." )
option (ASSIMP_BUILD_STATIC_LIB "Build a static (.a) version of the library" OFF)
SET(ASSIMP_DEBUG_POSTFIX "d" CACHE STRING "Debug Postfitx for lib, samples and tools")
# Allow the user to build a static library
# Allow the user to build a shared or static library
option ( BUILD_SHARED_LIBS "Build a shared version of the library" ON )
IF ( ASSIMP_BUILD_STATIC_LIB )
option ( BUILD_SHARED_LIBS "Build a shared version of the library" OFF )
ELSE ( ASSIMP_BUILD_STATIC_LIB )
option ( BUILD_SHARED_LIBS "Build a shared version of the library" ON )
ENDIF ( ASSIMP_BUILD_STATIC_LIB )
# Generate a pkg-config .pc for the Assimp library.
CONFIGURE_FILE( "${PROJECT_SOURCE_DIR}/assimp.pc.in" "${PROJECT_BINARY_DIR}/assimp.pc" @ONLY )
INSTALL( FILES "${PROJECT_BINARY_DIR}/assimp.pc" DESTINATION ${ASSIMP_LIB_INSTALL_DIR}/pkgconfig/ COMPONENT ${LIBASSIMP-DEV_COMPONENT})
# Only generate this target if no higher-level project already has
IF (NOT TARGET uninstall)
@ -136,6 +126,10 @@ option ( ASSIMP_NO_EXPORT
OFF
)
if( CMAKE_COMPILER_IS_GNUCXX )
set(LIBSTDC++_LIBRARIES -lstdc++)
endif( CMAKE_COMPILER_IS_GNUCXX )
# Search for external dependencies, and build them from source if not found
# Search for zlib
find_package(ZLIB)
@ -151,6 +145,7 @@ if( NOT ZLIB_FOUND )
set(ZLIB_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/contrib/zlib ${CMAKE_CURRENT_BINARY_DIR}/contrib/zlib)
else(NOT ZLIB_FOUND)
ADD_DEFINITIONS(-DASSIMP_BUILD_NO_OWN_ZLIB)
set(ZLIB_LIBRARIES_LINKED -lz)
endif(NOT ZLIB_FOUND)
INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIR})
@ -228,6 +223,10 @@ IF(MSVC)
)
ENDIF(MSVC)
# Generate a pkg-config .pc for the Assimp library.
CONFIGURE_FILE( "${PROJECT_SOURCE_DIR}/assimp.pc.in" "${PROJECT_BINARY_DIR}/assimp.pc" @ONLY )
INSTALL( FILES "${PROJECT_BINARY_DIR}/assimp.pc" DESTINATION ${ASSIMP_LIB_INSTALL_DIR}/pkgconfig/ COMPONENT ${LIBASSIMP-DEV_COMPONENT})
if(CMAKE_CPACK_COMMAND AND UNIX AND ASSIMP_OPT_BUILD_PACKAGES)
# Packing information
set(CPACK_PACKAGE_NAME "assimp{ASSIMP_VERSION_MAJOR}")

View File

@ -7,4 +7,5 @@ Name: @CMAKE_PROJECT_NAME@
Description: Import various well-known 3D model formats in an uniform manner.
Version: @PROJECT_VERSION@
Libs: -L${libdir} -lassimp@ASSIMP_LIBRARY_SUFFIX@
Libs.private: @LIBSTDC++_LIBRARIES@ @ZLIB_LIBRARIES_LINKED@
Cflags: -I${includedir}

View File

@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "GenericProperty.h"
#include "CInterfaceIOWrapper.h"
#include "../include/assimp/importerdesc.h"
#include "Importer.h"
// ------------------------------------------------------------------------------------------------
@ -84,7 +85,11 @@ namespace Assimp
/** Verbose logging active or not? */
static aiBool gVerboseLogging = false;
}
/** will return all registered importers. */
void GetImporterInstanceList(std::vector< BaseImporter* >& out);
} // namespace assimp
#ifndef ASSIMP_BUILD_SINGLETHREADED
@ -606,4 +611,22 @@ ASSIMP_API void aiIdentityMatrix4(
*mat = aiMatrix4x4();
}
// ------------------------------------------------------------------------------------------------
ASSIMP_API C_STRUCT const aiImporterDesc* aiGetImporterDesc( const char *extension ) {
if( NULL == extension ) {
return NULL;
}
const aiImporterDesc *desc( NULL );
std::vector< BaseImporter* > out;
GetImporterInstanceList( out );
for( size_t i = 0; i < out.size(); ++i ) {
if( 0 == strncmp( out[ i ]->GetInfo()->mFileExtensions, extension, strlen( extension ) ) ) {
desc = out[ i ]->GetInfo();
break;
}
}
return desc;
}
// ------------------------------------------------------------------------------------------------

View File

@ -90,6 +90,11 @@ struct ScopeGuard
}
private:
// no copying allowed.
ScopeGuard();
ScopeGuard( const ScopeGuard & );
ScopeGuard &operator = ( const ScopeGuard & );
T* obj;
bool mdismiss;
};

View File

@ -1867,14 +1867,15 @@ void ColladaParser::ReadIndexData( Mesh* pMesh)
// read primitive count from the attribute
int attrCount = GetAttribute( "count");
size_t numPrimitives = (size_t) mReader->getAttributeValueAsInt( attrCount);
// some mesh types (e.g. tristrips) don't specify primitive count upfront,
// so we need to sum up the actual number of primitives while we read the <p>-tags
size_t actualPrimitives = 0;
// material subgroup
int attrMaterial = TestAttribute( "material");
SubMesh subgroup;
if( attrMaterial > -1)
subgroup.mMaterial = mReader->getAttributeValue( attrMaterial);
subgroup.mNumFaces = numPrimitives;
pMesh->mSubMeshes.push_back( subgroup);
// distinguish between polys and triangles
std::string elementName = mReader->getNodeName();
@ -1933,7 +1934,7 @@ void ColladaParser::ReadIndexData( Mesh* pMesh)
if( !mReader->isEmptyElement())
{
// now here the actual fun starts - these are the indices to construct the mesh data from
ReadPrimitives( pMesh, perIndexData, numPrimitives, vcount, primType);
actualPrimitives += ReadPrimitives(pMesh, perIndexData, numPrimitives, vcount, primType);
}
} else
{
@ -1948,6 +1949,14 @@ void ColladaParser::ReadIndexData( Mesh* pMesh)
break;
}
}
// small sanity check
if (primType != Prim_TriFans && primType != Prim_TriStrips)
ai_assert(actualPrimitives == numPrimitives);
// only when we're done reading all <p> tags (and thus know the final vertex count) can we commit the submesh
subgroup.mNumFaces = actualPrimitives;
pMesh->mSubMeshes.push_back(subgroup);
}
// ------------------------------------------------------------------------------------------------
@ -1995,7 +2004,7 @@ void ColladaParser::ReadInputChannel( std::vector<InputChannel>& poChannels)
// ------------------------------------------------------------------------------------------------
// Reads a <p> primitive index list and assembles the mesh data into the given mesh
void ColladaParser::ReadPrimitives( Mesh* pMesh, std::vector<InputChannel>& pPerIndexChannels,
size_t ColladaParser::ReadPrimitives( Mesh* pMesh, std::vector<InputChannel>& pPerIndexChannels,
size_t pNumPrimitives, const std::vector<size_t>& pVCount, PrimitiveType pPrimType)
{
// determine number of indices coming per vertex
@ -2093,19 +2102,21 @@ void ColladaParser::ReadPrimitives( Mesh* pMesh, std::vector<InputChannel>& pPer
acc->mData = &ResolveLibraryReference( mDataLibrary, acc->mSource);
}
// now assemble vertex data according to those indices
std::vector<size_t>::const_iterator idx = indices.begin();
// For continued primitives, the given count does not come all in one <p>, but only one primitive per <p>
size_t numPrimitives = pNumPrimitives;
if( pPrimType == Prim_TriFans || pPrimType == Prim_Polygon)
numPrimitives = 1;
// For continued primitives, the given count is actually the number of <p>'s inside the parent tag
if ( pPrimType == Prim_TriStrips){
size_t numberOfVertices = indices.size() / numOffsets;
numPrimitives = numberOfVertices - 2;
}
pMesh->mFaceSize.reserve( numPrimitives);
pMesh->mFacePosIndices.reserve( indices.size() / numOffsets);
for( size_t a = 0; a < numPrimitives; a++)
size_t polylistStartVertex = 0;
for (size_t currentPrimitive = 0; currentPrimitive < numPrimitives; currentPrimitive++)
{
// determine number of points for this primitive
size_t numPoints = 0;
@ -2113,50 +2124,76 @@ void ColladaParser::ReadPrimitives( Mesh* pMesh, std::vector<InputChannel>& pPer
{
case Prim_Lines:
numPoints = 2;
for (size_t currentVertex = 0; currentVertex < numPoints; currentVertex++)
CopyVertex(currentVertex, numOffsets, numPoints, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices);
break;
case Prim_Triangles:
numPoints = 3;
for (size_t currentVertex = 0; currentVertex < numPoints; currentVertex++)
CopyVertex(currentVertex, numOffsets, numPoints, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices);
break;
case Prim_TriStrips:
numPoints = 3;
ReadPrimTriStrips(numOffsets, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices);
break;
case Prim_Polylist:
numPoints = pVCount[a];
numPoints = pVCount[currentPrimitive];
for (size_t currentVertex = 0; currentVertex < numPoints; currentVertex++)
CopyVertex(polylistStartVertex + currentVertex, numOffsets, 1, perVertexOffset, pMesh, pPerIndexChannels, 0, indices);
polylistStartVertex += numPoints;
break;
case Prim_TriFans:
case Prim_Polygon:
numPoints = indices.size() / numOffsets;
for (size_t currentVertex = 0; currentVertex < numPoints; currentVertex++)
CopyVertex(currentVertex, numOffsets, numPoints, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices);
break;
default:
// LineStrip and TriStrip not supported due to expected index unmangling
// LineStrip is not supported due to expected index unmangling
ThrowException( "Unsupported primitive type.");
break;
}
// store the face size to later reconstruct the face from
pMesh->mFaceSize.push_back( numPoints);
// gather that number of vertices
for( size_t b = 0; b < numPoints; b++)
{
// read all indices for this vertex. Yes, in a hacky local array
ai_assert( numOffsets < 20 && perVertexOffset < 20);
size_t vindex[20];
for( size_t offsets = 0; offsets < numOffsets; ++offsets)
vindex[offsets] = *idx++;
// extract per-vertex channels using the global per-vertex offset
for( std::vector<InputChannel>::iterator it = pMesh->mPerVertexData.begin(); it != pMesh->mPerVertexData.end(); ++it)
ExtractDataObjectFromChannel( *it, vindex[perVertexOffset], pMesh);
// and extract per-index channels using there specified offset
for( std::vector<InputChannel>::iterator it = pPerIndexChannels.begin(); it != pPerIndexChannels.end(); ++it)
ExtractDataObjectFromChannel( *it, vindex[it->mOffset], pMesh);
// store the vertex-data index for later assignment of bone vertex weights
pMesh->mFacePosIndices.push_back( vindex[perVertexOffset]);
}
}
// if I ever get my hands on that guy who invented this steaming pile of indirection...
TestClosing( "p");
return numPrimitives;
}
void ColladaParser::CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset, Mesh* pMesh, std::vector<InputChannel>& pPerIndexChannels, size_t currentPrimitive, const std::vector<size_t>& indices){
// calculate the base offset of the vertex whose attributes we ant to copy
size_t baseOffset = currentPrimitive * numOffsets * numPoints + currentVertex * numOffsets;
// don't overrun the boundaries of the index list
size_t maxIndexRequested = baseOffset + numOffsets - 1;
ai_assert(maxIndexRequested < indices.size());
// extract per-vertex channels using the global per-vertex offset
for (std::vector<InputChannel>::iterator it = pMesh->mPerVertexData.begin(); it != pMesh->mPerVertexData.end(); ++it)
ExtractDataObjectFromChannel(*it, indices[baseOffset + perVertexOffset], pMesh);
// and extract per-index channels using there specified offset
for (std::vector<InputChannel>::iterator it = pPerIndexChannels.begin(); it != pPerIndexChannels.end(); ++it)
ExtractDataObjectFromChannel(*it, indices[baseOffset + it->mOffset], pMesh);
// store the vertex-data index for later assignment of bone vertex weights
pMesh->mFacePosIndices.push_back(indices[baseOffset + perVertexOffset]);
}
void ColladaParser::ReadPrimTriStrips(size_t numOffsets, size_t perVertexOffset, Mesh* pMesh, std::vector<InputChannel>& pPerIndexChannels, size_t currentPrimitive, const std::vector<size_t>& indices){
if (currentPrimitive % 2 != 0){
//odd tristrip triangles need their indices mangled, to preserve winding direction
CopyVertex(1, numOffsets, 1, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices);
CopyVertex(0, numOffsets, 1, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices);
CopyVertex(2, numOffsets, 1, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices);
}
else {//for non tristrips or even tristrip triangles
CopyVertex(0, numOffsets, 1, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices);
CopyVertex(1, numOffsets, 1, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices);
CopyVertex(2, numOffsets, 1, perVertexOffset, pMesh, pPerIndexChannels, currentPrimitive, indices);
}
}
// ------------------------------------------------------------------------------------------------

View File

@ -177,9 +177,18 @@ protected:
void ReadInputChannel( std::vector<Collada::InputChannel>& poChannels);
/** Reads a <p> primitive index list and assembles the mesh data into the given mesh */
void ReadPrimitives( Collada::Mesh* pMesh, std::vector<Collada::InputChannel>& pPerIndexChannels,
size_t ReadPrimitives( Collada::Mesh* pMesh, std::vector<Collada::InputChannel>& pPerIndexChannels,
size_t pNumPrimitives, const std::vector<size_t>& pVCount, Collada::PrimitiveType pPrimType);
/** Copies the data for a single primitive into the mesh, based on the InputChannels */
void CopyVertex(size_t currentVertex, size_t numOffsets, size_t numPoints, size_t perVertexOffset,
Collada::Mesh* pMesh, std::vector<Collada::InputChannel>& pPerIndexChannels,
size_t currentPrimitive, const std::vector<size_t>& indices);
/** Reads one triangle of a tristrip into the mesh */
void ReadPrimTriStrips(size_t numOffsets, size_t perVertexOffset, Collada::Mesh* pMesh,
std::vector<Collada::InputChannel>& pPerIndexChannels, size_t currentPrimitive, const std::vector<size_t>& indices);
/** Extracts a single object from an input channel and stores it in the appropriate mesh data array */
void ExtractDataObjectFromChannel( const Collada::InputChannel& pInput, size_t pLocalIndex, Collada::Mesh* pMesh);

View File

@ -56,9 +56,13 @@ namespace Assimp {
class DefaultIOStream : public IOStream
{
friend class DefaultIOSystem;
#if __ANDROID__ and __ANDROID_API__ > 9 and defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT)
#if __ANDROID__
#if __ANDROID_API__ > 9
#if defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT)
friend class AndroidJNIIOSystem;
#endif //__ANDROID__ and __ANDROID_API__ > 9 and defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT)
#endif // defined(AI_CONFIG_ANDROID_JNI_ASSIMP_MANAGER_SUPPORT)
#endif // __ANDROID_API__ > 9
#endif // __ANDROID__
protected:
DefaultIOStream();
@ -69,42 +73,42 @@ public:
~DefaultIOStream ();
// -------------------------------------------------------------------
// Read from stream
/// Read from stream
size_t Read(void* pvBuffer,
size_t pSize,
size_t pCount);
// -------------------------------------------------------------------
// Write to stream
/// Write to stream
size_t Write(const void* pvBuffer,
size_t pSize,
size_t pCount);
// -------------------------------------------------------------------
// Seek specific position
/// Seek specific position
aiReturn Seek(size_t pOffset,
aiOrigin pOrigin);
// -------------------------------------------------------------------
// Get current seek position
/// Get current seek position
size_t Tell() const;
// -------------------------------------------------------------------
// Get size of file
/// Get size of file
size_t FileSize() const;
// -------------------------------------------------------------------
// Flush file contents
/// Flush file contents
void Flush();
private:
//! File datastructure, using clib
// File datastructure, using clib
FILE* mFile;
//! Filename
// Filename
std::string mFilename;
//! Cached file size
// Cached file size
mutable size_t cachedSize;
};

View File

@ -78,6 +78,7 @@ void ExportSceneObj(const char*,IOSystem*, const aiScene*);
void ExportSceneSTL(const char*,IOSystem*, const aiScene*);
void ExportSceneSTLBinary(const char*,IOSystem*, const aiScene*);
void ExportScenePly(const char*,IOSystem*, const aiScene*);
void ExportScenePlyBinary(const char*, IOSystem*, const aiScene*);
void ExportScene3DS(const char*, IOSystem*, const aiScene*);
void ExportSceneAssbin(const char*, IOSystem*, const aiScene*);
void ExportSceneAssxml(const char*, IOSystem*, const aiScene*);
@ -113,6 +114,9 @@ Exporter::ExportFormatEntry gExporters[] =
Exporter::ExportFormatEntry( "ply", "Stanford Polygon Library", "ply" , &ExportScenePly,
aiProcess_PreTransformVertices
),
Exporter::ExportFormatEntry( "plyb", "Stanford Polygon Library (binary)", "ply", &ExportScenePlyBinary,
aiProcess_PreTransformVertices
),
#endif
#ifndef ASSIMP_BUILD_NO_3DS_EXPORTER

View File

@ -376,7 +376,7 @@ float ParseTokenAsFloat(const Token& t, const char*& err_out)
return SafeParse<float>(data+1, t.end());
}
else {
return SafeParse<double>(data+1, t.end());
return static_cast<float>( SafeParse<double>(data+1, t.end()) );
}
}

View File

@ -166,12 +166,13 @@ void ObjFileMtlImporter::load()
}
break;
case 'N': // Shineness
case 'N':
case 'n':
{
++m_DataIt;
switch(*m_DataIt)
{
case 's':
case 's': // Specular exponent
++m_DataIt;
getFloatValue(m_pModel->m_pCurrentMaterial->shineness);
break;
@ -179,13 +180,14 @@ void ObjFileMtlImporter::load()
++m_DataIt;
getFloatValue(m_pModel->m_pCurrentMaterial->ior);
break;
case 'e': // New material
createMaterial();
break;
}
m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
break;
}
break;
case 'm': // Texture
case 'b': // quick'n'dirty - for 'bump' sections
{
@ -194,13 +196,6 @@ void ObjFileMtlImporter::load()
}
break;
case 'n': // New material name
{
createMaterial();
m_DataIt = skipLine<DataArrayIt>( m_DataIt, m_DataItEnd, m_uiLine );
}
break;
case 'i': // Illumination model
{
m_DataIt = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);

View File

@ -64,6 +64,20 @@ void ExportScenePly(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene
outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1);
}
void ExportScenePlyBinary(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene)
{
// invoke the exporter
PlyExporter exporter(pFile, pScene, true);
// we're still here - export successfully completed. Write the file.
boost::scoped_ptr<IOStream> outfile(pIOSystem->Open(pFile, "wb"));
if (outfile == NULL) {
throw DeadlyExportError("could not open output .ply file: " + std::string(pFile));
}
outfile->Write(exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()), 1);
}
} // end of namespace Assimp
#define PLY_EXPORT_HAS_NORMALS 0x1
@ -72,7 +86,7 @@ void ExportScenePly(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene
#define PLY_EXPORT_HAS_COLORS (PLY_EXPORT_HAS_TEXCOORDS << AI_MAX_NUMBER_OF_TEXTURECOORDS)
// ------------------------------------------------------------------------------------------------
PlyExporter :: PlyExporter(const char* _filename, const aiScene* pScene)
PlyExporter::PlyExporter(const char* _filename, const aiScene* pScene, bool binary)
: filename(_filename)
, pScene(pScene)
, endl("\n")
@ -102,7 +116,16 @@ PlyExporter :: PlyExporter(const char* _filename, const aiScene* pScene)
}
mOutput << "ply" << endl;
if (binary) {
#if (defined AI_BUILD_BIG_ENDIAN)
mOutput << "format binary_big_endian 1.0" << endl;
#else
mOutput << "format binary_little_endian 1.0" << endl;
#endif
}
else {
mOutput << "format ascii 1.0" << endl;
}
mOutput << "comment Created by Open Asset Import Library - http://assimp.sf.net (v"
<< aiGetVersionMajor() << '.' << aiGetVersionMinor() << '.'
<< aiGetVersionRevision() << ")" << endl;
@ -163,10 +186,20 @@ PlyExporter :: PlyExporter(const char* _filename, const aiScene* pScene)
mOutput << "end_header" << endl;
for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
if (binary) {
WriteMeshVertsBinary(pScene->mMeshes[i], components);
}
else {
WriteMeshVerts(pScene->mMeshes[i], components);
}
}
for (unsigned int i = 0, ofs = 0; i < pScene->mNumMeshes; ++i) {
if (binary) {
WriteMeshIndicesBinary(pScene->mMeshes[i], ofs);
}
else {
WriteMeshIndices(pScene->mMeshes[i], ofs);
}
ofs += pScene->mMeshes[i]->mNumVertices;
}
}
@ -174,6 +207,8 @@ PlyExporter :: PlyExporter(const char* _filename, const aiScene* pScene)
// ------------------------------------------------------------------------------------------------
void PlyExporter::WriteMeshVerts(const aiMesh* m, unsigned int components)
{
// If a component (for instance normal vectors) is present in at least one mesh in the scene,
// then default values are written for meshes that do not contain this component.
for (unsigned int i = 0; i < m->mNumVertices; ++i) {
mOutput <<
m->mVertices[i].x << " " <<
@ -236,6 +271,56 @@ void PlyExporter :: WriteMeshVerts(const aiMesh* m, unsigned int components)
}
}
// ------------------------------------------------------------------------------------------------
void PlyExporter::WriteMeshVertsBinary(const aiMesh* m, unsigned int components)
{
// If a component (for instance normal vectors) is present in at least one mesh in the scene,
// then default values are written for meshes that do not contain this component.
aiVector3D defaultNormal(0, 0, 0);
aiVector2D defaultUV(-1, -1);
aiColor4D defaultColor(-1, -1, -1, -1);
for (unsigned int i = 0; i < m->mNumVertices; ++i) {
mOutput.write(reinterpret_cast<const char*>(&m->mVertices[i].x), 12);
if (components & PLY_EXPORT_HAS_NORMALS) {
if (m->HasNormals()) {
mOutput.write(reinterpret_cast<const char*>(&m->mNormals[i].x), 12);
}
else {
mOutput.write(reinterpret_cast<const char*>(&defaultNormal.x), 12);
}
}
for (unsigned int n = PLY_EXPORT_HAS_TEXCOORDS, c = 0; (components & n) && c != AI_MAX_NUMBER_OF_TEXTURECOORDS; n <<= 1, ++c) {
if (m->HasTextureCoords(c)) {
mOutput.write(reinterpret_cast<const char*>(&m->mTextureCoords[c][i].x), 6);
}
else {
mOutput.write(reinterpret_cast<const char*>(&defaultUV.x), 6);
}
}
for (unsigned int n = PLY_EXPORT_HAS_COLORS, c = 0; (components & n) && c != AI_MAX_NUMBER_OF_COLOR_SETS; n <<= 1, ++c) {
if (m->HasVertexColors(c)) {
mOutput.write(reinterpret_cast<const char*>(&m->mColors[c][i].r), 16);
}
else {
mOutput.write(reinterpret_cast<const char*>(&defaultColor.r), 16);
}
}
if (components & PLY_EXPORT_HAS_TANGENTS_BITANGENTS) {
if (m->HasTangentsAndBitangents()) {
mOutput.write(reinterpret_cast<const char*>(&m->mTangents[i].x), 12);
mOutput.write(reinterpret_cast<const char*>(&m->mBitangents[i].x), 12);
}
else {
mOutput.write(reinterpret_cast<const char*>(&defaultNormal.x), 12);
mOutput.write(reinterpret_cast<const char*>(&defaultNormal.x), 12);
}
}
}
}
// ------------------------------------------------------------------------------------------------
void PlyExporter::WriteMeshIndices(const aiMesh* m, unsigned int offset)
{
@ -248,4 +333,16 @@ void PlyExporter :: WriteMeshIndices(const aiMesh* m, unsigned int offset)
}
}
void PlyExporter::WriteMeshIndicesBinary(const aiMesh* m, unsigned int offset)
{
for (unsigned int i = 0; i < m->mNumFaces; ++i) {
const aiFace& f = m->mFaces[i];
mOutput.write(reinterpret_cast<const char*>(&f.mNumIndices), 4);
for (unsigned int c = 0; c < f.mNumIndices; ++c) {
unsigned int index = f.mIndices[c] + offset;
mOutput.write(reinterpret_cast<const char*>(&index), 4);
}
}
}
#endif

View File

@ -59,7 +59,7 @@ class PlyExporter
{
public:
/// Constructor for a specific scene to export
PlyExporter(const char* filename, const aiScene* pScene);
PlyExporter(const char* filename, const aiScene* pScene, bool binary = false);
public:
@ -71,6 +71,9 @@ private:
void WriteMeshVerts(const aiMesh* m, unsigned int components);
void WriteMeshIndices(const aiMesh* m, unsigned int ofs);
void WriteMeshVertsBinary(const aiMesh* m, unsigned int components);
void WriteMeshIndicesBinary(const aiMesh* m, unsigned int offset);
private:
const std::string filename;

View File

@ -247,7 +247,7 @@ ASSIMP_API C_STRUCT aiLogStream aiGetPredefinedLogStream(
* Attaching a log stream can slightly reduce Assimp's overall import
* performance. Multiple log-streams can be attached.
* @param stream Describes the new log stream.
* @note To ensure proepr destruction of the logging system, you need to manually
* @note To ensure proper destruction of the logging system, you need to manually
* call aiDetachLogStream() on every single log stream you attach.
* Alternatively (for the lazy folks) #aiDetachAllLogStreams is provided.
*/

View File

@ -133,4 +133,12 @@ struct aiImporterDesc
const char* mFileExtensions;
};
/** \brief Returns the Importer description for a given extension.
Will return a NULL-pointer if no assigned importer desc. was found for the given extension
\param extension [in] The extension to look for
\return A pointer showing to the ImporterDesc, \see aiImporterDesc.
*/
ASSIMP_API C_STRUCT const aiImporterDesc* aiGetImporterDesc( const char *extension );
#endif

View File

@ -0,0 +1 @@
See the [AssimpPascal headers here](https://github.com/ev1313/Pascal-Assimp-Headers) (by Tim Blume / ev1313).

View File

@ -50,7 +50,7 @@ def make_tuple(ai_obj, type = None):
# It is faster and more correct to have an init function for each assimp class
def _init_face(aiFace):
aiFace.indices = [aiFace.mIndices[i] for i in xrange(aiFace.mNumIndices)]
aiFace.indices = [aiFace.mIndices[i] for i in range(aiFace.mNumIndices)]
assimp_struct_inits = { structs.Face : _init_face }
@ -177,7 +177,7 @@ def _init(self, target = None, parent = None):
"and quads. Try to load your mesh with"
" a post-processing to triangulate your"
" faces.")
sys.exit(1)
raise e
else: # starts with 'm' but not iterable

View File

@ -9,16 +9,23 @@ data structures in detail. It just verifies whether basic
loading and querying of 3d models using pyassimp works.
"""
import os
import sys
# Make the development (ie. GIT repo) version of PyAssimp available for import.
sys.path.insert(0, '..')
import sys,os
import sample
from pyassimp import errors
# paths to be walkd recursively
basepaths = [os.path.join('..','..','..','test','models'), os.path.join('..','..','..','test','models-nonbsd')]
# Paths to model files.
basepaths = [os.path.join('..', '..', '..', 'test', 'models'),
os.path.join('..', '..', '..', 'test', 'models-nonbsd')]
# Valid extensions for 3D model files.
extensions = ['.3ds', '.x', '.lwo', '.obj', '.md5mesh', '.dxf', '.ply', '.stl',
'.dae', '.md5anim', '.lws', '.irrmesh', '.nff', '.off', '.blend']
# file extensions to be considered
extensions = ['.3ds','.x','.lwo','.obj','.md5mesh','.dxf','.ply','.stl','.dae','.md5anim','.lws','.irrmesh','.nff','.off','.blend']
def run_tests():
ok, err = 0, 0
@ -32,17 +39,15 @@ def run_tests():
sample.main(os.path.join(root, afile))
ok += 1
except errors.AssimpError as error:
# assimp error is fine, this is a controlled case
print error
# Assimp error is fine; this is a controlled case.
print(error)
err += 1
except Exception:
print("Error encountered while loading <%s>"%os.path.join(root,afile))
print('** Loaded %s models, got controlled errors for %s files' % (ok,err))
print("Error encountered while loading <%s>"
% os.path.join(root, afile))
print('** Loaded %s models, got controlled errors for %s files'
% (ok, err))
if __name__ == '__main__':
run_tests()

View File

@ -1,4 +1,4 @@
# assimp for iOS-SDK 7.1
# assimp for iOS
(deployment target 6.0+, 32/64bit)
Builds assimp libraries for several iOS CPU architectures at once, and outputs a fat binary from the result.
@ -28,3 +28,12 @@ Supported architectures/devices:
- ARMv7
- ARMv7-s
- ARM64
### Building with older iOS SDK versions
The script should work out of the box for the iOS 8.x SDKs and probably newer releases as well.
If you are using SDK version 7.x or older, you need to specify the exact SDK version inside **build.sh**, for example:
```
IOS_SDK_VERSION=7.1
```
### Optimization
By default, no compiler optimizations are specified inside the build script. For an optimized build, add the corresponding flags to the CFLAGS definition inside **build.sh**.

View File

@ -6,7 +6,7 @@
BUILD_DIR="./lib/iOS"
IOS_SDK_VERSION=7.1
IOS_SDK_VERSION=
IOS_SDK_TARGET=6.0
#(iPhoneOS iPhoneSimulator) -- determined from arch
IOS_SDK_DEVICE=
@ -50,7 +50,7 @@ build_arch()
rm CMakeCache.txt
cmake -G 'Unix Makefiles' -DCMAKE_TOOLCHAIN_FILE=./port/iOS/IPHONEOS_$(echo $1 | tr '[:lower:]' '[:upper:]')_TOOLCHAIN.cmake -DENABLE_BOOST_WORKAROUND=ON -DASSIMP_BUILD_STATIC_LIB=ON
cmake -G 'Unix Makefiles' -DCMAKE_TOOLCHAIN_FILE=./port/iOS/IPHONEOS_$(echo $1 | tr '[:lower:]' '[:upper:]')_TOOLCHAIN.cmake -DENABLE_BOOST_WORKAROUND=ON -DBUILD_SHARED_LIBS=OFF
echo "[!] Building $1 library"

View File

@ -15,7 +15,12 @@ application examples using this wrapper
How To Build
------------
I) native library
I) native library, for example by issuing this command in jassimp-native/src:
$ gcc jassimp.cpp -I/usr/lib/jvm/default/include/ \
-I/usr/lib/jvm/default/include/linux -lassimp -shared -fPIC -o libjassimp.so
libjassimp.so is required at runtime and must be located in java.library.path.
II) Java binding
The java library is built using ant. Executing "ant" in the port/jassimp

View File

@ -1379,6 +1379,7 @@ JNIEXPORT jobject JNICALL Java_jassimp_Jassimp_aiImportFile
goto end;
error:
{
jclass exception = env->FindClass("java/io/IOException");
if (NULL == exception)
@ -1390,6 +1391,7 @@ error:
env->ThrowNew(exception, aiGetErrorString());
lprintf("problem detected\n");
}
end:
/*

View File

@ -7,8 +7,6 @@
#ifdef __cplusplus
extern "C" {
#endif
/* Inaccessible static: BUILTIN */
/* Inaccessible static: s_wrapperProvider */
/*
* Class: jassimp_Jassimp
* Method: getErrorString

View File

@ -67,7 +67,7 @@ public final class JaiDebug {
return;
}
for (int i = 0; i < mesh.getNumVertives(); i++) {
for (int i = 0; i < mesh.getNumVertices(); i++) {
System.out.println("[" +
mesh.getPositionX(i) + ", " +
mesh.getPositionY(i) + ", " +
@ -119,7 +119,7 @@ public final class JaiDebug {
return;
}
for (int i = 0; i < mesh.getNumVertives(); i++) {
for (int i = 0; i < mesh.getNumVertices(); i++) {
System.out.println("[" +
mesh.getColorR(i, colorset) + ", " +
mesh.getColorG(i, colorset) + ", " +
@ -142,7 +142,7 @@ public final class JaiDebug {
return;
}
for (int i = 0; i < mesh.getNumVertives(); i++) {
for (int i = 0; i < mesh.getNumVertices(); i++) {
int numComponents = mesh.getNumUVComponents(coords);
System.out.print("[" + mesh.getTexCoordU(i, coords));

View File

@ -16,6 +16,7 @@ SOURCE_GROUP( unit FILES
)
SET( TEST_SRCS
unit/AssimpAPITest.cpp
unit/utFastAtof.cpp
unit/utFindDegenerates.cpp
unit/utFindInvalidData.cpp

View File

@ -0,0 +1,167 @@
<?xml version="1.0" encoding="UTF-8"?>
<COLLADA xmlns="http://www.collada.org/2005/11/COLLADASchema" version="1.4.1">
<asset>
<contributor/>
<created>2014-12-01T18:05:27Z</created>
<modified>2014-12-01T18:05:27Z</modified>
<unit/>
<up_axis>Z_UP</up_axis>
</asset>
<library_visual_scenes>
<visual_scene id="defaultScene">
<node id="sceneRoot">
<node id="Collada visual scene group">
<rotate sid="rotate">1 0 0 90</rotate>
<node id="Camera">
<matrix sid="Camera_matrix">0.838671 0.205746 -0.504282 -427.749 0 0.925901 0.377766 333.855 0.544639 -0.316822 0.776526 655.017 0 0 0 1</matrix>
<instance_camera url="#PerspCamera"/>
</node>
<node id="Light">
<matrix sid="Light_matrix">1 0 0 -500 0 1 0 1000 0 0 1 400 0 0 0 1</matrix>
<instance_light url="#light"/>
</node>
<node id="Box">
<matrix sid="Box_matrix">1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1</matrix>
<instance_geometry url="#BlueSG">
<bind_material>
<technique_common>
<instance_material symbol="BlueSG_material" target="#material"/>
</technique_common>
</bind_material>
</instance_geometry>
</node>
<node id="testCamera">
<matrix sid="testCamera_matrix">0.838671 0.205746 -0.504282 -427.749 0 0.925901 0.377766 333.855 0.544639 -0.316822 0.776526 655.017 0 0 0 1</matrix>
<instance_camera url="#testCameraShape"/>
</node>
<node id="pointLight1">
<matrix sid="pointLight1_matrix">1 0 0 3 0 1 0 4 0 0 1 10 0 0 0 1</matrix>
<instance_light url="#pointLightShape1"/>
</node>
</node>
</node>
</visual_scene>
</library_visual_scenes>
<library_cameras>
<camera id="PerspCamera">
<optics>
<technique_common>
<perspective>
<yfov>37.8493</yfov>
<aspect_ratio>1</aspect_ratio>
<znear>1</znear>
<zfar>1000</zfar>
</perspective>
</technique_common>
</optics>
</camera>
<camera id="testCameraShape">
<optics>
<technique_common>
<perspective>
<yfov>37.8501</yfov>
<aspect_ratio>1</aspect_ratio>
<znear>1</znear>
<zfar>1000</zfar>
</perspective>
</technique_common>
</optics>
</camera>
</library_cameras>
<library_lights>
<light id="light"/>
<light id="light">
<technique_common>
<point>
<color>1 1 1</color>
<constant_attenuation>1</constant_attenuation>
<linear_attenuation>0</linear_attenuation>
<quadratic_attenuation>0</quadratic_attenuation>
</point>
</technique_common>
</light>
<light id="pointLightShape1"/>
<light id="pointLightShape1">
<technique_common>
<point>
<color>1 1 1</color>
<constant_attenuation>1</constant_attenuation>
<linear_attenuation>0</linear_attenuation>
<quadratic_attenuation>0</quadratic_attenuation>
</point>
</technique_common>
</light>
</library_lights>
<library_geometries>
<geometry id="BlueSG">
<mesh>
<source id="BlueSG-positions">
<float_array id="BlueSG-positions-array" count="72">-50 50 50 -50 50 50 -50 50 50 50 50 50 50 50 50 50 50 50 -50 -50 50 -50 -50 50 -50 -50 50 50 -50 50 50 -50 50 50 -50 50 -50 50 -50 -50 50 -50 -50 50 -50 50 50 -50 50 50 -50 50 50 -50 -50 -50 -50 -50 -50 -50 -50 -50 -50 50 -50 -50 50 -50 -50 50 -50 -50</float_array>
<technique_common>
<accessor count="24" source="#BlueSG-positions-array" stride="3">
<param name="X" type="float"/>
<param name="Y" type="float"/>
<param name="Z" type="float"/>
</accessor>
</technique_common>
</source>
<source id="BlueSG-normals">
<float_array id="BlueSG-normals-array" count="72">0 0 1 0 1 0 -1 0 0 0 0 1 0 1 0 1 0 0 0 0 1 0 -1 0 -1 0 0 0 0 1 0 -1 0 1 0 0 0 1 0 -1 0 0 0 0 -1 0 1 0 1 0 0 0 0 -1 0 -1 0 -1 0 0 0 0 -1 0 -1 0 1 0 0 0 0 -1</float_array>
<technique_common>
<accessor count="24" source="#BlueSG-normals-array" stride="3">
<param name="X" type="float"/>
<param name="Y" type="float"/>
<param name="Z" type="float"/>
</accessor>
</technique_common>
</source>
<vertices id="BlueSG-vertices">
<input semantic="POSITION" source="#BlueSG-positions"/>
</vertices>
<tristrips count="6" material="BlueSG_material">
<input offset="0" semantic="VERTEX" source="#BlueSG-vertices" set="0"/>
<input offset="1" semantic="NORMAL" source="#BlueSG-normals" set="0"/>
<p>6 6 9 9 0 0 3 3</p>
<p>12 12 1 1 15 15 4 4</p>
<p>14 14 17 17 20 20 23 23</p>
<p>5 5 11 11 16 16 22 22</p>
<p>13 13 19 19 2 2 8 8</p>
<p>21 21 10 10 18 18 7 7</p>
</tristrips>
</mesh>
</geometry>
</library_geometries>
<library_materials>
<material id="material">
<instance_effect url="#material_effect"/>
</material>
</library_materials>
<library_effects>
<effect id="material_effect">
<profile_COMMON>
<technique sid="t0">
<phong>
<emission>
<color>0 0 0 1</color>
</emission>
<ambient>
<color>0 0 0 1</color>
</ambient>
<diffuse>
<color>0.137255 0.403922 0.870588 1</color>
</diffuse>
<specular>
<color>0.5 0.5 0.5 1</color>
</specular>
<shininess>
<float>16</float>
</shininess>
</phong>
</technique>
</profile_COMMON>
</effect>
</library_effects>
<scene>
<instance_visual_scene url="#defaultScene"/>
</scene>
</COLLADA>

View File

@ -0,0 +1,57 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2014, 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/importerdesc.h>
using namespace Assimp;
class AssimpAPITest : public ::testing::Test {
};
TEST_F( AssimpAPITest, aiGetImporterDescTest ) {
const aiImporterDesc *desc( NULL );
desc = aiGetImporterDesc( NULL );
EXPECT_EQ( NULL, desc );
desc = aiGetImporterDesc( "obj" );
EXPECT_TRUE( NULL != desc );
}

View File

@ -22,7 +22,7 @@ protected:
template <typename Real, typename AtofFunc>
static void RunTest(AtofFunc atof_func)
{
const Real kEps = 1e-5;
const Real kEps = 1e-5f;
#define TEST_CASE(NUM) EXPECT_NEAR(static_cast<Real>(NUM), atof_func(#NUM), kEps)
#define TEST_CASE_NAN(NUM) EXPECT_TRUE(IsNan(atof_func(#NUM)))

View File

@ -40,6 +40,7 @@ TEST(NoBoostTest, Tuple) {
bool b = second.get<3>();
EXPECT_FALSE(b);
// check empty tuple, ignore compile warning
boost::tuple<> third;
// FIXME: Explicit conversion not really required yet

View File

@ -68,6 +68,8 @@ void RemoveVCProcessTest::SetUp()
// so we don't need a virtual destructor
char check[sizeof(aiMaterial) == sizeof(aiMaterial) ? 10 : -1];
check[0] = 0;
// to remove compiler warning
EXPECT_TRUE( check );
}
// ------------------------------------------------------------------------------------------------