Merge branch 'master' into ios-build-script

* master:
  Fix missing model error in Irr-instancing
  closes https://github.com/assimp/assimp/issues/2024: make code more readable.
  closes https://github.com/assimp/assimp/issues/2019: fix the qt-viewer without export.
  applied coding conventions added check against the known faces
  issue_2016 only add material uv mappings if set, ignore when no uvmapping set removed unneccessary pad_i1 field (to prevent unnecessary field read exceptions)
  Update XFileParser.cpp
  Update XFileParser.cpp
  Some FBX files have Null/LimbNode attributes with an empty Properties70 element, where the Element is not NULL, but it's Compound is. The code only checked if the Element itself is NULL, thus causing a DeadlyImportError when trying to instantiate a PropertyTable for an Element that doesn't have a Compound.
  fix build for independent build dir
  Some review findings.
pull/2045/head
Doron Adler 2018-06-19 10:02:25 +03:00
commit ee2f0bccac
20 changed files with 378 additions and 317 deletions

View File

@ -1045,7 +1045,9 @@ void BlenderImporter::ConvertMesh(const Scene& /*in*/, const Object* /*obj*/, co
}
}
}
matTexUvMappings.insert(std::make_pair(m, texuv));
if (texuv.size()) {
matTexUvMappings.insert(std::make_pair(m, texuv));
}
}
// collect texture coordinates, they're stored in a separate per-face buffer

View File

@ -800,7 +800,6 @@ template <> void Structure::Convert<CustomData>(
) const
{
ReadFieldArray<ErrorPolicy_Warn>(dest.typemap, "typemap", db);
ReadField<ErrorPolicy_Igno>(dest.pad_i1, "pad_i1", db);
ReadField<ErrorPolicy_Warn>(dest.totlayer, "totlayer", db);
ReadField<ErrorPolicy_Warn>(dest.maxlayer, "maxlayer", db);
ReadField<ErrorPolicy_Warn>(dest.totsize, "totsize", db);

View File

@ -432,7 +432,6 @@ CustomData 208
struct CustomData : ElemBase {
vector<std::shared_ptr<struct CustomDataLayer> > layers;
int typemap[42]; // CD_NUMTYPES
int pad_i1;
int totlayer;
int maxlayer;
int totsize;

View File

@ -272,12 +272,13 @@ struct Node
/** Node instances at this node */
std::vector<NodeInstance> mNodeInstances;
/** Rootnodes: Name of primary camera, if any */
/** Root-nodes: Name of primary camera, if any */
std::string mPrimaryCamera;
//! Constructor. Begin with a zero parent
Node() {
mParent = NULL;
Node()
: mParent( nullptr ){
// empty
}
//! Destructor: delete all children subsequently

View File

@ -181,26 +181,27 @@ void ColladaLoader::InternReadFile( const std::string& pFile, aiScene* pScene, I
// ... then fill the materials with the now adjusted settings
FillMaterials(parser, pScene);
// Apply unitsize scale calculation
pScene->mRootNode->mTransformation *= aiMatrix4x4(parser.mUnitSize, 0, 0, 0,
0, parser.mUnitSize, 0, 0,
0, 0, parser.mUnitSize, 0,
0, 0, 0, 1);
if( !ignoreUpDirection ) {
// Convert to Y_UP, if different orientation
if( parser.mUpDirection == ColladaParser::UP_X)
pScene->mRootNode->mTransformation *= aiMatrix4x4(
0, -1, 0, 0,
1, 0, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1);
else if( parser.mUpDirection == ColladaParser::UP_Z)
pScene->mRootNode->mTransformation *= aiMatrix4x4(
1, 0, 0, 0,
0, 0, 1, 0,
0, -1, 0, 0,
0, 0, 0, 1);
}
// Apply unitsize scale calculation
pScene->mRootNode->mTransformation *= aiMatrix4x4(parser.mUnitSize, 0, 0, 0,
0, parser.mUnitSize, 0, 0,
0, 0, parser.mUnitSize, 0,
0, 0, 0, 1);
if( !ignoreUpDirection ) {
// Convert to Y_UP, if different orientation
if( parser.mUpDirection == ColladaParser::UP_X)
pScene->mRootNode->mTransformation *= aiMatrix4x4(
0, -1, 0, 0,
1, 0, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1);
else if( parser.mUpDirection == ColladaParser::UP_Z)
pScene->mRootNode->mTransformation *= aiMatrix4x4(
1, 0, 0, 0,
0, 0, 1, 0,
0, -1, 0, 0,
0, 0, 0, 1);
}
// store all meshes
StoreSceneMeshes( pScene);
@ -740,10 +741,6 @@ aiMesh* ColladaLoader::CreateMesh( const ColladaParser& pParser, const Collada::
// create bones if given
if( pSrcController && pSrcController->mType == Collada::Skin)
{
// refuse if the vertex count does not match
// if( pSrcController->mWeightCounts.size() != dstMesh->mNumVertices)
// throw DeadlyImportError( "Joint Controller vertex count does not match mesh vertex count");
// resolve references - joint names
const Collada::Accessor& jointNamesAcc = pParser.ResolveLibraryReference( pParser.mAccessorLibrary, pSrcController->mJointNameSource);
const Collada::Data& jointNames = pParser.ResolveLibraryReference( pParser.mDataLibrary, jointNamesAcc.mSource);
@ -971,7 +968,8 @@ void ColladaLoader::StoreAnimations( aiScene* pScene, const ColladaParser& pPars
for( size_t b = a+1; b < mAnims.size(); ++b)
{
aiAnimation* other = mAnims[b];
if( other->mNumChannels == 1 && other->mDuration == templateAnim->mDuration && other->mTicksPerSecond == templateAnim->mTicksPerSecond )
if( other->mNumChannels == 1 && other->mDuration == templateAnim->mDuration &&
other->mTicksPerSecond == templateAnim->mTicksPerSecond )
collectedAnimIndices.push_back( b);
}

View File

@ -68,7 +68,7 @@ using namespace Assimp::Formatter;
// Constructor to be privately used by Importer
ColladaParser::ColladaParser( IOSystem* pIOHandler, const std::string& pFile)
: mFileName( pFile )
, mReader( NULL )
, mReader( nullptr )
, mDataLibrary()
, mAccessorLibrary()
, mMeshLibrary()
@ -79,20 +79,20 @@ ColladaParser::ColladaParser( IOSystem* pIOHandler, const std::string& pFile)
, mLightLibrary()
, mCameraLibrary()
, mControllerLibrary()
, mRootNode( NULL )
, mRootNode( nullptr )
, mAnims()
, mUnitSize( 1.0f )
, mUpDirection( UP_Y )
, mFormat(FV_1_5_n ) // We assume the newest file format by default
{
// validate io-handler instance
if ( NULL == pIOHandler ) {
if (nullptr == pIOHandler ) {
throw DeadlyImportError("IOSystem is NULL." );
}
// open the file
std::unique_ptr<IOStream> file( pIOHandler->Open(pFile ) );
if (file.get() == NULL) {
if (file.get() == nullptr) {
throw DeadlyImportError( "Failed to open file " + pFile + "." );
}
@ -363,17 +363,17 @@ void ColladaParser::ReadAnimationClipLibrary()
void ColladaParser::PostProcessControllers()
{
for (ControllerLibrary::iterator it = mControllerLibrary.begin(); it != mControllerLibrary.end(); ++it)
{
std::string meshId = it->second.mMeshId;
ControllerLibrary::iterator findItr = mControllerLibrary.find(meshId);
while(findItr != mControllerLibrary.end()) {
meshId = findItr->second.mMeshId;
findItr = mControllerLibrary.find(meshId);
}
std::string meshId;
for (ControllerLibrary::iterator it = mControllerLibrary.begin(); it != mControllerLibrary.end(); ++it) {
meshId = it->second.mMeshId;
ControllerLibrary::iterator findItr = mControllerLibrary.find(meshId);
while(findItr != mControllerLibrary.end()) {
meshId = findItr->second.mMeshId;
findItr = mControllerLibrary.find(meshId);
}
it->second.mMeshId = meshId;
}
it->second.mMeshId = meshId;
}
}
// ------------------------------------------------------------------------------------------------

View File

@ -115,7 +115,7 @@ std::shared_ptr<const PropertyTable> GetPropertyTable(const Document& doc,
}
}
if(!Properties70) {
if(!Properties70 || !Properties70->Compound()) {
if(!no_warn) {
DOMWarning("property table (Properties70) not found",&element);
}

View File

@ -55,7 +55,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/scene.h>
#include <assimp/importerdesc.h>
using namespace Assimp;
using namespace ::Assimp;
static const aiImporterDesc desc = {
"Stanford Polygon Library (PLY) Importer",
@ -73,22 +73,20 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------
// Internal stuff
namespace
{
// ------------------------------------------------------------------------------------------------
// Checks that property index is within range
template <class T>
const T &GetProperty(const std::vector<T> &props, int idx)
{
if (static_cast<size_t>(idx) >= props.size()) {
throw DeadlyImportError("Invalid .ply file: Property index is out of range.");
namespace {
// ------------------------------------------------------------------------------------------------
// Checks that property index is within range
template <class T>
inline
const T &GetProperty(const std::vector<T> &props, int idx) {
if (static_cast<size_t>(idx) >= props.size()) {
throw DeadlyImportError("Invalid .ply file: Property index is out of range.");
}
return props[idx];
}
return props[idx];
}
}
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
PLYImporter::PLYImporter()
@ -129,7 +127,7 @@ const aiImporterDesc* PLYImporter::GetInfo() const {
// ------------------------------------------------------------------------------------------------
static bool isBigEndian(const char* szMe) {
ai_assert(NULL != szMe);
ai_assert(nullptr != szMe);
// binary_little_endian
// binary_big_endian
@ -150,7 +148,7 @@ static bool isBigEndian(const char* szMe) {
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
void PLYImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) {
static const std::string mode = "rb";
const std::string mode = "rb";
std::unique_ptr<IOStream> fileStream(pIOHandler->Open(pFile, mode));
if (!fileStream.get()) {
throw DeadlyImportError("Failed to open file " + pFile + ".");
@ -184,7 +182,7 @@ void PLYImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
char* szMe = (char*)&this->mBuffer[0];
SkipSpacesAndLineEnd(szMe, (const char**)&szMe);
// determine the format of the file data and construct the aimesh
// determine the format of the file data and construct the aiMesh
PLY::DOM sPlyDom;
this->pcDOM = &sPlyDom;
@ -192,7 +190,7 @@ void PLYImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
if (TokenMatch(szMe, "ascii", 5)) {
SkipLine(szMe, (const char**)&szMe);
if (!PLY::DOM::ParseInstance(streamedBuffer, &sPlyDom, this)) {
if (mGeneratedMesh != NULL) {
if (mGeneratedMesh != nullptr) {
delete(mGeneratedMesh);
mGeneratedMesh = nullptr;
}
@ -206,7 +204,7 @@ void PLYImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
// skip the line, parse the rest of the header and build the DOM
if (!PLY::DOM::ParseInstanceBinary(streamedBuffer, &sPlyDom, this, bIsBE)) {
if (mGeneratedMesh != NULL) {
if (mGeneratedMesh != nullptr) {
delete(mGeneratedMesh);
mGeneratedMesh = nullptr;
}
@ -215,7 +213,7 @@ void PLYImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
throw DeadlyImportError("Invalid .ply file: Unable to build DOM (#2)");
}
} else {
if (mGeneratedMesh != NULL) {
if (mGeneratedMesh != nullptr) {
delete(mGeneratedMesh);
mGeneratedMesh = nullptr;
}
@ -225,7 +223,7 @@ void PLYImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
}
} else {
AI_DEBUG_INVALIDATE_PTR(this->mBuffer);
if (mGeneratedMesh != NULL) {
if (mGeneratedMesh != nullptr) {
delete(mGeneratedMesh);
mGeneratedMesh = nullptr;
}
@ -237,13 +235,13 @@ void PLYImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
//free the file buffer
streamedBuffer.close();
if (mGeneratedMesh == NULL) {
if (mGeneratedMesh == nullptr) {
throw DeadlyImportError("Invalid .ply file: Unable to extract mesh data ");
}
// if no face list is existing we assume that the vertex
// list is containing a list of points
bool pointsOnly = mGeneratedMesh->mFaces == NULL ? true : false;
bool pointsOnly = mGeneratedMesh->mFaces == nullptr ? true : false;
if (pointsOnly) {
mGeneratedMesh->mPrimitiveTypes = aiPrimitiveType::aiPrimitiveType_POINT;
}
@ -277,8 +275,8 @@ void PLYImporter::InternReadFile(const std::string& pFile, aiScene* pScene, IOSy
}
void PLYImporter::LoadVertex(const PLY::Element* pcElement, const PLY::ElementInstance* instElement, unsigned int pos) {
ai_assert(NULL != pcElement);
ai_assert(NULL != instElement);
ai_assert(nullptr != pcElement);
ai_assert(nullptr != instElement);
ai_uint aiPositions[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
PLY::EDataType aiTypes[3] = { EDT_Char, EDT_Char, EDT_Char };
@ -416,7 +414,7 @@ void PLYImporter::LoadVertex(const PLY::Element* pcElement, const PLY::ElementIn
haveColor = true;
}
// assume 1.0 for the alpha channel ifit is not set
// assume 1.0 for the alpha channel if it is not set
if (0xFFFFFFFF == aiColors[3]) {
cOut.a = 1.0;
} else {
@ -481,225 +479,205 @@ void PLYImporter::LoadVertex(const PLY::Element* pcElement, const PLY::ElementIn
// ------------------------------------------------------------------------------------------------
// Convert a color component to [0...1]
ai_real PLYImporter::NormalizeColorValue(PLY::PropertyInstance::ValueUnion val, PLY::EDataType eType) {
switch (eType)
{
case EDT_Float:
return val.fFloat;
case EDT_Double:
return (ai_real)val.fDouble;
switch (eType) {
case EDT_Float:
return val.fFloat;
case EDT_Double:
return (ai_real)val.fDouble;
case EDT_UChar:
return (ai_real)val.iUInt / (ai_real)0xFF;
case EDT_Char:
return (ai_real)(val.iInt + (0xFF / 2)) / (ai_real)0xFF;
case EDT_UShort:
return (ai_real)val.iUInt / (ai_real)0xFFFF;
case EDT_Short:
return (ai_real)(val.iInt + (0xFFFF / 2)) / (ai_real)0xFFFF;
case EDT_UInt:
return (ai_real)val.iUInt / (ai_real)0xFFFF;
case EDT_Int:
return ((ai_real)val.iInt / (ai_real)0xFF) + 0.5f;
default:
break;
}
case EDT_UChar:
return (ai_real)val.iUInt / (ai_real)0xFF;
case EDT_Char:
return (ai_real)(val.iInt + (0xFF / 2)) / (ai_real)0xFF;
case EDT_UShort:
return (ai_real)val.iUInt / (ai_real)0xFFFF;
case EDT_Short:
return (ai_real)(val.iInt + (0xFFFF / 2)) / (ai_real)0xFFFF;
case EDT_UInt:
return (ai_real)val.iUInt / (ai_real)0xFFFF;
case EDT_Int:
return ((ai_real)val.iInt / (ai_real)0xFF) + 0.5f;
default:;
};
return 0.0f;
return 0.0f;
}
// ------------------------------------------------------------------------------------------------
// Try to extract proper faces from the PLY DOM
void PLYImporter::LoadFace(const PLY::Element* pcElement, const PLY::ElementInstance* instElement, unsigned int pos)
{
ai_assert(NULL != pcElement);
ai_assert(NULL != instElement);
void PLYImporter::LoadFace(const PLY::Element* pcElement, const PLY::ElementInstance* instElement,
unsigned int pos) {
ai_assert(nullptr != pcElement);
ai_assert(nullptr != instElement);
if (mGeneratedMesh == NULL)
throw DeadlyImportError("Invalid .ply file: Vertices should be declared before faces");
bool bOne = false;
// index of the vertex index list
unsigned int iProperty = 0xFFFFFFFF;
PLY::EDataType eType = EDT_Char;
bool bIsTriStrip = false;
// index of the material index property
//unsigned int iMaterialIndex = 0xFFFFFFFF;
//PLY::EDataType eType2 = EDT_Char;
// texture coordinates
unsigned int iTextureCoord = 0xFFFFFFFF;
PLY::EDataType eType3 = EDT_Char;
// face = unique number of vertex indices
if (PLY::EEST_Face == pcElement->eSemantic)
{
unsigned int _a = 0;
for (std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
a != pcElement->alProperties.end(); ++a, ++_a)
{
if (PLY::EST_VertexIndex == (*a).Semantic)
{
// must be a dynamic list!
if (!(*a).bIsList)
continue;
iProperty = _a;
bOne = true;
eType = (*a).eType;
}
/*else if (PLY::EST_MaterialIndex == (*a).Semantic)
{
if ((*a).bIsList)
continue;
iMaterialIndex = _a;
bOne = true;
eType2 = (*a).eType;
}*/
else if (PLY::EST_TextureCoordinates == (*a).Semantic)
{
// must be a dynamic list!
if (!(*a).bIsList)
continue;
iTextureCoord = _a;
bOne = true;
eType3 = (*a).eType;
}
}
}
// triangle strip
// TODO: triangle strip and material index support???
else if (PLY::EEST_TriStrip == pcElement->eSemantic)
{
unsigned int _a = 0;
for (std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
a != pcElement->alProperties.end(); ++a, ++_a)
{
// must be a dynamic list!
if (!(*a).bIsList)
continue;
iProperty = _a;
bOne = true;
bIsTriStrip = true;
eType = (*a).eType;
break;
}
}
// check whether we have at least one per-face information set
if (bOne)
{
if (mGeneratedMesh->mFaces == NULL)
{
mGeneratedMesh->mNumFaces = pcElement->NumOccur;
mGeneratedMesh->mFaces = new aiFace[mGeneratedMesh->mNumFaces];
if (mGeneratedMesh == nullptr) {
throw DeadlyImportError("Invalid .ply file: Vertices should be declared before faces");
}
if (!bIsTriStrip)
{
// parse the list of vertex indices
if (0xFFFFFFFF != iProperty)
{
const unsigned int iNum = (unsigned int)GetProperty(instElement->alProperties, iProperty).avList.size();
mGeneratedMesh->mFaces[pos].mNumIndices = iNum;
mGeneratedMesh->mFaces[pos].mIndices = new unsigned int[iNum];
bool bOne = false;
std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator p =
GetProperty(instElement->alProperties, iProperty).avList.begin();
// index of the vertex index list
unsigned int iProperty = 0xFFFFFFFF;
PLY::EDataType eType = EDT_Char;
bool bIsTriStrip = false;
for (unsigned int a = 0; a < iNum; ++a, ++p)
{
mGeneratedMesh->mFaces[pos].mIndices[a] = PLY::PropertyInstance::ConvertTo<unsigned int>(*p, eType);
}
}
// index of the material index property
//unsigned int iMaterialIndex = 0xFFFFFFFF;
//PLY::EDataType eType2 = EDT_Char;
// parse the material index
// cannot be handled without processing the whole file first
/*if (0xFFFFFFFF != iMaterialIndex)
{
mGeneratedMesh->mFaces[pos]. = PLY::PropertyInstance::ConvertTo<unsigned int>(
GetProperty(instElement->alProperties, iMaterialIndex).avList.front(), eType2);
}*/
// texture coordinates
unsigned int iTextureCoord = 0xFFFFFFFF;
PLY::EDataType eType3 = EDT_Char;
if (0xFFFFFFFF != iTextureCoord)
{
const unsigned int iNum = (unsigned int)GetProperty(instElement->alProperties, iTextureCoord).avList.size();
// face = unique number of vertex indices
if (PLY::EEST_Face == pcElement->eSemantic) {
unsigned int _a = 0;
for (std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
a != pcElement->alProperties.end(); ++a, ++_a) {
if (PLY::EST_VertexIndex == (*a).Semantic) {
// must be a dynamic list!
if (!(*a).bIsList) {
continue;
}
//should be 6 coords
std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator p =
GetProperty(instElement->alProperties, iTextureCoord).avList.begin();
if ((iNum / 3) == 2) // X Y coord
{
for (unsigned int a = 0; a < iNum; ++a, ++p)
{
unsigned int vindex = mGeneratedMesh->mFaces[pos].mIndices[a / 2];
if (vindex < mGeneratedMesh->mNumVertices)
{
if (mGeneratedMesh->mTextureCoords[0] == NULL)
{
mGeneratedMesh->mNumUVComponents[0] = 2;
mGeneratedMesh->mTextureCoords[0] = new aiVector3D[mGeneratedMesh->mNumVertices];
}
if (a % 2 == 0)
mGeneratedMesh->mTextureCoords[0][vindex].x = PLY::PropertyInstance::ConvertTo<ai_real>(*p, eType3);
else
mGeneratedMesh->mTextureCoords[0][vindex].y = PLY::PropertyInstance::ConvertTo<ai_real>(*p, eType3);
mGeneratedMesh->mTextureCoords[0][vindex].z = 0;
iProperty = _a;
bOne = true;
eType = (*a).eType;
} else if (PLY::EST_TextureCoordinates == (*a).Semantic) {
// must be a dynamic list!
if (!(*a).bIsList) {
continue;
}
iTextureCoord = _a;
bOne = true;
eType3 = (*a).eType;
}
}
}
}
}
else // triangle strips
{
// normally we have only one triangle strip instance where
// a value of -1 indicates a restart of the strip
bool flip = false;
const std::vector<PLY::PropertyInstance::ValueUnion>& quak = GetProperty(instElement->alProperties, iProperty).avList;
//pvOut->reserve(pvOut->size() + quak.size() + (quak.size()>>2u)); //Limits memory consumption
int aiTable[2] = { -1, -1 };
for (std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator a = quak.begin(); a != quak.end(); ++a) {
const int p = PLY::PropertyInstance::ConvertTo<int>(*a, eType);
if (-1 == p) {
// restart the strip ...
aiTable[0] = aiTable[1] = -1;
flip = false;
continue;
// triangle strip
// TODO: triangle strip and material index support???
else if (PLY::EEST_TriStrip == pcElement->eSemantic) {
unsigned int _a = 0;
for (std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
a != pcElement->alProperties.end(); ++a, ++_a) {
// must be a dynamic list!
if (!(*a).bIsList) {
continue;
}
iProperty = _a;
bOne = true;
bIsTriStrip = true;
eType = (*a).eType;
break;
}
if (-1 == aiTable[0]) {
aiTable[0] = p;
continue;
}
if (-1 == aiTable[1]) {
aiTable[1] = p;
continue;
}
// check whether we have at least one per-face information set
if (bOne) {
if (mGeneratedMesh->mFaces == nullptr) {
mGeneratedMesh->mNumFaces = pcElement->NumOccur;
mGeneratedMesh->mFaces = new aiFace[mGeneratedMesh->mNumFaces];
}
if (mGeneratedMesh->mFaces == NULL)
if (!bIsTriStrip) {
// parse the list of vertex indices
if (0xFFFFFFFF != iProperty) {
const unsigned int iNum = (unsigned int)GetProperty(instElement->alProperties, iProperty).avList.size();
mGeneratedMesh->mFaces[pos].mNumIndices = iNum;
mGeneratedMesh->mFaces[pos].mIndices = new unsigned int[iNum];
std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator p =
GetProperty(instElement->alProperties, iProperty).avList.begin();
for (unsigned int a = 0; a < iNum; ++a, ++p) {
mGeneratedMesh->mFaces[pos].mIndices[a] = PLY::PropertyInstance::ConvertTo<unsigned int>(*p, eType);
}
}
// parse the material index
// cannot be handled without processing the whole file first
/*if (0xFFFFFFFF != iMaterialIndex)
{
mGeneratedMesh->mNumFaces = pcElement->NumOccur;
mGeneratedMesh->mFaces = new aiFace[mGeneratedMesh->mNumFaces];
mGeneratedMesh->mFaces[pos]. = PLY::PropertyInstance::ConvertTo<unsigned int>(
GetProperty(instElement->alProperties, iMaterialIndex).avList.front(), eType2);
}*/
if (0xFFFFFFFF != iTextureCoord) {
const unsigned int iNum = (unsigned int)GetProperty(instElement->alProperties, iTextureCoord).avList.size();
//should be 6 coords
std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator p =
GetProperty(instElement->alProperties, iTextureCoord).avList.begin();
if ((iNum / 3) == 2) // X Y coord
{
for (unsigned int a = 0; a < iNum; ++a, ++p) {
unsigned int vindex = mGeneratedMesh->mFaces[pos].mIndices[a / 2];
if (vindex < mGeneratedMesh->mNumVertices) {
if (mGeneratedMesh->mTextureCoords[0] == nullptr ) {
mGeneratedMesh->mNumUVComponents[0] = 2;
mGeneratedMesh->mTextureCoords[0] = new aiVector3D[mGeneratedMesh->mNumVertices];
}
if (a % 2 == 0) {
mGeneratedMesh->mTextureCoords[0][vindex].x = PLY::PropertyInstance::ConvertTo<ai_real>(*p, eType3);
} else {
mGeneratedMesh->mTextureCoords[0][vindex].y = PLY::PropertyInstance::ConvertTo<ai_real>(*p, eType3);
}
mGeneratedMesh->mTextureCoords[0][vindex].z = 0;
}
}
}
}
} else { // triangle strips
// normally we have only one triangle strip instance where
// a value of -1 indicates a restart of the strip
bool flip = false;
const std::vector<PLY::PropertyInstance::ValueUnion>& quak = GetProperty(instElement->alProperties, iProperty).avList;
//pvOut->reserve(pvOut->size() + quak.size() + (quak.size()>>2u)); //Limits memory consumption
int aiTable[2] = { -1, -1 };
for (std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator a = quak.begin(); a != quak.end(); ++a) {
const int p = PLY::PropertyInstance::ConvertTo<int>(*a, eType);
if (-1 == p) {
// restart the strip ...
aiTable[0] = aiTable[1] = -1;
flip = false;
continue;
}
if (-1 == aiTable[0]) {
aiTable[0] = p;
continue;
}
if (-1 == aiTable[1]) {
aiTable[1] = p;
continue;
}
if (mGeneratedMesh->mFaces == nullptr) {
mGeneratedMesh->mNumFaces = pcElement->NumOccur;
mGeneratedMesh->mFaces = new aiFace[mGeneratedMesh->mNumFaces];
}
mGeneratedMesh->mFaces[pos].mNumIndices = 3;
mGeneratedMesh->mFaces[pos].mIndices = new unsigned int[3];
mGeneratedMesh->mFaces[pos].mIndices[0] = aiTable[0];
mGeneratedMesh->mFaces[pos].mIndices[1] = aiTable[1];
mGeneratedMesh->mFaces[pos].mIndices[2] = p;
// every second pass swap the indices.
flip = !flip;
if ( flip ) {
std::swap(mGeneratedMesh->mFaces[pos].mIndices[0], mGeneratedMesh->mFaces[pos].mIndices[1]);
}
aiTable[0] = aiTable[1];
aiTable[1] = p;
}
}
mGeneratedMesh->mFaces[pos].mNumIndices = 3;
mGeneratedMesh->mFaces[pos].mIndices = new unsigned int[3];
mGeneratedMesh->mFaces[pos].mIndices[0] = aiTable[0];
mGeneratedMesh->mFaces[pos].mIndices[1] = aiTable[1];
mGeneratedMesh->mFaces[pos].mIndices[2] = p;
if ((flip = !flip)) {
std::swap(mGeneratedMesh->mFaces[pos].mIndices[0], mGeneratedMesh->mFaces[pos].mIndices[1]);
}
aiTable[0] = aiTable[1];
aiTable[1] = p;
}
}
}
}
// ------------------------------------------------------------------------------------------------

View File

@ -332,6 +332,11 @@ void XFileImporter::CreateMeshes( aiScene* pScene, aiNode* pNode, const std::vec
// collect vertex data for indices of this face
for( unsigned int d = 0; d < df.mNumIndices; ++d ) {
df.mIndices[d] = newIndex;
const unsigned int newIdx( pf.mIndices[ d ] );
if ( newIdx > sourceMesh->mPositions.size() ) {
continue;
}
orgPoints[newIndex] = pf.mIndices[d];
// Position
@ -459,7 +464,7 @@ void XFileImporter::CreateAnimations( aiScene* pScene, const XFile::Scene* pData
nbone->mNodeName.Set( bone->mBoneName);
nanim->mChannels[b] = nbone;
// keyframes are given as combined transformation matrix keys
// key-frames are given as combined transformation matrix keys
if( !bone->mTrafoKeys.empty() )
{
nbone->mNumPositionKeys = (unsigned int)bone->mTrafoKeys.size();

View File

@ -471,7 +471,10 @@ void XFileParser::ParseDataObjectMesh( Mesh* pMesh)
unsigned int numIndices = ReadInt();
Face& face = pMesh->mPosFaces[a];
for (unsigned int b = 0; b < numIndices; ++b) {
face.mIndices.push_back( ReadInt() );
const int idx( ReadInt() );
if ( static_cast<unsigned int>( idx ) <= numVertices ) {
face.mIndices.push_back( idx );
}
}
TestForSeparator();
}
@ -1293,7 +1296,7 @@ unsigned int XFileParser::ReadBinDWord() {
// ------------------------------------------------------------------------------------------------
unsigned int XFileParser::ReadInt()
{
if( mIsBinaryFormat)
if( mIsBinaryFormat)
{
if( mBinaryNumCount == 0 && mEnd - mP >= 2)
{
@ -1305,7 +1308,8 @@ unsigned int XFileParser::ReadInt()
}
--mBinaryNumCount;
if ( mEnd - mP >= 4) {
const size_t len( mEnd - mP );
if ( len >= 4) {
return ReadBinDWord();
} else {
mP = mEnd;
@ -1340,6 +1344,7 @@ unsigned int XFileParser::ReadInt()
}
CheckForSeparator();
return isNegative ? ((unsigned int) -int( number)) : number;
}
}

View File

@ -106,6 +106,7 @@ SET( IMPORTERS
unit/utBlendImportAreaLight.cpp
unit/utBlenderImportExport.cpp
unit/utBlendImportMaterials.cpp
unit/utBlenderWork.cpp
unit/utBVHImportExport.cpp
unit/utColladaExportCamera.cpp
unit/utColladaExportLight.cpp

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,83 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2018, 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/cexport.h>
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
using namespace ::Assimp;
class BlenderWorkTest : public ::testing::Test {
public:
virtual void SetUp()
{
im = new Assimp::Importer();
}
virtual void TearDown()
{
delete im;
}
protected:
Assimp::Importer* im;
};
TEST_F(BlenderWorkTest,work_279) {
const aiScene* pTest = im->ReadFile(ASSIMP_TEST_MODELS_DIR "/BLEND/test_279.blend", aiProcess_ValidateDataStructure);
ASSERT_TRUE(pTest != NULL);
// material has 2 diffuse textures
ASSERT_TRUE(pTest->HasMaterials());
ASSERT_TRUE(pTest->HasMeshes());
ASSERT_TRUE(pTest->mMeshes[0]->mNumVertices > 0);
ASSERT_EQ(44, pTest->mMeshes[0]->mNumFaces);
EXPECT_EQ(1, pTest->mNumMaterials);
}

View File

@ -42,6 +42,7 @@ cmake_minimum_required( VERSION 2.6 )
INCLUDE_DIRECTORIES(
${Assimp_SOURCE_DIR}/include
${Assimp_SOURCE_DIR}/code
${Assimp_BINARY_DIR}/tools/assimp_cmd
)
LINK_DIRECTORIES( ${Assimp_BINARY_DIR} ${Assimp_BINARY_DIR}/lib )

View File

@ -1261,9 +1261,10 @@ void CGLView::Camera_Set(const size_t pCameraNumber)
gluLookAt(hcam.Position.x, hcam.Position.y, hcam.Position.z, hcam.Target.x, hcam.Target.y, hcam.Target.z, up.x, up.y, up.z);
}
void CGLView::Camera_RotateScene(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z, const aiMatrix4x4* pMatrix_Rotation_Initial)
{
auto deg2rad = [](const GLfloat pDegree) -> GLfloat { return pDegree * M_PI / 180.0; };
void CGLView::Camera_RotateScene(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z, const aiMatrix4x4* pMatrix_Rotation_Initial) {
auto deg2rad = [](const GLfloat pDegree) -> GLfloat {
return pDegree * AI_MATH_PI / 180.0;
};
aiMatrix4x4 mat_rot;
@ -1276,7 +1277,7 @@ auto deg2rad = [](const GLfloat pDegree) -> GLfloat { return pDegree * M_PI / 18
void CGLView::Camera_Rotate(const GLfloat pAngle_X, const GLfloat pAngle_Y, const GLfloat pAngle_Z, const aiMatrix4x4* pMatrix_Rotation_Initial)
{
auto deg2rad = [](const GLfloat pDegree) -> GLfloat { return pDegree * M_PI / 180.0; };
auto deg2rad = [](const GLfloat pDegree) -> GLfloat { return pDegree * AI_MATH_PI / 180.0; };
aiMatrix4x4 mat_rot;
@ -1289,7 +1290,7 @@ auto deg2rad = [](const GLfloat pDegree) -> GLfloat { return pDegree * M_PI / 18
void CGLView::Camera_Translate(const GLfloat pTranslate_X, const GLfloat pTranslate_Y, const GLfloat pTranslate_Z)
{
aiVector3D vect_tr(pTranslate_X, pTranslate_Y, pTranslate_Z);
aiVector3D vect_tr(pTranslate_X, pTranslate_Y, pTranslate_Z);
vect_tr *= mHelper_Camera.Rotation_AroundCamera;
mHelper_Camera.Translation_ToScene += vect_tr;

View File

@ -132,9 +132,8 @@ void MainWindow::LogError(const QString& pMessage)
void MainWindow::mousePressEvent(QMouseEvent* pEvent)
{
const QPoint ms_pt = pEvent->pos();
__unused aiVector3D temp_v3;
const QPoint ms_pt = pEvent->pos();
aiVector3D temp_v3;
// Check if GLView is pointed.
if(childAt(ms_pt) == mGLView)
@ -305,30 +304,32 @@ void MainWindow::SceneObject_LightSource(const QString& pName)
ui->lstLight->selectAll();
}
void MainWindow::on_butOpenFile_clicked()
{
aiString filter_temp;
QString filename, filter;
void MainWindow::on_butOpenFile_clicked() {
aiString filter_temp;
mImporter.GetExtensionList( filter_temp );
mImporter.GetExtensionList(filter_temp);
filter = filter_temp.C_Str();
QString filename, filter;
filter = filter_temp.C_Str();
filter.replace(';', ' ');
filter.append(" ;; All (*.*)");
filename = QFileDialog::getOpenFileName(this, "Choose the file", "", filter);
if(!filename.isEmpty()) ImportFile(filename);
if (!filename.isEmpty()) {
ImportFile( filename );
}
}
void MainWindow::on_butExport_clicked()
{
using namespace Assimp;
using namespace Assimp;
QString filename, filter, format_id;
Exporter exporter;
QTime time_begin;
aiReturn rv;
QStringList exportersList;
QMap<QString, const aiExportFormatDesc*> exportersMap;
#ifndef ASSIMP_BUILD_NO_EXPORT
QString filename, filter, format_id;
Exporter exporter;
QTime time_begin;
aiReturn rv;
QStringList exportersList;
QMap<QString, const aiExportFormatDesc*> exportersMap;
if(mScene == nullptr)
@ -373,6 +374,7 @@ QMap<QString, const aiExportFormatDesc*> exportersMap;
LogError(errorMessage);
QMessageBox::critical(this, "Export error", errorMessage);
}
#endif
}
void MainWindow::on_cbxLighting_clicked(bool pChecked)
@ -382,11 +384,7 @@ void MainWindow::on_cbxLighting_clicked(bool pChecked)
else
mGLView->Lighting_Disable();
#if ASSIMP_QT4_VIEWER
mGLView->updateGL();
#else
mGLView->update();
#endif // ASSIMP_QT4_VIEWER
}
void MainWindow::on_lstLight_itemSelectionChanged()
@ -438,9 +436,5 @@ void MainWindow::on_cbxDrawAxes_clicked(bool checked)
void MainWindow::on_cbxTextures_clicked(bool checked)
{
mGLView->Enable_Textures(checked);
#if ASSIMP_QT4_VIEWER
mGLView->updateGL();
#else
mGLView->update();
#endif // ASSIMP_QT4_VIEWER
}

View File

@ -6,7 +6,7 @@
#pragma once
// Header files, Qt.
#if ASSIMP_QT4_VIEWER
#if defined ASSIMP_QT4_VIEWER
# include <QMainWindow>
#else
# include <QtWidgets>

View File

@ -363,9 +363,7 @@ int CDisplay::ReplaceCurrentTexture(const char* szPath)
*tex = piTexture;
m_pcCurrentTexture->piTexture = tex;
//if (!pcMesh->bSharedFX){
pcMesh->piEffect->SetTexture(tex_string,piTexture);
//}
pcMesh->piEffect->SetTexture(tex_string,piTexture);
}
}
@ -563,7 +561,6 @@ int CDisplay::AddMaterialToDisplayList(HTREEITEM hRoot,
tvi.iImage = m_aiImageList[AI_VIEW_IMGLIST_MATERIAL];
tvi.iSelectedImage = m_aiImageList[AI_VIEW_IMGLIST_MATERIAL];
tvi.lParam = (LPARAM)10;
//tvi.state = TVIS_EXPANDED | TVIS_EXPANDEDONCE ;
sNew.itemex = tvi;
sNew.hInsertAfter = TVI_LAST;
@ -630,7 +627,7 @@ int CDisplay::AddMaterialToDisplayList(HTREEITEM hRoot,
return 1;
}
//-------------------------------------------------------------------------------
// Expand all elements in the treeview
// Expand all elements in the tree-view
int CDisplay::ExpandTree()
{
// expand all materials
@ -780,7 +777,7 @@ int CDisplay::OnRender()
// Now render the log display in the upper right corner of the window
CLogDisplay::Instance().OnRender();
// present the backbuffer
// present the back-buffer
g_piDevice->EndScene();
g_piDevice->Present(NULL,NULL,NULL,NULL);
@ -1601,7 +1598,7 @@ int CDisplay::HandleInput()
return 1;
}
//-------------------------------------------------------------------------------
// Process input for an empty scen view to allow for skybox rotations
// Process input for an empty scene view to allow for sky-box rotations
int CDisplay::HandleInputEmptyScene()
{
if(CBackgroundPainter::TEXTURE_CUBE == CBackgroundPainter::Instance().GetMode())
@ -2043,7 +2040,7 @@ int CDisplay::RenderNode (aiNode* piNode,const aiMatrix4x4& piMatrix,
g_piDevice->SetVertexDeclaration( gDefaultVertexDecl);
if (g_sOptions.bNoAlphaBlending) {
// manually disable alphablending
// manually disable alpha-blending
g_piDevice->SetRenderState(D3DRS_ALPHABLENDENABLE,FALSE);
}
@ -2207,9 +2204,6 @@ int CDisplay::RenderTextureView()
// it might be that there is no texture ...
if (!m_pcCurrentTexture->piTexture)
{
// FIX: no such log message. it would be repeated to often
//CLogDisplay::Instance().AddEntry("Unable to display texture. Image is unreachable.",
// D3DCOLOR_ARGB(0xFF,0xFF,0,0));
return 0;
}
@ -2304,5 +2298,6 @@ int CDisplay::RenderTextureView()
// do we need to draw UV coordinates?
return 1;
}
};
}

View File

@ -183,7 +183,6 @@ DWORD WINAPI LoadThreadProc(LPVOID lpParameter)
// get the end time of zje operation, calculate delta t
double fEnd = (double)timeGetTime();
g_fLoadTime = (float)((fEnd - fCur) / 1000);
// char szTemp[128];
g_bLoadingFinished = true;
// check whether the loading process has failed ...