pull/3694/head
Kim Kulling 2021-03-09 21:08:28 +01:00
parent e09e4ab670
commit 6c89631581
32 changed files with 304 additions and 398 deletions

View File

@ -324,7 +324,7 @@ void Discreet3DSImporter::ParseObjectChunk() {
case Discreet3DS::CHUNK_MAT_MATERIAL: case Discreet3DS::CHUNK_MAT_MATERIAL:
// Add a new material to the list // Add a new material to the list
mScene->mMaterials.push_back(D3DS::Material(std::string("UNNAMED_" + to_string(mScene->mMaterials.size())))); mScene->mMaterials.push_back(D3DS::Material(std::string("UNNAMED_" + ai_to_string(mScene->mMaterials.size()))));
ParseMaterialChunk(); ParseMaterialChunk();
break; break;

View File

@ -237,7 +237,7 @@ void D3MFExporter::writeBaseMaterials() {
aiMaterial *mat = mScene->mMaterials[i]; aiMaterial *mat = mScene->mMaterials[i];
aiString name; aiString name;
if (mat->Get(AI_MATKEY_NAME, name) != aiReturn_SUCCESS) { if (mat->Get(AI_MATKEY_NAME, name) != aiReturn_SUCCESS) {
strName = "basemat_" + to_string(i); strName = "basemat_" + ai_to_string(i);
} else { } else {
strName = name.C_Str(); strName = name.C_Str();
} }
@ -248,7 +248,7 @@ void D3MFExporter::writeBaseMaterials() {
// rgbs % // rgbs %
if (color.r <= 1 && color.g <= 1 && color.b <= 1 && color.a <= 1) { if (color.r <= 1 && color.g <= 1 && color.b <= 1 && color.a <= 1) {
hexDiffuseColor = Rgba2Hex( hexDiffuseColor = ai_rgba2hex(
(int)((ai_real)color.r) * 255, (int)((ai_real)color.r) * 255,
(int)((ai_real)color.g) * 255, (int)((ai_real)color.g) * 255,
(int)((ai_real)color.b) * 255, (int)((ai_real)color.b) * 255,
@ -257,13 +257,13 @@ void D3MFExporter::writeBaseMaterials() {
} else { } else {
hexDiffuseColor = "#"; hexDiffuseColor = "#";
tmp = DecimalToHexa((ai_real)color.r); tmp = ai_decimal_to_hexa((ai_real)color.r);
hexDiffuseColor += tmp; hexDiffuseColor += tmp;
tmp = DecimalToHexa((ai_real)color.g); tmp = ai_decimal_to_hexa((ai_real)color.g);
hexDiffuseColor += tmp; hexDiffuseColor += tmp;
tmp = DecimalToHexa((ai_real)color.b); tmp = ai_decimal_to_hexa((ai_real)color.b);
hexDiffuseColor += tmp; hexDiffuseColor += tmp;
tmp = DecimalToHexa((ai_real)color.a); tmp = ai_decimal_to_hexa((ai_real)color.a);
hexDiffuseColor += tmp; hexDiffuseColor += tmp;
} }
} else { } else {
@ -339,7 +339,7 @@ void D3MFExporter::writeFaces(aiMesh *mesh, unsigned int matIdx) {
aiFace &currentFace = mesh->mFaces[i]; aiFace &currentFace = mesh->mFaces[i];
mModelOutput << "<" << XmlTag::triangle << " v1=\"" << currentFace.mIndices[0] << "\" v2=\"" mModelOutput << "<" << XmlTag::triangle << " v1=\"" << currentFace.mIndices[0] << "\" v2=\""
<< currentFace.mIndices[1] << "\" v3=\"" << currentFace.mIndices[2] << currentFace.mIndices[1] << "\" v3=\"" << currentFace.mIndices[2]
<< "\" pid=\"1\" p1=\"" + to_string(matIdx) + "\" />"; << "\" pid=\"1\" p1=\"" + ai_to_string(matIdx) + "\" />";
mModelOutput << std::endl; mModelOutput << std::endl;
} }
mModelOutput << "</" << XmlTag::triangles << ">"; mModelOutput << "</" << XmlTag::triangles << ">";

View File

@ -116,7 +116,7 @@ public:
Object(int id) : Object(int id) :
Resource(id), Resource(id),
mName (std::string("Object_") + to_string(id)){} mName(std::string("Object_") + ai_to_string(id)) {}
virtual ResourceType getType() { virtual ResourceType getType() {
return ResourceType::RT_Object; return ResourceType::RT_Object;
@ -321,7 +321,7 @@ private:
bool hasPid = getNodeAttribute(node, D3MF::XmlTag::pid, pid); bool hasPid = getNodeAttribute(node, D3MF::XmlTag::pid, pid);
bool hasPindex = getNodeAttribute(node, D3MF::XmlTag::pindex, pindex); bool hasPindex = getNodeAttribute(node, D3MF::XmlTag::pindex, pindex);
std::string idStr = to_string(id); std::string idStr = ai_to_string(id);
if (!hasId) { if (!hasId) {
return; return;
@ -531,7 +531,7 @@ private:
bool hasName = getNodeAttribute(node, D3MF::XmlTag::basematerials_name, name); bool hasName = getNodeAttribute(node, D3MF::XmlTag::basematerials_name, name);
std::string stdMaterialName; std::string stdMaterialName;
std::string strId(to_string(basematerialsId)); std::string strId(ai_to_string(basematerialsId));
stdMaterialName += "id"; stdMaterialName += "id";
stdMaterialName += strId; stdMaterialName += strId;
stdMaterialName += "_"; stdMaterialName += "_";
@ -539,7 +539,7 @@ private:
stdMaterialName += std::string(name); stdMaterialName += std::string(name);
} else { } else {
stdMaterialName += "basemat_"; stdMaterialName += "basemat_";
stdMaterialName += to_string(mMaterialCount - basematerialsId); stdMaterialName += ai_to_string(mMaterialCount - basematerialsId);
} }
aiString assimpMaterialName(stdMaterialName); aiString assimpMaterialName(stdMaterialName);

View File

@ -52,6 +52,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/DefaultIOSystem.h> #include <assimp/DefaultIOSystem.h>
#include <assimp/fast_atof.h> #include <assimp/fast_atof.h>
#include <assimp/StringUtils.h>
// Header files, stdlib. // Header files, stdlib.
#include <memory> #include <memory>
@ -306,7 +307,8 @@ void AMFImporter::ParseNode_Root() {
throw DeadlyImportError("Root node \"amf\" not found."); throw DeadlyImportError("Root node \"amf\" not found.");
} }
XmlNode node = *root; XmlNode node = *root;
mUnit = node.attribute("unit").as_string(); mUnit = ai_str_tolower(std::string(node.attribute("unit").as_string()));
mVersion = node.attribute("version").as_string(); mVersion = node.attribute("version").as_string();
// Read attributes for node <amf>. // Read attributes for node <amf>.

View File

@ -873,7 +873,7 @@ nl_clean_loop:
pScene->mNumMaterials = static_cast<unsigned int>(mTexture_Converted.size()); pScene->mNumMaterials = static_cast<unsigned int>(mTexture_Converted.size());
pScene->mMaterials = new aiMaterial *[pScene->mNumMaterials]; pScene->mMaterials = new aiMaterial *[pScene->mNumMaterials];
for (const SPP_Texture &tex_convd : mTexture_Converted) { for (const SPP_Texture &tex_convd : mTexture_Converted) {
const aiString texture_id(AI_EMBEDDED_TEXNAME_PREFIX + to_string(idx)); const aiString texture_id(AI_EMBEDDED_TEXNAME_PREFIX + ai_to_string(idx));
const int mode = aiTextureOp_Multiply; const int mode = aiTextureOp_Multiply;
const int repeat = tex_convd.Tiled ? 1 : 0; const int repeat = tex_convd.Tiled ? 1 : 0;

View File

@ -129,7 +129,7 @@ inline std::string MakeUniqueId(const std::unordered_set<std::string> &idSet, co
// Select a number to append // Select a number to append
size_t idnum = 1; size_t idnum = 1;
do { do {
result = idPrefix + '_' + to_string(idnum) + postfix; result = idPrefix + '_' + ai_to_string(idnum) + postfix;
++idnum; ++idnum;
} while (!IsUniqueId(idSet, result)); } while (!IsUniqueId(idSet, result));
} }
@ -1017,7 +1017,7 @@ void ColladaExporter::WriteGeometry(size_t pIndex) {
// texture coords // texture coords
for (size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) { for (size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) {
if (mesh->HasTextureCoords(static_cast<unsigned int>(a))) { if (mesh->HasTextureCoords(static_cast<unsigned int>(a))) {
WriteFloatArray(geometryId + "-tex" + to_string(a), mesh->mNumUVComponents[a] == 3 ? FloatType_TexCoord3 : FloatType_TexCoord2, WriteFloatArray(geometryId + "-tex" + ai_to_string(a), mesh->mNumUVComponents[a] == 3 ? FloatType_TexCoord3 : FloatType_TexCoord2,
(ai_real *)mesh->mTextureCoords[a], mesh->mNumVertices); (ai_real *)mesh->mTextureCoords[a], mesh->mNumVertices);
} }
} }
@ -1025,7 +1025,7 @@ void ColladaExporter::WriteGeometry(size_t pIndex) {
// vertex colors // vertex colors
for (size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) { for (size_t a = 0; a < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++a) {
if (mesh->HasVertexColors(static_cast<unsigned int>(a))) if (mesh->HasVertexColors(static_cast<unsigned int>(a)))
WriteFloatArray(geometryId + "-color" + to_string(a), FloatType_Color, (ai_real *)mesh->mColors[a], mesh->mNumVertices); WriteFloatArray(geometryId + "-color" + ai_to_string(a), FloatType_Color, (ai_real *)mesh->mColors[a], mesh->mNumVertices);
} }
// assemble vertex structure // assemble vertex structure
@ -1724,7 +1724,7 @@ ColladaExporter::NameIdPair ColladaExporter::AddObjectIndexToMaps(AiObjectType t
case AiObjectType::Camera: idStr = std::string("camera_"); break; case AiObjectType::Camera: idStr = std::string("camera_"); break;
case AiObjectType::Count: throw std::logic_error("ColladaExporter::AiObjectType::Count is not an object type"); case AiObjectType::Count: throw std::logic_error("ColladaExporter::AiObjectType::Count is not an object type");
} }
idStr.append(to_string(index)); idStr.append(ai_to_string(index));
} else { } else {
idStr = XMLIDEncode(name); idStr = XMLIDEncode(name);
} }

View File

@ -80,16 +80,16 @@ void ToCamelCase(std::string &text) {
return; return;
// Capitalise first character // Capitalise first character
auto it = text.begin(); auto it = text.begin();
(*it) = ToUpper(*it); (*it) = ai_toupper(*it);
++it; ++it;
for (/*started above*/; it != text.end(); /*iterated below*/) { for (/*started above*/; it != text.end(); /*iterated below*/) {
if ((*it) == '_') { if ((*it) == '_') {
it = text.erase(it); it = text.erase(it);
if (it != text.end()) if (it != text.end())
(*it) = ToUpper(*it); (*it) = ai_toupper(*it);
} else { } else {
// Make lower case // Make lower case
(*it) = ToLower(*it); (*it) = ai_tolower(*it);
++it; ++it;
} }
} }

View File

@ -372,7 +372,7 @@ void ColladaParser::ReadMetaDataItem(XmlNode &node, StringMetaData &metadata) {
return; return;
} }
trim(v); v = ai_trim(v);
aiString aistr; aiString aistr;
aistr.Set(v); aistr.Set(v);
@ -397,7 +397,7 @@ void ColladaParser::ReadAnimationClipLibrary(XmlNode &node) {
std::string animName; std::string animName;
if (!XmlParser::getStdStrAttribute(node, "name", animName)) { if (!XmlParser::getStdStrAttribute(node, "name", animName)) {
if (!XmlParser::getStdStrAttribute( node, "id", animName )) { if (!XmlParser::getStdStrAttribute( node, "id", animName )) {
animName = std::string("animation_") + to_string(mAnimationClipLibrary.size()); animName = std::string("animation_") + ai_to_string(mAnimationClipLibrary.size());
} }
} }
@ -1415,7 +1415,7 @@ void ColladaParser::ReadDataArray(XmlNode &node) {
XmlParser::getUIntAttribute(node, "count", count); XmlParser::getUIntAttribute(node, "count", count);
std::string v; std::string v;
XmlParser::getValueAsString(node, v); XmlParser::getValueAsString(node, v);
trim(v); v = ai_trim(v);
const char *content = v.c_str(); const char *content = v.c_str();
// read values and store inside an array in the data library // read values and store inside an array in the data library

View File

@ -473,7 +473,7 @@ void TokenizeBinary(TokenList& output_tokens, const char* input, size_t length)
catch (const DeadlyImportError& e) catch (const DeadlyImportError& e)
{ {
if (!is64bits && (length > std::numeric_limits<std::uint32_t>::max())) { if (!is64bits && (length > std::numeric_limits<std::uint32_t>::max())) {
throw DeadlyImportError("The FBX file is invalid. This may be because the content is too big for this older version (", to_string(version), ") of the FBX format. (", e.what(), ")"); throw DeadlyImportError("The FBX file is invalid. This may be because the content is too big for this older version (", ai_to_string(version), ") of the FBX format. (", e.what(), ")");
} }
throw; throw;
} }

View File

@ -3440,7 +3440,7 @@ void FBXConverter::ConvertGlobalSettings() {
mSceneOut->mMetaData->Set(12, "TimeSpanStart", doc.GlobalSettings().TimeSpanStart()); mSceneOut->mMetaData->Set(12, "TimeSpanStart", doc.GlobalSettings().TimeSpanStart());
mSceneOut->mMetaData->Set(13, "TimeSpanStop", doc.GlobalSettings().TimeSpanStop()); mSceneOut->mMetaData->Set(13, "TimeSpanStop", doc.GlobalSettings().TimeSpanStop());
mSceneOut->mMetaData->Set(14, "CustomFrameRate", doc.GlobalSettings().CustomFrameRate()); mSceneOut->mMetaData->Set(14, "CustomFrameRate", doc.GlobalSettings().CustomFrameRate());
mSceneOut->mMetaData->Set(15, AI_METADATA_SOURCE_FORMAT_VERSION, aiString(to_string(doc.FBXVersion()))); mSceneOut->mMetaData->Set(15, AI_METADATA_SOURCE_FORMAT_VERSION, aiString(ai_to_string(doc.FBXVersion())));
if (hasGenerator) { if (hasGenerator) {
mSceneOut->mMetaData->Set(16, AI_METADATA_SOURCE_GENERATOR, aiString(doc.Creator())); mSceneOut->mMetaData->Set(16, AI_METADATA_SOURCE_GENERATOR, aiString(doc.Creator()));
} }
@ -3454,42 +3454,42 @@ void FBXConverter::TransferDataToScene() {
// many C++ users seem to know this, so pointing it out to avoid // many C++ users seem to know this, so pointing it out to avoid
// confusion why this code works. // confusion why this code works.
if (mMeshes.size()) { if (!mMeshes.empty()) {
mSceneOut->mMeshes = new aiMesh *[mMeshes.size()](); mSceneOut->mMeshes = new aiMesh *[mMeshes.size()]();
mSceneOut->mNumMeshes = static_cast<unsigned int>(mMeshes.size()); mSceneOut->mNumMeshes = static_cast<unsigned int>(mMeshes.size());
std::swap_ranges(mMeshes.begin(), mMeshes.end(), mSceneOut->mMeshes); std::swap_ranges(mMeshes.begin(), mMeshes.end(), mSceneOut->mMeshes);
} }
if (materials.size()) { if (!materials.empty()) {
mSceneOut->mMaterials = new aiMaterial *[materials.size()](); mSceneOut->mMaterials = new aiMaterial *[materials.size()]();
mSceneOut->mNumMaterials = static_cast<unsigned int>(materials.size()); mSceneOut->mNumMaterials = static_cast<unsigned int>(materials.size());
std::swap_ranges(materials.begin(), materials.end(), mSceneOut->mMaterials); std::swap_ranges(materials.begin(), materials.end(), mSceneOut->mMaterials);
} }
if (animations.size()) { if (!animations.empty()) {
mSceneOut->mAnimations = new aiAnimation *[animations.size()](); mSceneOut->mAnimations = new aiAnimation *[animations.size()]();
mSceneOut->mNumAnimations = static_cast<unsigned int>(animations.size()); mSceneOut->mNumAnimations = static_cast<unsigned int>(animations.size());
std::swap_ranges(animations.begin(), animations.end(), mSceneOut->mAnimations); std::swap_ranges(animations.begin(), animations.end(), mSceneOut->mAnimations);
} }
if (lights.size()) { if (!lights.empty()) {
mSceneOut->mLights = new aiLight *[lights.size()](); mSceneOut->mLights = new aiLight *[lights.size()]();
mSceneOut->mNumLights = static_cast<unsigned int>(lights.size()); mSceneOut->mNumLights = static_cast<unsigned int>(lights.size());
std::swap_ranges(lights.begin(), lights.end(), mSceneOut->mLights); std::swap_ranges(lights.begin(), lights.end(), mSceneOut->mLights);
} }
if (cameras.size()) { if (!cameras.empty()) {
mSceneOut->mCameras = new aiCamera *[cameras.size()](); mSceneOut->mCameras = new aiCamera *[cameras.size()]();
mSceneOut->mNumCameras = static_cast<unsigned int>(cameras.size()); mSceneOut->mNumCameras = static_cast<unsigned int>(cameras.size());
std::swap_ranges(cameras.begin(), cameras.end(), mSceneOut->mCameras); std::swap_ranges(cameras.begin(), cameras.end(), mSceneOut->mCameras);
} }
if (textures.size()) { if (!textures.empty()) {
mSceneOut->mTextures = new aiTexture *[textures.size()](); mSceneOut->mTextures = new aiTexture *[textures.size()]();
mSceneOut->mNumTextures = static_cast<unsigned int>(textures.size()); mSceneOut->mNumTextures = static_cast<unsigned int>(textures.size());

View File

@ -426,7 +426,7 @@ void FBX::Node::WritePropertyNodeAscii(
char buffer[32]; char buffer[32];
FBX::Node node(name); FBX::Node node(name);
node.Begin(s, false, indent); node.Begin(s, false, indent);
std::string vsize = to_string(v.size()); std::string vsize = ai_to_string(v.size());
// *<size> { // *<size> {
s.PutChar('*'); s.PutString(vsize); s.PutString(" {\n"); s.PutChar('*'); s.PutString(vsize); s.PutString(" {\n");
// indent + 1 // indent + 1
@ -462,7 +462,7 @@ void FBX::Node::WritePropertyNodeAscii(
char buffer[32]; char buffer[32];
FBX::Node node(name); FBX::Node node(name);
node.Begin(s, false, indent); node.Begin(s, false, indent);
std::string vsize = to_string(v.size()); std::string vsize = ai_to_string(v.size());
// *<size> { // *<size> {
s.PutChar('*'); s.PutString(vsize); s.PutString(" {\n"); s.PutChar('*'); s.PutString(vsize); s.PutString(" {\n");
// indent + 1 // indent + 1

View File

@ -524,7 +524,7 @@ namespace pmx
if (version != 2.0f && version != 2.1f) if (version != 2.0f && version != 2.1f)
{ {
std::cerr << "this is not ver2.0 or ver2.1 but " << version << "." << std::endl; std::cerr << "this is not ver2.0 or ver2.1 but " << version << "." << std::endl;
throw DeadlyImportError("MMD: this is not ver2.0 or ver2.1 but ", to_string(version)); throw DeadlyImportError("MMD: this is not ver2.0 or ver2.1 but ", ai_to_string(version));
} }
this->setting.Read(stream); this->setting.Read(stream);

View File

@ -40,45 +40,38 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------- ----------------------------------------------------------------------
*/ */
#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER #ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
#include "OgreImporter.h" #include "OgreImporter.h"
#include <assimp/StringUtils.h>
#include <assimp/TinyFormatter.h> #include <assimp/TinyFormatter.h>
#include <assimp/fast_atof.h>
#include <assimp/material.h> #include <assimp/material.h>
#include <assimp/scene.h> #include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp> #include <assimp/DefaultLogger.hpp>
#include <assimp/fast_atof.h>
#include <vector>
#include <sstream>
#include <memory> #include <memory>
#include <sstream>
#include <vector>
using namespace std; using namespace std;
namespace Assimp namespace Assimp {
{ namespace Ogre {
namespace Ogre
{
static const string partComment = "//"; static const string partComment = "//";
static const string partBlockStart = "{"; static const string partBlockStart = "{";
static const string partBlockEnd = "}"; static const string partBlockEnd = "}";
void OgreImporter::ReadMaterials(const std::string &pFile, Assimp::IOSystem *pIOHandler, aiScene *pScene, Mesh *mesh) void OgreImporter::ReadMaterials(const std::string &pFile, Assimp::IOSystem *pIOHandler, aiScene *pScene, Mesh *mesh) {
{
std::vector<aiMaterial *> materials; std::vector<aiMaterial *> materials;
// Create materials that can be found and parsed via the IOSystem. // Create materials that can be found and parsed via the IOSystem.
for (size_t i=0, len=mesh->NumSubMeshes(); i<len; ++i) for (size_t i = 0, len = mesh->NumSubMeshes(); i < len; ++i) {
{
SubMesh *submesh = mesh->GetSubMesh(i); SubMesh *submesh = mesh->GetSubMesh(i);
if (submesh && !submesh->materialRef.empty()) if (submesh && !submesh->materialRef.empty()) {
{
aiMaterial *material = ReadMaterial(pFile, pIOHandler, submesh->materialRef); aiMaterial *material = ReadMaterial(pFile, pIOHandler, submesh->materialRef);
if (material) if (material) {
{
submesh->materialIndex = static_cast<int>(materials.size()); submesh->materialIndex = static_cast<int>(materials.size());
materials.push_back(material); materials.push_back(material);
} }
@ -88,19 +81,15 @@ void OgreImporter::ReadMaterials(const std::string &pFile, Assimp::IOSystem *pIO
AssignMaterials(pScene, materials); AssignMaterials(pScene, materials);
} }
void OgreImporter::ReadMaterials(const std::string &pFile, Assimp::IOSystem *pIOHandler, aiScene *pScene, MeshXml *mesh) void OgreImporter::ReadMaterials(const std::string &pFile, Assimp::IOSystem *pIOHandler, aiScene *pScene, MeshXml *mesh) {
{
std::vector<aiMaterial *> materials; std::vector<aiMaterial *> materials;
// Create materials that can be found and parsed via the IOSystem. // Create materials that can be found and parsed via the IOSystem.
for (size_t i=0, len=mesh->NumSubMeshes(); i<len; ++i) for (size_t i = 0, len = mesh->NumSubMeshes(); i < len; ++i) {
{
SubMeshXml *submesh = mesh->GetSubMesh(static_cast<uint16_t>(i)); SubMeshXml *submesh = mesh->GetSubMesh(static_cast<uint16_t>(i));
if (submesh && !submesh->materialRef.empty()) if (submesh && !submesh->materialRef.empty()) {
{
aiMaterial *material = ReadMaterial(pFile, pIOHandler, submesh->materialRef); aiMaterial *material = ReadMaterial(pFile, pIOHandler, submesh->materialRef);
if (material) if (material) {
{
submesh->materialIndex = static_cast<int>(materials.size()); submesh->materialIndex = static_cast<int>(materials.size());
materials.push_back(material); materials.push_back(material);
} }
@ -110,11 +99,9 @@ void OgreImporter::ReadMaterials(const std::string &pFile, Assimp::IOSystem *pIO
AssignMaterials(pScene, materials); AssignMaterials(pScene, materials);
} }
void OgreImporter::AssignMaterials(aiScene *pScene, std::vector<aiMaterial*> &materials) void OgreImporter::AssignMaterials(aiScene *pScene, std::vector<aiMaterial *> &materials) {
{
pScene->mNumMaterials = static_cast<unsigned int>(materials.size()); pScene->mNumMaterials = static_cast<unsigned int>(materials.size());
if (pScene->mNumMaterials > 0) if (pScene->mNumMaterials > 0) {
{
pScene->mMaterials = new aiMaterial *[pScene->mNumMaterials]; pScene->mMaterials = new aiMaterial *[pScene->mNumMaterials];
for (size_t i = 0; i < pScene->mNumMaterials; ++i) { for (size_t i = 0; i < pScene->mNumMaterials; ++i) {
pScene->mMaterials[i] = materials[i]; pScene->mMaterials[i] = materials[i];
@ -122,8 +109,7 @@ void OgreImporter::AssignMaterials(aiScene *pScene, std::vector<aiMaterial*> &ma
} }
} }
aiMaterial* OgreImporter::ReadMaterial(const std::string &pFile, Assimp::IOSystem *pIOHandler, const std::string &materialName) aiMaterial *OgreImporter::ReadMaterial(const std::string &pFile, Assimp::IOSystem *pIOHandler, const std::string &materialName) {
{
if (materialName.empty()) { if (materialName.empty()) {
return 0; return 0;
} }
@ -169,23 +155,20 @@ aiMaterial* OgreImporter::ReadMaterial(const std::string &pFile, Assimp::IOSyste
potentialFiles.push_back(m_userDefinedMaterialLibFile); potentialFiles.push_back(m_userDefinedMaterialLibFile);
IOStream *materialFile = 0; IOStream *materialFile = 0;
for(size_t i=0; i<potentialFiles.size(); ++i) for (size_t i = 0; i < potentialFiles.size(); ++i) {
{
materialFile = pIOHandler->Open(potentialFiles[i]); materialFile = pIOHandler->Open(potentialFiles[i]);
if (materialFile) { if (materialFile) {
break; break;
} }
ASSIMP_LOG_VERBOSE_DEBUG_F("Source file for material '", materialName, "' ", potentialFiles[i], " does not exist"); ASSIMP_LOG_VERBOSE_DEBUG_F("Source file for material '", materialName, "' ", potentialFiles[i], " does not exist");
} }
if (!materialFile) if (!materialFile) {
{
ASSIMP_LOG_ERROR_F("Failed to find source file for material '", materialName, "'"); ASSIMP_LOG_ERROR_F("Failed to find source file for material '", materialName, "'");
return 0; return 0;
} }
std::unique_ptr<IOStream> stream(materialFile); std::unique_ptr<IOStream> stream(materialFile);
if (stream->FileSize() == 0) if (stream->FileSize() == 0) {
{
ASSIMP_LOG_WARN_F("Source file for material '", materialName, "' is empty (size is 0 bytes)"); ASSIMP_LOG_WARN_F("Source file for material '", materialName, "' is empty (size is 0 bytes)");
return 0; return 0;
} }
@ -217,45 +200,38 @@ aiMaterial* OgreImporter::ReadMaterial(const std::string &pFile, Assimp::IOSyste
const string partMaterial = "material"; const string partMaterial = "material";
const string partTechnique = "technique"; const string partTechnique = "technique";
while(!ss.eof()) while (!ss.eof()) {
{
// Skip commented lines // Skip commented lines
if (linePart == partComment) if (linePart == partComment) {
{
NextAfterNewLine(ss, linePart); NextAfterNewLine(ss, linePart);
continue; continue;
} }
if (linePart != partMaterial) if (linePart != partMaterial) {
{
ss >> linePart; ss >> linePart;
continue; continue;
} }
ss >> linePart; ss >> linePart;
if (linePart != materialName) if (linePart != materialName) {
{
ss >> linePart; ss >> linePart;
continue; continue;
} }
NextAfterNewLine(ss, linePart); NextAfterNewLine(ss, linePart);
if (linePart != partBlockStart) if (linePart != partBlockStart) {
{
ASSIMP_LOG_ERROR_F("Invalid material: block start missing near index ", ss.tellg()); ASSIMP_LOG_ERROR_F("Invalid material: block start missing near index ", ss.tellg());
return material; return material;
} }
ASSIMP_LOG_VERBOSE_DEBUG_F("material '", materialName, "'"); ASSIMP_LOG_VERBOSE_DEBUG_F("material '", materialName, "'");
while(linePart != partBlockEnd) while (linePart != partBlockEnd) {
{
// Proceed to the first technique // Proceed to the first technique
ss >> linePart; ss >> linePart;
if (linePart == partTechnique) if (linePart == partTechnique) {
{ std::string techniqueName = SkipLine(ss);
string techniqueName = SkipLine(ss); ReadTechnique(ai_trim(techniqueName), ss, material);
ReadTechnique(Trim(techniqueName), ss, material);
} }
// Read information from a custom material // Read information from a custom material
@ -264,69 +240,49 @@ aiMaterial* OgreImporter::ReadMaterial(const std::string &pFile, Assimp::IOSyste
parent texture unit name in your cloned material. parent texture unit name in your cloned material.
This is not yet supported and below code is probably some hack from the original This is not yet supported and below code is probably some hack from the original
author of this Ogre importer. Should be removed? */ author of this Ogre importer. Should be removed? */
if (linePart=="set") if (linePart == "set") {
{
ss >> linePart; ss >> linePart;
if (linePart == "$specular") //todo load this values: if (linePart == "$specular") //todo load this values:
{ {
} } else if (linePart == "$diffuse") {
else if (linePart=="$diffuse") } else if (linePart == "$ambient") {
{ } else if (linePart == "$colormap") {
}
else if (linePart=="$ambient")
{
}
else if (linePart=="$colormap")
{
ss >> linePart; ss >> linePart;
aiString cm(linePart); aiString cm(linePart);
material->AddProperty(&cm, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0)); material->AddProperty(&cm, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0));
} } else if (linePart == "$normalmap") {
else if (linePart=="$normalmap")
{
ss >> linePart; ss >> linePart;
aiString nm(linePart); aiString nm(linePart);
material->AddProperty(&nm, AI_MATKEY_TEXTURE(aiTextureType_NORMALS, 0)); material->AddProperty(&nm, AI_MATKEY_TEXTURE(aiTextureType_NORMALS, 0));
} } else if (linePart == "$shininess_strength") {
else if (linePart=="$shininess_strength")
{
ss >> linePart; ss >> linePart;
float Shininess = fast_atof(linePart.c_str()); float Shininess = fast_atof(linePart.c_str());
material->AddProperty(&Shininess, 1, AI_MATKEY_SHININESS_STRENGTH); material->AddProperty(&Shininess, 1, AI_MATKEY_SHININESS_STRENGTH);
} } else if (linePart == "$shininess_exponent") {
else if (linePart=="$shininess_exponent")
{
ss >> linePart; ss >> linePart;
float Shininess = fast_atof(linePart.c_str()); float Shininess = fast_atof(linePart.c_str());
material->AddProperty(&Shininess, 1, AI_MATKEY_SHININESS); material->AddProperty(&Shininess, 1, AI_MATKEY_SHININESS);
} }
//Properties from Venetica: //Properties from Venetica:
else if (linePart=="$diffuse_map") else if (linePart == "$diffuse_map") {
{
ss >> linePart; ss >> linePart;
if (linePart[0] == '"') // "file" -> file if (linePart[0] == '"') // "file" -> file
linePart = linePart.substr(1, linePart.size() - 2); linePart = linePart.substr(1, linePart.size() - 2);
aiString ts(linePart); aiString ts(linePart);
material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0)); material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0));
} } else if (linePart == "$specular_map") {
else if (linePart=="$specular_map")
{
ss >> linePart; ss >> linePart;
if (linePart[0] == '"') // "file" -> file if (linePart[0] == '"') // "file" -> file
linePart = linePart.substr(1, linePart.size() - 2); linePart = linePart.substr(1, linePart.size() - 2);
aiString ts(linePart); aiString ts(linePart);
material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_SHININESS, 0)); material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_SHININESS, 0));
} } else if (linePart == "$normal_map") {
else if (linePart=="$normal_map")
{
ss >> linePart; ss >> linePart;
if (linePart[0] == '"') // "file" -> file if (linePart[0] == '"') // "file" -> file
linePart = linePart.substr(1, linePart.size() - 2); linePart = linePart.substr(1, linePart.size() - 2);
aiString ts(linePart); aiString ts(linePart);
material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_NORMALS, 0)); material->AddProperty(&ts, AI_MATKEY_TEXTURE(aiTextureType_NORMALS, 0));
} } else if (linePart == "$light_map") {
else if (linePart=="$light_map")
{
ss >> linePart; ss >> linePart;
if (linePart[0] == '"') { if (linePart[0] == '"') {
linePart = linePart.substr(1, linePart.size() - 2); linePart = linePart.substr(1, linePart.size() - 2);
@ -342,13 +298,11 @@ aiMaterial* OgreImporter::ReadMaterial(const std::string &pFile, Assimp::IOSyste
return material; return material;
} }
bool OgreImporter::ReadTechnique(const std::string &techniqueName, stringstream &ss, aiMaterial *material) bool OgreImporter::ReadTechnique(const std::string &techniqueName, stringstream &ss, aiMaterial *material) {
{
string linePart; string linePart;
ss >> linePart; ss >> linePart;
if (linePart != partBlockStart) if (linePart != partBlockStart) {
{
ASSIMP_LOG_ERROR_F("Invalid material: Technique block start missing near index ", ss.tellg()); ASSIMP_LOG_ERROR_F("Invalid material: Technique block start missing near index ", ss.tellg());
return false; return false;
} }
@ -357,34 +311,29 @@ bool OgreImporter::ReadTechnique(const std::string &techniqueName, stringstream
const string partPass = "pass"; const string partPass = "pass";
while(linePart != partBlockEnd) while (linePart != partBlockEnd) {
{
ss >> linePart; ss >> linePart;
// Skip commented lines // Skip commented lines
if (linePart == partComment) if (linePart == partComment) {
{
SkipLine(ss); SkipLine(ss);
continue; continue;
} }
/// @todo Techniques have other attributes than just passes. /// @todo Techniques have other attributes than just passes.
if (linePart == partPass) if (linePart == partPass) {
{
string passName = SkipLine(ss); string passName = SkipLine(ss);
ReadPass(Trim(passName), ss, material); ReadPass(ai_trim(passName), ss, material);
} }
} }
return true; return true;
} }
bool OgreImporter::ReadPass(const std::string &passName, stringstream &ss, aiMaterial *material) bool OgreImporter::ReadPass(const std::string &passName, stringstream &ss, aiMaterial *material) {
{
string linePart; string linePart;
ss >> linePart; ss >> linePart;
if (linePart != partBlockStart) if (linePart != partBlockStart) {
{
ASSIMP_LOG_ERROR_F("Invalid material: Pass block start missing near index ", ss.tellg()); ASSIMP_LOG_ERROR_F("Invalid material: Pass block start missing near index ", ss.tellg());
return false; return false;
} }
@ -397,60 +346,46 @@ bool OgreImporter::ReadPass(const std::string &passName, stringstream &ss, aiMat
const string partEmissive = "emissive"; const string partEmissive = "emissive";
const string partTextureUnit = "texture_unit"; const string partTextureUnit = "texture_unit";
while(linePart != partBlockEnd) while (linePart != partBlockEnd) {
{
ss >> linePart; ss >> linePart;
// Skip commented lines // Skip commented lines
if (linePart == partComment) if (linePart == partComment) {
{
SkipLine(ss); SkipLine(ss);
continue; continue;
} }
// Colors // Colors
/// @todo Support alpha via aiColor4D. /// @todo Support alpha via aiColor4D.
if (linePart == partAmbient || linePart == partDiffuse || linePart == partSpecular || linePart == partEmissive) if (linePart == partAmbient || linePart == partDiffuse || linePart == partSpecular || linePart == partEmissive) {
{
float r, g, b; float r, g, b;
ss >> r >> g >> b; ss >> r >> g >> b;
const aiColor3D color(r, g, b); const aiColor3D color(r, g, b);
ASSIMP_LOG_VERBOSE_DEBUG_F(" ", linePart, " ", r, " ", g, " ", b); ASSIMP_LOG_VERBOSE_DEBUG_F(" ", linePart, " ", r, " ", g, " ", b);
if (linePart == partAmbient) if (linePart == partAmbient) {
{
material->AddProperty(&color, 1, AI_MATKEY_COLOR_AMBIENT); material->AddProperty(&color, 1, AI_MATKEY_COLOR_AMBIENT);
} } else if (linePart == partDiffuse) {
else if (linePart == partDiffuse)
{
material->AddProperty(&color, 1, AI_MATKEY_COLOR_DIFFUSE); material->AddProperty(&color, 1, AI_MATKEY_COLOR_DIFFUSE);
} } else if (linePart == partSpecular) {
else if (linePart == partSpecular)
{
material->AddProperty(&color, 1, AI_MATKEY_COLOR_SPECULAR); material->AddProperty(&color, 1, AI_MATKEY_COLOR_SPECULAR);
} } else if (linePart == partEmissive) {
else if (linePart == partEmissive)
{
material->AddProperty(&color, 1, AI_MATKEY_COLOR_EMISSIVE); material->AddProperty(&color, 1, AI_MATKEY_COLOR_EMISSIVE);
} }
} } else if (linePart == partTextureUnit) {
else if (linePart == partTextureUnit)
{
string textureUnitName = SkipLine(ss); string textureUnitName = SkipLine(ss);
ReadTextureUnit(Trim(textureUnitName), ss, material); ReadTextureUnit(ai_trim(textureUnitName), ss, material);
} }
} }
return true; return true;
} }
bool OgreImporter::ReadTextureUnit(const std::string &textureUnitName, stringstream &ss, aiMaterial *material) bool OgreImporter::ReadTextureUnit(const std::string &textureUnitName, stringstream &ss, aiMaterial *material) {
{
string linePart; string linePart;
ss >> linePart; ss >> linePart;
if (linePart != partBlockStart) if (linePart != partBlockStart) {
{
ASSIMP_LOG_ERROR_F("Invalid material: Texture unit block start missing near index ", ss.tellg()); ASSIMP_LOG_ERROR_F("Invalid material: Texture unit block start missing near index ", ss.tellg());
return false; return false;
} }
@ -465,93 +400,64 @@ bool OgreImporter::ReadTextureUnit(const std::string &textureUnitName, stringstr
std::string textureRef; std::string textureRef;
int uvCoord = 0; int uvCoord = 0;
while(linePart != partBlockEnd) while (linePart != partBlockEnd) {
{
ss >> linePart; ss >> linePart;
// Skip commented lines // Skip commented lines
if (linePart == partComment) if (linePart == partComment) {
{
SkipLine(ss); SkipLine(ss);
continue; continue;
} }
if (linePart == partTexture) if (linePart == partTexture) {
{
ss >> linePart; ss >> linePart;
textureRef = linePart; textureRef = linePart;
// User defined Assimp config property to detect texture type from filename. // User defined Assimp config property to detect texture type from filename.
if (m_detectTextureTypeFromFilename) if (m_detectTextureTypeFromFilename) {
{
size_t posSuffix = textureRef.find_last_of("."); size_t posSuffix = textureRef.find_last_of(".");
size_t posUnderscore = textureRef.find_last_of("_"); size_t posUnderscore = textureRef.find_last_of("_");
if (posSuffix != string::npos && posUnderscore != string::npos && posSuffix > posUnderscore) if (posSuffix != string::npos && posUnderscore != string::npos && posSuffix > posUnderscore) {
{ string identifier = ai_str_tolower(textureRef.substr(posUnderscore, posSuffix - posUnderscore));
string identifier = Ogre::ToLower(textureRef.substr(posUnderscore, posSuffix - posUnderscore));
ASSIMP_LOG_VERBOSE_DEBUG_F("Detecting texture type from filename postfix '", identifier, "'"); ASSIMP_LOG_VERBOSE_DEBUG_F("Detecting texture type from filename postfix '", identifier, "'");
if (identifier == "_n" || identifier == "_nrm" || identifier == "_nrml" || identifier == "_normal" || identifier == "_normals" || identifier == "_normalmap") if (identifier == "_n" || identifier == "_nrm" || identifier == "_nrml" || identifier == "_normal" || identifier == "_normals" || identifier == "_normalmap") {
{
textureType = aiTextureType_NORMALS; textureType = aiTextureType_NORMALS;
} } else if (identifier == "_s" || identifier == "_spec" || identifier == "_specular" || identifier == "_specularmap") {
else if (identifier == "_s" || identifier == "_spec" || identifier == "_specular" || identifier == "_specularmap")
{
textureType = aiTextureType_SPECULAR; textureType = aiTextureType_SPECULAR;
} } else if (identifier == "_l" || identifier == "_light" || identifier == "_lightmap" || identifier == "_occ" || identifier == "_occlusion") {
else if (identifier == "_l" || identifier == "_light" || identifier == "_lightmap" || identifier == "_occ" || identifier == "_occlusion")
{
textureType = aiTextureType_LIGHTMAP; textureType = aiTextureType_LIGHTMAP;
} } else if (identifier == "_disp" || identifier == "_displacement") {
else if (identifier == "_disp" || identifier == "_displacement")
{
textureType = aiTextureType_DISPLACEMENT; textureType = aiTextureType_DISPLACEMENT;
} } else {
else
{
textureType = aiTextureType_DIFFUSE; textureType = aiTextureType_DIFFUSE;
} }
} } else {
else
{
textureType = aiTextureType_DIFFUSE; textureType = aiTextureType_DIFFUSE;
} }
} }
// Detect from texture unit name. This cannot be too broad as // Detect from texture unit name. This cannot be too broad as
// authors might give names like "LightSaber" or "NormalNinja". // authors might give names like "LightSaber" or "NormalNinja".
else else {
{ string unitNameLower = ai_str_tolower(textureUnitName);
string unitNameLower = Ogre::ToLower(textureUnitName); if (unitNameLower.find("normalmap") != string::npos) {
if (unitNameLower.find("normalmap") != string::npos)
{
textureType = aiTextureType_NORMALS; textureType = aiTextureType_NORMALS;
} } else if (unitNameLower.find("specularmap") != string::npos) {
else if (unitNameLower.find("specularmap") != string::npos)
{
textureType = aiTextureType_SPECULAR; textureType = aiTextureType_SPECULAR;
} } else if (unitNameLower.find("lightmap") != string::npos) {
else if (unitNameLower.find("lightmap") != string::npos)
{
textureType = aiTextureType_LIGHTMAP; textureType = aiTextureType_LIGHTMAP;
} } else if (unitNameLower.find("displacementmap") != string::npos) {
else if (unitNameLower.find("displacementmap") != string::npos)
{
textureType = aiTextureType_DISPLACEMENT; textureType = aiTextureType_DISPLACEMENT;
} } else {
else
{
textureType = aiTextureType_DIFFUSE; textureType = aiTextureType_DIFFUSE;
} }
} }
} } else if (linePart == partTextCoordSet) {
else if (linePart == partTextCoordSet)
{
ss >> uvCoord; ss >> uvCoord;
} }
/// @todo Implement /// @todo Implement
else if(linePart == partColorOp) else if (linePart == partColorOp) {
{
/* /*
ss >> linePart; ss >> linePart;
if("replace"==linePart)//I don't think, assimp has something for this... if("replace"==linePart)//I don't think, assimp has something for this...
@ -566,13 +472,11 @@ bool OgreImporter::ReadTextureUnit(const std::string &textureUnitName, stringstr
} }
} }
if (textureRef.empty()) if (textureRef.empty()) {
{
ASSIMP_LOG_WARN("Texture reference is empty, ignoring texture_unit."); ASSIMP_LOG_WARN("Texture reference is empty, ignoring texture_unit.");
return false; return false;
} }
if (textureType == aiTextureType_NONE) if (textureType == aiTextureType_NONE) {
{
ASSIMP_LOG_WARN("Failed to detect texture type for '" + textureRef + "', ignoring texture_unit."); ASSIMP_LOG_WARN("Failed to detect texture type for '" + textureRef + "', ignoring texture_unit.");
return false; return false;
} }
@ -590,7 +494,7 @@ bool OgreImporter::ReadTextureUnit(const std::string &textureUnitName, stringstr
return true; return true;
} }
} // Ogre } // namespace Ogre
} // Assimp } // namespace Assimp
#endif // ASSIMP_BUILD_NO_OGRE_IMPORTER #endif // ASSIMP_BUILD_NO_OGRE_IMPORTER

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2021, assimp team Copyright (c) 2006-2021, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -46,7 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER #ifndef ASSIMP_BUILD_NO_OGRE_IMPORTER
#include <assimp/ParsingUtils.h> #include <assimp/ParsingUtils.h>
#include <stdint.h> #include <cstdint>
#include <algorithm> #include <algorithm>
#include <cctype> #include <cctype>
#include <functional> #include <functional>
@ -55,16 +54,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp { namespace Assimp {
namespace Ogre { namespace Ogre {
/// Returns a lower cased copy of @s.
static AI_FORCE_INLINE std::string ToLower(const std::string &s) {
std::string lower(s);
std::transform(lower.begin(), lower.end(), lower.begin(), Assimp::ToLower<char>);
return lower;
}
/// Returns if @c s ends with @c suffix. If @c caseSensitive is false, both strings will be lower cased before matching. /// Returns if @c s ends with @c suffix. If @c caseSensitive is false, both strings will be lower cased before matching.
static AI_FORCE_INLINE bool EndsWith( const std::string &s, const std::string &suffix, bool caseSensitive = true) { static inline bool EndsWith(const std::string &s, const std::string &suffix, bool caseSensitive = true) {
if (s.empty() || suffix.empty()) { if (s.empty() || suffix.empty()) {
return false; return false;
} else if (s.length() < suffix.length()) { } else if (s.length() < suffix.length()) {
@ -72,7 +64,7 @@ static AI_FORCE_INLINE bool EndsWith( const std::string &s, const std::string &s
} }
if (!caseSensitive) { if (!caseSensitive) {
return EndsWith(ToLower(s), ToLower(suffix), true); return EndsWith(ai_str_tolower(s), ai_str_tolower(suffix), true);
} }
size_t len = suffix.length(); size_t len = suffix.length();
@ -81,53 +73,16 @@ static AI_FORCE_INLINE bool EndsWith( const std::string &s, const std::string &s
return (ASSIMP_stricmp(sSuffix, suffix) == 0); return (ASSIMP_stricmp(sSuffix, suffix) == 0);
} }
// Below trim functions adapted from http://stackoverflow.com/questions/216823/whats-the-best-way-to-trim-stdstring // Skips a line from current @ss position until a newline. Returns the skipped part.
static inline std::string SkipLine(std::stringstream &ss) {
/// Trim from start
static AI_FORCE_INLINE
std::string &
TrimLeft(std::string &s, bool newlines = true) {
if (!newlines) {
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](char c) { return !Assimp::IsSpace<char>(c); }));
} else {
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](char c) { return !Assimp::IsSpaceOrNewLine<char>(c); }));
}
return s;
}
/// Trim from end
static AI_FORCE_INLINE
std::string &
TrimRight(std::string &s, bool newlines = true) {
if (!newlines) {
s.erase(std::find_if(s.rbegin(), s.rend(), [](char c) { return !Assimp::IsSpace<char>(c); }).base(), s.end());
} else {
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](char c) { return !Assimp::IsSpaceOrNewLine<char>(c); }));
}
return s;
}
/// Trim from both ends
static AI_FORCE_INLINE
std::string &
Trim(std::string &s, bool newlines = true) {
return TrimLeft(TrimRight(s, newlines), newlines);
}
/// Skips a line from current @ss position until a newline. Returns the skipped part.
static AI_FORCE_INLINE
std::string
SkipLine(std::stringstream &ss) {
std::string skipped; std::string skipped;
getline(ss, skipped); getline(ss, skipped);
return skipped; return skipped;
} }
/// Skips a line and reads next element from @c ss to @c nextElement. // Skips a line and reads next element from @c ss to @c nextElement.
/** @return Skipped line content until newline. */ /** @return Skipped line content until newline. */
static AI_FORCE_INLINE static inline std::string NextAfterNewLine(std::stringstream &ss, std::string &nextElement) {
std::string
NextAfterNewLine(std::stringstream &ss, std::string &nextElement) {
std::string skipped = SkipLine(ss); std::string skipped = SkipLine(ss);
ss >> nextElement; ss >> nextElement;
return skipped; return skipped;

View File

@ -120,7 +120,7 @@ std::string OgreXmlSerializer::ReadAttribute<std::string>(XmlNode &xmlNode, cons
template <> template <>
bool OgreXmlSerializer::ReadAttribute<bool>(XmlNode &xmlNode, const char *name) const { bool OgreXmlSerializer::ReadAttribute<bool>(XmlNode &xmlNode, const char *name) const {
std::string value = Ogre::ToLower(ReadAttribute<std::string>(xmlNode, name)); std::string value = ai_str_tolower(ReadAttribute<std::string>(xmlNode, name));
if (ASSIMP_stricmp(value, "true") == 0) { if (ASSIMP_stricmp(value, "true") == 0) {
return true; return true;
} else if (ASSIMP_stricmp(value, "false") == 0) { } else if (ASSIMP_stricmp(value, "false") == 0) {
@ -529,7 +529,7 @@ XmlParserPtr OgreXmlSerializer::OpenXmlParser(Assimp::IOSystem *pIOHandler, cons
throw DeadlyImportError("Failed to open skeleton file ", filename); throw DeadlyImportError("Failed to open skeleton file ", filename);
} }
XmlParserPtr xmlParser = XmlParserPtr(new XmlParser); XmlParserPtr xmlParser = std::make_shared<XmlParser>();
if (!xmlParser->parse(file.get())) { if (!xmlParser->parse(file.get())) {
throw DeadlyImportError("Failed to create XML reader for skeleton file " + filename); throw DeadlyImportError("Failed to create XML reader for skeleton file " + filename);
} }
@ -545,7 +545,7 @@ void OgreXmlSerializer::ReadSkeleton(XmlNode &node, Skeleton *skeleton) {
// Optional blend mode from root node // Optional blend mode from root node
if (XmlParser::hasAttribute(node, "blendmode")) { if (XmlParser::hasAttribute(node, "blendmode")) {
skeleton->blendMode = (ToLower(ReadAttribute<std::string>(node, "blendmode")) == "cumulative" ? Skeleton::ANIMBLEND_CUMULATIVE : Skeleton::ANIMBLEND_AVERAGE); skeleton->blendMode = (ai_str_tolower(ReadAttribute<std::string>(node, "blendmode")) == "cumulative" ? Skeleton::ANIMBLEND_CUMULATIVE : Skeleton::ANIMBLEND_AVERAGE);
} }
for (XmlNode &currentNode : node.children()) { for (XmlNode &currentNode : node.children()) {

View File

@ -270,11 +270,15 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
} }
std::string::size_type ns = n0; std::string::size_type ns = n0;
do ++ns; while( IsSpace(s.at(ns))); do {
++ns;
} while (IsSpace(s.at(ns)));
std::string::size_type ne = n1; std::string::size_type ne = n1;
do --ne; while( IsSpace(s.at(ne))); do {
--ne;
} while (IsSpace(s.at(ne)));
std::string type = s.substr(ns, ne - ns + 1); std::string type = s.substr(ns, ne - ns + 1);
std::transform( type.begin(), type.end(), type.begin(), &Assimp::ToLower<char> ); type = ai_str_tolower(type);
const char* sz = scheme.GetStaticStringForToken(type); const char* sz = scheme.GetStaticStringForToken(type);
if(sz) { if(sz) {
const std::string::size_type szLen = n2-n1+1; const std::string::size_type szLen = n2-n1+1;
@ -317,7 +321,7 @@ std::shared_ptr<const EXPRESS::DataType> EXPRESS::DataType::Parse(const char*& i
} }
for(--t;IsSpace(*t);--t); for(--t;IsSpace(*t);--t);
std::string s(cur,static_cast<size_t>(t-cur+1)); std::string s(cur,static_cast<size_t>(t-cur+1));
std::transform(s.begin(),s.end(),s.begin(),&ToLower<char> ); std::transform(s.begin(),s.end(),s.begin(),&ai_tolower<char> );
if (schema->IsKnownToken(s)) { if (schema->IsKnownToken(s)) {
for(cur = t+1;*cur++ != '(';); for(cur = t+1;*cur++ != '(';);
const std::shared_ptr<const EXPRESS::DataType> dt = Parse(cur); const std::shared_ptr<const EXPRESS::DataType> dt = Parse(cur);

View File

@ -693,7 +693,7 @@ void XFileParser::ParseDataObjectMaterial(Material *pMaterial) {
std::string matName; std::string matName;
readHeadOfDataObject(&matName); readHeadOfDataObject(&matName);
if (matName.empty()) if (matName.empty())
matName = std::string("material") + to_string(mLineNumber); matName = std::string("material") + ai_to_string(mLineNumber);
pMaterial->mName = matName; pMaterial->mName = matName;
pMaterial->mIsReference = false; pMaterial->mIsReference = false;

View File

@ -318,13 +318,13 @@ inline void Buffer::Read(Value &obj, Asset &r) {
this->mData.reset(data, std::default_delete<uint8_t[]>()); this->mData.reset(data, std::default_delete<uint8_t[]>());
if (statedLength > 0 && this->byteLength != statedLength) { if (statedLength > 0 && this->byteLength != statedLength) {
throw DeadlyImportError("GLTF: buffer \"", id, "\", expected ", to_string(statedLength), throw DeadlyImportError("GLTF: buffer \"", id, "\", expected ", ai_to_string(statedLength),
" bytes, but found ", to_string(dataURI.dataLength)); " bytes, but found ", ai_to_string(dataURI.dataLength));
} }
} else { // assume raw data } else { // assume raw data
if (statedLength != dataURI.dataLength) { if (statedLength != dataURI.dataLength) {
throw DeadlyImportError("GLTF: buffer \"", id, "\", expected ", to_string(statedLength), throw DeadlyImportError("GLTF: buffer \"", id, "\", expected ", ai_to_string(statedLength),
" bytes, but found ", to_string(dataURI.dataLength)); " bytes, but found ", ai_to_string(dataURI.dataLength));
} }
this->mData.reset(new uint8_t[dataURI.dataLength], std::default_delete<uint8_t[]>()); this->mData.reset(new uint8_t[dataURI.dataLength], std::default_delete<uint8_t[]>());
@ -927,24 +927,24 @@ inline void Mesh::Decode_O3DGC(const SCompression_Open3DGC &pCompression_Open3DG
size_t size_coordindex = ifs.GetNCoordIndex() * 3; // See float attributes note. size_t size_coordindex = ifs.GetNCoordIndex() * 3; // See float attributes note.
if (primitives[0].indices->count != size_coordindex) if (primitives[0].indices->count != size_coordindex)
throw DeadlyImportError("GLTF: Open3DGC. Compressed indices count (", to_string(size_coordindex), throw DeadlyImportError("GLTF: Open3DGC. Compressed indices count (", ai_to_string(size_coordindex),
") not equal to uncompressed (", to_string(primitives[0].indices->count), ")."); ") not equal to uncompressed (", ai_to_string(primitives[0].indices->count), ").");
size_coordindex *= sizeof(IndicesType); size_coordindex *= sizeof(IndicesType);
// Coordinates // Coordinates
size_t size_coord = ifs.GetNCoord(); // See float attributes note. size_t size_coord = ifs.GetNCoord(); // See float attributes note.
if (primitives[0].attributes.position[0]->count != size_coord) if (primitives[0].attributes.position[0]->count != size_coord)
throw DeadlyImportError("GLTF: Open3DGC. Compressed positions count (", to_string(size_coord), throw DeadlyImportError("GLTF: Open3DGC. Compressed positions count (", ai_to_string(size_coord),
") not equal to uncompressed (", to_string(primitives[0].attributes.position[0]->count), ")."); ") not equal to uncompressed (", ai_to_string(primitives[0].attributes.position[0]->count), ").");
size_coord *= 3 * sizeof(float); size_coord *= 3 * sizeof(float);
// Normals // Normals
size_t size_normal = ifs.GetNNormal(); // See float attributes note. size_t size_normal = ifs.GetNNormal(); // See float attributes note.
if (primitives[0].attributes.normal[0]->count != size_normal) if (primitives[0].attributes.normal[0]->count != size_normal)
throw DeadlyImportError("GLTF: Open3DGC. Compressed normals count (", to_string(size_normal), throw DeadlyImportError("GLTF: Open3DGC. Compressed normals count (", ai_to_string(size_normal),
") not equal to uncompressed (", to_string(primitives[0].attributes.normal[0]->count), ")."); ") not equal to uncompressed (", ai_to_string(primitives[0].attributes.normal[0]->count), ").");
size_normal *= 3 * sizeof(float); size_normal *= 3 * sizeof(float);
// Additional attributes. // Additional attributes.
@ -965,8 +965,8 @@ inline void Mesh::Decode_O3DGC(const SCompression_Open3DGC &pCompression_Open3DG
// Check situation when encoded data contain texture coordinates but primitive not. // Check situation when encoded data contain texture coordinates but primitive not.
if (idx_texcoord < primitives[0].attributes.texcoord.size()) { if (idx_texcoord < primitives[0].attributes.texcoord.size()) {
if (primitives[0].attributes.texcoord[idx]->count != tval) if (primitives[0].attributes.texcoord[idx]->count != tval)
throw DeadlyImportError("GLTF: Open3DGC. Compressed texture coordinates count (", to_string(tval), throw DeadlyImportError("GLTF: Open3DGC. Compressed texture coordinates count (", ai_to_string(tval),
") not equal to uncompressed (", to_string(primitives[0].attributes.texcoord[idx]->count), ")."); ") not equal to uncompressed (", ai_to_string(primitives[0].attributes.texcoord[idx]->count), ").");
idx_texcoord++; idx_texcoord++;
} else { } else {
@ -975,7 +975,7 @@ inline void Mesh::Decode_O3DGC(const SCompression_Open3DGC &pCompression_Open3DG
break; break;
default: default:
throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of float attribute: ", to_string(ifs.GetFloatAttributeType(static_cast<unsigned long>(idx)))); throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of float attribute: ", ai_to_string(ifs.GetFloatAttributeType(static_cast<unsigned long>(idx))));
} }
tval *= ifs.GetFloatAttributeDim(static_cast<unsigned long>(idx)) * sizeof(o3dgc::Real); // After checking count of objects we can get size of array. tval *= ifs.GetFloatAttributeDim(static_cast<unsigned long>(idx)) * sizeof(o3dgc::Real); // After checking count of objects we can get size of array.
@ -994,7 +994,7 @@ inline void Mesh::Decode_O3DGC(const SCompression_Open3DGC &pCompression_Open3DG
break; break;
default: default:
throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of int attribute: ", to_string(ifs.GetIntAttributeType(static_cast<unsigned long>(idx)))); throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of int attribute: ", ai_to_string(ifs.GetIntAttributeType(static_cast<unsigned long>(idx))));
} }
tval *= ifs.GetIntAttributeDim(static_cast<unsigned long>(idx)) * sizeof(long); // See float attributes note. tval *= ifs.GetIntAttributeDim(static_cast<unsigned long>(idx)) * sizeof(long); // See float attributes note.
@ -1029,7 +1029,7 @@ inline void Mesh::Decode_O3DGC(const SCompression_Open3DGC &pCompression_Open3DG
break; break;
default: default:
throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of float attribute: ", to_string(ifs.GetFloatAttributeType(static_cast<unsigned long>(idx)))); throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of float attribute: ", ai_to_string(ifs.GetFloatAttributeType(static_cast<unsigned long>(idx))));
} }
} }
@ -1043,7 +1043,7 @@ inline void Mesh::Decode_O3DGC(const SCompression_Open3DGC &pCompression_Open3DG
// ifs.SetIntAttribute(idx, (long* const)(decoded_data + get_buf_offset(primitives[0].attributes.joint))); // ifs.SetIntAttribute(idx, (long* const)(decoded_data + get_buf_offset(primitives[0].attributes.joint)));
default: default:
throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of int attribute: ", to_string(ifs.GetIntAttributeType(static_cast<unsigned long>(idx)))); throw DeadlyImportError("GLTF: Open3DGC. Unsupported type of int attribute: ", ai_to_string(ifs.GetIntAttributeType(static_cast<unsigned long>(idx))));
} }
} }
@ -1254,7 +1254,7 @@ inline void Asset::ReadBinaryHeader(IOStream &stream) {
} }
AI_SWAP4(header.version); AI_SWAP4(header.version);
asset.version = to_string(header.version); asset.version = ai_to_string(header.version);
if (header.version != 1) { if (header.version != 1) {
throw DeadlyImportError("GLTF: Unsupported binary glTF version"); throw DeadlyImportError("GLTF: Unsupported binary glTF version");
} }

View File

@ -1003,7 +1003,7 @@ void glTFExporter::ExportAnimations()
// It appears that assimp stores this type of animation as multiple animations. // It appears that assimp stores this type of animation as multiple animations.
// where each aiNodeAnim in mChannels animates a specific node. // where each aiNodeAnim in mChannels animates a specific node.
std::string name = nameAnim + "_" + to_string(channelIndex); std::string name = nameAnim + "_" + ai_to_string(channelIndex);
name = mAsset->FindUniqueID(name, "animation"); name = mAsset->FindUniqueID(name, "animation");
Ref<Animation> animRef = mAsset->animations.Create(name); Ref<Animation> animRef = mAsset->animations.Create(name);

View File

@ -234,7 +234,7 @@ void glTFImporter::ImportMeshes(glTF::Asset &r) {
buf->EncodedRegion_SetCurrent(mesh.id); buf->EncodedRegion_SetCurrent(mesh.id);
} else } else
{ {
throw DeadlyImportError("GLTF: Can not import mesh: unknown mesh extension (code: \"", to_string(cur_ext->Type), throw DeadlyImportError("GLTF: Can not import mesh: unknown mesh extension (code: \"", ai_to_string(cur_ext->Type),
"\"), only Open3DGC is supported."); "\"), only Open3DGC is supported.");
} }
} }

View File

@ -197,7 +197,7 @@ inline unsigned int ComponentTypeSize(ComponentType t) {
case ComponentType_UNSIGNED_BYTE: case ComponentType_UNSIGNED_BYTE:
return 1; return 1;
default: default:
throw DeadlyImportError("GLTF: Unsupported Component Type ", to_string(t)); throw DeadlyImportError("GLTF: Unsupported Component Type ", ai_to_string(t));
} }
} }

View File

@ -446,7 +446,7 @@ Ref<T> LazyDict<T>::Retrieve(unsigned int i) {
// Unique ptr prevents memory leak in case of Read throws an exception // Unique ptr prevents memory leak in case of Read throws an exception
auto inst = std::unique_ptr<T>(new T()); auto inst = std::unique_ptr<T>(new T());
// Try to make this human readable so it can be used in error messages. // Try to make this human readable so it can be used in error messages.
inst->id = std::string(mDictId) + "[" + to_string(i) + "]"; inst->id = std::string(mDictId) + "[" + ai_to_string(i) + "]";
inst->oIndex = i; inst->oIndex = i;
ReadMember(obj, "name", inst->name); ReadMember(obj, "name", inst->name);
inst->Read(obj, mAsset); inst->Read(obj, mAsset);
@ -538,13 +538,13 @@ inline void Buffer::Read(Value &obj, Asset &r) {
this->mData.reset(data, std::default_delete<uint8_t[]>()); this->mData.reset(data, std::default_delete<uint8_t[]>());
if (statedLength > 0 && this->byteLength != statedLength) { if (statedLength > 0 && this->byteLength != statedLength) {
throw DeadlyImportError("GLTF: buffer \"", id, "\", expected ", to_string(statedLength), throw DeadlyImportError("GLTF: buffer \"", id, "\", expected ", ai_to_string(statedLength),
" bytes, but found ", to_string(dataURI.dataLength)); " bytes, but found ", ai_to_string(dataURI.dataLength));
} }
} else { // assume raw data } else { // assume raw data
if (statedLength != dataURI.dataLength) { if (statedLength != dataURI.dataLength) {
throw DeadlyImportError("GLTF: buffer \"", id, "\", expected ", to_string(statedLength), throw DeadlyImportError("GLTF: buffer \"", id, "\", expected ", ai_to_string(statedLength),
" bytes, but found ", to_string(dataURI.dataLength)); " bytes, but found ", ai_to_string(dataURI.dataLength));
} }
this->mData.reset(new uint8_t[dataURI.dataLength], std::default_delete<uint8_t[]>()); this->mData.reset(new uint8_t[dataURI.dataLength], std::default_delete<uint8_t[]>());
@ -1800,7 +1800,7 @@ inline void Asset::ReadBinaryHeader(IOStream &stream, std::vector<char> &sceneDa
} }
AI_SWAP4(header.version); AI_SWAP4(header.version);
asset.version = to_string(header.version); asset.version = ai_to_string(header.version);
if (header.version != 2) { if (header.version != 2) {
throw DeadlyImportError("GLTF: Unsupported binary glTF version"); throw DeadlyImportError("GLTF: Unsupported binary glTF version");
} }

View File

@ -602,7 +602,7 @@ void glTF2Exporter::ExportMaterials()
for (unsigned int i = 0; i < mScene->mNumMaterials; ++i) { for (unsigned int i = 0; i < mScene->mNumMaterials; ++i) {
const aiMaterial* mat = mScene->mMaterials[i]; const aiMaterial* mat = mScene->mMaterials[i];
std::string id = "material_" + to_string(i); std::string id = "material_" + ai_to_string(i);
Ref<Material> m = mAsset->materials.Create(id); Ref<Material> m = mAsset->materials.Create(id);
@ -1393,7 +1393,7 @@ void glTF2Exporter::ExportAnimations()
for (unsigned int channelIndex = 0; channelIndex < anim->mNumChannels; ++channelIndex) { for (unsigned int channelIndex = 0; channelIndex < anim->mNumChannels; ++channelIndex) {
const aiNodeAnim* nodeChannel = anim->mChannels[channelIndex]; const aiNodeAnim* nodeChannel = anim->mChannels[channelIndex];
std::string name = nameAnim + "_" + to_string(channelIndex); std::string name = nameAnim + "_" + ai_to_string(channelIndex);
name = mAsset->FindUniqueID(name, "animation"); name = mAsset->FindUniqueID(name, "animation");
Ref<Node> animNode = mAsset->nodes.Get(nodeChannel->mNodeName.C_Str()); Ref<Node> animNode = mAsset->nodes.Get(nodeChannel->mNodeName.C_Str());

View File

@ -276,7 +276,7 @@ std::string BaseImporter::GetExtension(const std::string &file) {
// thanks to Andy Maloney for the hint // thanks to Andy Maloney for the hint
std::string ret = file.substr(pos + 1); std::string ret = file.substr(pos + 1);
std::transform(ret.begin(), ret.end(), ret.begin(), ToLower<char>); ret = ai_str_tolower(ret);
return ret; return ret;
} }

View File

@ -975,15 +975,14 @@ size_t Importer::GetImporterIndex (const char* szExtension) const {
ASSIMP_BEGIN_EXCEPTION_REGION(); ASSIMP_BEGIN_EXCEPTION_REGION();
// skip over wildcard and dot characters at string head -- // skip over wild-card and dot characters at string head --
for ( ; *szExtension == '*' || *szExtension == '.'; ++szExtension ); for ( ; *szExtension == '*' || *szExtension == '.'; ++szExtension );
std::string ext(szExtension); std::string ext(szExtension);
if (ext.empty()) { if (ext.empty()) {
return static_cast<size_t>(-1); return static_cast<size_t>(-1);
} }
std::transform( ext.begin(), ext.end(), ext.begin(), ToLower<char> ); ext = ai_str_tolower(ext);
std::set<std::string> str; std::set<std::string> str;
for (std::vector<BaseImporter*>::const_iterator i = pimpl->mImporter.begin();i != pimpl->mImporter.end();++i) { for (std::vector<BaseImporter*>::const_iterator i = pimpl->mImporter.begin();i != pimpl->mImporter.end();++i) {
str.clear(); str.clear();

View File

@ -137,7 +137,7 @@ bool EmbedTexturesProcess::addTexture(aiScene* pScene, std::string path) const {
pTexture->pcData = imageContent; pTexture->pcData = imageContent;
auto extension = path.substr(path.find_last_of('.') + 1u); auto extension = path.substr(path.find_last_of('.') + 1u);
std::transform(extension.begin(), extension.end(), extension.begin(), ToLower<char> ); extension = ai_str_tolower(extension);
if (extension == "jpeg") { if (extension == "jpeg") {
extension = "jpg"; extension = "jpg";
} }

View File

@ -53,7 +53,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/StringComparison.h> #include <assimp/StringComparison.h>
#include <assimp/StringUtils.h> #include <assimp/StringUtils.h>
#include <assimp/defs.h> #include <assimp/defs.h>
#include <vector> #include <vector>
#include <algorithm>
namespace Assimp { namespace Assimp {
@ -68,17 +70,6 @@ namespace Assimp {
static const unsigned int BufferSize = 4096; static const unsigned int BufferSize = 4096;
// ---------------------------------------------------------------------------------
template <class char_t>
AI_FORCE_INLINE char_t ToLower(char_t in) {
return (in >= (char_t)'A' && in <= (char_t)'Z') ? (char_t)(in + 0x20) : in;
}
// ---------------------------------------------------------------------------------
template <class char_t>
AI_FORCE_INLINE char_t ToUpper(char_t in) {
return (in >= (char_t)'a' && in <= (char_t)'z') ? (char_t)(in - 0x20) : in;
}
// --------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------
template <class char_t> template <class char_t>

View File

@ -61,8 +61,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/ai_assert.h> #include <assimp/ai_assert.h>
#include <assimp/defs.h> #include <assimp/defs.h>
#include <stdint.h> #include <cstdint>
#include <string.h> #include <cstring>
#include <string> #include <string>
namespace Assimp { namespace Assimp {
@ -78,8 +78,7 @@ namespace Assimp {
* @param number Number to be written * @param number Number to be written
* @return Length of the output string, excluding the '\0' * @return Length of the output string, excluding the '\0'
*/ */
AI_FORCE_INLINE inline unsigned int ASSIMP_itoa10(char *out, unsigned int max, int32_t number) {
unsigned int ASSIMP_itoa10(char *out, unsigned int max, int32_t number) {
ai_assert(nullptr != out); ai_assert(nullptr != out);
// write the unary minus to indicate we have a negative number // write the unary minus to indicate we have a negative number
@ -97,7 +96,7 @@ unsigned int ASSIMP_itoa10(char *out, unsigned int max, int32_t number) {
const unsigned int digit = number / cur; const unsigned int digit = number / cur;
if (mustPrint || digit > 0 || 1 == cur) { if (mustPrint || digit > 0 || 1 == cur) {
// print all future zeroe's from now // print all future zero's from now
mustPrint = true; mustPrint = true;
*out++ = '0' + static_cast<char>(digit); *out++ = '0' + static_cast<char>(digit);
@ -122,7 +121,7 @@ unsigned int ASSIMP_itoa10(char *out, unsigned int max, int32_t number) {
* size of the array automatically. * size of the array automatically.
*/ */
template <size_t length> template <size_t length>
AI_FORCE_INLINE unsigned int ASSIMP_itoa10(char (&out)[length], int32_t number) { inline unsigned int ASSIMP_itoa10(char (&out)[length], int32_t number) {
return ASSIMP_itoa10(out, length, number); return ASSIMP_itoa10(out, length, number);
} }
@ -137,8 +136,7 @@ AI_FORCE_INLINE unsigned int ASSIMP_itoa10(char (&out)[length], int32_t number)
* @param s2 Second input string * @param s2 Second input string
* @return 0 if the given strings are identical * @return 0 if the given strings are identical
*/ */
AI_FORCE_INLINE inline int ASSIMP_stricmp(const char *s1, const char *s2) {
int ASSIMP_stricmp(const char *s1, const char *s2) {
ai_assert(nullptr != s1); ai_assert(nullptr != s1);
ai_assert(nullptr != s2); ai_assert(nullptr != s2);
@ -162,8 +160,7 @@ int ASSIMP_stricmp(const char *s1, const char *s2) {
* @param b Second string * @param b Second string
* @return 0 if a == b * @return 0 if a == b
*/ */
AI_FORCE_INLINE inline int ASSIMP_stricmp(const std::string &a, const std::string &b) {
int ASSIMP_stricmp(const std::string &a, const std::string &b) {
int i = (int)b.length() - (int)a.length(); int i = (int)b.length() - (int)a.length();
return (i ? i : ASSIMP_stricmp(a.c_str(), b.c_str())); return (i ? i : ASSIMP_stricmp(a.c_str(), b.c_str()));
} }
@ -177,11 +174,10 @@ int ASSIMP_stricmp(const std::string &a, const std::string &b) {
* *
* @param s1 First input string * @param s1 First input string
* @param s2 Second input string * @param s2 Second input string
* @param n Macimum number of characters to compare * @param n Maximum number of characters to compare
* @return 0 if the given strings are identical * @return 0 if the given strings are identical
*/ */
AI_FORCE_INLINE inline int ASSIMP_strincmp(const char *s1, const char *s2, unsigned int n) {
int ASSIMP_strincmp(const char *s1, const char *s2, unsigned int n) {
ai_assert(nullptr != s1); ai_assert(nullptr != s1);
ai_assert(nullptr != s2); ai_assert(nullptr != s2);
if (!n) { if (!n) {
@ -214,8 +210,7 @@ int ASSIMP_strincmp(const char *s1, const char *s2, unsigned int n) {
* *
* todo: move somewhere where it fits better in than here * todo: move somewhere where it fits better in than here
*/ */
AI_FORCE_INLINE inline unsigned int integer_pow(unsigned int base, unsigned int power) {
unsigned int integer_pow(unsigned int base, unsigned int power) {
unsigned int res = 1; unsigned int res = 1;
for (unsigned int i = 0; i < power; ++i) { for (unsigned int i = 0; i < power; ++i) {
res *= base; res *= base;

View File

@ -49,7 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/defs.h> #include <assimp/defs.h>
#include <stdarg.h> #include <cstdarg>
#include <algorithm> #include <algorithm>
#include <cctype> #include <cctype>
#include <cstdlib> #include <cstdlib>
@ -62,17 +62,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define AI_SIZEFMT "%zu" #define AI_SIZEFMT "%zu"
#endif #endif
// ---------------------------------------------------------------------------------
/// @fn ai_snprintf /// @fn ai_snprintf
/// @brief The portable version of the function snprintf ( C99 standard ), which works on visual studio compilers 2013 and earlier. /// @brief The portable version of the function snprintf ( C99 standard ), which
/// works on visual studio compilers 2013 and earlier.
/// @param outBuf The buffer to write in /// @param outBuf The buffer to write in
/// @param size The buffer size /// @param size The buffer size
/// @param format The format string /// @param format The format string
/// @param ap The additional arguments. /// @param ap The additional arguments.
/// @return The number of written characters if the buffer size was big enough. If an encoding error occurs, a negative number is returned. /// @return The number of written characters if the buffer size was big enough.
/// If an encoding error occurs, a negative number is returned.
// ---------------------------------------------------------------------------------
#if defined(_MSC_VER) && _MSC_VER < 1900 #if defined(_MSC_VER) && _MSC_VER < 1900
AI_FORCE_INLINE inline int c99_ai_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap) {
int c99_ai_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap) {
int count(-1); int count(-1);
if (0 != size) { if (0 != size) {
count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap); count = _vsnprintf_s(outBuf, size, _TRUNCATE, format, ap);
@ -84,8 +87,7 @@ int c99_ai_vsnprintf(char *outBuf, size_t size, const char *format, va_list ap)
return count; return count;
} }
AI_FORCE_INLINE inline int ai_snprintf(char *outBuf, size_t size, const char *format, ...) {
int ai_snprintf(char *outBuf, size_t size, const char *format, ...) {
int count; int count;
va_list ap; va_list ap;
@ -102,23 +104,28 @@ int ai_snprintf(char *outBuf, size_t size, const char *format, ...) {
#define ai_snprintf snprintf #define ai_snprintf snprintf
#endif #endif
// ---------------------------------------------------------------------------------
/// @fn to_string /// @fn to_string
/// @brief The portable version of to_string ( some gcc-versions on embedded devices are not supporting this). /// @brief The portable version of to_string ( some gcc-versions on embedded
/// devices are not supporting this).
/// @param value The value to write into the std::string. /// @param value The value to write into the std::string.
/// @return The value as a std::string /// @return The value as a std::string
// ---------------------------------------------------------------------------------
template <typename T> template <typename T>
AI_FORCE_INLINE std::string to_string(T value) { AI_FORCE_INLINE std::string ai_to_string(T value) {
std::ostringstream os; std::ostringstream os;
os << value; os << value;
return os.str(); return os.str();
} }
// ---------------------------------------------------------------------------------
/// @fn ai_strtof /// @fn ai_strtof
/// @brief The portable version of strtof. /// @brief The portable version of strtof.
/// @param begin The first character of the string. /// @param begin The first character of the string.
/// @param end The last character /// @param end The last character
/// @return The float value, 0.0f in cas of an error. /// @return The float value, 0.0f in case of an error.
// ---------------------------------------------------------------------------------
AI_FORCE_INLINE AI_FORCE_INLINE
float ai_strtof(const char *begin, const char *end) { float ai_strtof(const char *begin, const char *end) {
if (nullptr == begin) { if (nullptr == begin) {
@ -136,12 +143,14 @@ float ai_strtof(const char *begin, const char *end) {
return val; return val;
} }
// ---------------------------------------------------------------------------------
/// @fn DecimalToHexa /// @fn DecimalToHexa
/// @brief The portable to convert a decimal value into a hexadecimal string. /// @brief The portable to convert a decimal value into a hexadecimal string.
/// @param toConvert Value to convert /// @param toConvert Value to convert
/// @return The hexadecimal string, is empty in case of an error. /// @return The hexadecimal string, is empty in case of an error.
// ---------------------------------------------------------------------------------
template <class T> template <class T>
AI_FORCE_INLINE std::string DecimalToHexa(T toConvert) { AI_FORCE_INLINE std::string ai_decimal_to_hexa(T toConvert) {
std::string result; std::string result;
std::stringstream ss; std::stringstream ss;
ss << std::hex << toConvert; ss << std::hex << toConvert;
@ -154,6 +163,7 @@ AI_FORCE_INLINE std::string DecimalToHexa(T toConvert) {
return result; return result;
} }
// ---------------------------------------------------------------------------------
/// @brief translate RGBA to String /// @brief translate RGBA to String
/// @param r aiColor.r /// @param r aiColor.r
/// @param g aiColor.g /// @param g aiColor.g
@ -161,7 +171,8 @@ AI_FORCE_INLINE std::string DecimalToHexa(T toConvert) {
/// @param a aiColor.a /// @param a aiColor.a
/// @param with_head # /// @param with_head #
/// @return The hexadecimal string, is empty in case of an error. /// @return The hexadecimal string, is empty in case of an error.
AI_FORCE_INLINE std::string Rgba2Hex(int r, int g, int b, int a, bool with_head) { // ---------------------------------------------------------------------------------
AI_FORCE_INLINE std::string ai_rgba2hex(int r, int g, int b, int a, bool with_head) {
std::stringstream ss; std::stringstream ss;
if (with_head) { if (with_head) {
ss << "#"; ss << "#";
@ -171,25 +182,69 @@ AI_FORCE_INLINE std::string Rgba2Hex(int r, int g, int b, int a, bool with_head)
return ss.str(); return ss.str();
} }
// trim from start (in place) // ---------------------------------------------------------------------------------
AI_FORCE_INLINE void ltrim(std::string &s) { /// @brief Performs a trim from start (in place)
/// @param s string to trim.
AI_FORCE_INLINE void ai_trim_left(std::string &s) {
s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) { s.erase(s.begin(), std::find_if(s.begin(), s.end(), [](unsigned char ch) {
return !std::isspace(ch); return !std::isspace(ch);
})); }));
} }
// trim from end (in place) // ---------------------------------------------------------------------------------
AI_FORCE_INLINE void rtrim(std::string &s) { /// @brief Performs a trim from end (in place).
/// @param s string to trim.
// ---------------------------------------------------------------------------------
// ---------------------------------------------------------------------------------
AI_FORCE_INLINE void ai_trim_right(std::string &s) {
s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) { s.erase(std::find_if(s.rbegin(), s.rend(), [](unsigned char ch) {
return !std::isspace(ch); return !std::isspace(ch);
}).base(), }).base(), s.end());
s.end());
} }
// trim from both ends (in place) // ---------------------------------------------------------------------------------
AI_FORCE_INLINE void trim(std::string &s) { /// @brief Performs a trim from both ends (in place).
ltrim(s); /// @param s string to trim.
rtrim(s); // ---------------------------------------------------------------------------------
AI_FORCE_INLINE std::string ai_trim(std::string &s) {
std::string out(s);
ai_trim_left(s);
ai_trim_right(s);
return out;
} }
#endif // INCLUDED_AI_STRINGUTILS_H // ---------------------------------------------------------------------------------
template <class char_t>
AI_FORCE_INLINE char_t ai_tolower(char_t in) {
return (in >= (char_t)'A' && in <= (char_t)'Z') ? (char_t)(in + 0x20) : in;
}
// ---------------------------------------------------------------------------------
/// @brief Performs a ToLower-operation and return the lower-case string.
/// @param in The incoming string.
/// @return The string as lowercase.
// ---------------------------------------------------------------------------------
AI_FORCE_INLINE std::string ai_str_tolower(const std::string &in) {
std::string out(in);
std::transform(out.begin(), out.end(), out.begin(), [](unsigned char c) { return ai_tolower(c); });
return out;
}
// ---------------------------------------------------------------------------------
template <class char_t>
AI_FORCE_INLINE char_t ai_toupper(char_t in) {
return (in >= (char_t)'a' && in <= (char_t)'z') ? (char_t)(in - 0x20) : in;
}
// ---------------------------------------------------------------------------------
/// @brief Performs a ToLower-operation and return the upper-case string.
/// @param in The incoming string.
/// @return The string as uppercase.
AI_FORCE_INLINE std::string ai_str_toupper(const std::string &in) {
std::string out(in);
std::transform(out.begin(), out.end(), out.begin(), [](char c) { return ai_toupper(c); });
return out;
}
#endif

View File

@ -45,10 +45,10 @@ class utStringUtils : public ::testing::Test {
}; };
TEST_F( utStringUtils, to_string_Test ) { TEST_F( utStringUtils, to_string_Test ) {
std::string res = to_string( 1 ); std::string res = ai_to_string( 1 );
EXPECT_EQ( res, "1" ); EXPECT_EQ( res, "1" );
res = to_string( 1.0f ); res = ai_to_string( 1.0f );
EXPECT_EQ( res, "1" ); EXPECT_EQ( res, "1" );
} }

View File

@ -45,6 +45,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "Main.h" #include "Main.h"
#include <assimp/ParsingUtils.h> #include <assimp/ParsingUtils.h>
#include <assimp/StringUtils.h>
#ifndef ASSIMP_BUILD_NO_EXPORT #ifndef ASSIMP_BUILD_NO_EXPORT
@ -107,7 +108,7 @@ int Assimp_Export(const char *const *params, unsigned int num) {
} }
} }
std::transform(outf.begin(), outf.end(), outf.begin(), Assimp::ToLower<char>); std::transform(outf.begin(), outf.end(), outf.begin(), ai_tolower<char>);
// convert the output format to a format id // convert the output format to a format id
size_t outfi = GetMatchingFormat(outf); size_t outfi = GetMatchingFormat(outf);

View File

@ -266,7 +266,7 @@ int Assimp_Extract(const char *const *params, unsigned int num) {
#endif #endif
} }
std::transform(extension.begin(), extension.end(), extension.begin(), Assimp::ToLower<char>); std::transform(extension.begin(), extension.end(), extension.begin(), ai_tolower<char>);
if (out[0] == '-') { if (out[0] == '-') {
// take file name from input file // take file name from input file