Merge branch 'master' into FlorianBorn71-SmallAllocationFixInFBXLoader

pull/5096/head
Kim Kulling 2023-05-15 14:28:46 +02:00 committed by GitHub
commit aed43878ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
70 changed files with 752 additions and 829 deletions

View File

@ -138,7 +138,7 @@ IF (WIN32)
ELSE()
OPTION( ASSIMP_BUILD_ZLIB
"Build your own zlib"
OFF
ON
)
ENDIF()

View File

@ -397,10 +397,6 @@ struct Material {
Material(const Material &other) = default;
Material(Material &&other) AI_NO_EXCEPT = default;
Material &operator=(Material &&other) AI_NO_EXCEPT = default;
virtual ~Material() = default;
//! Name of the material

View File

@ -266,8 +266,15 @@ void Discreet3DSImporter::ParseMainChunk() {
};
ASSIMP_3DS_END_CHUNK();
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code-return"
#endif
// recursively continue processing this hierarchy level
return ParseMainChunk();
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
}
// ------------------------------------------------------------------------------------------------

View File

@ -68,7 +68,7 @@ using namespace D3DS;
class Discreet3DSImporter : public BaseImporter {
public:
Discreet3DSImporter();
~Discreet3DSImporter();
~Discreet3DSImporter() override;
// -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file.

View File

@ -93,7 +93,7 @@ public:
// empty
}
~EmbeddedTexture() = default;
~EmbeddedTexture() override = default;
ResourceType getType() const override {
return ResourceType::RT_EmbeddedTexture2D;
@ -110,7 +110,7 @@ public:
// empty
}
~Texture2DGroup() = default;
~Texture2DGroup() override = default;
ResourceType getType() const override {
return ResourceType::RT_Texture2DGroup;
@ -127,7 +127,7 @@ public:
// empty
}
~BaseMaterials() = default;
~BaseMaterials() override = default;
ResourceType getType() const override {
return ResourceType::RT_BaseMaterials;
@ -152,7 +152,7 @@ public:
// empty
}
~Object() = default;
~Object() override = default;
ResourceType getType() const override {
return ResourceType::RT_Object;

View File

@ -282,11 +282,11 @@ public:
bool Find_NodeElement(const std::string &pID, const AMFNodeElementBase::EType pType, AMFNodeElementBase **pNodeElement) const;
bool Find_ConvertedNode(const std::string &pID, NodeArray &nodeArray, aiNode **pNode) const;
bool Find_ConvertedMaterial(const std::string &pID, const SPP_Material **pConvertedMaterial) const;
void Throw_CloseNotFound(const std::string &nodeName);
void Throw_IncorrectAttr(const std::string &nodeName, const std::string &pAttrName);
void Throw_IncorrectAttrValue(const std::string &nodeName, const std::string &pAttrName);
void Throw_MoreThanOnceDefined(const std::string &nodeName, const std::string &pNodeType, const std::string &pDescription);
void Throw_ID_NotFound(const std::string &pID) const;
AI_WONT_RETURN void Throw_CloseNotFound(const std::string &nodeName) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void Throw_IncorrectAttr(const std::string &nodeName, const std::string &pAttrName) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void Throw_IncorrectAttrValue(const std::string &nodeName, const std::string &pAttrName) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void Throw_MoreThanOnceDefined(const std::string &nodeName, const std::string &pNodeType, const std::string &pDescription) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void Throw_ID_NotFound(const std::string &pID) const AI_WONT_RETURN_SUFFIX;
void XML_CheckNode_MustHaveChildren(pugi::xml_node &node);
bool XML_SearchNode(const std::string &nodeName);
void ParseHelper_FixTruncatedFloatString(const char *pInStr, std::string &pOutString);

View File

@ -304,7 +304,6 @@ void Parser::Parse() {
}
AI_ASE_HANDLE_TOP_LEVEL_SECTION();
}
return;
}
// ------------------------------------------------------------------------------------------------
@ -734,7 +733,6 @@ void Parser::ParseLV3MapBlock(Texture &map) {
}
AI_ASE_HANDLE_SECTION("3", "*MAP_XXXXXX");
}
return;
}
// ------------------------------------------------------------------------------------------------
@ -859,7 +857,6 @@ void Parser::ParseLV1ObjectBlock(ASE::BaseNode &node) {
}
AI_ASE_HANDLE_TOP_LEVEL_SECTION();
}
return;
}
// ------------------------------------------------------------------------------------------------
@ -883,7 +880,6 @@ void Parser::ParseLV2CameraSettingsBlock(ASE::Camera &camera) {
}
AI_ASE_HANDLE_SECTION("2", "CAMERA_SETTINGS");
}
return;
}
// ------------------------------------------------------------------------------------------------
@ -1189,7 +1185,6 @@ void Parser::ParseLV2NodeTransformBlock(ASE::BaseNode &mesh) {
}
AI_ASE_HANDLE_SECTION("2", "*NODE_TM");
}
return;
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV2MeshBlock(ASE::Mesh &mesh) {
@ -1310,7 +1305,6 @@ void Parser::ParseLV2MeshBlock(ASE::Mesh &mesh) {
}
AI_ASE_HANDLE_SECTION("2", "*MESH");
}
return;
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV3MeshWeightsBlock(ASE::Mesh &mesh) {
@ -1344,7 +1338,6 @@ void Parser::ParseLV3MeshWeightsBlock(ASE::Mesh &mesh) {
}
AI_ASE_HANDLE_SECTION("3", "*MESH_WEIGHTS");
}
return;
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV4MeshBones(unsigned int iNumBones, ASE::Mesh &mesh) {
@ -1414,7 +1407,6 @@ void Parser::ParseLV4MeshBonesVertices(unsigned int iNumVertices, ASE::Mesh &mes
}
AI_ASE_HANDLE_SECTION("4", "*MESH_BONE_VERTEX");
}
return;
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV3MeshVertexListBlock(
@ -1443,7 +1435,6 @@ void Parser::ParseLV3MeshVertexListBlock(
}
AI_ASE_HANDLE_SECTION("3", "*MESH_VERTEX_LIST");
}
return;
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV3MeshFaceListBlock(unsigned int iNumFaces, ASE::Mesh &mesh) {
@ -1470,7 +1461,6 @@ void Parser::ParseLV3MeshFaceListBlock(unsigned int iNumFaces, ASE::Mesh &mesh)
}
AI_ASE_HANDLE_SECTION("3", "*MESH_FACE_LIST");
}
return;
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV3MeshTListBlock(unsigned int iNumVertices,
@ -1503,7 +1493,6 @@ void Parser::ParseLV3MeshTListBlock(unsigned int iNumVertices,
}
AI_ASE_HANDLE_SECTION("3", "*MESH_TVERT_LIST");
}
return;
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV3MeshTFaceListBlock(unsigned int iNumFaces,
@ -1532,7 +1521,6 @@ void Parser::ParseLV3MeshTFaceListBlock(unsigned int iNumFaces,
}
AI_ASE_HANDLE_SECTION("3", "*MESH_TFACE_LIST");
}
return;
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV3MappingChannel(unsigned int iChannel, ASE::Mesh &mesh) {
@ -1567,7 +1555,6 @@ void Parser::ParseLV3MappingChannel(unsigned int iChannel, ASE::Mesh &mesh) {
}
AI_ASE_HANDLE_SECTION("3", "*MESH_MAPPING_CHANNEL");
}
return;
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV3MeshCListBlock(unsigned int iNumVertices, ASE::Mesh &mesh) {
@ -1595,7 +1582,6 @@ void Parser::ParseLV3MeshCListBlock(unsigned int iNumVertices, ASE::Mesh &mesh)
}
AI_ASE_HANDLE_SECTION("3", "*MESH_CVERTEX_LIST");
}
return;
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV3MeshCFaceListBlock(unsigned int iNumFaces, ASE::Mesh &mesh) {
@ -1623,7 +1609,6 @@ void Parser::ParseLV3MeshCFaceListBlock(unsigned int iNumFaces, ASE::Mesh &mesh)
}
AI_ASE_HANDLE_SECTION("3", "*MESH_CFACE_LIST");
}
return;
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh &sMesh) {
@ -1681,7 +1666,6 @@ void Parser::ParseLV3MeshNormalListBlock(ASE::Mesh &sMesh) {
}
AI_ASE_HANDLE_SECTION("3", "*MESH_NORMALS");
}
return;
}
// ------------------------------------------------------------------------------------------------
void Parser::ParseLV4MeshFace(ASE::Face &out) {

View File

@ -7,7 +7,7 @@ For details, see http://sourceforge.net/projects/libb64
#include "cencode.h" // changed from <B64/cencode.h>
const int CHARS_PER_LINE = 72;
static const int CHARS_PER_LINE = 72;
#ifdef _MSC_VER
#pragma warning(push)

View File

@ -96,7 +96,8 @@ struct CustomDataTypeDescription {
* other (like CD_ORCO, ...) uses arrays of rawtypes or even arrays of Structures
* use a special readfunction for that cases
*/
std::array<CustomDataTypeDescription, CD_NUMTYPES> customDataTypeDescriptions = { { DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MVert),
static std::array<CustomDataTypeDescription, CD_NUMTYPES> customDataTypeDescriptions = { {
DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MVert),
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
DECL_UNSUPPORTED_CUSTOMDATATYPEDESCRIPTION,
DECL_STRUCT_CUSTOMDATATYPEDESCRIPTION(MEdge),

View File

@ -1855,7 +1855,6 @@ size_t ColladaParser::ReadPrimitives(XmlNode &node, Mesh &pMesh, std::vector<Inp
default:
// LineStrip is not supported due to expected index unmangling
throw DeadlyImportError("Unsupported primitive type.");
break;
}
// store the face size to later reconstruct the face from

View File

@ -139,6 +139,7 @@ size_t Offset(const char* begin, const char* cursor) {
}
// ------------------------------------------------------------------------------------------------
AI_WONT_RETURN void TokenizeError(const std::string& message, const char* begin, const char* cursor) AI_WONT_RETURN_SUFFIX;
void TokenizeError(const std::string& message, const char* begin, const char* cursor) {
TokenizeError(message, Offset(begin, cursor));
}

View File

@ -138,20 +138,6 @@ Material::Material(uint64_t id, const Element& element, const Document& doc, con
// ------------------------------------------------------------------------------------------------
Material::~Material() = default;
aiVector2D uvTrans;
aiVector2D uvScaling;
ai_real uvRotation;
std::string type;
std::string relativeFileName;
std::string fileName;
std::string alphaSource;
std::shared_ptr<const PropertyTable> props;
unsigned int crop[4]{};
const Video* media;
// ------------------------------------------------------------------------------------------------
Texture::Texture(uint64_t id, const Element& element, const Document& doc, const std::string& name) :
Object(id,element,name),

View File

@ -88,6 +88,7 @@ namespace {
// ------------------------------------------------------------------------------------------------
AI_WONT_RETURN void ParseError(const std::string& message, TokenPtr token) AI_WONT_RETURN_SUFFIX;
void ParseError(const std::string& message, TokenPtr token)
{
if(token) {
@ -210,8 +211,8 @@ Scope::Scope(Parser& parser,bool topLevel)
elements.insert(ElementMap::value_type(str, element));
return;
}
ParseError("unexpected end of file",parser.LastToken());
delete element;
ParseError("unexpected end of file",parser.LastToken());
} else {
elements.insert(ElementMap::value_type(str, element));
}

View File

@ -86,7 +86,7 @@ protected:
// -------------------------------------------------------------------
/** Import a HMP4 file
*/
void InternReadFile_HMP4();
AI_WONT_RETURN void InternReadFile_HMP4() AI_WONT_RETURN_SUFFIX;
// -------------------------------------------------------------------
/** Import a HMP5 file

View File

@ -48,6 +48,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "AssetLib/IFC/IFCUtil.h"
#include "Common/PolyTools.h"
#include "Geometry/GeometryUtils.h"
#include "PostProcessing/ProcessHelper.h"
namespace Assimp {
@ -235,7 +236,7 @@ IfcVector3 TempMesh::ComputeLastPolygonNormal(bool normalize) const {
struct CompareVector {
bool operator () (const IfcVector3& a, const IfcVector3& b) const {
IfcVector3 d = a - b;
IfcFloat eps = ai_epsilon;
constexpr IfcFloat eps = ai_epsilon;
return d.x < -eps || (std::abs(d.x) < eps && d.y < -eps) || (std::abs(d.x) < eps && std::abs(d.y) < eps && d.z < -eps);
}
};

View File

@ -65,7 +65,6 @@ void LWOImporter::LoadLWOBFile()
if (mFileBuffer + head.length > end)
{
throw DeadlyImportError("LWOB: Invalid chunk length");
break;
}
uint8_t* const next = mFileBuffer+head.length;
switch (head.type)

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2022, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -51,6 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "AssetLib/LWO/LWOLoader.h"
#include "PostProcessing/ConvertToLHProcess.h"
#include "PostProcessing/ProcessHelper.h"
#include "Geometry/GeometryUtils.h"
#include <assimp/ByteSwapper.h>
#include <assimp/SGSpatialSort.h>
@ -528,7 +527,6 @@ void LWOImporter::ComputeNormals(aiMesh *mesh, const std::vector<unsigned int> &
continue;
vNormals += v;
}
mesh->mNormals[idx] = vNormals.Normalize();
}
}
}
@ -549,7 +547,6 @@ void LWOImporter::ComputeNormals(aiMesh *mesh, const std::vector<unsigned int> &
const aiVector3D &v = faceNormals[*a];
vNormals += v;
}
vNormals.Normalize();
for (std::vector<unsigned int>::const_iterator a = poResult.begin(); a != poResult.end(); ++a) {
mesh->mNormals[*a] = vNormals;
vertexDone[*a] = true;
@ -557,6 +554,7 @@ void LWOImporter::ComputeNormals(aiMesh *mesh, const std::vector<unsigned int> &
}
}
}
GeometryUtils::normalizeVectorArray(mesh->mNormals, mesh->mNormals, mesh->mNumVertices);
}
// ------------------------------------------------------------------------------------------------
@ -1486,7 +1484,6 @@ void LWOImporter::LoadLWO2File() {
if (mFileBuffer + head.length > end) {
throw DeadlyImportError("LWO2: Chunk length points behind the file");
break;
}
uint8_t *const next = mFileBuffer + head.length;
mFileBuffer += bufOffset;

View File

@ -365,9 +365,7 @@ public:
static void ReportWarning (const char* warn, unsigned int line);
void ReportError (const char* error) {
return ReportError(error, lineNumber);
}
AI_WONT_RETURN void ReportError (const char* error) AI_WONT_RETURN_SUFFIX;
void ReportWarning (const char* warn) {
return ReportWarning(warn, lineNumber);
@ -404,6 +402,9 @@ private:
unsigned int lineNumber;
};
inline void MD5Parser::ReportError(const char* error) {
ReportError(error, lineNumber);
}
// -------------------------------------------------------------------
inline bool MD5Parser::SkipLine(const char* in, const char** out) {
++lineNumber;

View File

@ -139,7 +139,7 @@ protected:
// -------------------------------------------------------------------
/** Import a CS:S/HL2 MDL file (not fully implemented)
*/
void InternReadFile_HL2( );
AI_WONT_RETURN void InternReadFile_HL2( ) AI_WONT_RETURN_SUFFIX;
// -------------------------------------------------------------------
/** Check whether a given position is inside the valid range

View File

@ -46,6 +46,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <iostream>
#include <fstream>
#include <memory>
#include <assimp/types.h>
#include "MMDCpp14.h"
namespace pmx
@ -730,7 +731,7 @@ namespace pmx
std::unique_ptr<PmxAncherRigidBody []> anchers;
int pin_vertex_count;
std::unique_ptr<int []> pin_vertices;
void Read(std::istream *stream, PmxSetting *setting);
AI_WONT_RETURN void Read(std::istream *stream, PmxSetting *setting) AI_WONT_RETURN_SUFFIX;
};
class PmxModel

View File

@ -236,7 +236,7 @@ void ObjFileParser::parseFile(IOStreamBuffer<char> &streamBuffer) {
getNameNoSpace(m_DataIt, m_DataItEnd, name);
insideCstype = name == "cstype";
goto pf_skip_line;
} break;
}
default: {
pf_skip_line:

View File

@ -57,7 +57,7 @@ namespace Assimp {
namespace Ogre {
//AI_WONT_RETURN void ThrowAttibuteError(const XmlParser *reader, const std::string &name, const std::string &error = "") AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void ThrowAttibuteError(const std::string &nodeName, const std::string &name, const std::string &error) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void ThrowAttibuteError(const std::string &nodeName, const std::string &name, const std::string &error) {
if (!error.empty()) {
throw DeadlyImportError(error, " in node '", nodeName, "' and attribute '", name, "'");
@ -128,7 +128,6 @@ bool OgreXmlSerializer::ReadAttribute<bool>(XmlNode &xmlNode, const char *name)
}
ThrowAttibuteError(xmlNode.name(), name, "Boolean value is expected to be 'true' or 'false', encountered '" + value + "'");
return false;
}
// Mesh XML constants

View File

@ -460,14 +460,12 @@ void OpenGEXImporter::handleMetricNode(DDLNode *node, aiScene * /*pScene*/) {
void OpenGEXImporter::handleNameNode(DDLNode *node, aiScene * /*pScene*/) {
if (nullptr == m_currentNode) {
throw DeadlyImportError("No current node for name.");
return;
}
Value *val(node->getValue());
if (nullptr != val) {
if (Value::ValueType::ddl_string != val->m_type) {
throw DeadlyImportError("OpenGEX: invalid data type for value in node name.");
return;
}
const std::string name(val->getString());
@ -508,7 +506,6 @@ static void getRefNames(DDLNode *node, std::vector<std::string> &names) {
void OpenGEXImporter::handleObjectRefNode(DDLNode *node, aiScene * /*pScene*/) {
if (nullptr == m_currentNode) {
throw DeadlyImportError("No parent node for name.");
return;
}
std::vector<std::string> objRefNames;
@ -532,7 +529,6 @@ void OpenGEXImporter::handleObjectRefNode(DDLNode *node, aiScene * /*pScene*/) {
void OpenGEXImporter::handleMaterialRefNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) {
if (nullptr == m_currentNode) {
throw DeadlyImportError("No parent node for name.");
return;
}
std::vector<std::string> matRefNames;
@ -672,14 +668,12 @@ static void setMatrix(aiNode *node, DataArrayList *transformData) {
void OpenGEXImporter::handleTransformNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) {
if (nullptr == m_currentNode) {
throw DeadlyImportError("No parent node for name.");
return;
}
DataArrayList *transformData(node->getDataArrayList());
if (nullptr != transformData) {
if (transformData->m_numItems != 16) {
throw DeadlyImportError("Invalid number of data for transform matrix.");
return;
}
setMatrix(m_currentNode, transformData);
}
@ -835,7 +829,6 @@ static void copyColor4DArray(size_t numItems, DataArrayList *vaList, aiColor4D *
void OpenGEXImporter::handleVertexArrayNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) {
if (nullptr == node) {
throw DeadlyImportError("No parent node for name.");
return;
}
Property *prop = node->getProperties();
@ -876,12 +869,10 @@ void OpenGEXImporter::handleVertexArrayNode(ODDLParser::DDLNode *node, aiScene *
void OpenGEXImporter::handleIndexArrayNode(ODDLParser::DDLNode *node, aiScene * /*pScene*/) {
if (nullptr == node) {
throw DeadlyImportError("No parent node for name.");
return;
}
if (nullptr == m_currentMesh) {
throw DeadlyImportError("No current mesh for index data found.");
return;
}
DataArrayList *vaList = node->getDataArrayList();

View File

@ -382,11 +382,10 @@ void Q3DImporter::InternReadFile(const std::string &pFile,
// TODO
goto outer;
} break;
}
default:
throw DeadlyImportError("Quick3D: Unknown chunk");
break;
};
}
outer:

View File

@ -58,7 +58,7 @@ namespace Assimp {
class RAWImporter : public BaseImporter {
public:
RAWImporter();
~RAWImporter();
~RAWImporter() override;
// -------------------------------------------------------------------
/** Returns whether the class can handle the format of the given file.

View File

@ -85,7 +85,7 @@ static const aiImporterDesc desc = {
struct SIBChunk {
uint32_t Tag;
uint32_t Size;
} PACK_STRUCT;
};
enum {
POS,

View File

@ -56,7 +56,7 @@ namespace Assimp {
class UnrealImporter : public BaseImporter {
public:
UnrealImporter();
~UnrealImporter();
~UnrealImporter() override;
// -------------------------------------------------------------------
/** @brief Returns whether we can handle the format of the given file

View File

@ -839,7 +839,6 @@ void XFileParser::ParseDataObjectAnimationKey(AnimBone *pAnimBone) {
default:
ThrowException("Unknown key type ", keyType, " in animation.");
break;
} // end switch
// key separator

View File

@ -58,8 +58,6 @@ class X3DExporter {
Value(value) {
// empty
}
SAttribute(SAttribute &&rhs) AI_NO_EXCEPT = default;
};
/***********************************************/

View File

@ -55,6 +55,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <string>
namespace Assimp {
AI_WONT_RETURN inline void Throw_ArgOutOfRange(const std::string &argument) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN inline void Throw_CloseNotFound(const std::string &node) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN inline void Throw_ConvertFail_Str2ArrF(const std::string &nodeName, const std::string &pAttrValue) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN inline void Throw_ConvertFail_Str2ArrD(const std::string &nodeName, const std::string &pAttrValue) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN inline void Throw_ConvertFail_Str2ArrB(const std::string &nodeName, const std::string &pAttrValue) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN inline void Throw_ConvertFail_Str2ArrI(const std::string &nodeName, const std::string &pAttrValue) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN inline void Throw_DEF_And_USE(const std::string &nodeName) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN inline void Throw_IncorrectAttr(const std::string &nodeName, const std::string &pAttrName) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN inline void Throw_IncorrectAttrValue(const std::string &nodeName, const std::string &pAttrName) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN inline void Throw_MoreThanOnceDefined(const std::string &nodeName, const std::string &pNodeType, const std::string &pDescription) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN inline void Throw_TagCountIncorrect(const std::string &pNode) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN inline void Throw_USE_NotFound(const std::string &nodeName, const std::string &pAttrValue) AI_WONT_RETURN_SUFFIX;
inline void Throw_ArgOutOfRange(const std::string &argument) {
throw DeadlyImportError("Argument value is out of range for: \"" + argument + "\".");

View File

@ -12,7 +12,6 @@ bool X3DXmlHelper::getColor3DAttribute(XmlNode &node, const char *attributeName,
tokenize<std::string>(val, values, " ");
if (values.size() != 3) {
Throw_ConvertFail_Str2ArrF(node.name(), attributeName);
return false;
}
auto it = values.begin();
color.r = stof(*it++);
@ -30,7 +29,6 @@ bool X3DXmlHelper::getVector2DAttribute(XmlNode &node, const char *attributeName
tokenize<std::string>(val, values, " ");
if (values.size() != 2) {
Throw_ConvertFail_Str2ArrF(node.name(), attributeName);
return false;
}
auto it = values.begin();
color.x = stof(*it++);
@ -47,7 +45,6 @@ bool X3DXmlHelper::getVector3DAttribute(XmlNode &node, const char *attributeName
tokenize<std::string>(val, values, " ");
if (values.size() != 3) {
Throw_ConvertFail_Str2ArrF(node.name(), attributeName);
return false;
}
auto it = values.begin();
color.x = stof(*it++);

View File

@ -483,7 +483,7 @@ private:
public:
Buffer();
~Buffer();
~Buffer() override;
void Read(Value &obj, Asset &r);

View File

@ -1213,7 +1213,6 @@ IF (ASSIMP_WARNINGS_AS_ERRORS)
-Wno-undef
-Wno-suggest-destructor-override
-Wno-suggest-override
-Wno-inconsistent-missing-destructor-override
-Wno-zero-as-null-pointer-constant
-Wno-global-constructors
-Wno-exit-time-destructors
@ -1237,19 +1236,14 @@ IF (ASSIMP_WARNINGS_AS_ERRORS)
-Wno-header-hygiene
-Wno-tautological-value-range-compare
-Wno-tautological-type-limit-compare
-Wno-missing-noreturn
-Wno-missing-variable-declarations
-Wno-extra-semi
-Wno-nonportable-system-include-path
-Wno-undefined-reinterpret-cast
-Wno-shift-sign-overflow
-Wno-deprecated-copy-with-user-provided-dtor
-Wno-deprecated-copy-with-dtor
-Wno-deprecated
-Wno-format-nonliteral
-Wno-comma
-Wno-unreachable-code-break
-Wno-unreachable-code-return
-Wno-implicit-fallthrough
-Wno-unused-template
-Wno-undefined-func-template

View File

@ -1349,6 +1349,9 @@ void SceneCombiner::Copy(aiMetadata **_dest, const aiMetadata *src) {
case AI_AIVECTOR3D:
out.mData = new aiVector3D(*static_cast<aiVector3D *>(in.mData));
break;
case AI_AIMETADATA:
out.mData = new aiMetadata(*static_cast<aiMetadata *>(in.mData));
break;
default:
ai_assert(false);
break;

View File

@ -68,7 +68,7 @@ class ZipFile : public IOStream {
public:
std::string m_Filename;
virtual ~ZipFile();
virtual ~ZipFile() override;
// IOStream interface
size_t Read(void *pvBuffer, size_t pSize, size_t pCount) override;

View File

@ -45,35 +45,59 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp {
// ------------------------------------------------------------------------------------------------
ai_real GeometryUtils::heron( ai_real a, ai_real b, ai_real c ) {
ai_real s = (a + b + c) / 2;
ai_real area = pow((s * ( s - a ) * ( s - b ) * ( s - c ) ), (ai_real)0.5 );
const ai_real s = (a + b + c) / 2;
const ai_real area = pow((s * ( s - a ) * ( s - b ) * ( s - c ) ), (ai_real)0.5 );
return area;
}
ai_real GeometryUtils::distance3D( const aiVector3D &vA, aiVector3D &vB ) {
// ------------------------------------------------------------------------------------------------
ai_real GeometryUtils::distance3D( const aiVector3D &vA, const aiVector3D &vB ) {
const ai_real lx = ( vB.x - vA.x );
const ai_real ly = ( vB.y - vA.y );
const ai_real lz = ( vB.z - vA.z );
ai_real a = lx*lx + ly*ly + lz*lz;
ai_real d = pow( a, (ai_real)0.5 );
const ai_real a = lx*lx + ly*ly + lz*lz;
const ai_real d = pow( a, (ai_real)0.5 );
return d;
}
// ------------------------------------------------------------------------------------------------
ai_real GeometryUtils::calculateAreaOfTriangle( const aiFace& face, aiMesh* mesh ) {
ai_real area = 0;
aiVector3D vA( mesh->mVertices[ face.mIndices[ 0 ] ] );
aiVector3D vB( mesh->mVertices[ face.mIndices[ 1 ] ] );
aiVector3D vC( mesh->mVertices[ face.mIndices[ 2 ] ] );
const aiVector3D vA( mesh->mVertices[ face.mIndices[ 0 ] ] );
const aiVector3D vB( mesh->mVertices[ face.mIndices[ 1 ] ] );
const aiVector3D vC( mesh->mVertices[ face.mIndices[ 2 ] ] );
ai_real a( distance3D( vA, vB ) );
ai_real b( distance3D( vB, vC ) );
ai_real c( distance3D( vC, vA ) );
const ai_real a = distance3D( vA, vB );
const ai_real b = distance3D( vB, vC );
const ai_real c = distance3D( vC, vA );
area = heron( a, b, c );
return area;
}
// ------------------------------------------------------------------------------------------------
// Check whether a ray intersects a plane and find the intersection point
bool GeometryUtils::PlaneIntersect(const aiRay& ray, const aiVector3D& planePos,
const aiVector3D& planeNormal, aiVector3D& pos) {
const ai_real b = planeNormal * (planePos - ray.pos);
ai_real h = ray.dir * planeNormal;
if ((h < 10e-5 && h > -10e-5) || (h = b/h) < 0)
return false;
pos = ray.pos + (ray.dir * h);
return true;
}
// ------------------------------------------------------------------------------------------------
void GeometryUtils::normalizeVectorArray(aiVector3D *vectorArrayIn, aiVector3D *vectorArrayOut,
size_t numVectors) {
for (size_t i=0; i<numVectors; ++i) {
vectorArrayOut[i] = vectorArrayIn[i].Normalize();
}
}
} // namespace Assimp

View File

@ -47,7 +47,7 @@ namespace Assimp {
// ---------------------------------------------------------------------------
/// @brief This helper class supports some basic geometry algorithms.
// ---------------------------------------------------------------------------
class GeometryUtils {
class ASSIMP_API GeometryUtils {
public:
static ai_real heron( ai_real a, ai_real b, ai_real c );
@ -55,13 +55,27 @@ public:
/// @param vA Vector a.
/// @param vB Vector b.
/// @return The distance.
static ai_real distance3D( const aiVector3D &vA, aiVector3D &vB );
static ai_real distance3D( const aiVector3D &vA, const aiVector3D &vB );
/// @brief Will calculate the area of a triangle described by a aiFace.
/// @param face The face
/// @param mesh The mesh containing the face
/// @return The area.
static ai_real calculateAreaOfTriangle( const aiFace& face, aiMesh* mesh );
/// @brief Will calculate the intersection between a ray and a plane
/// @param ray The ray to test for
/// @param planePos A point on the plane
/// @param planeNormal The plane normal to describe its orientation
/// @param pos The position of the intersection.
/// @return true is an intersection was detected, false if not.
static bool PlaneIntersect(const aiRay& ray, const aiVector3D& planePos, const aiVector3D& planeNormal, aiVector3D& pos);
/// @brief Will normalize an array of vectors.
/// @param vectorArrayIn The incoming arra of vectors.
/// @param vectorArrayOut The normalized vectors.
/// @param numVectors The array size.
static void normalizeVectorArray(aiVector3D *vectorArrayIn, aiVector3D *vectorArrayOut, size_t numVectors);
};
} // namespace Assimp

View File

@ -43,15 +43,18 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/DefaultLogger.hpp>
#include <assimp/postprocess.h>
#include <assimp/scene.h>
#include <iostream>
namespace Assimp {
/// The default class constructor.
ArmaturePopulate::ArmaturePopulate() = default;
static bool IsBoneNode(const aiString &bone_name, std::vector<aiBone *> &bones) {
for (aiBone *bone : bones) {
if (bone->mName == bone_name) {
return true;
}
}
/// The class destructor.
ArmaturePopulate::~ArmaturePopulate() = default;
return false;
}
bool ArmaturePopulate::IsActive(unsigned int pFlags) const {
return (pFlags & aiProcess_PopulateArmatureData) != 0;
@ -70,7 +73,7 @@ void ArmaturePopulate::Execute(aiScene *out) {
BuildBoneList(out->mRootNode, out->mRootNode, out, bones);
BuildNodeList(out->mRootNode, nodes);
BuildBoneStack(out->mRootNode, out->mRootNode, out, bones, bone_stack, nodes);
BuildBoneStack(out->mRootNode, out, bones, bone_stack, nodes);
ASSIMP_LOG_DEBUG("Bone stack size: ", bone_stack.size());
@ -78,9 +81,8 @@ void ArmaturePopulate::Execute(aiScene *out) {
aiBone *bone = kvp.first;
aiNode *bone_node = kvp.second;
ASSIMP_LOG_VERBOSE_DEBUG("active node lookup: ", bone->mName.C_Str());
// lcl transform grab - done in generate_nodes :)
// bone->mOffsetMatrix = bone_node->mTransformation;
// lcl transform grab - done in generate_nodes :)
aiNode *armature = GetArmatureRoot(bone_node, bones);
ai_assert(armature);
@ -159,8 +161,7 @@ void ArmaturePopulate::BuildNodeList(const aiNode *current_node,
// A bone stack allows us to have multiple armatures, with the same bone names
// A bone stack allows us also to retrieve bones true transform even with
// duplicate names :)
void ArmaturePopulate::BuildBoneStack(aiNode *,
const aiNode *root_node,
void ArmaturePopulate::BuildBoneStack(const aiNode *root_node,
const aiScene*,
const std::vector<aiBone *> &bones,
std::map<aiBone *, aiNode *> &bone_stack,
@ -196,8 +197,7 @@ void ArmaturePopulate::BuildBoneStack(aiNode *,
// This is required to be detected for a bone initially, it will recurse up
// until it cannot find another bone and return the node No known failure
// points. (yet)
aiNode *ArmaturePopulate::GetArmatureRoot(aiNode *bone_node,
std::vector<aiBone *> &bone_list) {
aiNode *ArmaturePopulate::GetArmatureRoot(aiNode *bone_node, std::vector<aiBone *> &bone_list) {
while (nullptr != bone_node) {
if (!IsBoneNode(bone_node->mName, bone_list)) {
ASSIMP_LOG_VERBOSE_DEBUG("GetArmatureRoot() Found valid armature: ", bone_node->mName.C_Str());
@ -212,18 +212,6 @@ aiNode *ArmaturePopulate::GetArmatureRoot(aiNode *bone_node,
return nullptr;
}
// Simple IsBoneNode check if this could be a bone
bool ArmaturePopulate::IsBoneNode(const aiString &bone_name,
std::vector<aiBone *> &bones) {
for (aiBone *bone : bones) {
if (bone->mName == bone_name) {
return true;
}
}
return false;
}
// Pop this node by name from the stack if found
// Used in multiple armature situations with duplicate node / bone names
// Known flaw: cannot have nodes with bone names, will be fixed in later release

View File

@ -69,10 +69,10 @@ namespace Assimp {
class ASSIMP_API ArmaturePopulate : public BaseProcess {
public:
/// The default class constructor.
ArmaturePopulate();
ArmaturePopulate() = default;
/// The class destructor.
virtual ~ArmaturePopulate();
virtual ~ArmaturePopulate() = default;
/// Overwritten, @see BaseProcess
virtual bool IsActive( unsigned int pFlags ) const;
@ -86,9 +86,6 @@ public:
static aiNode *GetArmatureRoot(aiNode *bone_node,
std::vector<aiBone *> &bone_list);
static bool IsBoneNode(const aiString &bone_name,
std::vector<aiBone *> &bones);
static aiNode *GetNodeFromStack(const aiString &node_name,
std::vector<aiNode *> &nodes);
@ -99,7 +96,7 @@ public:
const aiScene *scene,
std::vector<aiBone *> &bones);
static void BuildBoneStack(aiNode *current_node, const aiNode *root_node,
static void BuildBoneStack(const aiNode *root_node,
const aiScene *scene,
const std::vector<aiBone *> &bones,
std::map<aiBone *, aiNode *> &bone_stack,
@ -108,5 +105,4 @@ public:
} // Namespace Assimp
#endif // SCALE_PROCESS_H_

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2022, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -42,8 +41,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file GenUVCoords step */
#include "ComputeUVMappingProcess.h"
#include "Geometry/GeometryUtils.h"
#include "ProcessHelper.h"
#include <assimp/Exceptional.h>
@ -55,35 +54,21 @@ namespace {
const static aiVector3D base_axis_x(1.0, 0.0, 0.0);
const static aiVector3D base_axis_z(0.0, 0.0, 1.0);
const static ai_real angle_epsilon = ai_real(0.95);
}
} // namespace
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
bool ComputeUVMappingProcess::IsActive( unsigned int pFlags) const
{
bool ComputeUVMappingProcess::IsActive(unsigned int pFlags) const {
return (pFlags & aiProcess_GenUVCoords) != 0;
}
// ------------------------------------------------------------------------------------------------
// Check whether a ray intersects a plane and find the intersection point
inline bool PlaneIntersect(const aiRay& ray, const aiVector3D& planePos,
const aiVector3D& planeNormal, aiVector3D& pos)
{
const ai_real b = planeNormal * (planePos - ray.pos);
ai_real h = ray.dir * planeNormal;
if ((h < 10e-5 && h > -10e-5) || (h = b/h) < 0)
return false;
pos = ray.pos + (ray.dir * h);
return true;
}
// ------------------------------------------------------------------------------------------------
// Find the first empty UV channel in a mesh
inline unsigned int FindEmptyUVChannel (aiMesh* mesh)
{
inline unsigned int FindEmptyUVChannel(aiMesh *mesh) {
for (unsigned int m = 0; m < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++m)
if (!mesh->mTextureCoords[m])return m;
if (!mesh->mTextureCoords[m]) {
return m;
}
ASSIMP_LOG_ERROR("Unable to compute UV coordinates, no free UV slot found");
return UINT_MAX;
@ -91,8 +76,7 @@ inline unsigned int FindEmptyUVChannel (aiMesh* mesh)
// ------------------------------------------------------------------------------------------------
// Try to remove UV seams
void RemoveUVSeams (aiMesh* mesh, aiVector3D* out)
{
void RemoveUVSeams(aiMesh *mesh, aiVector3D *out) {
// TODO: just a very rough algorithm. I think it could be done
// much easier, but I don't know how and am currently too tired to
// to think about a better solution.
@ -103,10 +87,11 @@ void RemoveUVSeams (aiMesh* mesh, aiVector3D* out)
const static ai_real LOWER_EPSILON = ai_real(10e-3);
const static ai_real UPPER_EPSILON = ai_real(1.0 - 10e-3);
for (unsigned int fidx = 0; fidx < mesh->mNumFaces;++fidx)
{
for (unsigned int fidx = 0; fidx < mesh->mNumFaces; ++fidx) {
const aiFace &face = mesh->mFaces[fidx];
if (face.mNumIndices < 3) continue; // triangles and polygons only, please
if (face.mNumIndices < 3) {
continue; // triangles and polygons only, please
}
unsigned int smallV = face.mNumIndices, large = smallV;
bool zero = false, one = false, round_to_zero = false;
@ -115,20 +100,18 @@ void RemoveUVSeams (aiMesh* mesh, aiVector3D* out)
// but the assumption that a face with at least one very small
// on the one side and one very large U coord on the other side
// lies on a UV seam should work for most cases.
for (unsigned int n = 0; n < face.mNumIndices;++n)
{
if (out[face.mIndices[n]].x < LOWER_LIMIT)
{
for (unsigned int n = 0; n < face.mNumIndices; ++n) {
if (out[face.mIndices[n]].x < LOWER_LIMIT) {
smallV = n;
// If we have a U value very close to 0 we can't
// round the others to 0, too.
if (out[face.mIndices[n]].x <= LOWER_EPSILON)
zero = true;
else round_to_zero = true;
else
round_to_zero = true;
}
if (out[face.mIndices[n]].x > UPPER_LIMIT)
{
if (out[face.mIndices[n]].x > UPPER_LIMIT) {
large = n;
// If we have a U value very close to 1 we can't
@ -137,10 +120,8 @@ void RemoveUVSeams (aiMesh* mesh, aiVector3D* out)
one = true;
}
}
if (smallV != face.mNumIndices && large != face.mNumIndices)
{
for (unsigned int n = 0; n < face.mNumIndices;++n)
{
if (smallV != face.mNumIndices && large != face.mNumIndices) {
for (unsigned int n = 0; n < face.mNumIndices; ++n) {
// If the u value is over the upper limit and no other u
// value of that face is 0, round it to 0
if (out[face.mIndices[n]].x > UPPER_LIMIT && !zero)
@ -156,8 +137,7 @@ void RemoveUVSeams (aiMesh* mesh, aiVector3D* out)
// Due to numerical inaccuracies one U coord becomes 0, the
// other 1. But we do still have a third UV coord to determine
// to which side we must round to.
else if (one && zero)
{
else if (one && zero) {
if (round_to_zero && out[face.mIndices[n]].x >= UPPER_EPSILON)
out[face.mIndices[n]].x = 0.0;
else if (!round_to_zero && out[face.mIndices[n]].x <= LOWER_EPSILON)
@ -169,8 +149,7 @@ void RemoveUVSeams (aiMesh* mesh, aiVector3D* out)
}
// ------------------------------------------------------------------------------------------------
void ComputeUVMappingProcess::ComputeSphereMapping(aiMesh* mesh,const aiVector3D& axis, aiVector3D* out)
{
void ComputeUVMappingProcess::ComputeSphereMapping(aiMesh *mesh, const aiVector3D &axis, aiVector3D *out) {
aiVector3D center, min, max;
FindMeshCenter(mesh, center, min, max);
@ -197,16 +176,14 @@ void ComputeUVMappingProcess::ComputeSphereMapping(aiMesh* mesh,const aiVector3D
out[pnt] = aiVector3D((std::atan2(diff.z, diff.y) + AI_MATH_PI_F) / AI_MATH_TWO_PI_F,
(std::asin(diff.x) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.0);
}
}
else if (axis * base_axis_y >= angle_epsilon) {
} else if (axis * base_axis_y >= angle_epsilon) {
// ... just the same again
for (unsigned int pnt = 0; pnt < mesh->mNumVertices; ++pnt) {
const aiVector3D diff = (mesh->mVertices[pnt] - center).Normalize();
out[pnt] = aiVector3D((std::atan2(diff.x, diff.z) + AI_MATH_PI_F) / AI_MATH_TWO_PI_F,
(std::asin(diff.y) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.0);
}
}
else if (axis * base_axis_z >= angle_epsilon) {
} else if (axis * base_axis_z >= angle_epsilon) {
// ... just the same again
for (unsigned int pnt = 0; pnt < mesh->mNumVertices; ++pnt) {
const aiVector3D diff = (mesh->mVertices[pnt] - center).Normalize();
@ -227,7 +204,6 @@ void ComputeUVMappingProcess::ComputeSphereMapping(aiMesh* mesh,const aiVector3D
}
}
// Now find and remove UV seams. A seam occurs if a face has a tcoord
// close to zero on the one side, and a tcoord close to one on the
// other side.
@ -235,8 +211,7 @@ void ComputeUVMappingProcess::ComputeSphereMapping(aiMesh* mesh,const aiVector3D
}
// ------------------------------------------------------------------------------------------------
void ComputeUVMappingProcess::ComputeCylinderMapping(aiMesh* mesh,const aiVector3D& axis, aiVector3D* out)
{
void ComputeUVMappingProcess::ComputeCylinderMapping(aiMesh *mesh, const aiVector3D &axis, aiVector3D *out) {
aiVector3D center, min, max;
// If the axis is one of x,y,z run a faster code path. It's worth the extra effort ...
@ -258,8 +233,7 @@ void ComputeUVMappingProcess::ComputeCylinderMapping(aiMesh* mesh,const aiVector
uv.y = (pos.x - min.x) / diff;
uv.x = (std::atan2(pos.z - center.z, pos.y - center.y) + (ai_real)AI_MATH_PI) / (ai_real)AI_MATH_TWO_PI;
}
}
else if (axis * base_axis_y >= angle_epsilon) {
} else if (axis * base_axis_y >= angle_epsilon) {
FindMeshCenter(mesh, center, min, max);
const ai_real diff = max.y - min.y;
@ -271,8 +245,7 @@ void ComputeUVMappingProcess::ComputeCylinderMapping(aiMesh* mesh,const aiVector
uv.y = (pos.y - min.y) / diff;
uv.x = (std::atan2(pos.x - center.x, pos.z - center.z) + (ai_real)AI_MATH_PI) / (ai_real)AI_MATH_TWO_PI;
}
}
else if (axis * base_axis_z >= angle_epsilon) {
} else if (axis * base_axis_z >= angle_epsilon) {
FindMeshCenter(mesh, center, min, max);
const ai_real diff = max.z - min.z;
@ -309,8 +282,7 @@ void ComputeUVMappingProcess::ComputeCylinderMapping(aiMesh* mesh,const aiVector
}
// ------------------------------------------------------------------------------------------------
void ComputeUVMappingProcess::ComputePlaneMapping(aiMesh* mesh,const aiVector3D& axis, aiVector3D* out)
{
void ComputeUVMappingProcess::ComputePlaneMapping(aiMesh *mesh, const aiVector3D &axis, aiVector3D *out) {
ai_real diffu, diffv;
aiVector3D center, min, max;
@ -327,8 +299,7 @@ void ComputeUVMappingProcess::ComputePlaneMapping(aiMesh* mesh,const aiVector3D&
const aiVector3D &pos = mesh->mVertices[pnt];
out[pnt].Set((pos.z - min.z) / diffu, (pos.y - min.y) / diffv, 0.0);
}
}
else if (axis * base_axis_y >= angle_epsilon) {
} else if (axis * base_axis_y >= angle_epsilon) {
FindMeshCenter(mesh, center, min, max);
diffu = max.x - min.x;
diffv = max.z - min.z;
@ -337,8 +308,7 @@ void ComputeUVMappingProcess::ComputePlaneMapping(aiMesh* mesh,const aiVector3D&
const aiVector3D &pos = mesh->mVertices[pnt];
out[pnt].Set((pos.x - min.x) / diffu, (pos.z - min.z) / diffv, 0.0);
}
}
else if (axis * base_axis_z >= angle_epsilon) {
} else if (axis * base_axis_z >= angle_epsilon) {
FindMeshCenter(mesh, center, min, max);
diffu = max.x - min.x;
diffv = max.y - min.y;
@ -349,8 +319,7 @@ void ComputeUVMappingProcess::ComputePlaneMapping(aiMesh* mesh,const aiVector3D&
}
}
// slower code path in case the mapping axis is not one of the coordinate system axes
else
{
else {
aiMatrix4x4 mTrafo;
aiMatrix4x4::FromToMatrix(axis, base_axis_y, mTrafo);
FindMeshCenterTransformed(mesh, center, min, max, mTrafo);
@ -368,14 +337,12 @@ void ComputeUVMappingProcess::ComputePlaneMapping(aiMesh* mesh,const aiVector3D&
}
// ------------------------------------------------------------------------------------------------
void ComputeUVMappingProcess::ComputeBoxMapping( aiMesh*, aiVector3D* )
{
void ComputeUVMappingProcess::ComputeBoxMapping(aiMesh *, aiVector3D *) {
ASSIMP_LOG_ERROR("Mapping type currently not implemented");
}
// ------------------------------------------------------------------------------------------------
void ComputeUVMappingProcess::Execute( aiScene* pScene)
{
void ComputeUVMappingProcess::Execute(aiScene *pScene) {
ASSIMP_LOG_DEBUG("GenUVCoordsProcess begin");
char buffer[1024];
@ -386,20 +353,15 @@ void ComputeUVMappingProcess::Execute( aiScene* pScene)
/* Iterate through all materials and search for non-UV mapped textures
*/
for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
{
for (unsigned int i = 0; i < pScene->mNumMaterials; ++i) {
mappingStack.clear();
aiMaterial *mat = pScene->mMaterials[i];
for (unsigned int a = 0; a < mat->mNumProperties;++a)
{
for (unsigned int a = 0; a < mat->mNumProperties; ++a) {
aiMaterialProperty *prop = mat->mProperties[a];
if (!::strcmp( prop->mKey.data, "$tex.mapping"))
{
if (!::strcmp(prop->mKey.data, "$tex.mapping")) {
aiTextureMapping &mapping = *((aiTextureMapping *)prop->mData);
if (aiTextureMapping_UV != mapping)
{
if (!DefaultLogger::isNullLogger())
{
if (aiTextureMapping_UV != mapping) {
if (!DefaultLogger::isNullLogger()) {
ai_snprintf(buffer, 1024, "Found non-UV mapped texture (%s,%u). Mapping type: %s",
aiTextureTypeToString((aiTextureType)prop->mSemantic), prop->mIndex,
MappingTypeToString(mapping));
@ -413,8 +375,7 @@ void ComputeUVMappingProcess::Execute( aiScene* pScene)
MappingInfo info(mapping);
// Get further properties - currently only the major axis
for (unsigned int a2 = 0; a2 < mat->mNumProperties;++a2)
{
for (unsigned int a2 = 0; a2 < mat->mNumProperties; ++a2) {
aiMaterialProperty *prop2 = mat->mProperties[a2];
if (prop2->mSemantic != prop->mSemantic || prop2->mIndex != prop->mIndex)
continue;
@ -429,31 +390,25 @@ void ComputeUVMappingProcess::Execute( aiScene* pScene)
// Check whether we have this mapping mode already
std::list<MappingInfo>::iterator it = std::find(mappingStack.begin(), mappingStack.end(), info);
if (mappingStack.end() != it)
{
if (mappingStack.end() != it) {
idx = (*it).uv;
}
else
{
} else {
/* We have found a non-UV mapped texture. Now
* we need to find all meshes using this material
* that we can compute UV channels for them.
*/
for (unsigned int m = 0; m < pScene->mNumMeshes;++m)
{
for (unsigned int m = 0; m < pScene->mNumMeshes; ++m) {
aiMesh *mesh = pScene->mMeshes[m];
unsigned int outIdx = 0;
if (mesh->mMaterialIndex != i || (outIdx = FindEmptyUVChannel(mesh)) == UINT_MAX ||
!mesh->mNumVertices)
{
!mesh->mNumVertices) {
continue;
}
// Allocate output storage
aiVector3D *p = mesh->mTextureCoords[outIdx] = new aiVector3D[mesh->mNumVertices];
switch (mapping)
{
switch (mapping) {
case aiTextureMapping_SPHERE:
ComputeSphereMapping(mesh, info.axis, p);
break;
@ -469,8 +424,7 @@ void ComputeUVMappingProcess::Execute( aiScene* pScene)
default:
ai_assert(false);
}
if (m && idx != outIdx)
{
if (m && idx != outIdx) {
ASSIMP_LOG_WARN("UV index mismatch. Not all meshes assigned to "
"this material have equal numbers of UV channels. The UV index stored in "
"the material structure does therefore not apply for all meshes. ");

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2022, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -225,13 +223,6 @@ void MakeLeftHandedProcess::ProcessAnimation(aiNodeAnim *pAnim) {
// rotation keys
for (unsigned int a = 0; a < pAnim->mNumRotationKeys; a++) {
/* That's the safe version, but the float errors add up. So we try the short version instead
aiMatrix3x3 rotmat = pAnim->mRotationKeys[a].mValue.GetMatrix();
rotmat.a3 = -rotmat.a3; rotmat.b3 = -rotmat.b3;
rotmat.c1 = -rotmat.c1; rotmat.c2 = -rotmat.c2;
aiQuaternion rotquat( rotmat);
pAnim->mRotationKeys[a].mValue = rotquat;
*/
pAnim->mRotationKeys[a].mValue.x *= -1.0f;
pAnim->mRotationKeys[a].mValue.y *= -1.0f;
}
@ -241,7 +232,7 @@ void MakeLeftHandedProcess::ProcessAnimation(aiNodeAnim *pAnim) {
// Converts a single camera to left handed coordinates.
void MakeLeftHandedProcess::ProcessCamera( aiCamera* pCam)
{
pCam->mLookAt = 2.0f * pCam->mPosition - pCam->mLookAt;
pCam->mLookAt = ai_real(2.0f) * pCam->mPosition - pCam->mLookAt;
}
#endif // !! ASSIMP_BUILD_NO_MAKELEFTHANDED_PROCESS

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2022, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -87,7 +86,7 @@ void DeboneProcess::Execute( aiScene* pScene) {
if(!!mNumBonesCanDoWithout && (!mAllOrNone||mNumBonesCanDoWithout==mNumBones)) {
for(unsigned int a = 0; a < pScene->mNumMeshes; a++) {
if(splitList[a]) {
numSplits++;
++numSplits;
}
}
}
@ -119,8 +118,8 @@ void DeboneProcess::Execute( aiScene* pScene) {
aiNode *theNode = find ? pScene->mRootNode->FindNode(*find) : nullptr;
std::pair<unsigned int,aiNode*> push_pair(static_cast<unsigned int>(meshes.size()),theNode);
mSubMeshIndices[a].push_back(push_pair);
meshes.push_back(newMeshes[b].first);
mSubMeshIndices[a].emplace_back(push_pair);
meshes.emplace_back(newMeshes[b].first);
out+=newMeshes[b].first->mNumBones;
}
@ -360,9 +359,7 @@ void DeboneProcess::UpdateNode(aiNode* pNode) const {
unsigned int m = static_cast<unsigned int>(pNode->mNumMeshes), n = static_cast<unsigned int>(mSubMeshIndices.size());
// first pass, look for meshes which have not moved
for(unsigned int a=0;a<m;a++) {
unsigned int srcIndex = pNode->mMeshes[a];
const std::vector< std::pair< unsigned int,aiNode* > > &subMeshes = mSubMeshIndices[srcIndex];
unsigned int nSubmeshes = static_cast<unsigned int>(subMeshes.size());
@ -376,8 +373,7 @@ void DeboneProcess::UpdateNode(aiNode* pNode) const {
// second pass, collect deboned meshes
for(unsigned int a=0;a<n;a++)
{
for(unsigned int a=0;a<n;a++) {
const std::vector< std::pair< unsigned int,aiNode* > > &subMeshes = mSubMeshIndices[a];
unsigned int nSubmeshes = static_cast<unsigned int>(subMeshes.size());

View File

@ -45,12 +45,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* normals for all imported faces.
*/
#include "DropFaceNormalsProcess.h"
#include <assimp/Exceptional.h>
#include <assimp/postprocess.h>
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/Exceptional.h>
using namespace Assimp;

View File

@ -43,9 +43,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Implementation of the FindDegenerates post-process step.
*/
#include "ProcessHelper.h"
#include "FindDegenerates.h"
#include "Geometry/GeometryUtils.h"
#include "ProcessHelper.h"
#include <assimp/Exceptional.h>
@ -199,8 +199,7 @@ bool FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh) {
}
// We need to update the primitive flags array of the mesh.
switch (face.mNumIndices)
{
switch (face.mNumIndices) {
case 1u:
mesh->mPrimitiveTypes |= aiPrimitiveType_POINT;
break;
@ -221,8 +220,7 @@ evil_jump_outside:
// If AI_CONFIG_PP_FD_REMOVE is true, remove degenerated faces from the import
if (mConfigRemoveDegenerates && deg) {
unsigned int n = 0;
for (unsigned int a = 0; a < mesh->mNumFaces; ++a)
{
for (unsigned int a = 0; a < mesh->mNumFaces; ++a) {
aiFace &face_src = mesh->mFaces[a];
if (!remove_me[a]) {
aiFace &face_dest = mesh->mFaces[n++];
@ -236,8 +234,7 @@ evil_jump_outside:
face_src.mNumIndices = 0;
face_src.mIndices = nullptr;
}
}
else {
} else {
// Otherwise delete it if we don't need this face
delete[] face_src.mIndices;
face_src.mIndices = nullptr;

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2022, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -41,9 +39,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
/** @file PretransformVertices.cpp
* @brief Implementation of the "PretransformVertices" post processing step
*/
/// @file PretransformVertices.cpp
/// @brief Implementation of the "PretransformVertices" post processing step
#include "PretransformVertices.h"
#include "ConvertToLHProcess.h"
@ -57,16 +54,44 @@ using namespace Assimp;
#define AI_PTVS_VERTEX 0x0
#define AI_PTVS_FACE 0x1
namespace {
// Get a bitwise combination identifying the vertex format of a mesh
static unsigned int GetMeshVFormat(aiMesh *pcMesh) {
// the vertex format is stored in aiMesh::mBones for later retrieval.
// there isn't a good reason to compute it a few hundred times
// from scratch. The pointer is unused as animations are lost
// during PretransformVertices.
if (pcMesh->mBones)
return (unsigned int)(uint64_t)pcMesh->mBones;
const unsigned int iRet = GetMeshVFormatUnique(pcMesh);
// store the value for later use
pcMesh->mBones = (aiBone **)(uint64_t)iRet;
return iRet;
}
// Get a list of all vertex formats that occur for a given material index
// The output list contains duplicate elements
static void GetVFormatList(const aiScene *pcScene, unsigned int iMat, std::list<unsigned int> &aiOut) {
for (unsigned int i = 0; i < pcScene->mNumMeshes; ++i) {
aiMesh *pcMesh = pcScene->mMeshes[i];
if (iMat == pcMesh->mMaterialIndex) {
aiOut.push_back(GetMeshVFormat(pcMesh));
}
}
}
}
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
PretransformVertices::PretransformVertices() :
configKeepHierarchy(false),
configNormalize(false),
configTransform(false),
configTransformation(),
mConfigPointCloud(false) {
// empty
}
mConfigKeepHierarchy(false),
mConfigNormalize(false),
mConfigTransform(false),
mConfigTransformation(),
mConfigPointCloud(false) {}
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
@ -79,11 +104,11 @@ bool PretransformVertices::IsActive(unsigned int pFlags) const {
void PretransformVertices::SetupProperties(const Importer *pImp) {
// Get the current value of AI_CONFIG_PP_PTV_KEEP_HIERARCHY, AI_CONFIG_PP_PTV_NORMALIZE,
// AI_CONFIG_PP_PTV_ADD_ROOT_TRANSFORMATION and AI_CONFIG_PP_PTV_ROOT_TRANSFORMATION
configKeepHierarchy = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_PTV_KEEP_HIERARCHY, 0));
configNormalize = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_PTV_NORMALIZE, 0));
configTransform = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_PTV_ADD_ROOT_TRANSFORMATION, 0));
mConfigKeepHierarchy = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_PTV_KEEP_HIERARCHY, 0));
mConfigNormalize = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_PTV_NORMALIZE, 0));
mConfigTransform = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_PTV_ADD_ROOT_TRANSFORMATION, 0));
configTransformation = pImp->GetPropertyMatrix(AI_CONFIG_PP_PTV_ROOT_TRANSFORMATION, aiMatrix4x4());
mConfigTransformation = pImp->GetPropertyMatrix(AI_CONFIG_PP_PTV_ROOT_TRANSFORMATION, aiMatrix4x4());
mConfigPointCloud = pImp->GetPropertyBool(AI_CONFIG_EXPORT_POINT_CLOUDS);
}
@ -99,25 +124,7 @@ unsigned int PretransformVertices::CountNodes(const aiNode *pcNode) const {
}
// ------------------------------------------------------------------------------------------------
// Get a bitwise combination identifying the vertex format of a mesh
unsigned int PretransformVertices::GetMeshVFormat(aiMesh *pcMesh) const {
// the vertex format is stored in aiMesh::mBones for later retrieval.
// there isn't a good reason to compute it a few hundred times
// from scratch. The pointer is unused as animations are lost
// during PretransformVertices.
if (pcMesh->mBones)
return (unsigned int)(uint64_t)pcMesh->mBones;
const unsigned int iRet = GetMeshVFormatUnique(pcMesh);
// store the value for later use
pcMesh->mBones = (aiBone **)(uint64_t)iRet;
return iRet;
}
// ------------------------------------------------------------------------------------------------
// Count the number of vertices in the whole scene and a given
// material index
// Count the number of vertices in the whole scene and a given material index
void PretransformVertices::CountVerticesAndFaces(const aiScene *pcScene, const aiNode *pcNode, unsigned int iMat,
unsigned int iVFormat, unsigned int *piFaces, unsigned int *piVertices) const {
for (unsigned int i = 0; i < pcNode->mNumMeshes; ++i) {
@ -128,8 +135,7 @@ void PretransformVertices::CountVerticesAndFaces(const aiScene *pcScene, const a
}
}
for (unsigned int i = 0; i < pcNode->mNumChildren; ++i) {
CountVerticesAndFaces(pcScene, pcNode->mChildren[i], iMat,
iVFormat, piFaces, piVertices);
CountVerticesAndFaces(pcScene, pcNode->mChildren[i], iMat, iVFormat, piFaces, piVertices);
}
}
@ -272,19 +278,6 @@ void PretransformVertices::CollectData(const aiScene *pcScene, const aiNode *pcN
}
}
// ------------------------------------------------------------------------------------------------
// Get a list of all vertex formats that occur for a given material index
// The output list contains duplicate elements
void PretransformVertices::GetVFormatList(const aiScene *pcScene, unsigned int iMat,
std::list<unsigned int> &aiOut) const {
for (unsigned int i = 0; i < pcScene->mNumMeshes; ++i) {
aiMesh *pcMesh = pcScene->mMeshes[i];
if (iMat == pcMesh->mMaterialIndex) {
aiOut.push_back(GetMeshVFormat(pcMesh));
}
}
}
// ------------------------------------------------------------------------------------------------
// Compute the absolute transformation matrices of each node
void PretransformVertices::ComputeAbsoluteTransform(aiNode *pcNode) {
@ -297,11 +290,19 @@ void PretransformVertices::ComputeAbsoluteTransform(aiNode *pcNode) {
}
}
static void normalizeVectorArray(aiVector3D *vectorArrayIn, aiVector3D *vectorArrayOut, size_t numVectors) {
for (size_t i=0; i<numVectors; ++i) {
vectorArrayOut[i] = vectorArrayIn[i].Normalize();
}
}
// ------------------------------------------------------------------------------------------------
// Apply the node transformation to a mesh
void PretransformVertices::ApplyTransform(aiMesh *mesh, const aiMatrix4x4 &mat) const {
// Check whether we need to transform the coordinates at all
if (!mat.IsIdentity()) {
if (mat.IsIdentity()) {
return;
}
// Check for odd negative scale (mirror)
if (mesh->HasFaces() && mat.Determinant() < 0) {
@ -321,9 +322,7 @@ void PretransformVertices::ApplyTransform(aiMesh *mesh, const aiMatrix4x4 &mat)
const aiMatrix3x3 m = aiMatrix3x3(mat).Inverse().Transpose();
if (mesh->HasNormals()) {
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
mesh->mNormals[i] = (m * mesh->mNormals[i]).Normalize();
}
normalizeVectorArray(mesh->mNormals, mesh->mNormals, mesh->mNumVertices);
}
if (mesh->HasTangentsAndBitangents()) {
for (unsigned int i = 0; i < mesh->mNumVertices; ++i) {
@ -333,7 +332,6 @@ void PretransformVertices::ApplyTransform(aiMesh *mesh, const aiMatrix4x4 &mat)
}
}
}
}
// ------------------------------------------------------------------------------------------------
// Simple routine to build meshes in worldspace, no further optimization
@ -352,7 +350,8 @@ void PretransformVertices::BuildWCSMeshes(std::vector<aiMesh *> &out, aiMesh **i
// yes, we can.
mesh->mBones = reinterpret_cast<aiBone **>(&node->mTransformation);
mesh->mNumBones = UINT_MAX;
} else {
continue;
}
// try to find us in the list of newly created meshes
for (unsigned int n = 0; n < out.size(); ++n) {
@ -368,10 +367,10 @@ void PretransformVertices::BuildWCSMeshes(std::vector<aiMesh *> &out, aiMesh **i
ASSIMP_LOG_INFO("PretransformVertices: Copying mesh due to mismatching transforms");
aiMesh *ntz;
const unsigned int tmp = mesh->mNumBones; //
const unsigned int cacheNumBones = mesh->mNumBones; //
mesh->mNumBones = 0;
SceneCombiner::Copy(&ntz, mesh);
mesh->mNumBones = tmp;
mesh->mNumBones = cacheNumBones;
ntz->mNumBones = node->mMeshes[i];
ntz->mBones = reinterpret_cast<aiBone **>(&node->mTransformation);
@ -381,12 +380,12 @@ void PretransformVertices::BuildWCSMeshes(std::vector<aiMesh *> &out, aiMesh **i
node->mMeshes[i] = static_cast<unsigned int>(numIn + out.size() - 1);
}
}
}
// call children
for (unsigned int i = 0; i < node->mNumChildren; ++i)
for (unsigned int i = 0; i < node->mNumChildren; ++i) {
BuildWCSMeshes(out, in, numIn, node->mChildren[i]);
}
}
// ------------------------------------------------------------------------------------------------
// Reset transformation matrices to identity
@ -394,9 +393,10 @@ void PretransformVertices::MakeIdentityTransform(aiNode *nd) const {
nd->mTransformation = aiMatrix4x4();
// call children
for (unsigned int i = 0; i < nd->mNumChildren; ++i)
for (unsigned int i = 0; i < nd->mNumChildren; ++i) {
MakeIdentityTransform(nd->mChildren[i]);
}
}
// ------------------------------------------------------------------------------------------------
// Build reference counters for all meshes
@ -405,9 +405,28 @@ void PretransformVertices::BuildMeshRefCountArray(const aiNode *nd, unsigned int
refs[nd->mMeshes[i]]++;
// call children
for (unsigned int i = 0; i < nd->mNumChildren; ++i)
for (unsigned int i = 0; i < nd->mNumChildren; ++i) {
BuildMeshRefCountArray(nd->mChildren[i], refs);
}
}
// ------------------------------------------------------------------------------------------------
static void appendNewMeshesToScene(aiScene *pScene, std::vector<aiMesh*> &apcOutMeshes) {
ai_assert(pScene != nullptr);
if (apcOutMeshes.empty()) {
return;
}
aiMesh **npp = new aiMesh *[pScene->mNumMeshes + apcOutMeshes.size()];
::memcpy(npp, pScene->mMeshes, sizeof(aiMesh *) * pScene->mNumMeshes);
::memcpy(npp + pScene->mNumMeshes, &apcOutMeshes[0], sizeof(aiMesh *) * apcOutMeshes.size());
pScene->mNumMeshes += static_cast<unsigned int>(apcOutMeshes.size());
delete[] pScene->mMeshes;
pScene->mMeshes = npp;
}
// ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data.
@ -418,12 +437,12 @@ void PretransformVertices::Execute(aiScene *pScene) {
if (!pScene->mNumMeshes)
return;
const unsigned int iOldMeshes = pScene->mNumMeshes;
const unsigned int iOldAnimationChannels = pScene->mNumAnimations;
const unsigned int iOldNodes = CountNodes(pScene->mRootNode);
const unsigned int oldMeshes = pScene->mNumMeshes;
const unsigned int oldAnimationChannels = pScene->mNumAnimations;
const unsigned int oldNodes = CountNodes(pScene->mRootNode);
if (configTransform) {
pScene->mRootNode->mTransformation = configTransformation * pScene->mRootNode->mTransformation;
if (mConfigTransform) {
pScene->mRootNode->mTransformation = mConfigTransformation * pScene->mRootNode->mTransformation;
}
// first compute absolute transformation matrices for all nodes
@ -449,22 +468,13 @@ void PretransformVertices::Execute(aiScene *pScene) {
// we go on and transform all meshes, if one is referenced by nodes
// with different absolute transformations a depth copy of the mesh
// is required.
if (configKeepHierarchy) {
if (mConfigKeepHierarchy) {
// Hack: store the matrix we're transforming a mesh with in aiMesh::mBones
BuildWCSMeshes(apcOutMeshes, pScene->mMeshes, pScene->mNumMeshes, pScene->mRootNode);
// ... if new meshes have been generated, append them to the end of the scene
if (apcOutMeshes.size() > 0) {
aiMesh **npp = new aiMesh *[pScene->mNumMeshes + apcOutMeshes.size()];
memcpy(npp, pScene->mMeshes, sizeof(aiMesh *) * pScene->mNumMeshes);
memcpy(npp + pScene->mNumMeshes, &apcOutMeshes[0], sizeof(aiMesh *) * apcOutMeshes.size());
pScene->mNumMeshes += static_cast<unsigned int>(apcOutMeshes.size());
delete[] pScene->mMeshes;
pScene->mMeshes = npp;
}
appendNewMeshesToScene(pScene, apcOutMeshes);
// now iterate through all meshes and transform them to world-space
for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
@ -488,34 +498,35 @@ void PretransformVertices::Execute(aiScene *pScene) {
aiVFormats.sort();
aiVFormats.unique();
for (std::list<unsigned int>::const_iterator j = aiVFormats.begin(); j != aiVFormats.end(); ++j) {
unsigned int iVertices = 0;
unsigned int iFaces = 0;
CountVerticesAndFaces(pScene, pScene->mRootNode, i, *j, &iFaces, &iVertices);
if (0 != iFaces && 0 != iVertices) {
unsigned int numVertices = 0u;
unsigned int numFaces = 0u;
CountVerticesAndFaces(pScene, pScene->mRootNode, i, *j, &numFaces, &numVertices);
if (0 != numFaces && 0 != numVertices) {
apcOutMeshes.push_back(new aiMesh());
aiMesh *pcMesh = apcOutMeshes.back();
pcMesh->mNumFaces = iFaces;
pcMesh->mNumVertices = iVertices;
pcMesh->mFaces = new aiFace[iFaces];
pcMesh->mVertices = new aiVector3D[iVertices];
pcMesh->mNumFaces = numFaces;
pcMesh->mNumVertices = numVertices;
pcMesh->mFaces = new aiFace[numFaces];
pcMesh->mVertices = new aiVector3D[numVertices];
pcMesh->mMaterialIndex = i;
if ((*j) & 0x2) pcMesh->mNormals = new aiVector3D[iVertices];
if ((*j) & 0x2) pcMesh->mNormals = new aiVector3D[numVertices];
if ((*j) & 0x4) {
pcMesh->mTangents = new aiVector3D[iVertices];
pcMesh->mBitangents = new aiVector3D[iVertices];
pcMesh->mTangents = new aiVector3D[numVertices];
pcMesh->mBitangents = new aiVector3D[numVertices];
}
iFaces = 0;
while ((*j) & (0x100 << iFaces)) {
pcMesh->mTextureCoords[iFaces] = new aiVector3D[iVertices];
if ((*j) & (0x10000 << iFaces))
pcMesh->mNumUVComponents[iFaces] = 3;
else
pcMesh->mNumUVComponents[iFaces] = 2;
iFaces++;
numFaces = 0;
while ((*j) & (0x100 << numFaces)) {
pcMesh->mTextureCoords[numFaces] = new aiVector3D[numVertices];
if ((*j) & (0x10000 << numFaces)) {
pcMesh->mNumUVComponents[numFaces] = 3;
} else {
pcMesh->mNumUVComponents[numFaces] = 2;
}
iFaces = 0;
while ((*j) & (0x1000000 << iFaces))
pcMesh->mColors[iFaces++] = new aiColor4D[iVertices];
++numFaces;
}
numFaces = 0;
while ((*j) & (0x1000000 << numFaces))
pcMesh->mColors[numFaces++] = new aiColor4D[numVertices];
// fill the mesh ...
unsigned int aiTemp[2] = { 0, 0 };
@ -593,7 +604,7 @@ void PretransformVertices::Execute(aiScene *pScene) {
l->mUp = aiMatrix3x3(nd->mTransformation) * l->mUp;
}
if (!configKeepHierarchy) {
if (!mConfigKeepHierarchy) {
// now delete all nodes in the scene and build a new
// flat node graph with a root node and some level 1 children
@ -644,7 +655,7 @@ void PretransformVertices::Execute(aiScene *pScene) {
MakeIdentityTransform(pScene->mRootNode);
}
if (configNormalize) {
if (mConfigNormalize) {
// compute the boundary of all meshes
aiVector3D min, max;
MinMaxChooser<aiVector3D>()(min, max);
@ -674,9 +685,9 @@ void PretransformVertices::Execute(aiScene *pScene) {
if (!DefaultLogger::isNullLogger()) {
ASSIMP_LOG_DEBUG("PretransformVerticesProcess finished");
ASSIMP_LOG_INFO("Removed ", iOldNodes, " nodes and ", iOldAnimationChannels, " animation channels (",
ASSIMP_LOG_INFO("Removed ", oldNodes, " nodes and ", oldAnimationChannels, " animation channels (",
CountNodes(pScene->mRootNode), " output nodes)");
ASSIMP_LOG_INFO("Kept ", pScene->mNumLights, " lights and ", pScene->mNumCameras, " cameras.");
ASSIMP_LOG_INFO("Moved ", iOldMeshes, " meshes to WCS (number of output meshes: ", pScene->mNumMeshes, ")");
ASSIMP_LOG_INFO("Moved ", oldMeshes, " meshes to WCS (number of output meshes: ", pScene->mNumMeshes, ")");
}
}

View File

@ -90,7 +90,7 @@ public:
* @param keep true for keep configuration.
*/
void KeepHierarchy(bool keep) {
configKeepHierarchy = keep;
mConfigKeepHierarchy = keep;
}
// -------------------------------------------------------------------
@ -98,7 +98,7 @@ public:
* @return ...
*/
bool IsHierarchyKept() const {
return configKeepHierarchy;
return mConfigKeepHierarchy;
}
private:
@ -108,7 +108,7 @@ private:
// -------------------------------------------------------------------
// Get a bitwise combination identifying the vertex format of a mesh
unsigned int GetMeshVFormat(aiMesh *pcMesh) const;
//unsigned int GetMeshVFormat(aiMesh *pcMesh) const;
// -------------------------------------------------------------------
// Count the number of vertices in the whole scene and a given
@ -131,8 +131,8 @@ private:
// -------------------------------------------------------------------
// Get a list of all vertex formats that occur for a given material
// The output list contains duplicate elements
void GetVFormatList(const aiScene *pcScene, unsigned int iMat,
std::list<unsigned int> &aiOut) const;
/*void GetVFormatList(const aiScene *pcScene, unsigned int iMat,
std::list<unsigned int> &aiOut) const;*/
// -------------------------------------------------------------------
// Compute the absolute transformation matrices of each node
@ -156,10 +156,10 @@ private:
void BuildMeshRefCountArray(const aiNode *nd, unsigned int *refs) const;
//! Configuration option: keep scene hierarchy as long as possible
bool configKeepHierarchy;
bool configNormalize;
bool configTransform;
aiMatrix4x4 configTransformation;
bool mConfigKeepHierarchy;
bool mConfigNormalize;
bool mConfigTransform;
aiMatrix4x4 mConfigTransformation;
bool mConfigPointCloud;
};

View File

@ -175,10 +175,9 @@ unsigned int GetMeshVFormatUnique(const aiMesh *pcMesh) {
// tangents and bitangents
if (pcMesh->HasTangentsAndBitangents()) iRet |= 0x4;
#ifdef BOOST_STATIC_ASSERT
BOOST_STATIC_ASSERT(8 >= AI_MAX_NUMBER_OF_COLOR_SETS);
BOOST_STATIC_ASSERT(8 >= AI_MAX_NUMBER_OF_TEXTURECOORDS);
#endif
static_assert(8 >= AI_MAX_NUMBER_OF_COLOR_SETS);
static_assert(8 >= AI_MAX_NUMBER_OF_TEXTURECOORDS);
// texture coordinates
unsigned int p = 0;

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2022, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -45,7 +43,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
// internal headers
#include "RemoveRedundantMaterials.h"
#include <assimp/ParsingUtils.h>
#include "ProcessHelper.h"
@ -57,35 +54,28 @@ using namespace Assimp;
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
RemoveRedundantMatsProcess::RemoveRedundantMatsProcess()
: mConfigFixedMaterials() {
// nothing to do here
}
RemoveRedundantMatsProcess::RemoveRedundantMatsProcess() : mConfigFixedMaterials() {}
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
bool RemoveRedundantMatsProcess::IsActive( unsigned int pFlags) const
{
bool RemoveRedundantMatsProcess::IsActive( unsigned int pFlags) const {
return (pFlags & aiProcess_RemoveRedundantMaterials) != 0;
}
// ------------------------------------------------------------------------------------------------
// Setup import properties
void RemoveRedundantMatsProcess::SetupProperties(const Importer* pImp)
{
void RemoveRedundantMatsProcess::SetupProperties(const Importer* pImp) {
// Get value of AI_CONFIG_PP_RRM_EXCLUDE_LIST
mConfigFixedMaterials = pImp->GetPropertyString(AI_CONFIG_PP_RRM_EXCLUDE_LIST,"");
}
// ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data.
void RemoveRedundantMatsProcess::Execute( aiScene* pScene)
{
void RemoveRedundantMatsProcess::Execute( aiScene* pScene) {
ASSIMP_LOG_DEBUG("RemoveRedundantMatsProcess begin");
unsigned int redundantRemoved = 0, unreferencedRemoved = 0;
if (pScene->mNumMaterials)
{
if (pScene->mNumMaterials) {
// Find out which materials are referenced by meshes
std::vector<bool> abReferenced(pScene->mNumMaterials,false);
for (unsigned int i = 0;i < pScene->mNumMeshes;++i)
@ -134,8 +124,7 @@ void RemoveRedundantMatsProcess::Execute( aiScene* pScene)
// we do already have a specific hash. This allows us to
// determine which materials are identical.
uint32_t *aiHashes = new uint32_t[ pScene->mNumMaterials ];;
for (unsigned int i = 0; i < pScene->mNumMaterials;++i)
{
for (unsigned int i = 0; i < pScene->mNumMaterials;++i) {
// No mesh is referencing this material, remove it.
if (!abReferenced[i]) {
++unreferencedRemoved;
@ -147,8 +136,7 @@ void RemoveRedundantMatsProcess::Execute( aiScene* pScene)
// Check all previously mapped materials for a matching hash.
// On a match we can delete this material and just make it ref to the same index.
uint32_t me = aiHashes[i] = ComputeMaterialHash(pScene->mMaterials[i]);
for (unsigned int a = 0; a < i;++a)
{
for (unsigned int a = 0; a < i;++a) {
if (abReferenced[a] && me == aiHashes[a]) {
++redundantRemoved;
me = 0;
@ -205,12 +193,9 @@ void RemoveRedundantMatsProcess::Execute( aiScene* pScene)
delete[] aiHashes;
delete[] aiMappingTable;
}
if (redundantRemoved == 0 && unreferencedRemoved == 0)
{
if (redundantRemoved == 0 && unreferencedRemoved == 0) {
ASSIMP_LOG_DEBUG("RemoveRedundantMatsProcess finished ");
}
else
{
} else {
ASSIMP_LOG_INFO("RemoveRedundantMatsProcess finished. Removed ", redundantRemoved, " redundant and ",
unreferencedRemoved, " unused materials.");
}

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2022, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -74,63 +72,6 @@ inline void ArrayDelete(T **&in, unsigned int &num) {
num = 0;
}
#if 0
// ------------------------------------------------------------------------------------------------
// Updates the node graph - removes all nodes which have the "remove" flag set and the
// "don't remove" flag not set. Nodes with meshes are never deleted.
bool UpdateNodeGraph(aiNode* node,std::list<aiNode*>& childsOfParent,bool root)
{
bool b = false;
std::list<aiNode*> mine;
for (unsigned int i = 0; i < node->mNumChildren;++i)
{
if(UpdateNodeGraph(node->mChildren[i],mine,false))
b = true;
}
// somewhat tricky ... mNumMeshes must be originally 0 and MSB2 may not be set,
// so we can do a simple comparison against MSB here
if (!root && AI_RC_UINT_MSB == node->mNumMeshes )
{
// this node needs to be removed
if(node->mNumChildren)
{
childsOfParent.insert(childsOfParent.end(),mine.begin(),mine.end());
// set all children to nullptr to make sure they are not deleted when we delete ourself
for (unsigned int i = 0; i < node->mNumChildren;++i)
node->mChildren[i] = nullptr;
}
b = true;
delete node;
}
else
{
AI_RC_UNMASK(node->mNumMeshes);
childsOfParent.push_back(node);
if (b)
{
// reallocate the array of our children here
node->mNumChildren = (unsigned int)mine.size();
aiNode** const children = new aiNode*[mine.size()];
aiNode** ptr = children;
for (std::list<aiNode*>::iterator it = mine.begin(), end = mine.end();
it != end; ++it)
{
*ptr++ = *it;
}
delete[] node->mChildren;
node->mChildren = children;
return false;
}
}
return b;
}
#endif
// ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data.
void RemoveVCProcess::Execute(aiScene *pScene) {

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2022, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -140,7 +139,7 @@ void ScaleProcess::Execute( aiScene* pScene ) {
aiMatrix4x4 scaling;
aiMatrix4x4::Scaling( aiVector3D(scale), scaling );
aiMatrix4x4 RotMatrix = aiMatrix4x4 (rotation.GetMatrix());
const aiMatrix4x4 RotMatrix = aiMatrix4x4(rotation.GetMatrix());
bone->mOffsetMatrix = translation * RotMatrix * scaling;
}

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2022, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -54,10 +52,7 @@ using namespace Assimp;
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
SortByPTypeProcess::SortByPTypeProcess() :
mConfigRemoveMeshes(0) {
// empty
}
SortByPTypeProcess::SortByPTypeProcess() : mConfigRemoveMeshes(0) {}
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
@ -104,9 +99,10 @@ void UpdateNodes(const std::vector<unsigned int> &replaceMeshIndex, aiNode *node
}
// call all subnodes recursively
for (unsigned int m = 0; m < node->mNumChildren; ++m)
for (unsigned int m = 0; m < node->mNumChildren; ++m) {
UpdateNodes(replaceMeshIndex, node->mChildren[m]);
}
}
// ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data.
@ -155,7 +151,7 @@ void SortByPTypeProcess::Execute(aiScene *pScene) {
if (1 == num) {
if (!(mConfigRemoveMeshes & mesh->mPrimitiveTypes)) {
*meshIdx = static_cast<unsigned int>(outMeshes.size());
outMeshes.push_back(mesh);
outMeshes.emplace_back(mesh);
} else {
delete mesh;
pScene->mMeshes[i] = nullptr;
@ -311,21 +307,23 @@ void SortByPTypeProcess::Execute(aiScene *pScene) {
if (vert) {
*vert++ = mesh->mVertices[idx];
//mesh->mVertices[idx].x = get_qnan();
}
if (nor) *nor++ = mesh->mNormals[idx];
if (nor)
*nor++ = mesh->mNormals[idx];
if (tan) {
*tan++ = mesh->mTangents[idx];
*bit++ = mesh->mBitangents[idx];
}
for (unsigned int pp = 0; pp < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++pp) {
if (!uv[pp]) break;
if (!uv[pp])
break;
*uv[pp]++ = mesh->mTextureCoords[pp][idx];
}
for (unsigned int pp = 0; pp < AI_MAX_NUMBER_OF_COLOR_SETS; ++pp) {
if (!cols[pp]) break;
if (!cols[pp])
break;
*cols[pp]++ = mesh->mColors[pp][idx];
}
@ -351,7 +349,7 @@ void SortByPTypeProcess::Execute(aiScene *pScene) {
}
}
if (pp == mesh->mNumAnimMeshes)
amIdx++;
++amIdx;
in.mIndices[q] = outIdx++;
}

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2022, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -58,9 +57,7 @@ using namespace Assimp::Formatter;
// ------------------------------------------------------------------------------------------------
// Constructor
SplitByBoneCountProcess::SplitByBoneCountProcess() : mMaxBoneCount(AI_SBBC_DEFAULT_MAX_BONES) {
// empty
}
SplitByBoneCountProcess::SplitByBoneCountProcess() : mMaxBoneCount(AI_SBBC_DEFAULT_MAX_BONES) {}
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag.
@ -166,7 +163,7 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
unsigned int numBones = 0;
std::vector<bool> isBoneUsed( pMesh->mNumBones, false);
// indices of the faces which are going to go into this submesh
std::vector<unsigned int> subMeshFaces;
IndexArray subMeshFaces;
subMeshFaces.reserve( pMesh->mNumFaces);
// accumulated vertex count of all the faces in this submesh
unsigned int numSubMeshVertices = 0;
@ -202,7 +199,7 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
for (std::set<unsigned int>::iterator it = newBonesAtCurrentFace.begin(); it != newBonesAtCurrentFace.end(); ++it) {
if (!isBoneUsed[*it]) {
isBoneUsed[*it] = true;
numBones++;
++numBones;
}
}
@ -212,18 +209,17 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
// remember that this face is handled
isFaceHandled[a] = true;
numFacesHandled++;
++numFacesHandled;
}
// create a new mesh to hold this subset of the source mesh
aiMesh* newMesh = new aiMesh;
if( pMesh->mName.length > 0 )
{
if( pMesh->mName.length > 0 ) {
newMesh->mName.Set( format() << pMesh->mName.data << "_sub" << poNewMeshes.size());
}
newMesh->mMaterialIndex = pMesh->mMaterialIndex;
newMesh->mPrimitiveTypes = pMesh->mPrimitiveTypes;
poNewMeshes.push_back( newMesh);
poNewMeshes.emplace_back( newMesh);
// create all the arrays for this mesh if the old mesh contained them
newMesh->mNumVertices = numSubMeshVertices;
@ -251,7 +247,7 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
// and copy over the data, generating faces with linear indices along the way
newMesh->mFaces = new aiFace[subMeshFaces.size()];
unsigned int nvi = 0; // next vertex index
std::vector<unsigned int> previousVertexIndices( numSubMeshVertices, std::numeric_limits<unsigned int>::max()); // per new vertex: its index in the source mesh
IndexArray previousVertexIndices( numSubMeshVertices, std::numeric_limits<unsigned int>::max()); // per new vertex: its index in the source mesh
for( unsigned int a = 0; a < subMeshFaces.size(); ++a ) {
const aiFace& srcFace = pMesh->mFaces[subMeshFaces[a]];
aiFace& dstFace = newMesh->mFaces[a];
@ -399,10 +395,10 @@ void SplitByBoneCountProcess::SplitMesh( const aiMesh* pMesh, std::vector<aiMesh
void SplitByBoneCountProcess::UpdateNode( aiNode* pNode) const {
// rebuild the node's mesh index list
if( pNode->mNumMeshes == 0 ) {
std::vector<unsigned int> newMeshList;
IndexArray newMeshList;
for( unsigned int a = 0; a < pNode->mNumMeshes; ++a) {
unsigned int srcIndex = pNode->mMeshes[a];
const std::vector<unsigned int>& replaceMeshes = mSubMeshIndices[srcIndex];
const IndexArray& replaceMeshes = mSubMeshIndices[srcIndex];
newMeshList.insert( newMeshList.end(), replaceMeshes.begin(), replaceMeshes.end());
}

View File

@ -76,6 +76,10 @@ public:
/// basing on the Importer's configuration property list.
virtual void SetupProperties(const Importer* pImp) override;
/// @brief Will return the maximal number of bones.
/// @return The maximal number of bones.
size_t getMaxNumberOfBones() const;
protected:
/// Executes the post processing step on the given imported data.
/// At the moment a process is not supposed to fail.
@ -90,14 +94,19 @@ protected:
/// Recursively updates the node's mesh list to account for the changed mesh list
void UpdateNode( aiNode* pNode) const;
public:
private:
/// Max bone count. Splitting occurs if a mesh has more than that number of bones.
size_t mMaxBoneCount;
/// Per mesh index: Array of indices of the new submeshes.
std::vector< std::vector<unsigned int> > mSubMeshIndices;
using IndexArray = std::vector<unsigned int>;
std::vector<IndexArray> mSubMeshIndices;
};
inline size_t SplitByBoneCountProcess::getMaxNumberOfBones() const {
return mMaxBoneCount;
}
} // end of namespace Assimp
#endif // !!AI_SPLITBYBONECOUNTPROCESS_H_INC

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2022, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -40,9 +39,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
----------------------------------------------------------------------
*/
/**
* @file Implementation of the SplitLargeMeshes postprocessing step
*/
/// @file Implementation of the SplitLargeMeshes postprocessing step
// internal headers of the post-processing framework
#include "SplitLargeMeshes.h"
@ -75,7 +72,10 @@ void SplitLargeMeshesProcess_Triangle::Execute( aiScene* pScene) {
this->SplitMesh(a, pScene->mMeshes[a],avList);
}
if (avList.size() != pScene->mNumMeshes) {
if (avList.size() == pScene->mNumMeshes) {
ASSIMP_LOG_DEBUG("SplitLargeMeshesProcess_Triangle finished. There was nothing to do");
}
// it seems something has been split. rebuild the mesh list
delete[] pScene->mMeshes;
pScene->mNumMeshes = (unsigned int)avList.size();
@ -88,9 +88,6 @@ void SplitLargeMeshesProcess_Triangle::Execute( aiScene* pScene) {
// now we need to update all nodes
this->UpdateNode(pScene->mRootNode,avList);
ASSIMP_LOG_INFO("SplitLargeMeshesProcess_Triangle finished. Meshes have been split");
} else {
ASSIMP_LOG_DEBUG("SplitLargeMeshesProcess_Triangle finished. There was nothing to do");
}
}
// ------------------------------------------------------------------------------------------------
@ -102,8 +99,7 @@ void SplitLargeMeshesProcess_Triangle::SetupProperties( const Importer* pImp) {
// ------------------------------------------------------------------------------------------------
// Update a node after some meshes have been split
void SplitLargeMeshesProcess_Triangle::UpdateNode(aiNode* pcNode,
const std::vector<std::pair<aiMesh*, unsigned int> >& avList) {
void SplitLargeMeshesProcess_Triangle::UpdateNode(aiNode* pcNode, const std::vector<std::pair<aiMesh*, unsigned int> >& avList) {
// for every index in out list build a new entry
std::vector<unsigned int> aiEntries;
aiEntries.reserve(pcNode->mNumMeshes + 1);

View File

@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2022, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -42,8 +41,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/** @file A helper class that processes texture transformations */
#include <assimp/Importer.hpp>
#include <assimp/postprocess.h>
#include <assimp/DefaultLogger.hpp>
@ -494,8 +491,9 @@ void TextureTransformStep::Execute( aiScene* pScene) {
ai_assert(nullptr != src);
// Copy the data to the destination array
if (dest != src)
if (dest != src) {
::memcpy(dest,src,sizeof(aiVector3D)*mesh->mNumVertices);
}
end = dest + mesh->mNumVertices;

View File

@ -158,15 +158,13 @@ namespace {
// ------------------------------------------------------------------------------------------------
// Returns whether the processing step is present in the given flag field.
bool TriangulateProcess::IsActive( unsigned int pFlags) const
{
bool TriangulateProcess::IsActive( unsigned int pFlags) const {
return (pFlags & aiProcess_Triangulate) != 0;
}
// ------------------------------------------------------------------------------------------------
// Executes the post processing step on the given imported data.
void TriangulateProcess::Execute( aiScene* pScene)
{
void TriangulateProcess::Execute( aiScene* pScene) {
ASSIMP_LOG_DEBUG("TriangulateProcess begin");
bool bHas = false;
@ -187,8 +185,7 @@ void TriangulateProcess::Execute( aiScene* pScene)
// ------------------------------------------------------------------------------------------------
// Triangulates the given mesh.
bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
{
bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh) {
// Now we have aiMesh::mPrimitiveTypes, so this is only here for test cases
if (!pMesh->mPrimitiveTypes) {
bool bNeed = false;
@ -218,8 +215,7 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
if( face.mNumIndices <= 3) {
numOut++;
}
else {
} else {
numOut += face.mNumIndices-2;
max_out = std::max(max_out,face.mNumIndices);
}
@ -511,22 +507,6 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
#endif
num = 0;
break;
/*curOut -= (max-num); // undo all previous work
for (tmp = 0; tmp < max-2; ++tmp) {
aiFace& nface = *curOut++;
nface.mNumIndices = 3;
if (!nface.mIndices)
nface.mIndices = new unsigned int[3];
nface.mIndices[0] = 0;
nface.mIndices[1] = tmp+1;
nface.mIndices[2] = tmp+2;
}
num = 0;
break;*/
}
aiFace& nface = *curOut++;
@ -580,23 +560,6 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
for(aiFace* f = last_face; f != curOut; ) {
unsigned int* i = f->mIndices;
// drop dumb 0-area triangles - deactivated for now:
//FindDegenerates post processing step can do the same thing
//if (std::fabs(GetArea2D(temp_verts[i[0]],temp_verts[i[1]],temp_verts[i[2]])) < 1e-5f) {
// ASSIMP_LOG_VERBOSE_DEBUG("Dropping triangle with area 0");
// --curOut;
// delete[] f->mIndices;
// f->mIndices = nullptr;
// for(aiFace* ff = f; ff != curOut; ++ff) {
// ff->mNumIndices = (ff+1)->mNumIndices;
// ff->mIndices = (ff+1)->mIndices;
// (ff+1)->mIndices = nullptr;
// }
// continue;
//}
i[0] = idx[i[0]];
i[1] = idx[i[1]];
i[2] = idx[i[2]];

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2022, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -110,11 +108,15 @@ inline int HasNameMatch(const aiString &in, aiNode *node) {
template <typename T>
inline void ValidateDSProcess::DoValidation(T **parray, unsigned int size, const char *firstName, const char *secondName) {
// validate all entries
if (size) {
if (size == 0) {
return;
}
if (!parray) {
ReportError("aiScene::%s is nullptr (aiScene::%s is %i)",
firstName, secondName, size);
}
for (unsigned int i = 0; i < size; ++i) {
if (!parray[i]) {
ReportError("aiScene::%s[%i] is nullptr (aiScene::%s is %i)",
@ -123,14 +125,16 @@ inline void ValidateDSProcess::DoValidation(T **parray, unsigned int size, const
Validate(parray[i]);
}
}
}
// ------------------------------------------------------------------------------------------------
template <typename T>
inline void ValidateDSProcess::DoValidationEx(T **parray, unsigned int size,
const char *firstName, const char *secondName) {
// validate all entries
if (size) {
if (size == 0) {
return;
}
if (!parray) {
ReportError("aiScene::%s is nullptr (aiScene::%s is %i)",
firstName, secondName, size);
@ -152,7 +156,6 @@ inline void ValidateDSProcess::DoValidationEx(T **parray, unsigned int size,
}
}
}
}
// ------------------------------------------------------------------------------------------------
template <typename T>
@ -229,12 +232,6 @@ void ValidateDSProcess::Execute(aiScene *pScene) {
if (pScene->mNumMaterials) {
DoValidation(pScene->mMaterials, pScene->mNumMaterials, "mMaterials", "mNumMaterials");
}
#if 0
// NOTE: ScenePreprocessor generates a default material if none is there
else if (!(mScene->mFlags & AI_SCENE_FLAGS_INCOMPLETE)) {
ReportError("aiScene::mNumMaterials is 0. At least one material must be there");
}
#endif
else if (pScene->mMaterials) {
ReportError("aiScene::mMaterials is non-null although there are no materials");
}
@ -267,8 +264,7 @@ void ValidateDSProcess::Validate(const aiCamera *pCamera) {
if (pCamera->mClipPlaneFar <= pCamera->mClipPlaneNear)
ReportError("aiCamera::mClipPlaneFar must be >= aiCamera::mClipPlaneNear");
// FIX: there are many 3ds files with invalid FOVs. No reason to
// reject them at all ... a warning is appropriate.
// There are many 3ds files with invalid FOVs. No reason to reject them at all ... a warning is appropriate.
if (!pCamera->mHorizontalFOV || pCamera->mHorizontalFOV >= (float)AI_MATH_PI)
ReportWarning("%f is not a valid value for aiCamera::mHorizontalFOV", pCamera->mHorizontalFOV);
}
@ -290,7 +286,6 @@ void ValidateDSProcess::Validate(const aiMesh *pMesh) {
switch (face.mNumIndices) {
case 0:
ReportError("aiMesh::mFaces[%i].mNumIndices is 0", i);
break;
case 1:
if (0 == (pMesh->mPrimitiveTypes & aiPrimitiveType_POINT)) {
ReportError("aiMesh::mFaces[%i] is a POINT but aiMesh::mPrimitiveTypes "
@ -362,15 +357,6 @@ void ValidateDSProcess::Validate(const aiMesh *pMesh) {
if (face.mIndices[a] >= pMesh->mNumVertices) {
ReportError("aiMesh::mFaces[%i]::mIndices[%i] is out of range", i, a);
}
// the MSB flag is temporarily used by the extra verbose
// mode to tell us that the JoinVerticesProcess might have
// been executed already.
/*if ( !(this->mScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT ) && !(this->mScene->mFlags & AI_SCENE_FLAGS_ALLOW_SHARED) &&
abRefList[face.mIndices[a]])
{
ReportError("aiMesh::mVertices[%i] is referenced twice - second "
"time by aiMesh::mFaces[%i]::mIndices[%i]",face.mIndices[a],i,a);
}*/
abRefList[face.mIndices[a]] = true;
}
}
@ -466,7 +452,7 @@ void ValidateDSProcess::Validate(const aiMesh *pMesh, const aiBone *pBone, float
this->Validate(&pBone->mName);
if (!pBone->mNumWeights) {
//ReportError("aiBone::mNumWeights is zero");
ReportWarning("aiBone::mNumWeights is zero");
}
// check whether all vertices affected by this bone are valid

View File

@ -92,6 +92,7 @@ namespace o3dgc
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// - - Static functions - - - - - - - - - - - - - - - - - - - - - - - - - - -
AI_WONT_RETURN static void AC_Error(const char * msg) AI_WONT_RETURN_SUFFIX;
static void AC_Error(const char * msg)
{
fprintf(stderr, "\n\n -> Arithmetic coding error: ");

View File

@ -78,7 +78,7 @@
# pragma warning(disable : 4131 4244 4189 4245)
#endif // _MSC_VER
const char unz_copyright[] =
static const char unz_copyright[] =
" unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
/* unz_file_info_internal contain internal info about a file in zipfile*/

View File

@ -40,6 +40,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <assimp/cimport.h>
#include <assimp/Importer.hpp>
#include <assimp/Exporter.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
@ -53,6 +54,13 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t dataSize) {
const aiScene *sc = importer.ReadFileFromMemory(data, dataSize,
aiProcessPreset_TargetRealtime_Quality, nullptr );
if (sc == nullptr) {
return 0;
}
Exporter exporter;
exporter.ExportToBlob(sc, "fbx");
aiDetachLogStream(&stream);
return 0;

View File

@ -66,7 +66,7 @@ ASSIMP_API void setAiAssertHandler(AiAssertHandler handler);
*
* @brief This issues a message to stderr and calls abort.
*/
ASSIMP_API void defaultAiAssertHandler(const char* failedExpression, const char* file, int line);
AI_WONT_RETURN ASSIMP_API void defaultAiAssertHandler(const char* failedExpression, const char* file, int line) AI_WONT_RETURN_SUFFIX;
// ---------------------------------------------------------------------------
/**

View File

@ -84,7 +84,7 @@ protected:
public:
/** Destructor public to allow simple deletion to close the file. */
~DefaultIOStream ();
~DefaultIOStream () override;
// -------------------------------------------------------------------
/// Read from stream

View File

@ -145,7 +145,7 @@ public:
}
/// @brief Destructor.
~MemoryIOSystem() = default;
~MemoryIOSystem() override = default;
// -------------------------------------------------------------------
/// @brief Tests for the existence of a file at the given path.

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2022, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
@ -68,8 +66,7 @@ namespace Assimp {
*/
// --------------------------------------------------------------------------------------------
template <bool SwapEndianess = false, bool RuntimeSwitch = false>
class StreamWriter
{
class StreamWriter {
enum {
INITIAL_CAPACITY = 1024
};

View File

@ -97,15 +97,21 @@ namespace Assimp {
* to *all* vertex components equally. This is useful for stuff like interpolation
* or subdivision, but won't work if special handling is required for some vertex components. */
// ------------------------------------------------------------------------------------------------
class Vertex {
struct Vertex {
friend Vertex operator + (const Vertex&,const Vertex&);
friend Vertex operator - (const Vertex&,const Vertex&);
friend Vertex operator * (const Vertex&,ai_real);
friend Vertex operator / (const Vertex&,ai_real);
friend Vertex operator * (ai_real, const Vertex&);
public:
Vertex() {}
aiVector3D position;
aiVector3D normal;
aiVector3D tangent, bitangent;
aiVector3D texcoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
aiColor4D colors[AI_MAX_NUMBER_OF_COLOR_SETS];
Vertex() = default;
// ----------------------------------------------------------------------------
/** Extract a particular vertex from a mesh and interleave all components */
@ -178,7 +184,7 @@ public:
}
// ----------------------------------------------------------------------------
/** Convert back to non-interleaved storage */
/// Convert back to non-interleaved storage
void SortBack(aiMesh* out, unsigned int idx) const {
ai_assert(idx<out->mNumVertices);
out->mVertices[idx] = position;
@ -204,7 +210,7 @@ public:
private:
// ----------------------------------------------------------------------------
/** Construct from two operands and a binary operation to combine them */
/// Construct from two operands and a binary operation to combine them
template <template <typename t> class op> static Vertex BinaryOp(const Vertex& v0, const Vertex& v1) {
// this is a heavy task for the compiler to optimize ... *pray*
@ -224,7 +230,7 @@ private:
}
// ----------------------------------------------------------------------------
/** This time binary arithmetic of v0 with a floating-point number */
/// This time binary arithmetic of v0 with a floating-point number
template <template <typename, typename, typename> class op> static Vertex BinaryOp(const Vertex& v0, ai_real f) {
// this is a heavy task for the compiler to optimize ... *pray*
@ -262,15 +268,6 @@ private:
}
return res;
}
public:
aiVector3D position;
aiVector3D normal;
aiVector3D tangent, bitangent;
aiVector3D texcoords[AI_MAX_NUMBER_OF_TEXTURECOORDS];
aiColor4D colors[AI_MAX_NUMBER_OF_COLOR_SETS];
};
// ------------------------------------------------------------------------------------------------

View File

@ -63,7 +63,7 @@ public:
//! Open a Zip using the proffered IOSystem
ZipArchiveIOSystem(IOSystem* pIOHandler, const char *pFilename, const char* pMode = "r");
ZipArchiveIOSystem(IOSystem* pIOHandler, const std::string& rFilename, const char* pMode = "r");
virtual ~ZipArchiveIOSystem();
virtual ~ZipArchiveIOSystem() override;
bool Exists(const char* pFilename) const override;
char getOsSeparator() const override;
IOStream* Open(const char* pFilename, const char* pMode = "rb") override;

View File

@ -184,6 +184,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifdef __GNUC__
# define AI_WONT_RETURN_SUFFIX __attribute__((noreturn))
#elif _MSC_VER
#if defined(__clang__)
# define AI_WONT_RETURN_SUFFIX __attribute__((noreturn))
#else
# define AI_WONT_RETURN_SUFFIX
#endif
#else
# define AI_WONT_RETURN_SUFFIX
#endif // (defined __clang__)
@ -283,7 +289,11 @@ typedef unsigned int ai_uint;
#define AI_RAD_TO_DEG(x) ((x) * (ai_real) 57.2957795)
/* Numerical limits */
static const ai_real ai_epsilon = (ai_real) 1e-6;
#ifdef __cplusplus
constexpr ai_real ai_epsilon = (ai_real) 1e-6;
#else
const ai_real ai_epsilon = (ai_real) 1e-6;
#endif
/* Support for big-endian builds */
#if defined(__BYTE_ORDER__)

View File

@ -102,6 +102,10 @@ SET( COMMON
unit/Common/utBaseProcess.cpp
)
SET(Geometry
unit/Geometry/utGeometryUtils.cpp
)
SET( IMPORTERS
unit/ImportExport/Assxml/utAssxmlImportExport.cpp
unit/utLWSImportExport.cpp
@ -202,6 +206,7 @@ SET( POST_PROCESSES
SOURCE_GROUP( UnitTests\\Compiler FILES unit/CCompilerTest.c )
SOURCE_GROUP( UnitTests\\Common FILES ${COMMON} )
SOURCE_GROUP( UnitTests\\GeometryTools FILES ${Geometry} )
SOURCE_GROUP( UnitTests\\ImportExport FILES ${IMPORTERS} )
SOURCE_GROUP( UnitTests\\Material FILES ${MATERIAL} )
SOURCE_GROUP( UnitTests\\Math FILES ${MATH} )
@ -213,6 +218,7 @@ add_executable( unit
../code/Common/Version.cpp
../code/Common/Base64.cpp
${COMMON}
${Geometry}
${IMPORTERS}
${MATERIAL}
${MATH}

View File

@ -0,0 +1,68 @@
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2022, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#include "UnitTestPCH.h"
#include "Geometry/GeometryUtils.h"
using namespace Assimp;
class utGeometryUtils : public ::testing::Test {
protected:
void SetUp() override {
}
void TearDown() override {
}
};
static constexpr size_t NumVectors = 100;
TEST_F(utGeometryUtils, normalizeVectorArrayTest) {
aiVector3D *inNormals = new aiVector3D[NumVectors];
for (uint32_t i=0; i<NumVectors; ++i){
inNormals[i].x = static_cast<ai_real>(i);
inNormals[i].y = static_cast<ai_real>(i);
inNormals[i].z = static_cast<ai_real>(i);
}
aiVector3D *outNormals = new aiVector3D[NumVectors];
GeometryUtils::normalizeVectorArray(inNormals, outNormals, NumVectors);
delete[] outNormals;
delete[] inNormals;
}

View File

@ -1,38 +1,71 @@
#include "UnitTestPCH.h"
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2022, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,
with or without modification, are permitted provided that the following
conditions are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the
following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the
following disclaimer in the documentation and/or other
materials provided with the distribution.
* Neither the name of the assimp team, nor the names of its
contributors may be used to endorse or promote products
derived from this software without specific prior
written permission of the assimp team.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#include "UnitTestPCH.h"
#include <assimp/cexport.h>
#include <assimp/Exporter.hpp>
#ifndef ASSIMP_BUILD_NO_EXPORT
class ExporterTest : public ::testing::Test {
public:
virtual void SetUp()
{
void SetUp() override {
ex = new Assimp::Exporter();
im = new Assimp::Importer();
pTest = im->ReadFile(ASSIMP_TEST_MODELS_DIR "/X/test.x", aiProcess_ValidateDataStructure);
}
virtual void TearDown()
{
void TearDown() override {
delete ex;
delete im;
}
protected:
const aiScene* pTest;
Assimp::Exporter* ex;
Assimp::Importer* im;
};
// ------------------------------------------------------------------------------------------------
TEST_F(ExporterTest, testExportToFile)
{
TEST_F(ExporterTest, testExportToFile) {
const char* file = "unittest_output.dae";
EXPECT_EQ(AI_SUCCESS,ex->Export(pTest,"collada",file));
@ -41,8 +74,7 @@ TEST_F(ExporterTest, testExportToFile)
}
// ------------------------------------------------------------------------------------------------
TEST_F(ExporterTest, testExportToBlob)
{
TEST_F(ExporterTest, testExportToBlob) {
const aiExportDataBlob* blob = ex->ExportToBlob(pTest,"collada");
ASSERT_TRUE(blob);
EXPECT_TRUE(blob->data);
@ -56,8 +88,7 @@ TEST_F(ExporterTest, testExportToBlob)
}
// ------------------------------------------------------------------------------------------------
TEST_F(ExporterTest, testCppExportInterface)
{
TEST_F(ExporterTest, testCppExportInterface) {
EXPECT_TRUE(ex->GetExportFormatCount() > 0);
for(size_t i = 0; i < ex->GetExportFormatCount(); ++i) {
const aiExportFormatDesc* const desc = ex->GetExportFormatDescription(i);
@ -71,14 +102,13 @@ TEST_F(ExporterTest, testCppExportInterface)
}
// ------------------------------------------------------------------------------------------------
TEST_F(ExporterTest, testCExportInterface)
{
TEST_F(ExporterTest, testCExportInterface) {
EXPECT_TRUE(aiGetExportFormatCount() > 0);
for(size_t i = 0; i < aiGetExportFormatCount(); ++i) {
const aiExportFormatDesc* const desc = aiGetExportFormatDescription(i);
EXPECT_TRUE(desc);
// rest has already been validated by testCppExportInterface
}
}
#endif