Added support for point and line primitives.

Added SortByPType and DeterminePType (anon.) steps
Optimized ASE, fixed 3DS.
Rewrite all loaders to conform to the api changes.
Optimized normal computation code in LWOLoader.cpp
Added new unit tests
Added test file for AC3D (good old wuson again)
 

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@167 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
pull/1/head
aramis_acg 2008-09-30 20:20:56 +00:00
parent 8925813026
commit 927cd1cd46
42 changed files with 27578 additions and 961 deletions

View File

@ -413,6 +413,7 @@ void Dot3DSImporter::ConvertMeshes(aiScene* pcOut)
if (aiSplit[p].size() != 0)
{
aiMesh* p_pcOut = new aiMesh();
p_pcOut->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
// be sure to setup the correct material index
p_pcOut->mMaterialIndex = p;

View File

@ -750,9 +750,10 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, std::vector<aiMesh*>& avOutMesh
// now generate submeshes
for (unsigned int p = 0; p < vSubMaterials.size();++p)
{
if (aiSplit[p].size() != 0)
if (!aiSplit[p].empty())
{
aiMesh* p_pcOut = new aiMesh();
p_pcOut->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
// let the sub material index
p_pcOut->mMaterialIndex = p;
@ -900,6 +901,7 @@ void ASEImporter::ConvertMeshes(ASE::Mesh& mesh, std::vector<aiMesh*>& avOutMesh
{
// otherwise we can simply copy the data to one output mesh
aiMesh* p_pcOut = new aiMesh();
p_pcOut->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
// set an empty sub material index
p_pcOut->mMaterialIndex = ASE::Face::DEFAULT_MATINDEX;

File diff suppressed because it is too large Load Diff

View File

@ -164,9 +164,17 @@ protected:
* expected to be correct. Override this function to implement the
* actual importing.
* <br>
* The output scene must meet the following conditions:<br>
* - at least one mesh must be there<br>
* The output scene must meet the following requirements:<br>
* - at least a root node must be there<br>
* - aiMesh::mPrimitiveTypes may be 0. The types of primitives
* in the mesh are determined automatically in this case.<br>
* - the vertex data is stored in a pseudo-indexed "verbose" format.
* In fact this means that every vertex that is referenced by
* a face is unique. Or the other way round: a vertex index may
* not occur twice in a single aiMesh.
*
* If the "AnimationSkeletonOnly"-Flag is not set:<br>
* - at least one mesh must be there<br>
* - at least one material must be there<br>
* - there may be no meshes with 0 vertices or faces<br>
* This won't be checked (except by the validation step), Assimp will

View File

@ -158,7 +158,7 @@ public:
inline void RemoveProperty( const char* name)
{
AddProperty<int*>(name, NULL);
SetGenericPropertyPtr<Base>(pmap,name,NULL);
}
private:

View File

@ -114,11 +114,9 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
// assert() it here.
//assert( must be verbose, dammit);
// TODO (Aramis)
// If we had a model format in the lib which has native support for
// tangents and bitangents, it would be necessary to add a
// "KillTangentsAndBitangents" flag ...
if (pMesh->mTangents && pMesh->mBitangents)
if (pMesh->mTangents && pMesh->mBitangents ||
!(pMesh->mPrimitiveTypes & (aiPrimitiveType_TRIANGLE | aiPrimitiveType_POLYGON)))
{
return false;
}
@ -131,6 +129,8 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
}
const float angleEpsilon = 0.9999f;
std::vector<bool> vertexDone( pMesh->mNumVertices, false);
// create space for the tangents and bitangents
pMesh->mTangents = new aiVector3D[pMesh->mNumVertices];
pMesh->mBitangents = new aiVector3D[pMesh->mNumVertices];
@ -145,6 +145,13 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
{
const aiFace& face = pMesh->mFaces[a];
if (face.mNumIndices < 3)
{
for (unsigned int i = 0; i < face.mNumIndices;++i)
vertexDone[face.mIndices[i]] = true;
continue;
}
// triangle or polygon... we always use only the first three indices. A polygon
// is supposed to be planar anyways....
@ -215,7 +222,6 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
// in the second pass we now smooth out all tangents and bitangents at the same local position
// if they are not too far off.
std::vector<bool> vertexDone( pMesh->mNumVertices, false);
for( unsigned int a = 0; a < pMesh->mNumVertices; a++)
{
if( vertexDone[a])

View File

@ -166,6 +166,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#if (!defined AI_BUILD_NO_OPTIMIZEGRAPH_PROCESS)
# include "OptimizeGraphProcess.h"
#endif
#if (!defined AI_BUILD_NO_SORTBYPTYPE_PROCESS)
# include "SortByPTypeProcess.h"
#endif
@ -254,8 +257,11 @@ Importer::Importer() :
mPostProcessingSteps.reserve(25);
#if (!defined AI_BUILD_NO_VALIDATEDS_PROCESS)
mPostProcessingSteps.push_back( new ValidateDSProcess()); // must be first
mPostProcessingSteps.push_back( new ValidateDSProcess());
#endif
mPostProcessingSteps.push_back( new DeterminePTypeHelperProcess());
#if (!defined AI_BUILD_NO_REMOVE_REDUNDANTMATERIALS_PROCESS)
mPostProcessingSteps.push_back( new RemoveRedundantMatsProcess());
#endif
@ -265,6 +271,9 @@ Importer::Importer() :
#if (!defined AI_BUILD_NO_TRIANGULATE_PROCESS)
mPostProcessingSteps.push_back( new TriangulateProcess());
#endif
#if (!defined AI_BUILD_NO_SORTBYPTYPE_PROCESS)
mPostProcessingSteps.push_back( new SortByPTypeProcess());
#endif
#if (!defined AI_BUILD_NO_PRETRANSFORMVERTICES_PROCESS)
mPostProcessingSteps.push_back( new PretransformVertices());
#endif
@ -507,6 +516,13 @@ const aiScene* Importer::ReadFile( const std::string& pFile, unsigned int pFlags
#ifdef _DEBUG
if (bExtraVerbose)
{
#if (!defined AI_BUILD_NO_VALIDATEDS_PROCESS)
DefaultLogger::get()->error("Extra verbose mode not available, library"
" wasn't build with the ValidateDS-Step");
#endif
pFlags |= aiProcess_ValidateDataStructure;
// use the MSB to tell the ValidateDS-Step that e're in extra verbose mode
@ -526,6 +542,11 @@ const aiScene* Importer::ReadFile( const std::string& pFile, unsigned int pFlags
}
if( !mScene)break;
#ifdef _DEBUG
#ifndef AI_BUILD_NO_VALIDATEDS_PROCESS
continue;
#endif
// if the extra verbose mode is active execute the
// VaidateDataStructureStep again after each step
if (bExtraVerbose && a)

View File

@ -430,43 +430,73 @@ void LWOImporter::ComputeNormals(aiMesh* mesh, const std::vector<unsigned int>&
sSort.Add(mesh->mVertices[tt],tt,*it);
}
}
// sort everything - this takes O(logn) time
// sort everything - this takes O(nlogn) time
sSort.Prepare();
std::vector<unsigned int> poResult;
poResult.reserve(20);
const float fLimit = cos(surface.mMaximumSmoothAngle);
std::vector<bool> vertexDone(mesh->mNumVertices,false);
// generate vertex normals. We have O(logn) for the binary lookup, which we need
// for n elements, thus the EXPECTED complexity is O(nlogn)
for( begin = mesh->mFaces, it = smoothingGroups.begin(); begin != end; ++begin, ++it)
if (surface.mMaximumSmoothAngle < 3.f)
{
register unsigned int sg = *it;
const float fLimit = cos(surface.mMaximumSmoothAngle);
aiFace& face = *begin;
unsigned int* beginIdx = face.mIndices, *const endIdx = face.mIndices+face.mNumIndices;
for (; beginIdx != endIdx; ++beginIdx)
for( begin = mesh->mFaces, it = smoothingGroups.begin(); begin != end; ++begin, ++it)
{
register unsigned int idx = *beginIdx;
register unsigned int sg = *it;
if (vertexDone[idx])continue;
sSort.FindPositions(mesh->mVertices[idx],sg,posEpsilon,poResult,true);
std::vector<unsigned int>::const_iterator a, end = poResult.end();
aiVector3D vNormals;
for (a = poResult.begin();a != end;++a)
aiFace& face = *begin;
unsigned int* beginIdx = face.mIndices, *const endIdx = face.mIndices+face.mNumIndices;
for (; beginIdx != endIdx; ++beginIdx)
{
const aiVector3D& v = faceNormals[*a];
if (v * faceNormals[idx] < fLimit)continue;
vNormals += v;
register unsigned int idx = *beginIdx;
sSort.FindPositions(mesh->mVertices[idx],sg,posEpsilon,poResult,true);
std::vector<unsigned int>::const_iterator a, end = poResult.end();
aiVector3D vNormals;
for (a = poResult.begin();a != end;++a)
{
const aiVector3D& v = faceNormals[*a];
if (v * faceNormals[idx] < fLimit)continue;
vNormals += v;
}
vNormals.Normalize();
mesh->mNormals[idx] = vNormals;
}
vNormals.Normalize();
for (a = poResult.begin();a != end;++a)
}
}
else // faster code path in case there is no smooth angle
{
std::vector<bool> vertexDone(mesh->mNumVertices,false);
for( begin = mesh->mFaces, it = smoothingGroups.begin(); begin != end; ++begin, ++it)
{
register unsigned int sg = *it;
aiFace& face = *begin;
unsigned int* beginIdx = face.mIndices, *const endIdx = face.mIndices+face.mNumIndices;
for (; beginIdx != endIdx; ++beginIdx)
{
mesh->mNormals[*a] = vNormals;
vertexDone[*a] = true;
register unsigned int idx = *beginIdx;
if (vertexDone[idx])continue;
sSort.FindPositions(mesh->mVertices[idx],sg,posEpsilon,poResult,true);
std::vector<unsigned int>::const_iterator a, end = poResult.end();
aiVector3D vNormals;
for (a = poResult.begin();a != end;++a)
{
const aiVector3D& v = faceNormals[*a];
vNormals += v;
}
vNormals.Normalize();
for (a = poResult.begin();a != end;++a)
{
mesh->mNormals[*a] = vNormals;
vertexDone[*a] = true;
}
}
}
}

View File

@ -232,11 +232,14 @@ void MD2Importer::InternReadFile( const std::string& pFile,
pScene->mMaterials[0] = new MaterialHelper();
pScene->mNumMeshes = 1;
pScene->mMeshes = new aiMesh*[1];
aiMesh* pcMesh = pScene->mMeshes[0] = new aiMesh();
pcMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
// navigate to the begin of the frame data
const MD2::Frame* pcFrame = (const MD2::Frame*) ((uint8_t*)
this->m_pcHeader + this->m_pcHeader->offsetFrames);
pcFrame += this->configFrameID;
// navigate to the begin of the triangle data
@ -352,16 +355,14 @@ void MD2Importer::InternReadFile( const std::string& pFile,
if (!this->m_pcHeader->skinWidth)
{
DefaultLogger::get()->error("Skin width is zero but there are "
"valid absolute texture coordinates. Unable to compute "
"relative texture coordinates ranging from 0 to 1");
"valid absolute texture coordinates");
fDivisorU = 1.0f;
}
else fDivisorU = (float)this->m_pcHeader->skinWidth;
if (!this->m_pcHeader->skinHeight)
{
DefaultLogger::get()->error("Skin height is zero but there are "
"valid absolute texture coordinates. Unable to compute "
"relative texture coordinates ranging from 0 to 1");
"valid absolute texture coordinates ");
fDivisorV = 1.0f;
}
else fDivisorV = (float)this->m_pcHeader->skinHeight;

View File

@ -281,6 +281,7 @@ void MD3Importer::InternReadFile(
// allocate the output mesh
pScene->mMeshes[iNum] = new aiMesh();
aiMesh* pcMesh = pScene->mMeshes[iNum];
pcMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
pcMesh->mNumVertices = pcSurfaces->NUM_TRIANGLES*3;
pcMesh->mNumFaces = pcSurfaces->NUM_TRIANGLES;

View File

@ -318,6 +318,7 @@ void MD5Importer::LoadMD5MeshFile ()
continue;
aiMesh* mesh = pScene->mMeshes[n] = new aiMesh();
mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
// generate unique vertices in our internal verbose format
MakeDataUnique(meshSrc);

View File

@ -438,6 +438,7 @@ void MDLImporter::InternReadFile_Quake1( )
// allocate enough storage to hold all vertices and triangles
aiMesh* pcMesh = new aiMesh();
pcMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
pcMesh->mNumVertices = pcHeader->num_tris * 3;
pcMesh->mNumFaces = pcHeader->num_tris;
pcMesh->mVertices = new aiVector3D[pcMesh->mNumVertices];
@ -632,6 +633,7 @@ void MDLImporter::InternReadFile_3DGS_MDL345( )
// allocate enough storage to hold all vertices and triangles
aiMesh* pcMesh = new aiMesh();
pcMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
pcMesh->mNumVertices = pcHeader->num_tris * 3;
pcMesh->mNumFaces = pcHeader->num_tris;
@ -835,7 +837,7 @@ void MDLImporter::CalculateUVCoordinates_MDL5()
piPtr += 3;
iHeight = (unsigned int)*piPtr++;
iWidth = (unsigned int)*piPtr;
iWidth = (unsigned int)*piPtr;
if (!iHeight || !iWidth)
{
DefaultLogger::get()->warn("Either the width or the height of the "
@ -874,21 +876,21 @@ void MDLImporter::ValidateHeader_3DGS_MDL7(const MDL::Header_MDL7* pcHeader)
if (sizeof(MDL::ColorValue_MDL7) != pcHeader->colorvalue_stc_size)
{
// LOG
throw new ImportErrorException(
"[3DGS MDL7] sizeof(MDL::ColorValue_MDL7) != pcHeader->colorvalue_stc_size");
"[3DGS MDL7] sizeof(MDL::ColorValue_MDL7) != pcHeader->colorvalue_stc_size"
);
}
if (sizeof(MDL::TexCoord_MDL7) != pcHeader->skinpoint_stc_size)
{
// LOG
throw new ImportErrorException(
"[3DGS MDL7] sizeof(MDL::TexCoord_MDL7) != pcHeader->skinpoint_stc_size");
"[3DGS MDL7] sizeof(MDL::TexCoord_MDL7) != pcHeader->skinpoint_stc_size"
);
}
if (sizeof(MDL::Skin_MDL7) != pcHeader->skin_stc_size)
{
// LOG
throw new ImportErrorException(
"sizeof(MDL::Skin_MDL7) != pcHeader->skin_stc_size");
"sizeof(MDL::Skin_MDL7) != pcHeader->skin_stc_size"
);
}
// if there are no groups ... how should we load such a file?
@ -1837,6 +1839,8 @@ void MDLImporter::GenerateOutputMeshes_3DGS_MDL7(
{
// allocate the output mesh
aiMesh* pcMesh = new aiMesh();
pcMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
pcMesh->mMaterialIndex = (unsigned int)i;
// allocate output storage

View File

@ -124,16 +124,7 @@ void MDRImporter::ValidateHeader()
DefaultLogger::get()->warn("MDR: At least one bone must be there");
// validate all LODs
uint32_t cur = pcHeader->ofsLODs;
for (uint32_t i = 0; i < pcHeader->numLODs;++i)
{
if (cur + sizeof(MDR::LOD) > fileSize)
throw new ImportErrorException("MDR: header is invalid - LOD out of range");
BE_NCONST MDR::LOD* pcSurf = (BE_NCONST MDR::LOD*)((int8_t*)pcHeader + cur);
ValidateLODHeader(pcSurf);
cur = pcSurf->ofsEnd;
}
if (pcHeader->ofsLODs > fileSize)
// validate all frames
if (pcHeader->ofsFrames + sizeof(MDR::Frame) * (pcHeader->numBones-1) *
@ -159,17 +150,6 @@ void MDRImporter::ValidateLODHeader(BE_NCONST MDR::LOD* pcLOD)
if (!pcLOD->numSurfaces)
throw new ImportErrorException("MDR: LOD has zero surfaces assigned");
uint32_t cur = pcLOD->ofsSurfaces;
for (unsigned int i = 0; i < pcLOD->numSurfaces;++i)
{
if (cur + sizeof(MDR::Surface) > iMax)
throw new ImportErrorException("MDR: LOD header is invalid");
BE_NCONST MDR::Surface* pcSurf = (BE_NCONST MDR::Surface*)((int8_t*)pcLOD + cur);
ValidateSurfaceHeader(pcSurf);
cur = pcSurf->ofsEnd;
}
}
// ------------------------------------------------------------------------------------------------
@ -214,7 +194,6 @@ void MDRImporter::SetupProperties(const Importer* pImp)
void MDRImporter::InternReadFile( const std::string& pFile,
aiScene* pScene, IOSystem* pIOHandler)
{
#if 0
boost::scoped_ptr<IOStream> file( pIOHandler->Open( pFile));
// Check whether we can read from the file
@ -264,15 +243,6 @@ void MDRImporter::InternReadFile( const std::string& pFile,
bone->mName.length = ::sprintf( bone->mName.data, "B_%i",p);
}
struct VertexInfo
{
aiVector3D xyz;
aiVector3D normal;
aiVector3D uv;
unsigned int start,num;
};
typedef std::pair<uint32_t,float> BoneWeightInfo;
std::vector<BoneWeightInfo> mWeights;
mWeights.reserve(surf->numVerts << 1);
@ -341,5 +311,4 @@ void MDRImporter::InternReadFile( const std::string& pFile,
pScene->mNumMeshes = (unsigned int) outMeshes.size();
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
::memcpy(pScene->mMeshes,&outMeshes[0],sizeof(void*)*pScene->mNumMeshes);
#endif
}

View File

@ -120,6 +120,16 @@ protected:
protected:
struct VertexInfo
{
aiVector3D xyz;
aiVector3D normal;
aiVector3D uv;
unsigned int start,num;
};
typedef std::pair<uint32_t,float> BoneWeightInfo;
/** Configuration option: frame to be loaded */
unsigned int configFrameID;

View File

@ -443,6 +443,9 @@ void OptimizeGraphProcess::JoinMeshes(std::vector<aiMesh*>& meshList,
out->mNumVertices += (*it)->mNumVertices;
out->mNumFaces += (*it)->mNumFaces;
out->mNumBones += AI_OG_UNMASK((*it)->mNumBones);
// combine primitive type flags
out->mPrimitiveTypes |= (*it)->mPrimitiveTypes;
}
if (out->mNumVertices) // just for safety

View File

@ -787,13 +787,6 @@ void PLYImporter::LoadFaces(std::vector<PLY::Face>* pvOut)
const unsigned int iNum = (unsigned int)(*i)->alProperties[iProperty].avList.size();
sFace.mIndices.resize(iNum);
if (3 > iNum)
{
// We must filter out all degenerates.
DefaultLogger::get()->warn("PLY: Found degenerated triangle");
continue;
}
std::list<PLY::PropertyInstance::ValueUnion>::const_iterator p =
(*i)->alProperties[iProperty].avList.begin();

View File

@ -41,12 +41,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_PROCESS_HELPER_H_INCLUDED
#define AI_PROCESS_HELPER_H_INCLUDED
#include "SpatialSort.h"
#include "../include/aiPostProcess.h"
#include "SpatialSort.h"
#include "BaseProcess.h"
namespace Assimp {
typedef std::pair< unsigned int,float > PerVertexWeight;
typedef std::vector< PerVertexWeight > VertexWeightTable;
// ------------------------------------------------------------------------------------------------
// compute a good epsilon value for position comparisons
inline float ComputePositionEpsilon(const aiMesh* pMesh)
{
const float epsilon = 1e-5f;
@ -65,6 +71,28 @@ inline float ComputePositionEpsilon(const aiMesh* pMesh)
return (maxVec - minVec).Length() * epsilon;
}
// ------------------------------------------------------------------------------------------------
// Compute a per-vertex bone weight table
// NOTE: delete result with operator delete[] ...
inline VertexWeightTable* ComputeVertexBoneWeightTable(aiMesh* pMesh)
{
if (!pMesh || !pMesh->mNumVertices || !pMesh->mNumBones) return NULL;
VertexWeightTable* avPerVertexWeights = new VertexWeightTable[pMesh->mNumVertices];
for (unsigned int i = 0; i < pMesh->mNumBones;++i)
{
aiBone* bone = pMesh->mBones[i];
for (unsigned int a = 0; a < bone->mNumWeights;++a)
{
aiVertexWeight& weight = bone->mWeights[a];
avPerVertexWeights[weight.mVertexId].push_back(
std::pair<unsigned int,float>(a,weight.mWeight));
}
}
return avPerVertexWeights;
}
// ------------------------------------------------------------------------------------------------
class ComputeSpatialSortProcess : public BaseProcess
{

View File

@ -283,6 +283,8 @@ void RAWImporter::InternReadFile( const std::string& pFile,
aiMesh* mesh = pScene->mMeshes[meshIdx] = new aiMesh();
mesh->mMaterialIndex = meshIdx++;
mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
// allocate storage for the vertex components and copy them
mesh->mNumVertices = (unsigned int)(*it2).vertices.size();
mesh->mVertices = new aiVector3D[ mesh->mNumVertices ];

View File

@ -307,6 +307,7 @@ void SMDImporter::CreateOutputMeshes()
aiMesh*& pcMesh = this->pScene->mMeshes[i] = new aiMesh();
ai_assert(!aaiFaces[i].empty()); // should not be empty ...
pcMesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
pcMesh->mNumVertices = (unsigned int)aaiFaces[i].size()*3;
pcMesh->mNumFaces = (unsigned int)aaiFaces[i].size();
pcMesh->mMaterialIndex = i;
@ -341,7 +342,7 @@ void SMDImporter::CreateOutputMeshes()
pcMesh->mFaces[iFace].mIndices = new unsigned int[3];
pcMesh->mFaces[iFace].mNumIndices = 3;
// fill the vertices (hardcode the loop for performance)
// fill the vertices
unsigned int iSrcFace = aaiFaces[i][iFace];
SMD::Face& face = this->asTriangles[iSrcFace];

View File

@ -0,0 +1,444 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (ASSIMP)
---------------------------------------------------------------------------
Copyright (c) 2006-2008, ASSIMP Development Team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the ASSIMP team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the ASSIMP Development Team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
/** @file Implementation of the DeterminePTypeHelperProcess and
* SortByPTypeProcess post-process steps.
*/
// public ASSIMP headers
#include "../include/DefaultLogger.h"
#include "../include/aiPostProcess.h"
#include "../include/aiScene.h"
// internal headers
#include "ProcessHelper.h"
#include "SortByPTypeProcess.h"
#include "qnan.h"
using namespace Assimp;
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
DeterminePTypeHelperProcess ::DeterminePTypeHelperProcess()
{
// nothing to do here
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
DeterminePTypeHelperProcess::~DeterminePTypeHelperProcess()
{
// nothing to do here
}
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
bool DeterminePTypeHelperProcess::IsActive( unsigned int pFlags) const
{
// this step is always active
return true;
}
// ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data.
void DeterminePTypeHelperProcess::Execute( aiScene* pScene)
{
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
{
aiMesh* mesh = pScene->mMeshes[i];
if (!mesh->mPrimitiveTypes)
{
bool bDeg = false;
for (unsigned int a = 0; a < mesh->mNumFaces; ++a)
{
aiFace& face = mesh->mFaces[a];
switch (face.mNumIndices)
{
case 3u:
// check whether the triangle is degenerated
if (mesh->mVertices[face.mIndices[0]] == mesh->mVertices[face.mIndices[1]] ||
mesh->mVertices[face.mIndices[1]] == mesh->mVertices[face.mIndices[2]])
{
face.mNumIndices = 2;
unsigned int* pi = new unsigned int[2];
pi[0] = face.mIndices[0];
pi[1] = face.mIndices[2];
delete[] face.mIndices;
face.mIndices = pi;
bDeg = true;
}
else if (mesh->mVertices[face.mIndices[2]] == mesh->mVertices[face.mIndices[0]])
{
face.mNumIndices = 2;
unsigned int* pi = new unsigned int[2];
pi[0] = face.mIndices[0];
pi[1] = face.mIndices[1];
delete[] face.mIndices;
face.mIndices = pi;
bDeg = true;
}
else
{
mesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
break;
}
case 2u:
// check whether the line is degenerated
if (mesh->mVertices[face.mIndices[0]] == mesh->mVertices[face.mIndices[1]])
{
face.mNumIndices = 1;
unsigned int* pi = new unsigned int[1];
pi[0] = face.mIndices[0];
delete[] face.mIndices;
face.mIndices = pi;
bDeg = true;
}
else
{
mesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
break;
}
case 1u:
mesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
break;
default:
mesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
break;
}
}
if (bDeg)
{
DefaultLogger::get()->warn("Found degenerated primitives");
}
}
}
}
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
SortByPTypeProcess::SortByPTypeProcess()
{
// nothing to do here
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
SortByPTypeProcess::~SortByPTypeProcess()
{
// nothing to do here
}
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
bool SortByPTypeProcess::IsActive( unsigned int pFlags) const
{
return (pFlags & aiProcess_SortByPType) != 0;
}
// ------------------------------------------------------------------------------------------------
// Update changed meshes in all nodes
void UpdateNodes(const std::vector<unsigned int>& replaceMeshIndex, aiNode* node)
{
std::vector<unsigned int>::const_iterator it;
if (node->mNumMeshes)
{
unsigned int newSize = 0;
for (unsigned int m = 0; m< node->mNumMeshes; ++m)
{
it = replaceMeshIndex.begin()+(node->mMeshes[m]*5u);
for (;*it != 0xcdcdcdcd;++it)
{
if (0xffffffff != *it)++newSize;
}
}
ai_assert(0 != newSize);
unsigned int* newMeshes = new unsigned int[newSize];
for (unsigned int m = 0; m< node->mNumMeshes; ++m)
{
it = replaceMeshIndex.begin()+(node->mMeshes[m]*5u);
for (;*it != 0xcdcdcdcd;++it)
{
if (0xffffffff != *it)*newMeshes++ = *it;
}
}
delete[] node->mMeshes;
node->mMeshes = newMeshes-(node->mNumMeshes = newSize);
}
// call all subnodes recursively
for (unsigned int m = 0; m < node->mNumChildren; ++m)
UpdateNodes(replaceMeshIndex,node->mChildren[m]);
}
// ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data.
void SortByPTypeProcess::Execute( aiScene* pScene)
{
if (!pScene->mNumMeshes)return;
std::vector<aiMesh*> outMeshes;
outMeshes.reserve(pScene->mNumMeshes<<1u);
std::vector<unsigned int> replaceMeshIndex(pScene->mNumMeshes*5,0xffffffff);
std::vector<unsigned int>::iterator meshIdx = replaceMeshIndex.begin();
for (unsigned int i = 0; i < pScene->mNumMeshes;++i)
{
aiMesh* mesh = pScene->mMeshes[i];
ai_assert(0 != mesh->mPrimitiveTypes);
// if there's just one primitive type in the mesh there's nothing to do for us
unsigned int num = 0;
if (mesh->mPrimitiveTypes & aiPrimitiveType_POINT) ++num;
if (mesh->mPrimitiveTypes & aiPrimitiveType_LINE) ++num;
if (mesh->mPrimitiveTypes & aiPrimitiveType_TRIANGLE) ++num;
if (mesh->mPrimitiveTypes & aiPrimitiveType_POLYGON) ++num;
if (1 == num)
{
*meshIdx = (unsigned int) outMeshes.size();
outMeshes.push_back(mesh);
meshIdx += 4;
*meshIdx = 0xcdcdcdcd;
++meshIdx;
continue;
}
const unsigned int first = (unsigned int)outMeshes.size();
// reuse our current mesh arrays for the submesh
// with the largest numer of primitives
unsigned int aiNumPerPType[4] = {0,0,0,0};
aiFace* pFirstFace = mesh->mFaces;
aiFace* const pLastFace = pFirstFace + mesh->mNumFaces;
unsigned int numPolyVerts = 0;
for (;pFirstFace != pLastFace; ++pFirstFace)
{
if (pFirstFace->mNumIndices <= 3)
++aiNumPerPType[pFirstFace->mNumIndices-1];
else
{
++aiNumPerPType[3];
numPolyVerts += pFirstFace-> mNumIndices;
}
}
VertexWeightTable* avw = ComputeVertexBoneWeightTable(mesh);
for (unsigned int real = 0; real < 4; ++real,++meshIdx)
{
if ( !aiNumPerPType[real])
{
continue;
}
*meshIdx = (unsigned int) outMeshes.size();
outMeshes.push_back(new aiMesh());
aiMesh* out = outMeshes.back();
// copy data members
out->mPrimitiveTypes = 1u << real;
out->mMaterialIndex = mesh->mMaterialIndex;
// allocate output storage
out->mNumFaces = aiNumPerPType[real];
aiFace* outFaces = out->mFaces = new aiFace[out->mNumFaces];
out->mNumVertices = (3 == real ? numPolyVerts : out->mNumFaces * (real+1));
aiVector3D *vert(NULL), *nor(NULL), *tan(NULL), *bit(NULL);
aiVector3D *uv [AI_MAX_NUMBER_OF_TEXTURECOORDS];
aiColor4D *cols [AI_MAX_NUMBER_OF_COLOR_SETS];
if (mesh->mVertices)
vert = out->mVertices = new aiVector3D[out->mNumVertices];
if (mesh->mNormals)
nor = out->mNormals = new aiVector3D[out->mNumVertices];
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;
out->mNumUVComponents[i] = mesh->mNumUVComponents[i];
}
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;
}
typedef std::vector< aiVertexWeight > TempBoneInfo;
std::vector< TempBoneInfo > tempBones(mesh->mNumBones);
// try to guess how much storage we'll need
for (unsigned int q = 0; q < mesh->mNumBones;++q)
{
tempBones[q].reserve(mesh->mBones[q]->mNumWeights / (num-1));
}
unsigned int outIdx = 0;
for (unsigned int m = 0; m < mesh->mNumFaces; ++m)
{
aiFace& in = mesh->mFaces[m];
if ((real == 3 && in.mNumIndices <= 3) || (real != 3 && in.mNumIndices != real+1))
{
continue;
}
outFaces->mNumIndices = in.mNumIndices;
outFaces->mIndices = in.mIndices;
for (unsigned int q = 0; q < in.mNumIndices; ++q)
{
register unsigned int idx = in.mIndices[q];
// process all bones of this index
if (avw)
{
VertexWeightTable& tbl = avw[idx];
for (VertexWeightTable::const_iterator it = tbl.begin(), end = tbl.end();
it != end; ++it)
{
tempBones[ (*it).first ].push_back( aiVertexWeight(idx, (*it).second) );
}
}
if (vert)
{
*vert++ = mesh->mVertices[idx];
mesh->mVertices[idx].x = std::numeric_limits<float>::quiet_NaN();
}
if (nor )*nor++ = mesh->mNormals[idx];
if (tan )
{
*tan++ = mesh->mTangents[idx];
*bit++ = mesh->mBitangents[idx];
}
for (unsigned int pp = 0; pp < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++pp)
{
if (!uv[pp])break;
*uv[pp]++ = mesh->mTextureCoords[pp][idx];
}
for (unsigned int pp = 0; pp < AI_MAX_NUMBER_OF_COLOR_SETS; ++pp)
{
if (!cols[pp])break;
*cols[pp]++ = mesh->mColors[pp][idx];
}
in.mIndices[q] = outIdx++;
}
in.mIndices = NULL;
++outFaces;
}
// now generate output bones
for (unsigned int q = 0; q < mesh->mNumBones;++q)
if (!tempBones[q].empty())++out->mNumBones;
if (out->mNumBones)
{
out->mBones = new aiBone*[out->mNumBones];
for (unsigned int q = 0, real = 0; q < mesh->mNumBones;++q)
{
TempBoneInfo& in = tempBones[q];
if (in.empty())continue;
aiBone* srcBone = mesh->mBones[q];
aiBone* bone = out->mBones[real] = new aiBone();
bone->mName = srcBone->mName;
bone->mOffsetMatrix = srcBone->mOffsetMatrix;
bone->mNumWeights = (unsigned int)in.size();
bone->mWeights = new aiVertexWeight[bone->mNumWeights];
::memcpy(bone->mWeights,&in[0],bone->mNumWeights*sizeof(void*));
++real;
}
}
}
*meshIdx = 0xcdcdcdcd;
++meshIdx;
// delete the per-vertex bone weights table
delete[] avw;
// delete the input mesh
delete mesh;
}
UpdateNodes(replaceMeshIndex,pScene->mRootNode);
if (outMeshes.size() != pScene->mNumMeshes)
{
delete[] pScene->mMeshes;
pScene->mNumMeshes = (unsigned int)outMeshes.size();
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
::memcpy(pScene->mMeshes,&outMeshes[0],pScene->mNumMeshes*sizeof(void*));
}
}

View File

@ -0,0 +1,105 @@
/*
Open Asset Import Library (ASSIMP)
----------------------------------------------------------------------
Copyright (c) 2006-2008, ASSIMP Development Team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the
following conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the ASSIMP team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the ASSIMP Development Team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
/** @file Defines a post processing step to sort meshes by the types
of primitives they contain */
#ifndef AI_SORTBYPTYPEPROCESS_H_INC
#define AI_SORTBYPTYPEPROCESS_H_INC
#include "BaseProcess.h"
#include "../include/aiMesh.h"
class SortByPTypeProcessTest;
namespace Assimp {
// ---------------------------------------------------------------------------
/** DeterminePTypeHelperProcess: If aiMesh::mPrimitiveTypes is 0,
* this step determines the types of primitive a mesh consists of.
*/
class ASSIMP_API DeterminePTypeHelperProcess : public BaseProcess
{
friend class Importer;
friend class ::SortByPTypeProcessTest; // grant the unit test full access to us
protected:
/** Constructor to be privately used by Importer */
DeterminePTypeHelperProcess();
/** Destructor, private as well */
~DeterminePTypeHelperProcess();
public:
// -------------------------------------------------------------------
bool IsActive( unsigned int pFlags) const;
// -------------------------------------------------------------------
void Execute( aiScene* pScene);
};
// ---------------------------------------------------------------------------
/** SortByPTypeProcess: Sorts meshes by the types of primitives they contain.
* A mesh with 5 lines, 3 points and 145 triangles would be split in 3
* submeshes.
*/
class ASSIMP_API SortByPTypeProcess : public BaseProcess
{
friend class Importer;
friend class ::SortByPTypeProcessTest; // grant the unit test full access to us
protected:
/** Constructor to be privately used by Importer */
SortByPTypeProcess();
/** Destructor, private as well */
~SortByPTypeProcess();
public:
// -------------------------------------------------------------------
bool IsActive( unsigned int pFlags) const;
// -------------------------------------------------------------------
void Execute( aiScene* pScene);
};
} // end of namespace Assimp
#endif // !!AI_SORTBYPTYPEPROCESS_H_INC

View File

@ -41,13 +41,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file Implementation of the SplitLargeMeshes postprocessing step
*/
#include "SplitLargeMeshes.h"
// public Assimp headers
#include "../include/DefaultLogger.h"
#include "../include/aiPostProcess.h"
#include "../include/aiMesh.h"
#include "../include/aiScene.h"
#include "../include/assimp.hpp"
// internal headers of the post-processing framework
#include "SplitLargeMeshes.h"
#include "ProcessHelper.h"
using namespace Assimp;
@ -276,6 +281,22 @@ void SplitLargeMeshesProcess_Triangle::SplitMesh(
unsigned int* pi = pMesh->mFaces[iTemp].mIndices;
unsigned int* piOut = pcMesh->mFaces[p].mIndices = new unsigned int[iNumIndices];
// need to update the output primitive types
switch (iNumIndices)
{
case 1:
pcMesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
break;
case 2:
pcMesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
break;
case 3:
pcMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
break;
default:
pcMesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
}
// and copy the contents of the old array, offset by current base
for (unsigned int v = 0; v < iNumIndices;++v)
{
@ -384,23 +405,9 @@ void SplitLargeMeshesProcess_Vertex::SplitMesh(
if (pMesh->mNumVertices > SplitLargeMeshesProcess_Vertex::LIMIT)
{
typedef std::vector< std::pair<unsigned int,float> > VertexWeightTable;
VertexWeightTable* avPerVertexWeights = NULL;
// build a per-vertex weight list if necessary
if (pMesh->HasBones())
{
avPerVertexWeights = new VertexWeightTable[pMesh->mNumVertices];
for (unsigned int i = 0; i < pMesh->mNumBones;++i)
{
aiBone* bone = pMesh->mBones[i];
for (unsigned int a = 0; a < bone->mNumWeights;++a)
{
aiVertexWeight& weight = bone->mWeights[a];
avPerVertexWeights[weight.mVertexId].push_back(
std::pair<unsigned int,float>(a,weight.mWeight));
}
}
}
VertexWeightTable* avPerVertexWeights = ComputeVertexBoneWeightTable(pMesh);
// we need to split this mesh into sub meshes
// determine the estimated size of a submesh
@ -506,6 +513,22 @@ void SplitLargeMeshesProcess_Vertex::SplitMesh(
rFace.mNumIndices = iNumIndices;
rFace.mIndices = new unsigned int[iNumIndices];
// need to update the output primitive types
switch (rFace.mNumIndices)
{
case 1:
pcMesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
break;
case 2:
pcMesh->mPrimitiveTypes |= aiPrimitiveType_LINE;
break;
case 3:
pcMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
break;
default:
pcMesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
}
// and copy the contents of the old array, offset by current base
for (unsigned int v = 0; v < iNumIndices;++v)
{

View File

@ -51,7 +51,7 @@ namespace Assimp
*
* This is required since stricmp() is not consistently available on
* all platforms. Some platforms use the '_' prefix, others don't even
* have such a function. Yes, this is called an ISO standard.
* have such a function.
*
* \param s1 First input string
* \param s2 Second input string
@ -94,7 +94,7 @@ inline int ASSIMP_stricmp(const std::string& a, const std::string& b)
*
* This is required since strincmp() is not consistently available on
* all platforms. Some platforms use the '_' prefix, others don't even
* have such a function. Yes, this is called an ISO standard.
* have such a function.
*
* \param s1 First input string
* \param s2 Second input string

View File

@ -94,31 +94,41 @@ void TriangulateProcess::Execute( aiScene* pScene)
bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
{
// check whether we will need to do something ...
bool bNeed = false;
for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
// FIX: now we have aiMesh::mPrimitiveTypes, so this is only here for test cases
if (!pMesh->mPrimitiveTypes)
{
const aiFace& face = pMesh->mFaces[a];
if( face.mNumIndices != 3)
bool bNeed = false;
for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
{
bNeed = true;
const aiFace& face = pMesh->mFaces[a];
if( face.mNumIndices != 3)
{
bNeed = true;
}
}
if (!bNeed)return false;
}
if (!bNeed)return false;
else if (!(pMesh->mPrimitiveTypes & aiPrimitiveType_POLYGON))
return false;
// the output mesh will contain triangles, but no polys anymore
pMesh->mPrimitiveTypes |= aiPrimitiveType_TRIANGLE;
pMesh->mPrimitiveTypes &= ~aiPrimitiveType_POLYGON;
std::vector<aiFace> newFaces;
newFaces.reserve( pMesh->mNumFaces*2);
for( unsigned int a = 0; a < pMesh->mNumFaces; a++)
{
const aiFace& face = pMesh->mFaces[a];
aiFace& face = pMesh->mFaces[a];
// if it's a simple primitive, just copy it
if( face.mNumIndices == 3)
if( face.mNumIndices <= 3)
{
newFaces.push_back( aiFace());
aiFace& nface = newFaces.back();
nface.mNumIndices = face.mNumIndices;
nface.mIndices = new unsigned int[nface.mNumIndices];
memcpy( nface.mIndices, face.mIndices, nface.mNumIndices * sizeof( unsigned int));
nface.mIndices = face.mIndices;
face.mIndices = NULL;
}
else
{
@ -138,11 +148,17 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
// kill the old faces
delete [] pMesh->mFaces;
// and insert our newly generated faces
pMesh->mNumFaces = (unsigned int)newFaces.size();
pMesh->mFaces = new aiFace[pMesh->mNumFaces];
for( unsigned int a = 0; a < newFaces.size(); a++)
pMesh->mFaces[a] = newFaces[a];
{
// operator= would copy the whole array which is definitely not necessary
pMesh->mFaces[a].mNumIndices = newFaces[a].mNumIndices;
pMesh->mFaces[a].mIndices = newFaces[a].mIndices;
newFaces[a].mIndices = NULL;
}
return true;
}

View File

@ -48,6 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
struct aiMesh;
class TriangulateProcessTest;
namespace Assimp
{
@ -59,6 +60,7 @@ namespace Assimp
class ASSIMP_API TriangulateProcess : public BaseProcess
{
friend class Importer;
friend class ::TriangulateProcessTest; // grant the unit test full access to us
protected:
/** Constructor to be privately used by Importer */

View File

@ -251,6 +251,50 @@ void ValidateDSProcess::Validate( const aiMesh* pMesh)
pMesh->mMaterialIndex,this->mScene->mNumMaterials-1);
}
for (unsigned int i = 0; i < pMesh->mNumFaces; ++i)
{
aiFace& face = pMesh->mFaces[i];
if (pMesh->mPrimitiveTypes)
{
switch (face.mNumIndices)
{
case 0:
this->ReportError("aiMesh::mFaces[%i].mNumIndices is 0",i);
case 1:
if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_POINT))
{
this->ReportError("aiMesh::mFaces[%i] is a POINT but aiMesh::mPrimtiveTypes "
"does not report the POINT flag",i);
}
break;
case 2:
if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_LINE))
{
this->ReportError("aiMesh::mFaces[%i] is a LINE but aiMesh::mPrimtiveTypes "
"does not report the LINE flag",i);
}
break;
case 3:
if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_TRIANGLE))
{
this->ReportError("aiMesh::mFaces[%i] is a TRIANGLE but aiMesh::mPrimtiveTypes "
"does not report the TRIANGLE flag",i);
}
break;
default:
if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_POLYGON))
{
this->ReportError("aiMesh::mFaces[%i] is a POLYGON but aiMesh::mPrimtiveTypes "
"does not report the POLYGON flag",i);
}
break;
};
}
if (!face.mIndices)this->ReportError("aiMesh::mFaces[%i].mIndices is NULL",i);
}
if (this->mScene->mFlags & AI_SCENE_FLAGS_ANIM_SKELETON_ONLY)
{
if (pMesh->mNumVertices || pMesh->mVertices ||
@ -281,10 +325,6 @@ void ValidateDSProcess::Validate( const aiMesh* pMesh)
for (unsigned int i = 0; i < pMesh->mNumFaces;++i)
{
aiFace& face = pMesh->mFaces[i];
if (!face.mIndices)this->ReportError("aiMesh::mFaces[%i].mIndices is NULL",i);
if (face.mNumIndices < 3)this->ReportError(
"aiMesh::mFaces[%i].mIndices is not a triangle or polygon",i);
for (unsigned int a = 0; a < face.mNumIndices;++a)
{
if (face.mIndices[a] >= pMesh->mNumVertices)

View File

@ -58,6 +58,7 @@ SOURCES = 3DSConverter.cpp \
MDRLoader.cpp \
RawLoader.cpp \
OFFLoader.cpp \
SortByPTypeProcess.cpp \
XFileParser.cpp
OBJECTS = $(SOURCES:.cpp=.o)

View File

@ -12,7 +12,7 @@ inline bool is_qnan(const float in)
// Another method would be to check whether in != in.
// This should also wor since nan compares to inequal,
// even when compared with itself. However, this could
// case problems with other special floats like snan or inf
// cause problems with other special floats like snan
union _tagFPUNION
{
float f;

View File

@ -290,9 +290,9 @@ inline aiMatrix4x4& aiMatrix4x4::RotationZ(float a, aiMatrix4x4& out)
inline aiMatrix4x4& aiMatrix4x4::Translation(aiVector3D v, aiMatrix4x4& out)
{
out = aiMatrix4x4();
out.d1 = v.x;
out.d2 = v.y;
out.d3 = v.z;
out.a4 = v.x;
out.b4 = v.y;
out.c4 = v.z;
return out;
}

View File

@ -250,6 +250,40 @@ struct aiBone
#define AI_MESH_SMOOTHING_ANGLE_NOT_SET (10e10f)
// ---------------------------------------------------------------------------
/** Enumerates the types of geometric primitives supported by Assimp.
*/
// ---------------------------------------------------------------------------
enum aiPrimitiveType
{
/** A point primitive.
* This is just a single vertex in the virtual world,
* #aiFace contains just one index for such a primitive,
*/
aiPrimitiveType_POINT = 0x1,
/** A line primitive.
* This is a line defined through a start and an end position.
* #aiFace contains exactly two indices for such a primitive,
*/
aiPrimitiveType_LINE = 0x2,
/** A triangular primitive.
* A triangle consists of three indices.
*/
aiPrimitiveType_TRIANGLE = 0x4,
/** A higher-level polygon with more than 3 edges.
* A triangle is a polygon, but polygon in this context means
* "all polygons that are not triangles". The "Triangulate"-Step
* is provided for your convinience, it splits all polygons in
* triangles (which are much easier to handle).
*/
aiPrimitiveType_POLYGON = 0x8
};
// ---------------------------------------------------------------------------
/** A mesh represents a geometry or model with a single material.
*
@ -269,6 +303,13 @@ struct aiBone
// ---------------------------------------------------------------------------
struct aiMesh
{
/** Bitwise combination of the members of the #aiPrimitiveType enum.
* This specifies which types of primitives are present in the mesh.
* The "SortByPrimitiveType"-Step can be used to make sure the
* output meshes consist of one primitive type each.
*/
unsigned int mPrimitiveTypes;
/** The number of vertices in this mesh.
* This is also the size of all of the per-vertex data arrays
*/
@ -361,9 +402,11 @@ struct aiMesh
//! Default constructor. Initializes all members to 0
aiMesh()
{
mNumVertices = 0; mNumFaces = 0;
mVertices = NULL; mFaces = NULL;
mNormals = NULL; mTangents = NULL;
mNumVertices = 0;
mNumFaces = 0;
mPrimitiveTypes = 0;
mVertices = NULL; mFaces = NULL;
mNormals = NULL; mTangents = NULL;
mBitangents = NULL;
for( unsigned int a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; a++)
{

View File

@ -186,12 +186,21 @@ enum aiPostProcessSteps
* are used by the same node or by nodes on the same hierarchy (with
* equal local transformations). Unlike PreTransformVertices, the
* OptimizeGraph-step doesn't transform vertices from one space
* another.<br>
* 3. Remove hierarchy levels<br>
* another (at least with the default configuration).<br>
*
* It is recommended to have this step run with the default configuration.
*/
aiProcess_OptimizeGraph = 0x4000
aiProcess_OptimizeGraph = 0x4000,
/** This step splits meshes with more than one primitive type in
* homogenous submeshes.
*
* The step is executed after the triangulation step. After the step
* returns, just one bit is set in aiMesh::mPrimitiveTypes. This is
* especially useful for real-time rendering where point and line
* primitives are often ignored or rendered separately.
*/
aiProcess_SortByPType = 0x8000
};

25609
test/ACFiles/Wuson.ac 100644

File diff suppressed because it is too large Load Diff

View File

@ -29,6 +29,6 @@ void GenNormalsTest :: tearDown (void)
void GenNormalsTest :: testSimpleTriangle (void)
{
this->piProcess->GenMeshVertexNormals(pcMesh);
this->piProcess->GenMeshVertexNormals(pcMesh,0);
CPPUNIT_ASSERT(0 != pcMesh->mNormals);
}

View File

@ -0,0 +1,164 @@
#include "utSortByPType.h"
CPPUNIT_TEST_SUITE_REGISTRATION (SortByPTypeProcessTest);
static unsigned int num[10][4] =
{
{0,0,0,1000},
{0,0,1000,0},
{0,1000,0,0},
{1000,0,0,0},
{500,500,0,0},
{500,0,500,0},
{0,330,330,340},
{250,250,250,250},
{100,100,100,700},
{0,100,0,900},
};
static unsigned int result[10] =
{
aiPrimitiveType_POLYGON,
aiPrimitiveType_TRIANGLE,
aiPrimitiveType_LINE,
aiPrimitiveType_POINT,
aiPrimitiveType_POINT | aiPrimitiveType_LINE,
aiPrimitiveType_POINT | aiPrimitiveType_TRIANGLE,
aiPrimitiveType_TRIANGLE | aiPrimitiveType_LINE | aiPrimitiveType_POLYGON,
aiPrimitiveType_POLYGON | aiPrimitiveType_LINE | aiPrimitiveType_TRIANGLE | aiPrimitiveType_POINT,
aiPrimitiveType_POLYGON | aiPrimitiveType_LINE | aiPrimitiveType_TRIANGLE | aiPrimitiveType_POINT,
aiPrimitiveType_LINE | aiPrimitiveType_POLYGON,
};
void SortByPTypeProcessTest :: setUp (void)
{
process0 = new DeterminePTypeHelperProcess();
process1 = new SortByPTypeProcess();
scene = new aiScene();
scene->mNumMeshes = 10;
scene->mMeshes = new aiMesh*[10];
bool five = false;
for (unsigned int i = 0; i < 10; ++i)
{
aiMesh* mesh = scene->mMeshes[i] = new aiMesh();
mesh->mNumFaces = 1000;
aiFace* faces = mesh->mFaces = new aiFace[1000];
aiVector3D* pv = mesh->mVertices = new aiVector3D[mesh->mNumFaces*5];
aiVector3D* pn = mesh->mNormals = new aiVector3D[mesh->mNumFaces*5];
aiVector3D* pt = mesh->mTangents = new aiVector3D[mesh->mNumFaces*5];
aiVector3D* pb = mesh->mBitangents = new aiVector3D[mesh->mNumFaces*5];
aiVector3D* puv = mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumFaces*5];
unsigned int remaining[4] = {num[i][0],num[i][1],num[i][2],num[i][3]};
unsigned int n = 0;
for (unsigned int m = 0; m < 1000; ++m)
{
unsigned int idx = m % 4;
while (true)
{
if (!remaining[idx])
{
if (4 == ++idx)idx = 0;
continue;
}
break;
}
faces->mNumIndices = idx+1;
if (4 == faces->mNumIndices)
{
if(five)++faces->mNumIndices;
five = !five;
}
faces->mIndices = new unsigned int[faces->mNumIndices];
for (unsigned int q = 0; q <faces->mNumIndices;++q,++n)
{
faces->mIndices[q] = n;
float f = (float)remaining[idx];
// (the values need to be unique - otherwise all degenerates would be removed)
*pv++ = aiVector3D(f,f+1.f,f+q);
*pn++ = aiVector3D(f,f+1.f,f+q);
*pt++ = aiVector3D(f,f+1.f,f+q);
*pb++ = aiVector3D(f,f+1.f,f+q);
*puv++ = aiVector3D(f,f+1.f,f+q);
}
++faces;
--remaining[idx];
}
mesh->mNumVertices = n;
}
scene->mRootNode = new aiNode();
scene->mRootNode->mNumChildren = 5;
scene->mRootNode->mChildren = new aiNode*[5];
for (unsigned int i = 0; i< 5;++i )
{
aiNode* node = scene->mRootNode->mChildren[i] = new aiNode();
node->mNumMeshes = 2;
node->mMeshes = new unsigned int[2];
node->mMeshes[0] = (i<<1u);
node->mMeshes[1] = (i<<1u)+1;
}
}
void SortByPTypeProcessTest :: tearDown (void)
{
delete process0;
delete process1;
delete scene;
}
void SortByPTypeProcessTest :: testDeterminePTypeStep (void)
{
process0->Execute(scene);
for (unsigned int i = 0; i < 10; ++i)
{
aiMesh* mesh = scene->mMeshes[i];
CPPUNIT_ASSERT(mesh->mPrimitiveTypes == result[i]);
}
}
void SortByPTypeProcessTest :: testSortByPTypeStep (void)
{
process0->Execute(scene);
process1->Execute(scene);
unsigned int idx = 0;
for (unsigned int m = 0,real = 0; m< 10;++m)
{
for (unsigned int n = 0; n < 4;++n)
{
if ((idx = num[m][n]))
{
CPPUNIT_ASSERT(real < scene->mNumMeshes);
aiMesh* mesh = scene->mMeshes[real];
CPPUNIT_ASSERT(NULL != mesh);
CPPUNIT_ASSERT(mesh->mPrimitiveTypes == 1u<<n);
CPPUNIT_ASSERT(NULL != mesh->mVertices);
CPPUNIT_ASSERT(NULL != mesh->mNormals);
CPPUNIT_ASSERT(NULL != mesh->mTangents);
CPPUNIT_ASSERT(NULL != mesh->mBitangents);
CPPUNIT_ASSERT(NULL != mesh->mTextureCoords[0]);
CPPUNIT_ASSERT(mesh->mNumFaces == idx);
for (unsigned int f = 0; f < mesh->mNumFaces;++f)
{
aiFace& face = mesh->mFaces[f];
CPPUNIT_ASSERT(face.mNumIndices == (n+1) || (3 == n && face.mNumIndices > 3));
}
++real;
}
}
}
}

View File

@ -0,0 +1,38 @@
#ifndef TESTPPD_H
#define TESTPPD_H
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
#include <aiTypes.h>
#include <aiScene.h>
#include <SortByPTypeProcess.h>
using namespace std;
using namespace Assimp;
class SortByPTypeProcessTest : public CPPUNIT_NS :: TestFixture
{
CPPUNIT_TEST_SUITE (SortByPTypeProcessTest);
CPPUNIT_TEST (testDeterminePTypeStep);
CPPUNIT_TEST (testSortByPTypeStep);
CPPUNIT_TEST_SUITE_END ();
public:
void setUp (void);
void tearDown (void);
protected:
void testDeterminePTypeStep (void);
void testSortByPTypeStep (void);
private:
DeterminePTypeHelperProcess* process0;
SortByPTypeProcess* process1;
aiScene* scene;
};
#endif

View File

@ -0,0 +1,88 @@
#include "utTriangulate.h"
CPPUNIT_TEST_SUITE_REGISTRATION (TriangulateProcessTest);
void TriangulateProcessTest :: setUp (void)
{
piProcess = new TriangulateProcess();
pcMesh = new aiMesh();
pcMesh->mNumFaces = 1000;
pcMesh->mFaces = new aiFace[1000];
pcMesh->mPrimitiveTypes = aiPrimitiveType_POINT | aiPrimitiveType_LINE |
aiPrimitiveType_LINE | aiPrimitiveType_POLYGON;
for (unsigned int m = 0, t = 0, q = 4; m < 1000; ++m)
{
++t;
aiFace& face = pcMesh->mFaces[m];
face.mNumIndices = t;
if (4 == t)
{
face.mNumIndices = q++;
t = 0;
if (10 == q)q = 4;
}
face.mIndices = new unsigned int[face.mNumIndices];
for (unsigned int p = 0; p < face.mNumIndices; ++p)
{
face.mIndices[p] = pcMesh->mNumVertices++;
}
}
}
void TriangulateProcessTest :: tearDown (void)
{
delete piProcess;
delete pcMesh;
}
void TriangulateProcessTest :: testTriangulation (void)
{
piProcess->TriangulateMesh(pcMesh);
for (unsigned int m = 0, t = 0, q = 4, max = 1000, idx = 0; m < max;++m)
{
++t;
aiFace& face = pcMesh->mFaces[m];
if (4 == t)
{
t = 0;
max += q-3;
std::vector<bool> ait(q,false);
for (unsigned int i = 0, tt = q-2; i < tt; ++i,++m)
{
aiFace& face = pcMesh->mFaces[m];
CPPUNIT_ASSERT(face.mNumIndices == 3);
for (unsigned int qqq = 0; qqq < face.mNumIndices; ++qqq)
{
ait[face.mIndices[qqq]-idx] = true;
}
}
for (std::vector<bool>::const_iterator it = ait.begin(); it != ait.end(); ++it)
{
CPPUNIT_ASSERT(*it);
}
--m;
idx+=q;
if(++q == 10)q = 4;
}
else
{
CPPUNIT_ASSERT(face.mNumIndices == t);
for (unsigned int i = 0; i < face.mNumIndices; ++i,++idx)
{
CPPUNIT_ASSERT(face.mIndices[i] == idx);
}
}
}
}

View File

@ -0,0 +1,37 @@
#ifndef TESTNORMALS_H
#define TESTNORMALS_H
#include <cppunit/TestFixture.h>
#include <cppunit/extensions/HelperMacros.h>
#include <aiTypes.h>
#include <aiMesh.h>
#include <aiScene.h>
#include <TriangulateProcess.h>
using namespace std;
using namespace Assimp;
class TriangulateProcessTest : public CPPUNIT_NS :: TestFixture
{
CPPUNIT_TEST_SUITE (TriangulateProcessTest);
CPPUNIT_TEST (testTriangulation);
CPPUNIT_TEST_SUITE_END ();
public:
void setUp (void);
void tearDown (void);
protected:
void testTriangulation (void);
private:
aiMesh* pcMesh;
TriangulateProcess* piProcess;
};
#endif

View File

@ -134,7 +134,7 @@ DWORD WINAPI LoadThreadProc(LPVOID lpParameter)
aiProcess_ConvertToLeftHanded | // convert everything to D3D left handed space
aiProcess_SplitLargeMeshes | // split large, unrenderable meshes into submeshes
aiProcess_ValidateDataStructure | aiProcess_ImproveCacheLocality
| aiProcess_RemoveRedundantMaterials ); // validate the output data structure
| aiProcess_RemoveRedundantMaterials | aiProcess_SortByPType); // validate the output data structure
// get the end time of zje operation, calculate delta t
double fEnd = (double)timeGetTime();
@ -432,6 +432,12 @@ int CreateAssetData()
g_pcAsset->apcMeshes[i],g_pcAsset->pcScene->mMeshes[i]);
}
if (g_pcAsset->pcScene->mMeshes[i]->mPrimitiveTypes == aiPrimitiveType_LINE ||
g_pcAsset->pcScene->mMeshes[i]->mPrimitiveTypes == aiPrimitiveType_POINT)
{
continue;
}
// create vertex buffer
if(FAILED( g_piDevice->CreateVertexBuffer(sizeof(AssetHelper::Vertex) *
g_pcAsset->pcScene->mMeshes[i]->mNumVertices,

View File

@ -683,10 +683,18 @@
RelativePath="..\..\test\unit\utGenNormals.cpp"
>
</File>
<File
RelativePath="..\..\test\unit\utGenNormals.h"
>
</File>
<File
RelativePath="..\..\test\unit\utImporter.cpp"
>
</File>
<File
RelativePath="..\..\test\unit\utImporter.h"
>
</File>
<File
RelativePath="..\..\test\unit\utImproveCacheLocality.cpp"
>
@ -695,99 +703,103 @@
RelativePath="..\..\test\unit\utJoinVertices.cpp"
>
</File>
<File
RelativePath="..\..\test\unit\utLimitBoneWeights.cpp"
>
</File>
<File
RelativePath="..\..\test\unit\utMaterialSystem.cpp"
>
</File>
<File
RelativePath="..\..\test\unit\utOptimizeGraph.cpp"
>
</File>
<File
RelativePath="..\..\test\unit\utPretransformVertices.cpp"
>
</File>
<File
RelativePath="..\..\test\unit\utRemoveComments.cpp"
>
</File>
<File
RelativePath="..\..\test\unit\utRemoveRedundantMaterials.cpp"
>
</File>
<File
RelativePath="..\..\test\unit\utSplitLargeMeshes.cpp"
>
</File>
<File
RelativePath="..\..\test\unit\utTextureTransform.cpp"
>
</File>
<File
RelativePath="..\..\test\unit\utVertexTriangleAdjacency.cpp"
>
</File>
</Filter>
<Filter
Name="headers"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath="..\..\test\unit\utGenNormals.h"
>
</File>
<File
RelativePath="..\..\test\unit\utImporter.h"
>
</File>
<File
RelativePath="..\..\test\unit\utJoinVertices.h"
>
</File>
<File
RelativePath="..\..\test\unit\utLimitBoneWeights.cpp"
>
</File>
<File
RelativePath="..\..\test\unit\utLimitBoneWeights.h"
>
</File>
<File
RelativePath="..\..\test\unit\utMaterialSystem.cpp"
>
</File>
<File
RelativePath="..\..\test\unit\utMaterialSystem.h"
>
</File>
<File
RelativePath="..\..\test\unit\utOptimizeGraph.cpp"
>
</File>
<File
RelativePath="..\..\test\unit\utOptimizeGraph.h"
>
</File>
<File
RelativePath="..\..\test\unit\utPretransformVertices.cpp"
>
</File>
<File
RelativePath="..\..\test\unit\utPretransformVertices.h"
>
</File>
<File
RelativePath="..\..\test\unit\utRemoveComments.cpp"
>
</File>
<File
RelativePath="..\..\test\unit\utRemoveComments.h"
>
</File>
<File
RelativePath="..\..\test\unit\utRemoveRedundantMaterials.cpp"
>
</File>
<File
RelativePath="..\..\test\unit\utRemoveRedundantMaterials.h"
>
</File>
<File
RelativePath="..\..\test\unit\utSharedPPData.cpp"
>
</File>
<File
RelativePath="..\..\test\unit\utSharedPPData.h"
>
</File>
<File
RelativePath="..\..\test\unit\utSortByPType.cpp"
>
</File>
<File
RelativePath="..\..\test\unit\utSortByPType.h"
>
</File>
<File
RelativePath="..\..\test\unit\utSplitLargeMeshes.cpp"
>
</File>
<File
RelativePath="..\..\test\unit\utSplitLargeMeshes.h"
>
</File>
<File
RelativePath="..\..\test\unit\utTextureTransform.cpp"
>
</File>
<File
RelativePath="..\..\test\unit\utTriangulate.cpp"
>
</File>
<File
RelativePath="..\..\test\unit\utTriangulate.h"
>
</File>
<File
RelativePath="..\..\test\unit\utVertexTriangleAdjacency.cpp"
>
</File>
<File
RelativePath="..\..\test\unit\utVertexTriangleAdjacency.h"
>
</File>
</Filter>
<Filter
Name="resources"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
</Files>
<Globals>
</Globals>

View File

@ -699,12 +699,28 @@
</Filter>
</Filter>
<Filter
Name="headers"
Name="sources"
>
<File
RelativePath="..\..\code\aiAssert.cpp"
>
</File>
<File
RelativePath="..\..\code\Assimp.cpp"
>
</File>
<File
RelativePath="..\..\code\BaseImporter.cpp"
>
</File>
<File
RelativePath="..\..\code\BaseImporter.h"
>
</File>
<File
RelativePath="..\..\code\BaseProcess.cpp"
>
</File>
<File
RelativePath="..\..\code\BaseProcess.h"
>
@ -713,18 +729,34 @@
RelativePath="..\..\code\ByteSwap.h"
>
</File>
<File
RelativePath="..\..\code\DefaultIOStream.cpp"
>
</File>
<File
RelativePath="..\..\code\DefaultIOStream.h"
>
</File>
<File
RelativePath="..\..\code\DefaultIOSystem.cpp"
>
</File>
<File
RelativePath="..\..\code\DefaultIOSystem.h"
>
</File>
<File
RelativePath="..\..\code\DefaultLogger.cpp"
>
</File>
<File
RelativePath="..\..\code\fast_atof.h"
>
</File>
<File
RelativePath="..\..\code\FileLogStream.h"
>
</File>
<File
RelativePath="..\..\code\GenericProperty.h"
>
@ -737,6 +769,14 @@
RelativePath="..\..\code\IFF.h"
>
</File>
<File
RelativePath="..\..\code\Importer.cpp"
>
</File>
<File
RelativePath="..\..\code\MaterialSystem.cpp"
>
</File>
<File
RelativePath="..\..\code\MaterialSystem.h"
>
@ -749,10 +789,18 @@
RelativePath="..\..\code\qnan.h"
>
</File>
<File
RelativePath="..\..\code\RemoveComments.cpp"
>
</File>
<File
RelativePath="..\..\code\RemoveComments.h"
>
</File>
<File
RelativePath="..\..\code\SGSpatialSort.cpp"
>
</File>
<File
RelativePath="..\..\code\SGSpatialSort.h"
>
@ -765,10 +813,18 @@
RelativePath="..\..\code\SmoothingGroups.inl"
>
</File>
<File
RelativePath="..\..\code\SpatialSort.cpp"
>
</File>
<File
RelativePath="..\..\code\SpatialSort.h"
>
</File>
<File
RelativePath="..\..\code\StandardShapes.cpp"
>
</File>
<File
RelativePath="..\..\code\StandardShapes.h"
>
@ -777,41 +833,33 @@
RelativePath="..\..\code\StringComparison.h"
>
</File>
<File
RelativePath="..\..\code\TextureTransform.cpp"
>
</File>
<File
RelativePath="..\..\code\TextureTransform.h"
>
</File>
<File
RelativePath="..\..\code\VertexTriangleAdjacency.cpp"
>
</File>
<File
RelativePath="..\..\code\VertexTriangleAdjacency.h"
>
</File>
<Filter
Name="Compiler"
<File
RelativePath="..\..\code\Win32DebugLogStream.h"
>
<File
RelativePath="..\..\code\Compiler\poppack1.h"
>
</File>
<File
RelativePath="..\..\code\Compiler\pushpack1.h"
>
</File>
</Filter>
<Filter
Name="Logger"
>
<File
RelativePath="..\..\code\FileLogStream.h"
>
</File>
<File
RelativePath="..\..\code\Win32DebugLogStream.h"
>
</File>
</Filter>
</File>
<Filter
Name="extra"
>
<File
RelativePath="..\..\code\extra\MakeVerboseFormat.cpp"
>
</File>
<File
RelativePath="..\..\code\extra\MakeVerboseFormat.h"
>
@ -827,10 +875,18 @@
<Filter
Name="3DS"
>
<File
RelativePath="..\..\code\3DSConverter.cpp"
>
</File>
<File
RelativePath="..\..\code\3DSHelper.h"
>
</File>
<File
RelativePath="..\..\code\3DSLoader.cpp"
>
</File>
<File
RelativePath="..\..\code\3DSLoader.h"
>
@ -839,10 +895,18 @@
<Filter
Name="ASE"
>
<File
RelativePath="..\..\code\ASELoader.cpp"
>
</File>
<File
RelativePath="..\..\code\ASELoader.h"
>
</File>
<File
RelativePath="..\..\code\ASEParser.cpp"
>
</File>
<File
RelativePath="..\..\code\ASEParser.h"
>
@ -855,6 +919,10 @@
RelativePath="..\..\code\HMPFileData.h"
>
</File>
<File
RelativePath="..\..\code\HMPLoader.cpp"
>
</File>
<File
RelativePath="..\..\code\HMPLoader.h"
>
@ -863,14 +931,26 @@
<Filter
Name="LWO"
>
<File
RelativePath="..\..\code\LWOBLoader.cpp"
>
</File>
<File
RelativePath="..\..\code\LWOFileData.h"
>
</File>
<File
RelativePath="..\..\code\LWOLoader.cpp"
>
</File>
<File
RelativePath="..\..\code\LWOLoader.h"
>
</File>
<File
RelativePath="..\..\code\LWOMaterial.cpp"
>
</File>
</Filter>
<Filter
Name="MD2"
@ -879,6 +959,10 @@
RelativePath="..\..\code\MD2FileData.h"
>
</File>
<File
RelativePath="..\..\code\MD2Loader.cpp"
>
</File>
<File
RelativePath="..\..\code\MD2Loader.h"
>
@ -895,6 +979,10 @@
RelativePath="..\..\code\MD3FileData.h"
>
</File>
<File
RelativePath="..\..\code\MD3Loader.cpp"
>
</File>
<File
RelativePath="..\..\code\MD3Loader.h"
>
@ -903,10 +991,18 @@
<Filter
Name="MD5"
>
<File
RelativePath="..\..\code\MD5Loader.cpp"
>
</File>
<File
RelativePath="..\..\code\MD5Loader.h"
>
</File>
<File
RelativePath="..\..\code\MD5Parser.cpp"
>
</File>
<File
RelativePath="..\..\code\MD5Parser.h"
>
@ -919,6 +1015,10 @@
RelativePath="..\..\code\MDCFileData.h"
>
</File>
<File
RelativePath="..\..\code\MDCLoader.cpp"
>
</File>
<File
RelativePath="..\..\code\MDCLoader.h"
>
@ -943,20 +1043,16 @@
RelativePath="..\..\code\MDLFileData.h"
>
</File>
<File
RelativePath="..\..\code\MDLLoader.cpp"
>
</File>
<File
RelativePath="..\..\code\MDLLoader.h"
>
</File>
</Filter>
<Filter
Name="MDR"
>
<File
RelativePath="..\..\code\MDRFileData.h"
>
</File>
<File
RelativePath="..\..\code\MDRLoader.h"
RelativePath="..\..\code\MDLMaterialLoader.cpp"
>
</File>
</Filter>
@ -967,14 +1063,26 @@
RelativePath="..\..\code\ObjFileData.h"
>
</File>
<File
RelativePath="..\..\code\ObjFileImporter.cpp"
>
</File>
<File
RelativePath="..\..\code\ObjFileImporter.h"
>
</File>
<File
RelativePath="..\..\code\ObjFileMtlImporter.cpp"
>
</File>
<File
RelativePath="..\..\code\ObjFileMtlImporter.h"
>
</File>
<File
RelativePath="..\..\code\ObjFileParser.cpp"
>
</File>
<File
RelativePath="..\..\code\ObjFileParser.h"
>
@ -987,10 +1095,18 @@
<Filter
Name="Ply"
>
<File
RelativePath="..\..\code\PlyLoader.cpp"
>
</File>
<File
RelativePath="..\..\code\PlyLoader.h"
>
</File>
<File
RelativePath="..\..\code\PlyParser.cpp"
>
</File>
<File
RelativePath="..\..\code\PlyParser.h"
>
@ -999,6 +1115,10 @@
<Filter
Name="SMD"
>
<File
RelativePath="..\..\code\SMDLoader.cpp"
>
</File>
<File
RelativePath="..\..\code\SMDLoader.h"
>
@ -1007,6 +1127,10 @@
<Filter
Name="STL"
>
<File
RelativePath="..\..\code\STLLoader.cpp"
>
</File>
<File
RelativePath="..\..\code\STLLoader.h"
>
@ -1019,367 +1143,23 @@
RelativePath="..\..\code\XFileHelper.h"
>
</File>
<File
RelativePath="..\..\code\XFileImporter.cpp"
>
</File>
<File
RelativePath="..\..\code\XFileImporter.h"
>
</File>
<File
RelativePath="..\..\code\XFileParser.cpp"
>
</File>
<File
RelativePath="..\..\code\XFileParser.h"
>
</File>
</Filter>
<Filter
Name="DXF"
>
<File
RelativePath="..\..\code\DXFLoader.h"
>
</File>
</Filter>
<Filter
Name="RAW"
>
<File
RelativePath="..\..\code\RawLoader.h"
>
</File>
</Filter>
<Filter
Name="NFF"
>
<File
RelativePath="..\..\code\NFFLoader.h"
>
</File>
</Filter>
<Filter
Name="FBX"
>
</Filter>
<Filter
Name="Collada"
>
</Filter>
<Filter
Name="WRL"
>
</Filter>
<Filter
Name="OFF"
>
<File
RelativePath="..\..\code\OFFLoader.h"
>
</File>
</Filter>
<Filter
Name="AC"
>
</Filter>
</Filter>
<Filter
Name="PostProcess"
>
<File
RelativePath="..\..\code\CalcTangentsProcess.h"
>
</File>
<File
RelativePath="..\..\code\ConvertToLHProcess.h"
>
</File>
<File
RelativePath="..\..\code\FixNormalsStep.h"
>
</File>
<File
RelativePath="..\..\code\GenFaceNormalsProcess.h"
>
</File>
<File
RelativePath="..\..\code\GenVertexNormalsProcess.h"
>
</File>
<File
RelativePath="..\..\code\ImproveCacheLocality.h"
>
</File>
<File
RelativePath="..\..\code\JoinVerticesProcess.h"
>
</File>
<File
RelativePath="..\..\code\KillNormalsProcess.h"
>
</File>
<File
RelativePath="..\..\code\LimitBoneWeightsProcess.h"
>
</File>
<File
RelativePath="..\..\code\OptimizeGraphProcess.h"
>
</File>
<File
RelativePath="..\..\code\PretransformVertices.h"
>
</File>
<File
RelativePath="..\..\code\RemoveRedundantMaterials.h"
>
</File>
<File
RelativePath="..\..\code\SplitLargeMeshes.h"
>
</File>
<File
RelativePath="..\..\code\TriangulateProcess.h"
>
</File>
<File
RelativePath="..\..\code\ValidateDataStructure.h"
>
</File>
<Filter
Name="util"
>
<File
RelativePath="..\..\code\ProcessHelper.h"
>
</File>
</Filter>
</Filter>
</Filter>
<Filter
Name="sources"
>
<File
RelativePath="..\..\code\aiAssert.cpp"
>
</File>
<File
RelativePath="..\..\code\Assimp.cpp"
>
</File>
<File
RelativePath="..\..\code\BaseImporter.cpp"
>
</File>
<File
RelativePath="..\..\code\BaseProcess.cpp"
>
</File>
<File
RelativePath="..\..\code\DefaultIOStream.cpp"
>
</File>
<File
RelativePath="..\..\code\DefaultIOSystem.cpp"
>
</File>
<File
RelativePath="..\..\code\DefaultLogger.cpp"
>
</File>
<File
RelativePath="..\..\code\Importer.cpp"
>
</File>
<File
RelativePath="..\..\code\MaterialSystem.cpp"
>
</File>
<File
RelativePath="..\..\code\RemoveComments.cpp"
>
</File>
<File
RelativePath="..\..\code\SGSpatialSort.cpp"
>
</File>
<File
RelativePath="..\..\code\SpatialSort.cpp"
>
</File>
<File
RelativePath="..\..\code\StandardShapes.cpp"
>
</File>
<File
RelativePath="..\..\code\TextureTransform.cpp"
>
</File>
<File
RelativePath="..\..\code\VertexTriangleAdjacency.cpp"
>
</File>
<Filter
Name="Compiler"
>
</Filter>
<Filter
Name="extra"
>
<File
RelativePath="..\..\code\extra\MakeVerboseFormat.cpp"
>
</File>
</Filter>
<Filter
Name="Loaders"
>
<Filter
Name="3DS"
>
<File
RelativePath="..\..\code\3DSConverter.cpp"
>
</File>
<File
RelativePath="..\..\code\3DSLoader.cpp"
>
</File>
</Filter>
<Filter
Name="ASE"
>
<File
RelativePath="..\..\code\ASELoader.cpp"
>
</File>
<File
RelativePath="..\..\code\ASEParser.cpp"
>
</File>
</Filter>
<Filter
Name="HMP"
>
<File
RelativePath="..\..\code\HMPLoader.cpp"
>
</File>
</Filter>
<Filter
Name="LWO"
>
<File
RelativePath="..\..\code\LWOBLoader.cpp"
>
</File>
<File
RelativePath="..\..\code\LWOLoader.cpp"
>
</File>
<File
RelativePath="..\..\code\LWOMaterial.cpp"
>
</File>
</Filter>
<Filter
Name="MD2"
>
<File
RelativePath="..\..\code\MD2Loader.cpp"
>
</File>
</Filter>
<Filter
Name="MD3"
>
<File
RelativePath="..\..\code\MD3Loader.cpp"
>
</File>
</Filter>
<Filter
Name="MD5"
>
<File
RelativePath="..\..\code\MD5Loader.cpp"
>
</File>
<File
RelativePath="..\..\code\MD5Parser.cpp"
>
</File>
</Filter>
<Filter
Name="MDC"
>
<File
RelativePath="..\..\code\MDCLoader.cpp"
>
</File>
</Filter>
<Filter
Name="MDL"
>
<File
RelativePath="..\..\code\MDLLoader.cpp"
>
</File>
<File
RelativePath="..\..\code\MDLMaterialLoader.cpp"
>
</File>
</Filter>
<Filter
Name="Obj"
>
<File
RelativePath="..\..\code\ObjFileImporter.cpp"
>
</File>
<File
RelativePath="..\..\code\ObjFileMtlImporter.cpp"
>
</File>
<File
RelativePath="..\..\code\ObjFileParser.cpp"
>
</File>
</Filter>
<Filter
Name="Ply"
>
<File
RelativePath="..\..\code\PlyLoader.cpp"
>
</File>
<File
RelativePath="..\..\code\PlyParser.cpp"
>
</File>
</Filter>
<Filter
Name="SMD"
>
<File
RelativePath="..\..\code\SMDLoader.cpp"
>
</File>
</Filter>
<Filter
Name="STL"
>
<File
RelativePath="..\..\code\STLLoader.cpp"
>
</File>
</Filter>
<Filter
Name="X"
>
<File
RelativePath="..\..\code\XFileImporter.cpp"
>
</File>
<File
RelativePath="..\..\code\XFileParser.cpp"
>
</File>
</Filter>
<Filter
Name="DXF"
>
@ -1387,6 +1167,10 @@
RelativePath="..\..\code\DXFLoader.cpp"
>
</File>
<File
RelativePath="..\..\code\DXFLoader.h"
>
</File>
</Filter>
<Filter
Name="RAW"
@ -1395,6 +1179,10 @@
RelativePath="..\..\code\RawLoader.cpp"
>
</File>
<File
RelativePath="..\..\code\RawLoader.h"
>
</File>
</Filter>
<Filter
Name="NFF"
@ -1403,17 +1191,29 @@
RelativePath="..\..\code\NFFLoader.cpp"
>
</File>
<File
RelativePath="..\..\code\NFFLoader.h"
>
</File>
</Filter>
<Filter
Name="MDR"
>
<File
RelativePath="..\..\code\MDRFileData.h"
>
</File>
<File
RelativePath="..\..\code\MDRLoader.cpp"
>
</File>
<File
RelativePath="..\..\code\MDRLoader.h"
>
</File>
</Filter>
<Filter
Name="WRL"
Name="VRML97"
>
</Filter>
<Filter
@ -1423,6 +1223,10 @@
RelativePath="..\..\code\OFFLoader.cpp"
>
</File>
<File
RelativePath="..\..\code\OFFLoader.h"
>
</File>
</Filter>
<Filter
Name="AC"
@ -1436,62 +1240,150 @@
RelativePath="..\..\code\CalcTangentsProcess.cpp"
>
</File>
<File
RelativePath="..\..\code\CalcTangentsProcess.h"
>
</File>
<File
RelativePath="..\..\code\ConvertToLHProcess.cpp"
>
</File>
<File
RelativePath="..\..\code\ConvertToLHProcess.h"
>
</File>
<File
RelativePath="..\..\code\FixNormalsStep.cpp"
>
</File>
<File
RelativePath="..\..\code\FixNormalsStep.h"
>
</File>
<File
RelativePath="..\..\code\GenFaceNormalsProcess.cpp"
>
</File>
<File
RelativePath="..\..\code\GenFaceNormalsProcess.h"
>
</File>
<File
RelativePath="..\..\code\GenVertexNormalsProcess.cpp"
>
</File>
<File
RelativePath="..\..\code\GenVertexNormalsProcess.h"
>
</File>
<File
RelativePath="..\..\code\ImproveCacheLocality.cpp"
>
</File>
<File
RelativePath="..\..\code\ImproveCacheLocality.h"
>
</File>
<File
RelativePath="..\..\code\JoinVerticesProcess.cpp"
>
</File>
<File
RelativePath="..\..\code\JoinVerticesProcess.h"
>
</File>
<File
RelativePath="..\..\code\KillNormalsProcess.cpp"
>
</File>
<File
RelativePath="..\..\code\KillNormalsProcess.h"
>
</File>
<File
RelativePath="..\..\code\LimitBoneWeightsProcess.cpp"
>
</File>
<File
RelativePath="..\..\code\LimitBoneWeightsProcess.h"
>
</File>
<File
RelativePath="..\..\code\OptimizeGraphProcess.cpp"
>
</File>
<File
RelativePath="..\..\code\OptimizeGraphProcess.h"
>
</File>
<File
RelativePath="..\..\code\PretransformVertices.cpp"
>
</File>
<File
RelativePath="..\..\code\PretransformVertices.h"
>
</File>
<File
RelativePath="..\..\code\RemoveRedundantMaterials.cpp"
>
</File>
<File
RelativePath="..\..\code\RemoveRedundantMaterials.h"
>
</File>
<File
RelativePath="..\..\code\SortByPTypeProcess.cpp"
>
</File>
<File
RelativePath="..\..\code\SortByPTypeProcess.h"
>
</File>
<File
RelativePath="..\..\code\SplitLargeMeshes.cpp"
>
</File>
<File
RelativePath="..\..\code\SplitLargeMeshes.h"
>
</File>
<File
RelativePath="..\..\code\TriangulateProcess.cpp"
>
</File>
<File
RelativePath="..\..\code\TriangulateProcess.h"
>
</File>
<File
RelativePath="..\..\code\ValidateDataStructure.cpp"
>
</File>
<File
RelativePath="..\..\code\ValidateDataStructure.h"
>
</File>
<Filter
Name="util"
>
<File
RelativePath="..\..\code\ProcessHelper.h"
>
</File>
</Filter>
</Filter>
<Filter
Name="Compiler"
>
<File
RelativePath="..\..\code\Compiler\poppack1.h"
>
</File>
<File
RelativePath="..\..\code\Compiler\pushpack1.h"
>
</File>
</Filter>
</Filter>
<Filter

View File

@ -679,18 +679,38 @@
Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath="..\..\tools\assimp_view\AssetHelper.h"
>
</File>
<File
RelativePath="..\..\tools\assimp_view\assimp_view.cpp"
>
</File>
<File
RelativePath="..\..\tools\assimp_view\assimp_view.h"
>
</File>
<File
RelativePath="..\..\tools\assimp_view\Background.cpp"
>
</File>
<File
RelativePath="..\..\tools\assimp_view\Background.h"
>
</File>
<File
RelativePath="..\..\tools\assimp_view\Camera.h"
>
</File>
<File
RelativePath="..\..\tools\assimp_view\Display.cpp"
>
</File>
<File
RelativePath="..\..\tools\assimp_view\Display.h"
>
</File>
<File
RelativePath="..\..\tools\assimp_view\HelpDialog.cpp"
>
@ -703,18 +723,34 @@
RelativePath="..\..\tools\assimp_view\LogDisplay.cpp"
>
</File>
<File
RelativePath="..\..\tools\assimp_view\LogDisplay.h"
>
</File>
<File
RelativePath="..\..\tools\assimp_view\LogWindow.cpp"
>
</File>
<File
RelativePath="..\..\tools\assimp_view\LogWindow.h"
>
</File>
<File
RelativePath="..\..\tools\assimp_view\Material.cpp"
>
</File>
<File
RelativePath="..\..\tools\assimp_view\MaterialManager.h"
>
</File>
<File
RelativePath="..\..\tools\assimp_view\MeshRenderer.cpp"
>
</File>
<File
RelativePath="..\..\tools\assimp_view\MeshRenderer.h"
>
</File>
<File
RelativePath="..\..\tools\assimp_view\MessageProc.cpp"
>
@ -727,10 +763,22 @@
RelativePath="..\..\tools\assimp_view\Normals.cpp"
>
</File>
<File
RelativePath="..\..\tools\assimp_view\RenderOptions.h"
>
</File>
<File
RelativePath="..\..\tools\assimp_view\Resource.h"
>
</File>
<File
RelativePath="..\..\tools\assimp_view\Shaders.cpp"
>
</File>
<File
RelativePath="..\..\tools\assimp_view\Shaders.h"
>
</File>
<File
RelativePath="..\..\tools\assimp_view\stdafx.cpp"
>
@ -799,60 +847,6 @@
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="headers"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath="..\..\tools\assimp_view\AssetHelper.h"
>
</File>
<File
RelativePath="..\..\tools\assimp_view\assimp_view.h"
>
</File>
<File
RelativePath="..\..\tools\assimp_view\Background.h"
>
</File>
<File
RelativePath="..\..\tools\assimp_view\Camera.h"
>
</File>
<File
RelativePath="..\..\tools\assimp_view\Display.h"
>
</File>
<File
RelativePath="..\..\tools\assimp_view\LogDisplay.h"
>
</File>
<File
RelativePath="..\..\tools\assimp_view\LogWindow.h"
>
</File>
<File
RelativePath="..\..\tools\assimp_view\MaterialManager.h"
>
</File>
<File
RelativePath="..\..\tools\assimp_view\MeshRenderer.h"
>
</File>
<File
RelativePath="..\..\tools\assimp_view\RenderOptions.h"
>
</File>
<File
RelativePath="..\..\tools\assimp_view\Resource.h"
>
</File>
<File
RelativePath="..\..\tools\assimp_view\Shaders.h"
>
</File>
<File
RelativePath="..\..\tools\assimp_view\stdafx.h"
>

View File

@ -365,6 +365,10 @@
RelativePath="..\..\port\jAssimp\jni_bridge\JNIEnvironment.cpp"
>
</File>
<File
RelativePath="..\..\port\jAssimp\jni_bridge\JNIEnvironment.h"
>
</File>
<File
RelativePath="..\..\port\jAssimp\jni_bridge\JNIIOStream.cpp"
>
@ -377,6 +381,10 @@
RelativePath="..\..\port\jAssimp\jni_bridge\JNILogger.cpp"
>
</File>
<File
RelativePath="..\..\port\jAssimp\jni_bridge\JNILogger.h"
>
</File>
<File
RelativePath="..\..\port\jAssimp\jni_bridge\JNIMaterial.cpp"
>
@ -401,20 +409,6 @@
RelativePath="..\..\port\jAssimp\jni_bridge\JNITexture.cpp"
>
</File>
</Filter>
<Filter
Name="headers"
Filter="h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath="..\..\port\jAssimp\jni_bridge\JNIEnvironment.h"
>
</File>
<File
RelativePath="..\..\port\jAssimp\jni_bridge\JNILogger.h"
>
</File>
<Filter
Name="javah"
>
@ -424,12 +418,6 @@
</File>
</Filter>
</Filter>
<Filter
Name="resources"
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
>
</Filter>
</Files>
<Globals>
</Globals>