#ifndef ASSIMP_BUILD_NO_PLY_IMPORTER
#include "PlyLoader.h"
#include "IOStreamBuffer.h"
#include "Macros.h"
#include <memory>
#include <assimp/IOSystem.hpp>
#include <assimp/scene.h>
#include <assimp/importerdesc.h>
using namespace Assimp;
static const aiImporterDesc desc = {
"Stanford Polygon Library (PLY) Importer",
"",
"",
"",
aiImporterFlags_SupportBinaryFlavour | aiImporterFlags_SupportTextFlavour,
0,
0,
0,
0,
"ply"
};
namespace
{
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.");
}
return props[idx];
}
}
PLYImporter::PLYImporter()
: mBuffer()
, pcDOM()
, mGeneratedMesh(NULL){
}
PLYImporter::~PLYImporter() {
}
bool PLYImporter::CanRead(const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const
{
const std::string extension = GetExtension(pFile);
if (extension == "ply")
return true;
else if (!extension.length() || checkSig)
{
if (!pIOHandler)return true;
const char* tokens[] = { "ply" };
return SearchFileHeaderForToken(pIOHandler, pFile, tokens, 1);
}
return false;
}
const aiImporterDesc* PLYImporter::GetInfo() const
{
return &desc;
}
static bool isBigEndian(const char* szMe) {
ai_assert(NULL != szMe);
bool isBigEndian(false);
#if (defined AI_BUILD_BIG_ENDIAN)
if ( 'l' == *szMe || 'L' == *szMe ) {
isBigEndian = true;
}
#else
if ('b' == *szMe || 'B' == *szMe) {
isBigEndian = true;
}
#endif
return isBigEndian;
}
void PLYImporter::InternReadFile(const std::string& pFile,
aiScene* pScene, IOSystem* pIOHandler)
{
static const std::string mode = "rb";
std::unique_ptr<IOStream> fileStream(pIOHandler->Open(pFile, mode));
if (!fileStream.get()) {
throw DeadlyImportError("Failed to open file " + pFile + ".");
}
size_t fileSize = fileStream->FileSize();
if ( 0 == fileSize ) {
throw DeadlyImportError("File " + pFile + " is empty.");
}
IOStreamBuffer<char> streamedBuffer(1024 * 1024);
streamedBuffer.open(fileStream.get());
std::vector<char> headerCheck;
streamedBuffer.getNextLine(headerCheck);
if ((headerCheck.size() >= 3) && (headerCheck[0] != 'P' && headerCheck[0] != 'p') ||
(headerCheck[1] != 'L' && headerCheck[1] != 'l') ||
(headerCheck[2] != 'Y' && headerCheck[2] != 'y'))
{
streamedBuffer.close();
throw DeadlyImportError("Invalid .ply file: Magic number \'ply\' is no there");
}
std::vector<char> mBuffer2;
streamedBuffer.getNextLine(mBuffer2);
mBuffer = (unsigned char*)&mBuffer2[0];
char* szMe = (char*)&this->mBuffer[0];
SkipSpacesAndLineEnd(szMe, (const char**)&szMe);
PLY::DOM sPlyDom;
this->pcDOM = &sPlyDom;
if (TokenMatch(szMe, "format", 6)) {
if (TokenMatch(szMe, "ascii", 5)) {
SkipLine(szMe, (const char**)&szMe);
if (!PLY::DOM::ParseInstance(streamedBuffer, &sPlyDom, this))
{
if (mGeneratedMesh != NULL)
delete(mGeneratedMesh);
streamedBuffer.close();
throw DeadlyImportError("Invalid .ply file: Unable to build DOM (#1)");
}
}
else if (!::strncmp(szMe, "binary_", 7))
{
szMe += 7;
const bool bIsBE(isBigEndian(szMe));
if (!PLY::DOM::ParseInstanceBinary(streamedBuffer, &sPlyDom, this, bIsBE))
{
if (mGeneratedMesh != NULL)
delete(mGeneratedMesh);
streamedBuffer.close();
throw DeadlyImportError("Invalid .ply file: Unable to build DOM (#2)");
}
}
else
{
if (mGeneratedMesh != NULL)
delete(mGeneratedMesh);
streamedBuffer.close();
throw DeadlyImportError("Invalid .ply file: Unknown file format");
}
}
else
{
AI_DEBUG_INVALIDATE_PTR(this->mBuffer);
if (mGeneratedMesh != NULL)
delete(mGeneratedMesh);
streamedBuffer.close();
throw DeadlyImportError("Invalid .ply file: Missing format specification");
}
streamedBuffer.close();
if (mGeneratedMesh == NULL)
{
throw DeadlyImportError("Invalid .ply file: Unable to extract mesh data ");
}
bool pointsOnly = mGeneratedMesh->mFaces == NULL ? true : false;
if (pointsOnly)
{
if (mGeneratedMesh->mNumVertices < 3)
{
if (mGeneratedMesh != NULL)
delete(mGeneratedMesh);
streamedBuffer.close();
throw DeadlyImportError("Invalid .ply file: Not enough "
"vertices to build a proper face list. ");
}
const unsigned int iNum = (unsigned int)mGeneratedMesh->mNumVertices / 3;
mGeneratedMesh->mNumFaces = iNum;
mGeneratedMesh->mFaces = new aiFace[mGeneratedMesh->mNumFaces];
for (unsigned int i = 0; i < iNum; ++i)
{
mGeneratedMesh->mFaces[i].mNumIndices = 3;
mGeneratedMesh->mFaces[i].mIndices = new unsigned int[3];
mGeneratedMesh->mFaces[i].mIndices[0] = (i * 3);
mGeneratedMesh->mFaces[i].mIndices[1] = (i * 3) + 1;
mGeneratedMesh->mFaces[i].mIndices[2] = (i * 3) + 2;
}
}
std::vector<aiMaterial*> avMaterials;
std::string defaultTexture;
LoadMaterial(&avMaterials, defaultTexture, pointsOnly);
pScene->mNumMaterials = (unsigned int)avMaterials.size();
pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials];
for (unsigned int i = 0; i < pScene->mNumMaterials; ++i) {
pScene->mMaterials[i] = avMaterials[i];
}
pScene->mNumMeshes = 1;
pScene->mMeshes = new aiMesh*[pScene->mNumMeshes];
pScene->mMeshes[0] = mGeneratedMesh;
pScene->mRootNode = new aiNode();
pScene->mRootNode->mNumMeshes = pScene->mNumMeshes;
pScene->mRootNode->mMeshes = new unsigned int[pScene->mNumMeshes];
for (unsigned int i = 0; i < pScene->mRootNode->mNumMeshes; ++i) {
pScene->mRootNode->mMeshes[i] = i;
}
}
void PLYImporter::LoadVertex(const PLY::Element* pcElement, const PLY::ElementInstance* instElement, unsigned int pos) {
ai_assert(NULL != pcElement);
ai_assert(NULL != instElement);
ai_uint aiPositions[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
PLY::EDataType aiTypes[3] = { EDT_Char, EDT_Char, EDT_Char };
ai_uint aiNormal[3] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
PLY::EDataType aiNormalTypes[3] = { EDT_Char, EDT_Char, EDT_Char };
unsigned int aiColors[4] = { 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF };
PLY::EDataType aiColorsTypes[4] = { EDT_Char, EDT_Char, EDT_Char, EDT_Char };
unsigned int aiTexcoord[2] = { 0xFFFFFFFF, 0xFFFFFFFF };
PLY::EDataType aiTexcoordTypes[2] = { EDT_Char, EDT_Char };
unsigned int _a( 0 ), cnt( 0 );
for ( std::vector<PLY::Property>::const_iterator a = pcElement->alProperties.begin();
a != pcElement->alProperties.end(); ++a, ++_a) {
if ((*a).bIsList) {
continue;
}
if (PLY::EST_XCoord == (*a).Semantic) {
++cnt;
aiPositions[0] = _a;
aiTypes[0] = (*a).eType;
} else if (PLY::EST_YCoord == (*a).Semantic) {
++cnt;
aiPositions[1] = _a;
aiTypes[1] = (*a).eType;
} else if (PLY::EST_ZCoord == (*a).Semantic) {
++cnt;
aiPositions[2] = _a;
aiTypes[2] = (*a).eType;
} else if (PLY::EST_XNormal == (*a).Semantic) {
++cnt;
aiNormal[0] = _a;
aiNormalTypes[0] = (*a).eType;
} else if (PLY::EST_YNormal == (*a).Semantic) {
++cnt;
aiNormal[1] = _a;
aiNormalTypes[1] = (*a).eType;
} else if (PLY::EST_ZNormal == (*a).Semantic) {
++cnt;
aiNormal[2] = _a;
aiNormalTypes[2] = (*a).eType;
} else if (PLY::EST_Red == (*a).Semantic) {
++cnt;
aiColors[0] = _a;
aiColorsTypes[0] = (*a).eType;
} else if (PLY::EST_Green == (*a).Semantic) {
++cnt;
aiColors[1] = _a;
aiColorsTypes[1] = (*a).eType;
} else if (PLY::EST_Blue == (*a).Semantic) {
++cnt;
aiColors[2] = _a;
aiColorsTypes[2] = (*a).eType;
} else if (PLY::EST_Alpha == (*a).Semantic) {
++cnt;
aiColors[3] = _a;
aiColorsTypes[3] = (*a).eType;
} else if (PLY::EST_UTextureCoord == (*a).Semantic) {
++cnt;
aiTexcoord[0] = _a;
aiTexcoordTypes[0] = (*a).eType;
} else if (PLY::EST_VTextureCoord == (*a).Semantic) {
++cnt;
aiTexcoord[1] = _a;
aiTexcoordTypes[1] = (*a).eType;
}
}
if (0 != cnt) {
aiVector3D vOut;
if (0xFFFFFFFF != aiPositions[0]) {
vOut.x = PLY::PropertyInstance::ConvertTo<ai_real>(
GetProperty(instElement->alProperties, aiPositions[0]).avList.front(), aiTypes[0]);
}
if (0xFFFFFFFF != aiPositions[1]) {
vOut.y = PLY::PropertyInstance::ConvertTo<ai_real>(
GetProperty(instElement->alProperties, aiPositions[1]).avList.front(), aiTypes[1]);
}
if (0xFFFFFFFF != aiPositions[2]) {
vOut.z = PLY::PropertyInstance::ConvertTo<ai_real>(
GetProperty(instElement->alProperties, aiPositions[2]).avList.front(), aiTypes[2]);
}
aiVector3D nOut;
bool haveNormal = false;
if (0xFFFFFFFF != aiNormal[0]) {
nOut.x = PLY::PropertyInstance::ConvertTo<ai_real>(
GetProperty(instElement->alProperties, aiNormal[0]).avList.front(), aiNormalTypes[0]);
haveNormal = true;
}
if (0xFFFFFFFF != aiNormal[1]) {
nOut.y = PLY::PropertyInstance::ConvertTo<ai_real>(
GetProperty(instElement->alProperties, aiNormal[1]).avList.front(), aiNormalTypes[1]);
haveNormal = true;
}
if (0xFFFFFFFF != aiNormal[2]) {
nOut.z = PLY::PropertyInstance::ConvertTo<ai_real>(
GetProperty(instElement->alProperties, aiNormal[2]).avList.front(), aiNormalTypes[2]);
haveNormal = true;
}
aiColor4D cOut;
bool haveColor = false;
if (0xFFFFFFFF != aiColors[0]) {
cOut.r = NormalizeColorValue(GetProperty(instElement->alProperties,
aiColors[0]).avList.front(), aiColorsTypes[0]);
haveColor = true;
}
if (0xFFFFFFFF != aiColors[1]) {
cOut.g = NormalizeColorValue(GetProperty(instElement->alProperties,
aiColors[1]).avList.front(), aiColorsTypes[1]);
haveColor = true;
}
if (0xFFFFFFFF != aiColors[2]) {
cOut.b = NormalizeColorValue(GetProperty(instElement->alProperties,
aiColors[2]).avList.front(), aiColorsTypes[2]);
haveColor = true;
}
if (0xFFFFFFFF == aiColors[3]) {
cOut.a = 1.0;
} else {
cOut.a = NormalizeColorValue(GetProperty(instElement->alProperties,
aiColors[3]).avList.front(), aiColorsTypes[3]);
haveColor = true;
}
aiVector3D tOut;
tOut.z = 0;
bool haveTextureCoords = false;
if (0xFFFFFFFF != aiTexcoord[0]) {
tOut.x = PLY::PropertyInstance::ConvertTo<ai_real>(
GetProperty(instElement->alProperties, aiTexcoord[0]).avList.front(), aiTexcoordTypes[0]);
haveTextureCoords = true;
}
if (0xFFFFFFFF != aiTexcoord[1]) {
tOut.y = PLY::PropertyInstance::ConvertTo<ai_real>(
GetProperty(instElement->alProperties, aiTexcoord[1]).avList.front(), aiTexcoordTypes[1]);
haveTextureCoords = true;
}
if ( nullptr == mGeneratedMesh ) {
mGeneratedMesh = new aiMesh();
mGeneratedMesh->mMaterialIndex = 0;
}
if (nullptr == mGeneratedMesh->mVertices) {
mGeneratedMesh->mNumVertices = pcElement->NumOccur;
mGeneratedMesh->mVertices = new aiVector3D[mGeneratedMesh->mNumVertices];
}
mGeneratedMesh->mVertices[pos] = vOut;
if (haveNormal) {
if (nullptr == mGeneratedMesh->mNormals)
mGeneratedMesh->mNormals = new aiVector3D[mGeneratedMesh->mNumVertices];
mGeneratedMesh->mNormals[pos] = nOut;
}
if (haveColor) {
if (nullptr == mGeneratedMesh->mColors[0])
mGeneratedMesh->mColors[0] = new aiColor4D[mGeneratedMesh->mNumVertices];
mGeneratedMesh->mColors[0][pos] = cOut;
}
if (haveTextureCoords) {
if (nullptr == mGeneratedMesh->mTextureCoords[0]) {
mGeneratedMesh->mNumUVComponents[0] = 2;
mGeneratedMesh->mTextureCoords[0] = new aiVector3D[mGeneratedMesh->mNumVertices];
}
mGeneratedMesh->mTextureCoords[0][pos] = tOut;
}
}
}
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;
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;
}
void PLYImporter::LoadFace(const PLY::Element* pcElement, const PLY::ElementInstance* instElement, unsigned int pos)
{
ai_assert(NULL != pcElement);
ai_assert(NULL != instElement);
if (mGeneratedMesh == NULL)
throw DeadlyImportError("Invalid .ply file: Vertices shoud be declared before faces");
bool bOne = false;
unsigned int iProperty = 0xFFFFFFFF;
PLY::EDataType eType = EDT_Char;
bool bIsTriStrip = false;
unsigned int iTextureCoord = 0xFFFFFFFF;
PLY::EDataType eType3 = EDT_Char;
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)
{
if (!(*a).bIsList)
continue;
iProperty = _a;
bOne = true;
eType = (*a).eType;
}
else if (PLY::EST_TextureCoordinates == (*a).Semantic)
{
if (!(*a).bIsList)
continue;
iTextureCoord = _a;
bOne = true;
eType3 = (*a).eType;
}
}
}
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)
{
if (!(*a).bIsList)
continue;
iProperty = _a;
bOne = true;
bIsTriStrip = true;
eType = (*a).eType;
break;
}
}
if (bOne)
{
if (mGeneratedMesh->mFaces == NULL)
{
mGeneratedMesh->mNumFaces = pcElement->NumOccur;
mGeneratedMesh->mFaces = new aiFace[mGeneratedMesh->mNumFaces];
}
if (!bIsTriStrip)
{
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);
}
}
if (0xFFFFFFFF != iTextureCoord)
{
const unsigned int iNum = (unsigned int)GetProperty(instElement->alProperties, iTextureCoord).avList.size();
std::vector<PLY::PropertyInstance::ValueUnion>::const_iterator p =
GetProperty(instElement->alProperties, iTextureCoord).avList.begin();
if ((iNum / 3) == 2) {
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;
}
}
}
}
}
else {
bool flip = false;
const std::vector<PLY::PropertyInstance::ValueUnion>& quak = GetProperty(instElement->alProperties, iProperty).avList;
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) {
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 == NULL)
{
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;
if ((flip = !flip)) {
std::swap(mGeneratedMesh->mFaces[pos].mIndices[0], mGeneratedMesh->mFaces[pos].mIndices[1]);
}
aiTable[0] = aiTable[1];
aiTable[1] = p;
}
}
}
}
void PLYImporter::GetMaterialColor(const std::vector<PLY::PropertyInstance>& avList,
unsigned int aiPositions[4],
PLY::EDataType aiTypes[4],
aiColor4D* clrOut)
{
ai_assert(NULL != clrOut);
if (0xFFFFFFFF == aiPositions[0])clrOut->r = 0.0f;
else
{
clrOut->r = NormalizeColorValue(GetProperty(avList,
aiPositions[0]).avList.front(), aiTypes[0]);
}
if (0xFFFFFFFF == aiPositions[1])clrOut->g = 0.0f;
else
{
clrOut->g = NormalizeColorValue(GetProperty(avList,
aiPositions[1]).avList.front(), aiTypes[1]);
}
if (0xFFFFFFFF == aiPositions[2])clrOut->b = 0.0f;
else
{
clrOut->b = NormalizeColorValue(GetProperty(avList,
aiPositions[2]).avList.front(), aiTypes[2]);
}
if (0xFFFFFFFF == aiPositions[3])clrOut->a = 1.0f;
else
{
clrOut->a = NormalizeColorValue(GetProperty(avList,
aiPositions[3]).avList.front(), aiTypes[3]);
}
}
void PLYImporter::LoadMaterial(std::vector<aiMaterial*>* pvOut, std::string &defaultTexture, const bool pointsOnly)
{
ai_assert(NULL != pvOut);
unsigned int aaiPositions[3][4] = {
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF },
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF },
{ 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF },
};
PLY::EDataType aaiTypes[3][4] = {
{ EDT_Char, EDT_Char, EDT_Char, EDT_Char },
{ EDT_Char, EDT_Char, EDT_Char, EDT_Char },
{ EDT_Char, EDT_Char, EDT_Char, EDT_Char }
};
PLY::ElementInstanceList* pcList = NULL;
unsigned int iPhong = 0xFFFFFFFF;
PLY::EDataType ePhong = EDT_Char;
unsigned int iOpacity = 0xFFFFFFFF;
PLY::EDataType eOpacity = EDT_Char;
unsigned int _i = 0;
for (std::vector<PLY::Element>::const_iterator i = this->pcDOM->alElements.begin();
i != this->pcDOM->alElements.end(); ++i, ++_i)
{
if (PLY::EEST_Material == (*i).eSemantic)
{
pcList = &this->pcDOM->alElementData[_i];
unsigned int _a = 0;
for (std::vector<PLY::Property>::const_iterator
a = (*i).alProperties.begin();
a != (*i).alProperties.end(); ++a, ++_a)
{
if ((*a).bIsList)continue;
if (PLY::EST_PhongPower == (*a).Semantic)
{
iPhong = _a;
ePhong = (*a).eType;
}
if (PLY::EST_Opacity == (*a).Semantic)
{
iOpacity = _a;
eOpacity = (*a).eType;
}
if (PLY::EST_DiffuseRed == (*a).Semantic)
{
aaiPositions[0][0] = _a;
aaiTypes[0][0] = (*a).eType;
}
else if (PLY::EST_DiffuseGreen == (*a).Semantic)
{
aaiPositions[0][1] = _a;
aaiTypes[0][1] = (*a).eType;
}
else if (PLY::EST_DiffuseBlue == (*a).Semantic)
{
aaiPositions[0][2] = _a;
aaiTypes[0][2] = (*a).eType;
}
else if (PLY::EST_DiffuseAlpha == (*a).Semantic)
{
aaiPositions[0][3] = _a;
aaiTypes[0][3] = (*a).eType;
}
else if (PLY::EST_SpecularRed == (*a).Semantic)
{
aaiPositions[1][0] = _a;
aaiTypes[1][0] = (*a).eType;
}
else if (PLY::EST_SpecularGreen == (*a).Semantic)
{
aaiPositions[1][1] = _a;
aaiTypes[1][1] = (*a).eType;
}
else if (PLY::EST_SpecularBlue == (*a).Semantic)
{
aaiPositions[1][2] = _a;
aaiTypes[1][2] = (*a).eType;
}
else if (PLY::EST_SpecularAlpha == (*a).Semantic)
{
aaiPositions[1][3] = _a;
aaiTypes[1][3] = (*a).eType;
}
else if (PLY::EST_AmbientRed == (*a).Semantic)
{
aaiPositions[2][0] = _a;
aaiTypes[2][0] = (*a).eType;
}
else if (PLY::EST_AmbientGreen == (*a).Semantic)
{
aaiPositions[2][1] = _a;
aaiTypes[2][1] = (*a).eType;
}
else if (PLY::EST_AmbientBlue == (*a).Semantic)
{
aaiPositions[2][2] = _a;
aaiTypes[2][2] = (*a).eType;
}
else if (PLY::EST_AmbientAlpha == (*a).Semantic)
{
aaiPositions[2][3] = _a;
aaiTypes[2][3] = (*a).eType;
}
}
break;
}
else if (PLY::EEST_TextureFile == (*i).eSemantic)
{
defaultTexture = (*i).szName;
}
}
if (NULL != pcList) {
for (std::vector<ElementInstance>::const_iterator i = pcList->alInstances.begin(); i != pcList->alInstances.end(); ++i) {
aiColor4D clrOut;
aiMaterial* pcHelper = new aiMaterial();
GetMaterialColor((*i).alProperties, aaiPositions[0], aaiTypes[0], &clrOut);
pcHelper->AddProperty<aiColor4D>(&clrOut, 1, AI_MATKEY_COLOR_DIFFUSE);
GetMaterialColor((*i).alProperties, aaiPositions[1], aaiTypes[1], &clrOut);
pcHelper->AddProperty<aiColor4D>(&clrOut, 1, AI_MATKEY_COLOR_SPECULAR);
GetMaterialColor((*i).alProperties, aaiPositions[2], aaiTypes[2], &clrOut);
pcHelper->AddProperty<aiColor4D>(&clrOut, 1, AI_MATKEY_COLOR_AMBIENT);
int iMode = (int)aiShadingMode_Gouraud;
if (0xFFFFFFFF != iPhong) {
ai_real fSpec = PLY::PropertyInstance::ConvertTo<ai_real>(GetProperty((*i).alProperties, iPhong).avList.front(), ePhong);
if (fSpec) {
fSpec *= 15;
pcHelper->AddProperty<ai_real>(&fSpec, 1, AI_MATKEY_SHININESS);
iMode = (int)aiShadingMode_Phong;
}
}
pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
if (0xFFFFFFFF != iOpacity) {
ai_real fOpacity = PLY::PropertyInstance::ConvertTo<ai_real>(GetProperty((*i).alProperties, iPhong).avList.front(), eOpacity);
pcHelper->AddProperty<ai_real>(&fOpacity, 1, AI_MATKEY_OPACITY);
}
const int two_sided = 1;
pcHelper->AddProperty(&two_sided, 1, AI_MATKEY_TWOSIDED);
if (!defaultTexture.empty())
{
const aiString name(defaultTexture.c_str());
pcHelper->AddProperty(&name, _AI_MATKEY_TEXTURE_BASE, aiTextureType_DIFFUSE, 0);
}
if (!pointsOnly)
{
const int two_sided = 1;
pcHelper->AddProperty(&two_sided, 1, AI_MATKEY_TWOSIDED);
}
if (pointsOnly)
{
const int wireframe = 1;
pcHelper->AddProperty(&wireframe, 1, AI_MATKEY_ENABLE_WIREFRAME);
}
pvOut->push_back(pcHelper);
}
}
else
{
aiMaterial* pcHelper = new aiMaterial();
int iMode = (int)aiShadingMode_Gouraud;
pcHelper->AddProperty<int>(&iMode, 1, AI_MATKEY_SHADING_MODEL);
aiColor3D clr;
clr.b = clr.g = clr.r = 1.0f;
pcHelper->AddProperty<aiColor3D>(&clr, 1, AI_MATKEY_COLOR_DIFFUSE);
pcHelper->AddProperty<aiColor3D>(&clr, 1, AI_MATKEY_COLOR_SPECULAR);
clr.b = clr.g = clr.r = 1.0f;
pcHelper->AddProperty<aiColor3D>(&clr, 1, AI_MATKEY_COLOR_AMBIENT);
if (!pointsOnly)
{
const int two_sided = 1;
pcHelper->AddProperty(&two_sided, 1, AI_MATKEY_TWOSIDED);
}
if (!defaultTexture.empty())
{
const aiString name(defaultTexture.c_str());
pcHelper->AddProperty(&name, _AI_MATKEY_TEXTURE_BASE, aiTextureType_DIFFUSE, 0);
}
if (pointsOnly)
{
const int wireframe = 1;
pcHelper->AddProperty(&wireframe, 1, AI_MATKEY_ENABLE_WIREFRAME);
}
pvOut->push_back(pcHelper);
}
}
#endif