Merge pull request #3736 from assimp/issue_3678

Issue 3678
pull/3737/head
Kim Kulling 2021-04-03 11:23:17 +02:00 committed by GitHub
commit 456af8c493
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 129 additions and 306 deletions

View File

@ -39,16 +39,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
*/ */
/// \file AMFImporter.cpp
/// \brief AMF-format files importer for Assimp: main algorithm implementation.
/// \date 2016
/// \author smal.root@gmail.com
#ifndef ASSIMP_BUILD_NO_AMF_IMPORTER #ifndef ASSIMP_BUILD_NO_AMF_IMPORTER
// Header files, Assimp. // Header files, Assimp.
#include "AMFImporter.hpp" #include "AMFImporter.hpp"
#include "AMFImporter_Macro.hpp"
#include <assimp/DefaultIOSystem.h> #include <assimp/DefaultIOSystem.h>
#include <assimp/fast_atof.h> #include <assimp/fast_atof.h>
@ -307,14 +301,14 @@ 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 = ai_str_tolower(std::string(node.attribute("unit").as_string())); mUnit = ai_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>.
// Check attributes // Check attributes
if (!mUnit.empty()) { if (!mUnit.empty()) {
if ((mUnit != "inch") && (mUnit != "millimeter") && (mUnit != "meter") && (mUnit != "feet") && (mUnit != "micron")) { if ((mUnit != "inch") && (mUnit != "millimeters") && (mUnit != "millimeter") && (mUnit != "meter") && (mUnit != "feet") && (mUnit != "micron")) {
Throw_IncorrectAttrValue("unit", mUnit); Throw_IncorrectAttrValue("unit", mUnit);
} }
} }
@ -409,20 +403,20 @@ void AMFImporter::ParseNode_Instance(XmlNode &node) {
if (!node.empty()) { if (!node.empty()) {
ParseHelper_Node_Enter(ne); ParseHelper_Node_Enter(ne);
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { for (auto &currentNode : node.children()) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "deltax") { if (currentName == "deltax") {
als.Delta.x = (ai_real)std::atof(currentNode.value()); XmlParser::getValueAsFloat(currentNode, als.Delta.x);
} else if (currentName == "deltay") { } else if (currentName == "deltay") {
als.Delta.y = (ai_real)std::atof(currentNode.value()); XmlParser::getValueAsFloat(currentNode, als.Delta.y);
} else if (currentName == "deltaz") { } else if (currentName == "deltaz") {
als.Delta.z = (ai_real)std::atof(currentNode.value()); XmlParser::getValueAsFloat(currentNode, als.Delta.z);
} else if (currentName == "rx") { } else if (currentName == "rx") {
als.Delta.x = (ai_real)std::atof(currentNode.value()); XmlParser::getValueAsFloat(currentNode, als.Delta.x);
} else if (currentName == "ry") { } else if (currentName == "ry") {
als.Delta.y = (ai_real)std::atof(currentNode.value()); XmlParser::getValueAsFloat(currentNode, als.Delta.y);
} else if (currentName == "rz") { } else if (currentName == "rz") {
als.Delta.z = (ai_real)std::atof(currentNode.value()); XmlParser::getValueAsFloat(currentNode, als.Delta.z);
} }
} }
ParseHelper_Node_Exit(); ParseHelper_Node_Exit();
@ -458,7 +452,7 @@ void AMFImporter::ParseNode_Object(XmlNode &node) {
// Check for child nodes // Check for child nodes
if (!node.empty()) { if (!node.empty()) {
ParseHelper_Node_Enter(ne); ParseHelper_Node_Enter(ne);
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { for (auto &currentNode : node.children()) {
const std::string &currentName = currentNode.name(); const std::string &currentName = currentNode.name();
if (currentName == "color") { if (currentName == "color") {
ParseNode_Color(currentNode); ParseNode_Color(currentNode);

View File

@ -39,16 +39,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
*/ */
/// \file AMFImporter_Geometry.cpp
/// \brief Parsing data from geometry nodes.
/// \date 2016
/// \author smal.root@gmail.com
#ifndef ASSIMP_BUILD_NO_AMF_IMPORTER #ifndef ASSIMP_BUILD_NO_AMF_IMPORTER
#include "AMFImporter.hpp" #include "AMFImporter.hpp"
#include "AMFImporter_Macro.hpp"
#include <assimp/ParsingUtils.h> #include <assimp/ParsingUtils.h>
namespace Assimp { namespace Assimp {
@ -103,18 +96,18 @@ void AMFImporter::ParseNode_Vertices(XmlNode &node) {
// create new mesh object. // create new mesh object.
ne = new AMFVertices(mNodeElement_Cur); ne = new AMFVertices(mNodeElement_Cur);
// Check for child nodes // Check for child nodes
pugi::xml_node vertexNode = node.child("vertex"); if (node.empty()) {
if (!vertexNode.empty()) {
ParseHelper_Node_Enter(ne);
ParseNode_Vertex(vertexNode);
ParseHelper_Node_Exit();
} else {
mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element mNodeElement_Cur->Child.push_back(ne); // Add element to child list of current element
} // if(!mReader->isEmptyElement()) else return;
}
ParseHelper_Node_Enter(ne);
for (XmlNode &currentNode : node.children()) {
const std::string &currentName = currentNode.name();
if (currentName == "vertex") {
ParseNode_Vertex(currentNode);
}
}
ParseHelper_Node_Exit();
mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph. mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph.
} }
@ -166,27 +159,25 @@ void AMFImporter::ParseNode_Vertex(XmlNode &node) {
// X, Y, or Z coordinate, respectively, of a vertex position in space. // X, Y, or Z coordinate, respectively, of a vertex position in space.
void AMFImporter::ParseNode_Coordinates(XmlNode &node) { void AMFImporter::ParseNode_Coordinates(XmlNode &node) {
AMFNodeElementBase *ne = nullptr; AMFNodeElementBase *ne = nullptr;
// create new color object.
ne = new AMFCoordinates(mNodeElement_Cur);
AMFCoordinates &als = *((AMFCoordinates *)ne); // alias for convenience
if (!node.empty()) { if (!node.empty()) {
ne = new AMFCoordinates(mNodeElement_Cur);
ParseHelper_Node_Enter(ne); ParseHelper_Node_Enter(ne);
for (XmlNode &currentNode : node.children()) { for (XmlNode &currentNode : node.children()) {
const std::string &currentName = currentNode.name(); // create new color object.
if (currentName == "X") { AMFCoordinates &als = *((AMFCoordinates *)ne); // alias for convenience
const std::string &currentName = ai_tolower(currentNode.name());
if (currentName == "x") {
XmlParser::getValueAsFloat(currentNode, als.Coordinate.x); XmlParser::getValueAsFloat(currentNode, als.Coordinate.x);
} else if (currentName == "Y") { } else if (currentName == "y") {
XmlParser::getValueAsFloat(currentNode, als.Coordinate.y); XmlParser::getValueAsFloat(currentNode, als.Coordinate.y);
} else if (currentName == "Z") { } else if (currentName == "z") {
XmlParser::getValueAsFloat(currentNode, als.Coordinate.z); XmlParser::getValueAsFloat(currentNode, als.Coordinate.z);
} }
} }
ParseHelper_Node_Exit(); ParseHelper_Node_Exit();
} else { } else {
mNodeElement_Cur->Child.push_back(ne); mNodeElement_Cur->Child.push_back(new AMFCoordinates(mNodeElement_Cur));
} }
mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph. mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph.
@ -216,7 +207,7 @@ void AMFImporter::ParseNode_Volume(XmlNode &node) {
bool col_read = false; bool col_read = false;
if (!node.empty()) { if (!node.empty()) {
ParseHelper_Node_Enter(ne); ParseHelper_Node_Enter(ne);
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { for (auto &currentNode : node.children()) {
const std::string currentName = currentNode.name(); const std::string currentName = currentNode.name();
if (currentName == "color") { if (currentName == "color") {
if (col_read) Throw_MoreThanOnceDefined(currentName, "color", "Only one color can be defined for <volume>."); if (col_read) Throw_MoreThanOnceDefined(currentName, "color", "Only one color can be defined for <volume>.");
@ -258,7 +249,8 @@ void AMFImporter::ParseNode_Triangle(XmlNode &node) {
bool col_read = false; bool col_read = false;
if (!node.empty()) { if (!node.empty()) {
ParseHelper_Node_Enter(ne); ParseHelper_Node_Enter(ne);
for (XmlNode currentNode = node.first_child(); currentNode; currentNode = currentNode.next_sibling()) { std::string v;
for (auto &currentNode : node.children()) {
const std::string currentName = currentNode.name(); const std::string currentName = currentNode.name();
if (currentName == "color") { if (currentName == "color") {
if (col_read) Throw_MoreThanOnceDefined(currentName, "color", "Only one color can be defined for <triangle>."); if (col_read) Throw_MoreThanOnceDefined(currentName, "color", "Only one color can be defined for <triangle>.");
@ -269,11 +261,14 @@ void AMFImporter::ParseNode_Triangle(XmlNode &node) {
} else if (currentName == "map") { } else if (currentName == "map") {
ParseNode_TexMap(currentNode, true); ParseNode_TexMap(currentNode, true);
} else if (currentName == "v1") { } else if (currentName == "v1") {
als.V[0] = std::atoi(currentNode.value()); XmlParser::getValueAsString(currentNode, v);
als.V[0] = std::atoi(v.c_str());
} else if (currentName == "v2") { } else if (currentName == "v2") {
als.V[1] = std::atoi(currentNode.value()); XmlParser::getValueAsString(currentNode, v);
als.V[1] = std::atoi(v.c_str());
} else if (currentName == "v3") { } else if (currentName == "v3") {
als.V[2] = std::atoi(currentNode.value()); XmlParser::getValueAsString(currentNode, v);
als.V[2] = std::atoi(v.c_str());
} }
} }
ParseHelper_Node_Exit(); ParseHelper_Node_Exit();

View File

@ -1,164 +0,0 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
/// \file AMFImporter_Macro.hpp
/// \brief Useful macrodefines.
/// \date 2016
/// \author smal.root@gmail.com
#pragma once
#ifndef AMFIMPORTER_MACRO_HPP_INCLUDED
#define AMFIMPORTER_MACRO_HPP_INCLUDED
/// \def MACRO_ATTRREAD_LOOPBEG
/// Begin of loop that read attributes values.
#define MACRO_ATTRREAD_LOOPBEG \
for(int idx = 0, idx_end = mReader->getAttributeCount(); idx < idx_end; idx++) \
{ \
std::string an(mReader->getAttributeName(idx));
/// \def MACRO_ATTRREAD_LOOPEND
/// End of loop that read attributes values.
#define MACRO_ATTRREAD_LOOPEND \
Throw_IncorrectAttr(an); \
}
/// \def MACRO_ATTRREAD_LOOPEND_WSKIP
/// End of loop that read attributes values. Difference from \ref MACRO_ATTRREAD_LOOPEND in that: current macro skip unknown attributes, but
/// \ref MACRO_ATTRREAD_LOOPEND throw an exception.
#define MACRO_ATTRREAD_LOOPEND_WSKIP \
continue; \
}
/// \def MACRO_ATTRREAD_CHECK_REF
/// Check current attribute name and if it equal to requested then read value. Result write to output variable by reference. If result was read then
/// "continue" will called.
/// \param [in] pAttrName - attribute name.
/// \param [out] pVarName - output variable name.
/// \param [in] pFunction - function which read attribute value and write it to pVarName.
#define MACRO_ATTRREAD_CHECK_REF(pAttrName, pVarName, pFunction) \
if(an == pAttrName) \
{ \
pFunction(idx, pVarName); \
continue; \
}
/// \def MACRO_ATTRREAD_CHECK_RET
/// Check current attribute name and if it equal to requested then read value. Result write to output variable using return value of \ref pFunction.
/// If result was read then "continue" will called.
/// \param [in] pAttrName - attribute name.
/// \param [out] pVarName - output variable name.
/// \param [in] pFunction - function which read attribute value and write it to pVarName.
#define MACRO_ATTRREAD_CHECK_RET(pAttrName, pVarName, pFunction) \
if(an == pAttrName) \
{ \
pVarName = pFunction(idx); \
continue; \
}
/// \def MACRO_NODECHECK_LOOPBEGIN(pNodeName)
/// Begin of loop of parsing child nodes. Do not add ';' at end.
/// \param [in] pNodeName - current node name.
#define MACRO_NODECHECK_LOOPBEGIN(pNodeName) \
do { \
bool close_found = false; \
\
while(mReader->read()) \
{ \
if(mReader->getNodeType() == irr::io::EXN_ELEMENT) \
{
/// \def MACRO_NODECHECK_LOOPEND(pNodeName)
/// End of loop of parsing child nodes.
/// \param [in] pNodeName - current node name.
#define MACRO_NODECHECK_LOOPEND(pNodeName) \
XML_CheckNode_SkipUnsupported(pNodeName); \
}/* if(mReader->getNodeType() == irr::io::EXN_ELEMENT) */ \
else if(mReader->getNodeType() == irr::io::EXN_ELEMENT_END) \
{ \
if(XML_CheckNode_NameEqual(pNodeName)) \
{ \
close_found = true; \
\
break; \
} \
}/* else if(mReader->getNodeType() == irr::io::EXN_ELEMENT_END) */ \
}/* while(mReader->read()) */ \
\
if(!close_found) Throw_CloseNotFound(pNodeName); \
\
} while(false)
/// \def MACRO_NODECHECK_READCOMP_F
/// Check current node name and if it equal to requested then read value. Result write to output variable of type "float".
/// If result was read then "continue" will called. Also check if node data already read then raise exception.
/// \param [in] pNodeName - node name.
/// \param [in, out] pReadFlag - read flag.
/// \param [out] pVarName - output variable name.
#define MACRO_NODECHECK_READCOMP_F(pNodeName, pReadFlag, pVarName) \
if(XML_CheckNode_NameEqual(pNodeName)) \
{ \
/* Check if field already read before. */ \
if(pReadFlag) Throw_MoreThanOnceDefined(pNodeName, "Only one component can be defined."); \
/* Read color component and assign it to object. */ \
pVarName = XML_ReadNode_GetVal_AsFloat(); \
pReadFlag = true; \
continue; \
}
/// \def MACRO_NODECHECK_READCOMP_U32
/// Check current node name and if it equal to requested then read value. Result write to output variable of type "uint32_t".
/// If result was read then "continue" will called. Also check if node data already read then raise exception.
/// \param [in] pNodeName - node name.
/// \param [in, out] pReadFlag - read flag.
/// \param [out] pVarName - output variable name.
#define MACRO_NODECHECK_READCOMP_U32(pNodeName, pReadFlag, pVarName) \
if(XML_CheckNode_NameEqual(pNodeName)) \
{ \
/* Check if field already read before. */ \
if(pReadFlag) Throw_MoreThanOnceDefined(pNodeName, "Only one component can be defined."); \
/* Read color component and assign it to object. */ \
pVarName = XML_ReadNode_GetVal_AsU32(); \
pReadFlag = true; \
continue; \
}
#endif // AMFIMPORTER_MACRO_HPP_INCLUDED

View File

@ -65,48 +65,45 @@ namespace Assimp {
// Red, Greed, Blue and Alpha (transparency) component of a color in sRGB space, values ranging from 0 to 1. The // Red, Greed, Blue and Alpha (transparency) component of a color in sRGB space, values ranging from 0 to 1. The
// values can be specified as constants, or as a formula depending on the coordinates. // values can be specified as constants, or as a formula depending on the coordinates.
void AMFImporter::ParseNode_Color(XmlNode &node) { void AMFImporter::ParseNode_Color(XmlNode &node) {
std::string profile = node.attribute("profile").as_string(); if (node.empty()) {
return;
// create new color object. }
AMFNodeElementBase *ne = new AMFColor(mNodeElement_Cur);
AMFColor& als = *((AMFColor*)ne);// alias for convenience
als.Profile = profile; const std::string &profile = node.attribute("profile").as_string();
if (!node.empty()) { bool read_flag[4] = { false, false, false, false };
ParseHelper_Node_Enter(ne); AMFNodeElementBase *ne = new AMFColor(mNodeElement_Cur);
bool read_flag[4] = { false, false, false, false }; AMFColor &als = *((AMFColor *)ne); // alias for convenience
for (pugi::xml_node &child : node.children()) { ParseHelper_Node_Enter(ne);
std::string name = child.name(); for (pugi::xml_node &child : node.children()) {
if ( name == "r") { // create new color object.
read_flag[0] = true; als.Profile = profile;
XmlParser::getValueAsFloat(child, als.Color.r);
} else if (name == "g") { const std::string &name = child.name();
read_flag[1] = true; if ( name == "r") {
XmlParser::getValueAsFloat(child, als.Color.g); read_flag[0] = true;
} else if (name == "b") { XmlParser::getValueAsFloat(child, als.Color.r);
read_flag[2] = true; } else if (name == "g") {
XmlParser::getValueAsFloat(child, als.Color.b); read_flag[1] = true;
} else if (name == "a") { XmlParser::getValueAsFloat(child, als.Color.g);
read_flag[3] = true; } else if (name == "b") {
XmlParser::getValueAsFloat(child, als.Color.a); read_flag[2] = true;
} XmlParser::getValueAsFloat(child, als.Color.b);
ParseHelper_Node_Exit(); } else if (name == "a") {
read_flag[3] = true;
XmlParser::getValueAsFloat(child, als.Color.a);
} }
// check that all components was defined // check if <a> is absent. Then manually add "a == 1".
if (!(read_flag[0] && read_flag[1] && read_flag[2])) { if (!read_flag[3]) {
throw DeadlyImportError("Not all color components are defined."); als.Color.a = 1;
} }
}
// check if <a> is absent. Then manually add "a == 1". als.Composed = false;
if (!read_flag[3]) { mNodeElement_List.push_back(ne); // and to node element list because its a new object in graph.
als.Color.a = 1; ParseHelper_Node_Exit();
} // check that all components was defined
} else { if (!(read_flag[0] && read_flag[1] && read_flag[2])) {
mNodeElement_Cur->Child.push_back(ne);// Add element to child list of current element throw DeadlyImportError("Not all color components are defined.");
} }
als.Composed = false;
mNodeElement_List.push_back(ne);// and to node element list because its a new object in graph.
} }
// <material // <material
@ -158,11 +155,11 @@ void AMFImporter::ParseNode_Material(XmlNode &node) {
// Multi elements - Yes. // Multi elements - Yes.
// Parent element - <amf>. // Parent element - <amf>.
void AMFImporter::ParseNode_Texture(XmlNode &node) { void AMFImporter::ParseNode_Texture(XmlNode &node) {
std::string id = node.attribute("id").as_string(); const std::string id = node.attribute("id").as_string();
uint32_t width = node.attribute("width").as_uint(); const uint32_t width = node.attribute("width").as_uint();
uint32_t height = node.attribute("height").as_uint(); const uint32_t height = node.attribute("height").as_uint();
uint32_t depth = node.attribute("depth").as_uint(); uint32_t depth = node.attribute("depth").as_uint();
std::string type = node.attribute("type").as_string(); const std::string type = node.attribute("type").as_string();
bool tiled = node.attribute("tiled").as_bool(); bool tiled = node.attribute("tiled").as_bool();
if (node.empty()) { if (node.empty()) {
@ -174,22 +171,20 @@ void AMFImporter::ParseNode_Texture(XmlNode &node) {
AMFTexture& als = *((AMFTexture*)ne);// alias for convenience AMFTexture& als = *((AMFTexture*)ne);// alias for convenience
std::string enc64_data = node.value(); std::string enc64_data;
// Check for child nodes XmlParser::getValueAsString(node, enc64_data);
// Check for child nodes
// check that all components was defined // check that all components was defined
if (id.empty()) { if (id.empty()) {
throw DeadlyImportError("ID for texture must be defined."); throw DeadlyImportError("ID for texture must be defined.");
} }
if (width < 1) { if (width < 1) {
throw DeadlyImportError("INvalid width for texture."); throw DeadlyImportError("Invalid width for texture.");
} }
if (height < 1) { if (height < 1) {
throw DeadlyImportError("Invalid height for texture."); throw DeadlyImportError("Invalid height for texture.");
} }
if (depth < 1) {
throw DeadlyImportError("Invalid depth for texture.");
}
if (type != "grayscale") { if (type != "grayscale") {
throw DeadlyImportError("Invalid type for texture."); throw DeadlyImportError("Invalid type for texture.");
} }
@ -203,7 +198,9 @@ void AMFImporter::ParseNode_Texture(XmlNode &node) {
als.Depth = depth; als.Depth = depth;
als.Tiled = tiled; als.Tiled = tiled;
ParseHelper_Decode_Base64(enc64_data, als.Data); ParseHelper_Decode_Base64(enc64_data, als.Data);
if (depth == 0) {
depth = (uint32_t)(als.Data.size() / (width * height));
}
// check data size // check data size
if ((width * height * depth) != als.Data.size()) { if ((width * height * depth) != als.Data.size()) {
throw DeadlyImportError("Texture has incorrect data size."); throw DeadlyImportError("Texture has incorrect data size.");
@ -233,20 +230,18 @@ void AMFImporter::ParseNode_TexMap(XmlNode &node, const bool pUseOldName) {
AMFTexMap &als = *((AMFTexMap *)ne); // AMFTexMap &als = *((AMFTexMap *)ne); //
std::string rtexid, gtexid, btexid, atexid; std::string rtexid, gtexid, btexid, atexid;
if (!node.empty()) { if (!node.empty()) {
ParseHelper_Node_Enter(ne); for (pugi::xml_attribute &attr : node.attributes()) {
for (XmlNode &currentNode : node.children()) { const std::string &currentAttr = attr.name();
const std::string &currentName = currentNode.name(); if (currentAttr == "rtexid") {
if (currentName == "rtexid") { rtexid = attr.as_string();
XmlParser::getValueAsString(node, rtexid); } else if (currentAttr == "gtexid") {
} else if (currentName == "gtexid") { gtexid = attr.as_string();
XmlParser::getValueAsString(node, gtexid); } else if (currentAttr == "btexid") {
} else if (currentName == "btexid") { btexid = attr.as_string();
XmlParser::getValueAsString(node, btexid); } else if (currentAttr == "atexid") {
} else if (currentName == "atexid") { atexid = attr.as_string();
XmlParser::getValueAsString(node, atexid);
} }
} }
ParseHelper_Node_Exit();
} }
// create new texture coordinates object, alias for convenience // create new texture coordinates object, alias for convenience
@ -256,7 +251,6 @@ void AMFImporter::ParseNode_TexMap(XmlNode &node, const bool pUseOldName) {
} }
// Check for children nodes // Check for children nodes
//XML_CheckNode_MustHaveChildren();
if (node.children().begin() == node.children().end()) { if (node.children().begin() == node.children().end()) {
throw DeadlyImportError("Invalid children definition."); throw DeadlyImportError("Invalid children definition.");
} }
@ -264,28 +258,31 @@ void AMFImporter::ParseNode_TexMap(XmlNode &node, const bool pUseOldName) {
bool read_flag[6] = { false, false, false, false, false, false }; bool read_flag[6] = { false, false, false, false, false, false };
if (!pUseOldName) { if (!pUseOldName) {
for (pugi::xml_attribute &attr : node.attributes()) { ParseHelper_Node_Enter(ne);
const std::string name = attr.name(); for ( XmlNode &currentNode : node.children()) {
const std::string &name = currentNode.name();
if (name == "utex1") { if (name == "utex1") {
read_flag[0] = true; read_flag[0] = true;
als.TextureCoordinate[0].x = attr.as_float(); XmlParser::getValueAsFloat(node, als.TextureCoordinate[0].x);
} else if (name == "utex2") { } else if (name == "utex2") {
read_flag[1] = true; read_flag[1] = true;
als.TextureCoordinate[1].x = attr.as_float(); XmlParser::getValueAsFloat(node, als.TextureCoordinate[1].x);
} else if (name == "utex3") { } else if (name == "utex3") {
read_flag[2] = true; read_flag[2] = true;
als.TextureCoordinate[2].x = attr.as_float(); XmlParser::getValueAsFloat(node, als.TextureCoordinate[2].x);
} else if (name == "vtex1") { } else if (name == "vtex1") {
read_flag[3] = true; read_flag[3] = true;
als.TextureCoordinate[0].y = attr.as_float(); XmlParser::getValueAsFloat(node, als.TextureCoordinate[0].y);
} else if (name == "vtex2") { } else if (name == "vtex2") {
read_flag[4] = true; read_flag[4] = true;
als.TextureCoordinate[1].y = attr.as_float(); XmlParser::getValueAsFloat(node, als.TextureCoordinate[1].y);
} else if (name == "vtex3") { } else if (name == "vtex3") {
read_flag[5] = true; read_flag[5] = true;
als.TextureCoordinate[0].y = attr.as_float(); XmlParser::getValueAsFloat(node, als.TextureCoordinate[2].y);
} }
} }
ParseHelper_Node_Exit();
} else { } else {
for (pugi::xml_attribute &attr : node.attributes()) { for (pugi::xml_attribute &attr : node.attributes()) {
const std::string name = attr.name(); const std::string name = attr.name();

View File

@ -62,12 +62,14 @@ aiColor4D AMFImporter::SPP_Material::GetColor(const float /*pX*/, const float /*
// Check if stored data are supported. // Check if stored data are supported.
if (!Composition.empty()) { if (!Composition.empty()) {
throw DeadlyImportError("IME. GetColor for composition"); throw DeadlyImportError("IME. GetColor for composition");
} else if (Color->Composed) {
throw DeadlyImportError("IME. GetColor, composed color");
} else {
tcol = Color->Color;
} }
if (Color->Composed) {
throw DeadlyImportError("IME. GetColor, composed color");
}
tcol = Color->Color;
// Check if default color must be used // Check if default color must be used
if ((tcol.r == 0) && (tcol.g == 0) && (tcol.b == 0) && (tcol.a == 0)) { if ((tcol.r == 0) && (tcol.g == 0) && (tcol.b == 0) && (tcol.a == 0)) {
tcol.r = 0.5f; tcol.r = 0.5f;
@ -79,13 +81,13 @@ aiColor4D AMFImporter::SPP_Material::GetColor(const float /*pX*/, const float /*
return tcol; return tcol;
} }
void AMFImporter::PostprocessHelper_CreateMeshDataArray(const AMFMesh &pNodeElement, std::vector<aiVector3D> &pVertexCoordinateArray, void AMFImporter::PostprocessHelper_CreateMeshDataArray(const AMFMesh &nodeElement, std::vector<aiVector3D> &vertexCoordinateArray,
std::vector<AMFColor *> &pVertexColorArray) const { std::vector<AMFColor *> &pVertexColorArray) const {
AMFVertices *vn = nullptr; AMFVertices *vn = nullptr;
size_t col_idx; size_t col_idx;
// All data stored in "vertices", search for it. // All data stored in "vertices", search for it.
for (AMFNodeElementBase *ne_child : pNodeElement.Child) { for (AMFNodeElementBase *ne_child : nodeElement.Child) {
if (ne_child->Type == AMFNodeElementBase::ENET_Vertices) { if (ne_child->Type == AMFNodeElementBase::ENET_Vertices) {
vn = (AMFVertices*)ne_child; vn = (AMFVertices*)ne_child;
} }
@ -97,7 +99,7 @@ void AMFImporter::PostprocessHelper_CreateMeshDataArray(const AMFMesh &pNodeElem
} }
// all coordinates stored as child and we need to reserve space for future push_back's. // all coordinates stored as child and we need to reserve space for future push_back's.
pVertexCoordinateArray.reserve(vn->Child.size()); vertexCoordinateArray.reserve(vn->Child.size());
// colors count equal vertices count. // colors count equal vertices count.
pVertexColorArray.resize(vn->Child.size()); pVertexColorArray.resize(vn->Child.size());
@ -112,7 +114,7 @@ void AMFImporter::PostprocessHelper_CreateMeshDataArray(const AMFMesh &pNodeElem
for (AMFNodeElementBase *vtx : vn_child->Child) { for (AMFNodeElementBase *vtx : vn_child->Child) {
if (vtx->Type == AMFNodeElementBase::ENET_Coordinates) { if (vtx->Type == AMFNodeElementBase::ENET_Coordinates) {
pVertexCoordinateArray.push_back(((AMFCoordinates *)vtx)->Coordinate); vertexCoordinateArray.push_back(((AMFCoordinates *)vtx)->Coordinate);
continue; continue;
} }

View File

@ -419,7 +419,7 @@ bool OgreImporter::ReadTextureUnit(const std::string &textureUnitName, stringstr
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 = ai_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") {
@ -440,7 +440,7 @@ bool OgreImporter::ReadTextureUnit(const std::string &textureUnitName, stringstr
// 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 = ai_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) {

View File

@ -64,7 +64,7 @@ static inline bool EndsWith(const std::string &s, const std::string &suffix, boo
} }
if (!caseSensitive) { if (!caseSensitive) {
return EndsWith(ai_str_tolower(s), ai_str_tolower(suffix), true); return EndsWith(ai_tolower(s), ai_tolower(suffix), true);
} }
size_t len = suffix.length(); size_t len = suffix.length();

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 = ai_str_tolower(ReadAttribute<std::string>(xmlNode, name)); std::string value = ai_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) {
@ -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 = (ai_str_tolower(ReadAttribute<std::string>(node, "blendmode")) == "cumulative" ? Skeleton::ANIMBLEND_CUMULATIVE : Skeleton::ANIMBLEND_AVERAGE); skeleton->blendMode = (ai_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

@ -278,7 +278,7 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
--ne; --ne;
} while (IsSpace(s.at(ne))); } while (IsSpace(s.at(ne)));
std::string type = s.substr(ns, ne - ns + 1); std::string type = s.substr(ns, ne - ns + 1);
type = ai_str_tolower(type); type = ai_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;

View File

@ -298,7 +298,6 @@ SET(ASSIMP_EXPORTERS_DISABLED "") # disabled exporters list (used to print)
ADD_ASSIMP_IMPORTER( AMF ADD_ASSIMP_IMPORTER( AMF
AssetLib/AMF/AMFImporter.hpp AssetLib/AMF/AMFImporter.hpp
AssetLib/AMF/AMFImporter_Macro.hpp
AssetLib/AMF/AMFImporter_Node.hpp AssetLib/AMF/AMFImporter_Node.hpp
AssetLib/AMF/AMFImporter.cpp AssetLib/AMF/AMFImporter.cpp
AssetLib/AMF/AMFImporter_Geometry.cpp AssetLib/AMF/AMFImporter_Geometry.cpp

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);
ret = ai_str_tolower(ret); ret = ai_tolower(ret);
return ret; return ret;
} }

View File

@ -982,7 +982,7 @@ size_t Importer::GetImporterIndex (const char* szExtension) const {
if (ext.empty()) { if (ext.empty()) {
return static_cast<size_t>(-1); return static_cast<size_t>(-1);
} }
ext = ai_str_tolower(ext); ext = ai_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);
extension = ai_str_tolower(extension); extension = ai_tolower(extension);
if (extension == "jpeg") { if (extension == "jpeg") {
extension = "jpg"; extension = "jpg";
} }

View File

@ -225,7 +225,7 @@ AI_FORCE_INLINE char_t ai_tolower(char_t in) {
/// @param in The incoming string. /// @param in The incoming string.
/// @return The string as lowercase. /// @return The string as lowercase.
// --------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------
AI_FORCE_INLINE std::string ai_str_tolower(const std::string &in) { AI_FORCE_INLINE std::string ai_tolower(const std::string &in) {
std::string out(in); std::string out(in);
ai_trim_left(out); ai_trim_left(out);
ai_trim_right(out); ai_trim_right(out);

View File

@ -105,7 +105,7 @@ void CLogWindow::Init() {
// setup the log text // setup the log text
this->szText = AI_VIEW_RTF_LOG_HEADER; this->szText = AI_VIEW_RTF_LOG_HEADER;
;
this->szPlainText = ""; this->szPlainText = "";
} }