Compare commits

..

38 Commits

Author SHA1 Message Date
Kim Kulling
a34688230d Merge pull request #4393 from TerenceRussell/master
Added support for "map_Bump -bm"
2022-02-20 20:14:21 +01:00
Kim Kulling
52b106bf7e Merge branch 'master' into master 2022-02-20 19:04:32 +01:00
Kim Kulling
eed5570c39 Merge pull request #4399 from assimp/kimkulling/fix_typo_in_cmake
Update CMakeLists.txt
2022-02-20 18:45:06 +01:00
Kim Kulling
3e7294feeb Merge branch 'master' into kimkulling/fix_typo_in_cmake 2022-02-20 15:33:54 +01:00
Kim Kulling
2c33ed1087 Merge pull request #4397 from youkeyao/issue_3191
update the calculation and orthogonalization for bitangent
2022-02-20 15:32:41 +01:00
Kim Kulling
b625961197 Merge branch 'master' into issue_3191 2022-02-20 15:14:46 +01:00
Kim Kulling
03f44cd983 Merge branch 'master' into kimkulling/fix_typo_in_cmake 2022-02-20 14:17:27 +01:00
Kim Kulling
5c53726c8e Merge pull request #4394 from BA7LYA/master
udpate build script to fit "Visual Studio 16 2019" Generator
2022-02-20 14:07:49 +01:00
Kim Kulling
96522bc114 Update CMakeLists.txt 2022-02-20 14:06:11 +01:00
Kim Kulling
b825740df7 Merge branch 'master' into master 2022-02-20 12:53:26 +01:00
Kim Kulling
f952100dbb Merge pull request #4398 from assimp/kimkulling-patch-1
Fix stat for 32-biut linuxes
2022-02-20 12:19:06 +01:00
Kim Kulling
14874d26f4 Fix stat for 32-biut linuxes
- Reenable fix to ensure that stat works correctly on 32-bit linuxes again
  - stat will return 32-bit inodes when checking a file. So when this call will be used on a 64-bit linux this will cause errors like:
Error writing to foo: Value too large for defined data type
File I/O error: foo
- closes https://github.com/assimp/assimp/issues/4390
2022-02-20 11:53:26 +01:00
youkeyao
ad766cb738 update the calculation and orthogonalization for bitangent 2022-02-20 17:15:11 +08:00
ChenJunshuai
efc60076dc udpate build script to fit "Visual Studio 16 2019" Generator 2022-02-18 19:01:47 +08:00
Terence Russell
17123ed4a1 Add support for bump -bm (bump/normal multiplier) 2022-02-17 22:10:46 -07:00
Kim Kulling
dff3620138 Merge pull request #4391 from jcfr/fix-assimp-target-install-rule-fully-specifying-components
cmake: Fix assimp target install rule fully specifying component
2022-02-17 23:13:43 +01:00
Jean-Christophe Fillion-Robin
33a48c6ca6 cmake: Fix assimp target install rule fully specifying component
This commit ensures generated install rules for the assimp target are
all consistently associated with components named after LIBASSIMP_COMPONENT
or LIBASSIMP-DEV_COMPONENT CMake variables.

It streamlines the packaging of specific components of assimp in client
projects leveraging the CPACK_INSTALL_CMAKE_PROJECTS variable.

Failing to do so leads to "/path/to/assimp-build/code/cmake_install.cmake"
file having install rules associated with a component called "Unspecified".

See https://cmake.org/cmake/help/v3.10/command/install.html#installing-targets
and https://cmake.org/cmake/help/v3.22/module/CPack.html#variable:CPACK_INSTALL_CMAKE_PROJECTS
2022-02-17 05:47:34 -05:00
Kim Kulling
510504a2c6 Merge pull request #4387 from assimp/kimkulling/fbx_use_ai_epsilon
Refactoring: add usage of ai_epsilon to fbx.
2022-02-16 22:38:34 +01:00
Kim Kulling
9bf5d01469 Fix invalid initialization of constexpr. 2022-02-16 21:22:35 +01:00
Kim Kulling
9e23d771bc Fix invalid initialization of constexpr. 2022-02-16 21:19:17 +01:00
Kim Kulling
76a7614c4b Adapt ai_epsilon to code 2022-02-16 20:07:27 +01:00
Kim Kulling
067c5d9ec4 Refactoring: add usage of ai_epsilon to fbx. 2022-02-16 00:17:26 +01:00
Kim Kulling
884bb39391 Merge pull request #4381 from assimp/kimkulling/introduce_compression
Kimkulling/introduce compression
2022-02-15 19:09:52 +01:00
Kim Kulling
5d8e5fd130 Update XFileParser.cpp
Fix typo
2022-02-15 16:10:33 +01:00
Kim Kulling
7c13b16d30 Add missing flush modes supported by zlib 2022-02-14 20:51:06 +01:00
Kim Kulling
416f823866 Merge branch 'kimkulling/introduce_compression' of https://github.com/assimp/assimp into kimkulling/introduce_compression 2022-02-14 20:25:27 +01:00
Kim Kulling
c718500c55 Fix last review findings and finish windows bits 2022-02-14 20:25:18 +01:00
Kim Kulling
9a585d7b3c Merge branch 'master' into kimkulling/introduce_compression 2022-02-13 19:58:22 +01:00
Kim Kulling
52b6c4f7c0 Fix broken importer and add some review findings2 2022-02-13 18:44:22 +01:00
Kim Kulling
3e09d462fa Fix compression for fbx 2022-02-12 09:25:45 +01:00
Kim Kulling
97c7e084c2 Merge pull request #4380 from malytomas/tomas/fixsizet
fix missing include for size_t
2022-02-11 08:55:35 +01:00
Kim Kulling
23b43d1825 Fix X-Importer decompress algorithm 2022-02-08 21:43:14 +01:00
Kim Kulling
27bcddfb1a Migrate more importers to compression class 2022-02-08 20:43:47 +01:00
Tomas Maly
acf73659d8 fix missing include for size_t 2022-02-08 00:08:46 +01:00
Kim Kulling
dcd5c1dcfd Merge pull request #4375 from assimp/kimkulling/introduce_compression
Introduce compression class to encapsulate compression via zlib
2022-02-07 10:23:23 +01:00
Kim Kulling
ce61ea56a5 Merge branch 'master' into kimkulling/introduce_compression 2022-02-07 10:02:51 +01:00
Kim Kulling
eb5a7938e0 Remove dead code 2022-02-06 21:16:04 +01:00
Kim Kulling
9335cc30ab INtroduce compression class to encapsulate compression via zlib 2022-02-06 20:42:58 +01:00
37 changed files with 609 additions and 301 deletions

View File

@@ -10,16 +10,15 @@
:: Also see: https://github.com/assimp/assimp/pull/2646
SET SOURCE_DIR=.
SET GENERATOR=Visual Studio 16 2019
:: For generators see "cmake --help"
SET GENERATOR=Visual Studio 15 2017
SET BINARIES_DIR="./BINARIES/Win32"
cmake CMakeLists.txt -G "%GENERATOR%" -S %SOURCE_DIR% -B %BINARIES_DIR%
SET BINARIES_DIR="./build/Win32"
cmake . -G "%GENERATOR%" -A Win32 -S %SOURCE_DIR% -B %BINARIES_DIR%
cmake --build %BINARIES_DIR% --config debug
cmake --build %BINARIES_DIR% --config release
SET BINARIES_DIR="./BINARIES/x64"
cmake CMakeLists.txt -G "%GENERATOR% Win64" -S %SOURCE_DIR% -B %BINARIES_DIR%
SET BINARIES_DIR="./build/x64"
cmake . -G "%GENERATOR%" -A x64 -S %SOURCE_DIR% -B %BINARIES_DIR%
cmake --build %BINARIES_DIR% --config debug
cmake --build %BINARIES_DIR% --config release

View File

@@ -243,6 +243,13 @@ SET(ASSIMP_LIBRARY_SUFFIX "" CACHE STRING "Suffix to append to library names")
IF( UNIX )
# Use GNUInstallDirs for Unix predefined directories
INCLUDE(GNUInstallDirs)
# Ensure that we do not run into issues like http://www.tcm.phy.cam.ac.uk/sw/inodes64.html on 32 bit linux
IF( ${OPERATING_SYSTEM} MATCHES "Android")
ELSE()
IF ( CMAKE_SIZEOF_VOID_P EQUAL 4) # only necessary for 32-bit linux
ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64 )
ENDIF()
ENDIF()
ENDIF()
# Grouped compiler settings ########################################

View File

@@ -182,6 +182,8 @@ inline size_t Write<aiVertexWeight>(IOStream *stream, const aiVertexWeight &v) {
return t + Write<float>(stream, v.mWeight);
}
constexpr size_t MatrixSize = 64;
// -----------------------------------------------------------------------------------
// Serialize a mat4x4
template <>
@@ -192,7 +194,7 @@ inline size_t Write<aiMatrix4x4>(IOStream *stream, const aiMatrix4x4 &m) {
}
}
return 64;
return MatrixSize;
}
// -----------------------------------------------------------------------------------

View File

@@ -66,11 +66,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// zlib is needed for compressed blend files
#ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND
# ifdef ASSIMP_BUILD_NO_OWN_ZLIB
#include "Common/Compression.h"
/* #ifdef ASSIMP_BUILD_NO_OWN_ZLIB
# include <zlib.h>
# else
# include "../contrib/zlib/zlib.h"
# endif
# endif*/
#endif
namespace Assimp {
@@ -141,7 +142,7 @@ void BlenderImporter::SetupProperties(const Importer * /*pImp*/) {
void BlenderImporter::InternReadFile(const std::string &pFile,
aiScene *pScene, IOSystem *pIOHandler) {
#ifndef ASSIMP_BUILD_NO_COMPRESSED_BLEND
std::vector<Bytef> uncompressed;
std::vector<char> uncompressed;
#endif
FileDatabase file;
@@ -159,7 +160,6 @@ void BlenderImporter::InternReadFile(const std::string &pFile,
#ifdef ASSIMP_BUILD_NO_COMPRESSED_BLEND
ThrowException("BLENDER magic bytes are missing, is this file compressed (Assimp was built without decompression support)?");
#else
if (magic[0] != 0x1f || static_cast<uint8_t>(magic[1]) != 0x8b) {
ThrowException("BLENDER magic bytes are missing, couldn't find GZIP header either");
}
@@ -173,42 +173,12 @@ void BlenderImporter::InternReadFile(const std::string &pFile,
stream->Seek(0L, aiOrigin_SET);
std::shared_ptr<StreamReaderLE> reader = std::shared_ptr<StreamReaderLE>(new StreamReaderLE(stream));
// build a zlib stream
z_stream zstream;
zstream.opaque = Z_NULL;
zstream.zalloc = Z_NULL;
zstream.zfree = Z_NULL;
zstream.data_type = Z_BINARY;
// http://hewgill.com/journal/entries/349-how-to-decompress-gzip-stream-with-zlib
inflateInit2(&zstream, 16 + MAX_WBITS);
zstream.next_in = reinterpret_cast<Bytef *>(reader->GetPtr());
zstream.avail_in = (uInt)reader->GetRemainingSize();
size_t total = 0l;
// TODO: be smarter about this, decompress directly into heap buffer
// and decompress the data .... do 1k chunks in the hope that we won't kill the stack
#define MYBLOCK 1024
Bytef block[MYBLOCK];
int ret;
do {
zstream.avail_out = MYBLOCK;
zstream.next_out = block;
ret = inflate(&zstream, Z_NO_FLUSH);
if (ret != Z_STREAM_END && ret != Z_OK) {
ThrowException("Failure decompressing this file using gzip, seemingly it is NOT a compressed .BLEND file");
}
const size_t have = MYBLOCK - zstream.avail_out;
total += have;
uncompressed.resize(total);
memcpy(uncompressed.data() + total - have, block, have);
} while (ret != Z_STREAM_END);
// terminate zlib
inflateEnd(&zstream);
size_t total = 0;
Compression compression;
if (compression.open(Compression::Format::Binary, Compression::FlushMode::NoFlush, 16 + Compression::MaxWBits)) {
total = compression.decompress((unsigned char *)reader->GetPtr(), reader->GetRemainingSize(), uncompressed);
compression.close();
}
// replace the input stream with a memory stream
stream.reset(new MemoryIOStream(reinterpret_cast<uint8_t *>(uncompressed.data()), total));

View File

@@ -357,9 +357,9 @@ void ColladaLoader::BuildLightsForNode(const ColladaParser &pParser, const Node
out->mAngleInnerCone = AI_DEG_TO_RAD(srcLight->mFalloffAngle);
// ... some extension magic.
if (srcLight->mOuterAngle >= ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET * (1 - 1e-6f)) {
if (srcLight->mOuterAngle >= ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET * (1 - ai_epsilon)) {
// ... some deprecation magic.
if (srcLight->mPenumbraAngle >= ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET * (1 - 1e-6f)) {
if (srcLight->mPenumbraAngle >= ASSIMP_COLLADA_LIGHT_ANGLE_NOT_SET * (1 - ai_epsilon)) {
// Need to rely on falloff_exponent. I don't know how to interpret it, so I need to guess ....
// epsilon chosen to be 0.1
float f = 1.0f;
@@ -1065,7 +1065,7 @@ void insertMorphTimeValue(std::vector<MorphTimeValues> &values, float time, floa
return;
}
for (unsigned int i = 0; i < values.size(); i++) {
if (std::abs(time - values[i].mTime) < 1e-6f) {
if (std::abs(time - values[i].mTime) < ai_epsilon) {
values[i].mKeys.push_back(k);
return;
} else if (time > values[i].mTime && time < values[i + 1].mTime) {

View File

@@ -80,8 +80,10 @@ enum TransformInheritance {
TransformInheritance_MAX // end-of-enum sentinel
};
} // namespace FBX
} // namespace Assimp
#endif // ASSIMP_BUILD_NO_FBX_EXPORTER
#endif // AI_FBXCOMMON_H_INC

View File

@@ -653,7 +653,7 @@ bool FBXConverter::NeedsComplexTransformationChain(const Model &model) {
const PropertyTable &props = model.Props();
bool ok;
const float zero_epsilon = 1e-6f;
const float zero_epsilon = ai_epsilon;
const aiVector3D all_ones(1.0f, 1.0f, 1.0f);
for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) {
const TransformationComp comp = static_cast<TransformationComp>(i);
@@ -3187,7 +3187,8 @@ aiNodeAnim* FBXConverter::GenerateSimpleNodeAnim(const std::string& name,
}
bool ok = false;
const float zero_epsilon = 1e-6f;
const float zero_epsilon = ai_epsilon;
const aiVector3D& preRotation = PropertyGet<aiVector3D>(props, "PreRotation", ok);
if (ok && preRotation.SquareLength() > zero_epsilon) {

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,
@@ -46,11 +45,12 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_FBX_IMPORTER
#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
# include <zlib.h>
#else
# include "../contrib/zlib/zlib.h"
#endif
//#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
#include "Common/Compression.h"
//# include <zlib.h>
//#else
//# include "../contrib/zlib/zlib.h"
//#endif
#include "FBXTokenizer.h"
#include "FBXParser.h"
@@ -115,9 +115,7 @@ namespace Assimp {
namespace FBX {
// ------------------------------------------------------------------------------------------------
Element::Element(const Token& key_token, Parser& parser)
: key_token(key_token)
{
Element::Element(const Token& key_token, Parser& parser) : key_token(key_token) {
TokenPtr n = nullptr;
do {
n = parser.AdvanceToNextToken();
@@ -210,8 +208,7 @@ Scope::Scope(Parser& parser,bool topLevel)
}
// ------------------------------------------------------------------------------------------------
Scope::~Scope()
{
Scope::~Scope() {
for(ElementMap::value_type& v : elements) {
delete v.second;
}
@@ -527,9 +524,7 @@ void ReadBinaryDataArrayHead(const char*& data, const char* end, char& type, uin
// ------------------------------------------------------------------------------------------------
// read binary data array, assume cursor points to the 'compression mode' field (i.e. behind the header)
void ReadBinaryDataArray(char type, uint32_t count, const char*& data, const char* end,
std::vector<char>& buff,
const Element& /*el*/)
{
std::vector<char>& buff, const Element& /*el*/) {
BE_NCONST uint32_t encmode = SafeParse<uint32_t>(data, end);
AI_SWAP4(encmode);
data += 4;
@@ -571,31 +566,11 @@ void ReadBinaryDataArray(char type, uint32_t count, const char*& data, const cha
else if(encmode == 1) {
// zlib/deflate, next comes ZIP head (0x78 0x01)
// see http://www.ietf.org/rfc/rfc1950.txt
z_stream zstream;
zstream.opaque = Z_NULL;
zstream.zalloc = Z_NULL;
zstream.zfree = Z_NULL;
zstream.data_type = Z_BINARY;
// http://hewgill.com/journal/entries/349-how-to-decompress-gzip-stream-with-zlib
if(Z_OK != inflateInit(&zstream)) {
ParseError("failure initializing zlib");
Compression compress;
if (compress.open(Compression::Format::Binary, Compression::FlushMode::Finish, 0)) {
compress.decompress(data, comp_len, buff);
compress.close();
}
zstream.next_in = reinterpret_cast<Bytef*>( const_cast<char*>(data) );
zstream.avail_in = comp_len;
zstream.avail_out = static_cast<uInt>(buff.size());
zstream.next_out = reinterpret_cast<Bytef*>(&*buff.begin());
const int ret = inflate(&zstream, Z_FINISH);
if (ret != Z_STREAM_END && ret != Z_OK) {
ParseError("failure decompressing compressed data section");
}
// terminate zlib
inflateEnd(&zstream);
}
#ifdef ASSIMP_BUILD_DEBUG
else {
@@ -701,7 +676,6 @@ void ParseVectorDataArray(std::vector<aiVector3D>& out, const Element& el)
}
}
// ------------------------------------------------------------------------------------------------
// read an array of color4 tuples
void ParseVectorDataArray(std::vector<aiColor4D>& out, const Element& el)
@@ -786,8 +760,7 @@ void ParseVectorDataArray(std::vector<aiColor4D>& out, const Element& el)
// ------------------------------------------------------------------------------------------------
// read an array of float2 tuples
void ParseVectorDataArray(std::vector<aiVector2D>& out, const Element& el)
{
void ParseVectorDataArray(std::vector<aiVector2D>& out, const Element& el) {
out.resize( 0 );
const TokenList& tok = el.Tokens();
if(tok.empty()) {
@@ -831,8 +804,7 @@ void ParseVectorDataArray(std::vector<aiVector2D>& out, const Element& el)
out.push_back(aiVector2D(static_cast<float>(d[0]),
static_cast<float>(d[1])));
}
}
else if (type == 'f') {
} else if (type == 'f') {
const float* f = reinterpret_cast<const float*>(&buff[0]);
for (unsigned int i = 0; i < count2; ++i, f += 2) {
out.push_back(aiVector2D(f[0],f[1]));
@@ -865,8 +837,7 @@ void ParseVectorDataArray(std::vector<aiVector2D>& out, const Element& el)
// ------------------------------------------------------------------------------------------------
// read an array of ints
void ParseVectorDataArray(std::vector<int>& out, const Element& el)
{
void ParseVectorDataArray(std::vector<int>& out, const Element& el) {
out.resize( 0 );
const TokenList& tok = el.Tokens();
if(tok.empty()) {

View File

@@ -66,12 +66,12 @@ bool IntersectSegmentPlane(const IfcVector3 &p, const IfcVector3 &n, const IfcVe
// if segment ends on plane, do not report a hit. We stay on that side until a following segment starting at this
// point leaves the plane through the other side
if (std::abs(dotOne + dotTwo) < 1e-6)
if (std::abs(dotOne + dotTwo) < ai_epsilon)
return false;
// if segment starts on the plane, report a hit only if the end lies on the *other* side
if (std::abs(dotTwo) < 1e-6) {
if ((assumeStartOnWhiteSide && dotOne + dotTwo < 1e-6) || (!assumeStartOnWhiteSide && dotOne + dotTwo > -1e-6)) {
if (std::abs(dotTwo) < ai_epsilon) {
if ((assumeStartOnWhiteSide && dotOne + dotTwo < ai_epsilon) || (!assumeStartOnWhiteSide && dotOne + dotTwo > -ai_epsilon)) {
out = e0;
return true;
} else {
@@ -81,7 +81,7 @@ bool IntersectSegmentPlane(const IfcVector3 &p, const IfcVector3 &n, const IfcVe
// ignore if segment is parallel to plane and far away from it on either side
// Warning: if there's a few thousand of such segments which slowly accumulate beyond the epsilon, no hit would be registered
if (std::abs(dotOne) < 1e-6)
if (std::abs(dotOne) < ai_epsilon)
return false;
// t must be in [0..1] if the intersection point is within the given segment
@@ -163,7 +163,7 @@ void ProcessBooleanHalfSpaceDifference(const Schema_2x3::IfcHalfSpaceSolid *hs,
for (iit = begin; iit != end; vidx += *iit++) {
unsigned int newcount = 0;
bool isAtWhiteSide = (in[vidx] - p) * n > -1e-6;
bool isAtWhiteSide = (in[vidx] - p) * n > -ai_epsilon;
for (unsigned int i = 0; i < *iit; ++i) {
const IfcVector3 &e0 = in[vidx + i], e1 = in[vidx + (i + 1) % *iit];
@@ -259,7 +259,7 @@ bool IntersectsBoundaryProfile(const IfcVector3 &e0, const IfcVector3 &e1, const
// segment-segment intersection
// solve b0 + b*s = e0 + e*t for (s,t)
const IfcFloat det = (-b.x * e.y + e.x * b.y);
if (std::abs(det) < 1e-6) {
if (std::abs(det) < ai_epsilon) {
// no solutions (parallel lines)
continue;
}
@@ -316,7 +316,7 @@ bool IntersectsBoundaryProfile(const IfcVector3 &e0, const IfcVector3 &e1, const
// for a valid intersection, s and t should be in range [0,1]. Including a bit of epsilon on s, potential double
// hits on two consecutive boundary segments are filtered
if (s >= -1e-6 * b_sqlen_inv && s <= 1.0 + 1e-6 * b_sqlen_inv && t >= 0.0 && (t <= 1.0 || halfOpen)) {
if (s >= -ai_epsilon * b_sqlen_inv && s <= 1.0 + ai_epsilon * b_sqlen_inv && t >= 0.0 && (t <= 1.0 || halfOpen)) {
// only insert the point into the list if it is sufficiently far away from the previous intersection point.
// This way, we avoid duplicate detection if the intersection is directly on the vertex between two segments.
if (!intersect_results.empty() && intersect_results.back().first == i - 1) {
@@ -431,14 +431,14 @@ void ProcessPolygonalBoundedBooleanHalfSpaceDifference(const Schema_2x3::IfcPoly
// if the poly is parallel to the plane, put it completely on the black or white side
if (std::abs(polyNormal * n) > 0.9999) {
bool isOnWhiteSide = (srcVertices[0] - p) * n > -1e-6;
bool isOnWhiteSide = (srcVertices[0] - p) * n > -ai_epsilon;
std::vector<IfcVector3> &targetSide = isOnWhiteSide ? whiteside : blackside;
targetSide.insert(targetSide.end(), srcVertices, srcVertices + srcVtxCount);
} else {
// otherwise start building one polygon for each side. Whenever the current line segment intersects the plane
// we put a point there as an end of the current segment. Then we switch to the other side, put a point there, too,
// as a beginning of the current segment, and simply continue accumulating vertices.
bool isCurrentlyOnWhiteSide = ((srcVertices[0]) - p) * n > -1e-6;
bool isCurrentlyOnWhiteSide = ((srcVertices[0]) - p) * n > -ai_epsilon;
for (size_t a = 0; a < srcVtxCount; ++a) {
IfcVector3 e0 = srcVertices[a];
IfcVector3 e1 = srcVertices[(a + 1) % srcVtxCount];

View File

@@ -380,21 +380,19 @@ void ProcessSweptDiskSolid(const Schema_2x3::IfcSweptDiskSolid &solid, TempMesh&
bool take_any = false;
for (unsigned int j = 0; j < 2; ++j, take_any = true) {
if ((last_dir == 0 || take_any) && std::abs(d.x) > 1e-6) {
if ((last_dir == 0 || take_any) && std::abs(d.x) > ai_epsilon) {
q.y = startvec.y;
q.z = startvec.z;
q.x = -(d.y * q.y + d.z * q.z) / d.x;
last_dir = 0;
break;
}
else if ((last_dir == 1 || take_any) && std::abs(d.y) > 1e-6) {
} else if ((last_dir == 1 || take_any) && std::abs(d.y) > ai_epsilon) {
q.x = startvec.x;
q.z = startvec.z;
q.y = -(d.x * q.x + d.z * q.z) / d.y;
last_dir = 1;
break;
}
else if ((last_dir == 2 && std::abs(d.z) > 1e-6) || take_any) {
} else if ((last_dir == 2 && std::abs(d.z) > ai_epsilon) || take_any) {
q.y = startvec.y;
q.x = startvec.x;
q.z = -(d.y * q.y + d.x * q.x) / d.z;
@@ -529,7 +527,7 @@ IfcMatrix3 DerivePlaneCoordinateSpace(const TempMesh& curmesh, bool& ok, IfcVect
return m;
}
const auto closeDistance = 1e-6;
const auto closeDistance = ai_epsilon;
bool areClose(Schema_2x3::IfcCartesianPoint pt1,Schema_2x3::IfcCartesianPoint pt2) {
if(pt1.Coordinates.size() != pt2.Coordinates.size())
@@ -561,7 +559,7 @@ void ProcessExtrudedArea(const Schema_2x3::IfcExtrudedAreaSolid& solid, const Te
// Outline: 'curve' is now a list of vertex points forming the underlying profile, extrude along the given axis,
// forming new triangles.
const bool has_area = solid.SweptArea->ProfileType == "AREA" && curve.mVerts.size() > 2;
if( solid.Depth < 1e-6 ) {
if (solid.Depth < ai_epsilon) {
if( has_area ) {
result.Append(curve);
}

View File

@@ -1133,7 +1133,7 @@ IfcMatrix4 ProjectOntoPlane(std::vector<IfcVector2>& out_contour, const TempMesh
}
for(size_t i = 0; i < out_contour.size(); ++i) {
ai_assert((out_contour[i]-out_contour2[i]).SquareLength() < 1e-6);
ai_assert((out_contour[i] - out_contour2[i]).SquareLength() < ai_epsilon);
}
#endif
@@ -1435,7 +1435,7 @@ std::vector<IfcVector2> GetContourInPlane2D(std::shared_ptr<TempMesh> mesh,IfcMa
const auto outernor = ((mesh->mVerts[2] - mesh->mVerts[0]) ^ (mesh->mVerts[1] - mesh->mVerts[0])).Normalize();
const IfcFloat dot = planeNor * outernor;
if(std::fabs(dot) < 1.f - 1e-6f) {
if (std::fabs(dot) < 1.f - ai_epsilon) {
std::stringstream msg;
msg << "Skipping: Unaligned opening (" << planeNor.x << ", " << planeNor.y << ", " << planeNor.z << ")";
msg << " . ( " << outernor.x << ", " << outernor.y << ", " << outernor.z << ") = " << dot;
@@ -1476,7 +1476,7 @@ std::vector<IfcVector2> GetContourInPlane2D(std::shared_ptr<TempMesh> mesh,IfcMa
return contour;
}
const float close { 1e-6f };
const float close{ ai_epsilon };
static bool isClose(IfcVector2 first,IfcVector2 second) {
auto diff = (second - first);

View File

@@ -228,25 +228,24 @@ void TempMesh::ComputePolygonNormals(std::vector<IfcVector3>& normals,
// ------------------------------------------------------------------------------------------------
// Compute the normal of the last polygon in the given mesh
IfcVector3 TempMesh::ComputeLastPolygonNormal(bool normalize) const
{
IfcVector3 TempMesh::ComputeLastPolygonNormal(bool normalize) const {
return ComputePolygonNormal(&mVerts[mVerts.size() - mVertcnt.back()], mVertcnt.back(), normalize);
}
struct CompareVector
{
bool operator () (const IfcVector3& a, const IfcVector3& b) const
{
struct CompareVector {
bool operator () (const IfcVector3& a, const IfcVector3& b) const {
IfcVector3 d = a - b;
IfcFloat eps = 1e-6;
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);
}
};
struct FindVector
{
struct FindVector {
IfcVector3 v;
FindVector(const IfcVector3& p) : v(p) { }
bool operator () (const IfcVector3& p) { return FuzzyVectorCompare(1e-6)(p, v); }
bool operator()(const IfcVector3 &p) {
return FuzzyVectorCompare(ai_epsilon)(p, v);
}
};
// ------------------------------------------------------------------------------------------------
@@ -357,8 +356,7 @@ void TempMesh::FixupFaceOrientation()
// to reverse the neighbour
nb_vidx = (nb_vidx + 1) % nbvc;
size_t oursideidx = (a + 1) % vc;
if( FuzzyVectorCompare(1e-6)(mVerts[vsi + oursideidx], mVerts[nbvsi + nb_vidx]) )
{
if (FuzzyVectorCompare(ai_epsilon)(mVerts[vsi + oursideidx], mVerts[nbvsi + nb_vidx])) {
std::reverse(mVerts.begin() + nbvsi, mVerts.begin() + nbvsi + nbvc);
std::reverse(neighbour.begin() + nbvsi, neighbour.begin() + nbvsi + nbvc);
for (size_t aa = 0; aa < nbvc - 1; ++aa) {
@@ -564,7 +562,7 @@ void ConvertDirection(IfcVector3& out, const Schema_2x3::IfcDirection& in)
out[static_cast<unsigned int>(i)] = in.DirectionRatios[i];
}
const IfcFloat len = out.Length();
if (len<1e-6) {
if (len < ai_epsilon) {
IFCImporter::LogWarn("direction vector magnitude too small, normalization would result in a division by zero");
return;
}

View File

@@ -195,6 +195,9 @@ struct Material {
//! PBR Anisotropy
ai_real anisotropy;
//! bump map multipler (normal map scalar)(-bm)
ai_real bump_multiplier;
//! Constructor
Material() :
diffuse(ai_real(0.6), ai_real(0.6), ai_real(0.6)),
@@ -208,7 +211,8 @@ struct Material {
sheen(ai_real(1.0), ai_real(1.0), ai_real(1.0)),
clearcoat_thickness(ai_real(0.0)),
clearcoat_roughness(ai_real(0.0)),
anisotropy(ai_real(0.0)) {
anisotropy(ai_real(0.0)),
bump_multiplier(ai_real(1.0)) {
std::fill_n(clamp, static_cast<unsigned int>(TextureTypeCount), false);
}

View File

@@ -51,6 +51,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/scene.h>
#include <assimp/DefaultLogger.hpp>
#include <assimp/Importer.hpp>
#include <assimp/ObjMaterial.h>
#include <memory>
static const aiImporterDesc desc = {
@@ -657,6 +658,9 @@ void ObjFileImporter::createMaterials(const ObjFile::Model *pModel, aiScene *pSc
if (0 != pCurrentMaterial->textureBump.length) {
mat->AddProperty(&pCurrentMaterial->textureBump, AI_MATKEY_TEXTURE_HEIGHT(0));
mat->AddProperty(&uvwIndex, 1, AI_MATKEY_UVWSRC_HEIGHT(0));
if (pCurrentMaterial->bump_multiplier != 1.0) {
mat->AddProperty(&pCurrentMaterial->bump_multiplier, 1, AI_MATKEY_OBJ_BUMPMULT_HEIGHT(0));
}
if (pCurrentMaterial->clamp[ObjFile::Material::TextureBumpType]) {
addTextureMappingModeProperty(mat, aiTextureType_HEIGHT);
}
@@ -665,6 +669,9 @@ void ObjFileImporter::createMaterials(const ObjFile::Model *pModel, aiScene *pSc
if (0 != pCurrentMaterial->textureNormal.length) {
mat->AddProperty(&pCurrentMaterial->textureNormal, AI_MATKEY_TEXTURE_NORMALS(0));
mat->AddProperty(&uvwIndex, 1, AI_MATKEY_UVWSRC_NORMALS(0));
if (pCurrentMaterial->bump_multiplier != 1.0) {
mat->AddProperty(&pCurrentMaterial->bump_multiplier, 1, AI_MATKEY_OBJ_BUMPMULT_NORMALS(0));
}
if (pCurrentMaterial->clamp[ObjFile::Material::TextureNormalType]) {
addTextureMappingModeProperty(mat, aiTextureType_NORMALS);
}

View File

@@ -472,7 +472,11 @@ void ObjFileMtlImporter::getTextureOption(bool &clamp, int &clampIndex, aiString
}
skipToken = 2;
} else if (!ASSIMP_strincmp(pPtr, BlendUOption.c_str(), static_cast<unsigned int>(BlendUOption.size())) || !ASSIMP_strincmp(pPtr, BlendVOption.c_str(), static_cast<unsigned int>(BlendVOption.size())) || !ASSIMP_strincmp(pPtr, BoostOption.c_str(), static_cast<unsigned int>(BoostOption.size())) || !ASSIMP_strincmp(pPtr, ResolutionOption.c_str(), static_cast<unsigned int>(ResolutionOption.size())) || !ASSIMP_strincmp(pPtr, BumpOption.c_str(), static_cast<unsigned int>(BumpOption.size())) || !ASSIMP_strincmp(pPtr, ChannelOption.c_str(), static_cast<unsigned int>(ChannelOption.size()))) {
} else if (!ASSIMP_strincmp(pPtr, BumpOption.c_str(), static_cast<unsigned int>(BumpOption.size()))) {
DataArrayIt it = getNextToken<DataArrayIt>(m_DataIt, m_DataItEnd);
getFloat(it, m_DataItEnd, m_pModel->m_pCurrentMaterial->bump_multiplier);
skipToken = 2;
} else if (!ASSIMP_strincmp(pPtr, BlendUOption.c_str(), static_cast<unsigned int>(BlendUOption.size())) || !ASSIMP_strincmp(pPtr, BlendVOption.c_str(), static_cast<unsigned int>(BlendVOption.size())) || !ASSIMP_strincmp(pPtr, BoostOption.c_str(), static_cast<unsigned int>(BoostOption.size())) || !ASSIMP_strincmp(pPtr, ResolutionOption.c_str(), static_cast<unsigned int>(ResolutionOption.size())) || !ASSIMP_strincmp(pPtr, ChannelOption.c_str(), static_cast<unsigned int>(ChannelOption.size()))) {
skipToken = 2;
} else if (!ASSIMP_strincmp(pPtr, ModifyMapOption.c_str(), static_cast<unsigned int>(ModifyMapOption.size()))) {
skipToken = 3;

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,
@@ -60,25 +58,11 @@ using namespace Assimp::Formatter;
#ifndef ASSIMP_BUILD_NO_COMPRESSED_X
#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
#include <zlib.h>
#else
#include "../contrib/zlib/zlib.h"
#endif
#include "Common/Compression.h"
// Magic identifier for MSZIP compressed data
#define MSZIP_MAGIC 0x4B43
#define MSZIP_BLOCK 32786
// ------------------------------------------------------------------------------------------------
// Dummy memory wrappers for use with zlib
static void *dummy_alloc(void * /*opaque*/, unsigned int items, unsigned int size) {
return ::operator new(items *size);
}
static void dummy_free(void * /*opaque*/, void *address) {
return ::operator delete(address);
}
constexpr unsigned int MSZIP_MAGIC = 0x4B43;
constexpr size_t MSZIP_BLOCK = 32786l;
#endif // !! ASSIMP_BUILD_NO_COMPRESSED_X
@@ -133,13 +117,13 @@ XFileParser::XFileParser(const std::vector<char> &pBuffer) :
mIsBinaryFormat = true;
compressed = true;
} else
ThrowException("Unsupported xfile format '", mP[8], mP[9], mP[10], mP[11], "'");
ThrowException("Unsupported x-file format '", mP[8], mP[9], mP[10], mP[11], "'");
// float size
mBinaryFloatSize = (unsigned int)(mP[12] - 48) * 1000 + (unsigned int)(mP[13] - 48) * 100 + (unsigned int)(mP[14] - 48) * 10 + (unsigned int)(mP[15] - 48);
if (mBinaryFloatSize != 32 && mBinaryFloatSize != 64)
ThrowException("Unknown float size ", mBinaryFloatSize, " specified in xfile header.");
ThrowException("Unknown float size ", mBinaryFloatSize, " specified in x-file header.");
// The x format specifies size in bits, but we work in bytes
mBinaryFloatSize /= 8;
@@ -171,16 +155,6 @@ XFileParser::XFileParser(const std::vector<char> &pBuffer) :
* ///////////////////////////////////////////////////////////////////////
*/
// build a zlib stream
z_stream stream;
stream.opaque = nullptr;
stream.zalloc = &dummy_alloc;
stream.zfree = &dummy_free;
stream.data_type = (mIsBinaryFormat ? Z_BINARY : Z_ASCII);
// initialize the inflation algorithm
::inflateInit2(&stream, -MAX_WBITS);
// skip unknown data (checksum, flags?)
mP += 6;
@@ -207,43 +181,29 @@ XFileParser::XFileParser(const std::vector<char> &pBuffer) :
// and advance to the next offset
P1 += ofs;
est_out += MSZIP_BLOCK; // one decompressed block is 32786 in size
est_out += MSZIP_BLOCK; // one decompressed block is 327861 in size
}
// Allocate storage and terminating zero and do the actual uncompressing
Compression compression;
uncompressed.resize(est_out + 1);
char *out = &uncompressed.front();
while (mP + 3 < mEnd) {
uint16_t ofs = *((uint16_t *)mP);
AI_SWAP2(ofs);
mP += 4;
if (compression.open(mIsBinaryFormat ? Compression::Format::Binary : Compression::Format::ASCII,
Compression::FlushMode::SyncFlush, -Compression::MaxWBits)) {
while (mP + 3 < mEnd) {
uint16_t ofs = *((uint16_t *)mP);
AI_SWAP2(ofs);
mP += 4;
if (mP + ofs > mEnd + 2) {
throw DeadlyImportError("X: Unexpected EOF in compressed chunk");
if (mP + ofs > mEnd + 2) {
throw DeadlyImportError("X: Unexpected EOF in compressed chunk");
}
out += compression.decompressBlock(mP, ofs, out, MSZIP_BLOCK);
mP += ofs;
}
// push data to the stream
stream.next_in = (Bytef *)mP;
stream.avail_in = ofs;
stream.next_out = (Bytef *)out;
stream.avail_out = MSZIP_BLOCK;
// and decompress the data ....
int ret = ::inflate(&stream, Z_SYNC_FLUSH);
if (ret != Z_OK && ret != Z_STREAM_END)
throw DeadlyImportError("X: Failed to decompress MSZIP-compressed data");
::inflateReset(&stream);
::inflateSetDictionary(&stream, (const Bytef *)out, MSZIP_BLOCK - stream.avail_out);
// and advance to the next offset
out += MSZIP_BLOCK - stream.avail_out;
mP += ofs;
compression.close();
}
// terminate zlib
::inflateEnd(&stream);
// ok, update pointers to point to the uncompressed file data
mP = &uncompressed[0];
mEnd = out;
@@ -279,15 +239,16 @@ void XFileParser::ParseFile() {
while (running) {
// read name of next object
std::string objectName = GetNextToken();
if (objectName.length() == 0)
if (objectName.length() == 0) {
break;
}
// parse specific object
if (objectName == "template")
if (objectName == "template") {
ParseDataObjectTemplate();
else if (objectName == "Frame")
} else if (objectName == "Frame") {
ParseDataObjectFrame(nullptr);
else if (objectName == "Mesh") {
} else if (objectName == "Mesh") {
// some meshes have no frames at all
Mesh *mesh = new Mesh;
ParseDataObjectMesh(mesh);
@@ -326,11 +287,13 @@ void XFileParser::ParseDataObjectTemplate() {
while (running) {
std::string s = GetNextToken();
if (s == "}")
if (s == "}") {
break;
}
if (s.length() == 0)
if (s.length() == 0) {
ThrowException("Unexpected end of file reached while parsing template definition");
}
}
}
@@ -500,7 +463,7 @@ void XFileParser::ParseDataObjectSkinWeights(Mesh *pMesh) {
bone.mWeights.reserve(numWeights);
for (unsigned int a = 0; a < numWeights; a++) {
BoneWeight weight;
BoneWeight weight = {};
weight.mVertex = ReadInt();
bone.mWeights.push_back(weight);
}

View File

@@ -44,28 +44,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_XGL_IMPORTER
#include "XGLLoader.h"
#include "Common/Compression.h"
#include <assimp/ParsingUtils.h>
#include <assimp/fast_atof.h>
#include <assimp/MemoryIOWrapper.h>
#include <assimp/StreamReader.h>
#include <assimp/importerdesc.h>
#include <assimp/mesh.h>
#include <assimp/scene.h>
#include <cctype>
#include <memory>
//#include <cctype>
//#include <memory>
using namespace Assimp;
// zlib is needed for compressed XGL files
#ifndef ASSIMP_BUILD_NO_COMPRESSED_XGL
# ifdef ASSIMP_BUILD_NO_OWN_ZLIB
# include <zlib.h>
# else
# include <contrib/zlib/zlib.h>
# endif
#endif
namespace Assimp { // this has to be in here because LogFunctions is in ::Assimp
template <>
@@ -73,6 +65,7 @@ const char *LogFunctions<XGLImporter>::Prefix() {
static auto prefix = "XGL: ";
return prefix;
}
} // namespace Assimp
static const aiImporterDesc desc = {
@@ -118,8 +111,8 @@ const aiImporterDesc *XGLImporter::GetInfo() const {
// ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure.
void XGLImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler) {
#ifndef ASSIMP_BUILD_NO_COMPRESSED_XGL
std::vector<Bytef> uncompressed;
#ifndef ASSIMP_BUILD_NO_COMPRESSED_XGL
std::vector<char> uncompressed;
#endif
m_scene = pScene;
@@ -137,48 +130,16 @@ void XGLImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
#else
std::unique_ptr<StreamReaderLE> raw_reader(new StreamReaderLE(stream));
// build a zlib stream
z_stream zstream;
zstream.opaque = Z_NULL;
zstream.zalloc = Z_NULL;
zstream.zfree = Z_NULL;
zstream.data_type = Z_BINARY;
// raw decompression without a zlib or gzip header
inflateInit2(&zstream, -MAX_WBITS);
// skip two extra bytes, zgl files do carry a crc16 upfront (I think)
raw_reader->IncPtr(2);
zstream.next_in = reinterpret_cast<Bytef *>(raw_reader->GetPtr());
zstream.avail_in = (uInt) raw_reader->GetRemainingSize();
size_t total = 0l;
// TODO: be smarter about this, decompress directly into heap buffer
// and decompress the data .... do 1k chunks in the hope that we won't kill the stack
#define MYBLOCK 1024
Bytef block[MYBLOCK];
int ret;
do {
zstream.avail_out = MYBLOCK;
zstream.next_out = block;
ret = inflate(&zstream, Z_NO_FLUSH);
if (ret != Z_STREAM_END && ret != Z_OK) {
ThrowException("Failure decompressing this file using gzip, seemingly it is NOT a compressed .XGL file");
}
const size_t have = MYBLOCK - zstream.avail_out;
total += have;
uncompressed.resize(total);
memcpy(uncompressed.data() + total - have, block, have);
} while (ret != Z_STREAM_END);
// terminate zlib
inflateEnd(&zstream);
Compression compression;
size_t total = 0l;
if (compression.open(Compression::Format::Binary, Compression::FlushMode::NoFlush, -Compression::MaxWBits)) {
// skip two extra bytes, zgl files do carry a crc16 upfront (I think)
raw_reader->IncPtr(2);
total = compression.decompress((unsigned char *)raw_reader->GetPtr(), raw_reader->GetRemainingSize(), uncompressed);
compression.close();
}
// replace the input stream with a memory stream
stream.reset(new MemoryIOStream(reinterpret_cast<uint8_t *>(uncompressed.data()), total));
stream.reset(new MemoryIOStream(reinterpret_cast<uint8_t*>(uncompressed.data()), total));
#endif
}
@@ -239,7 +200,7 @@ void XGLImporter::ReadWorld(XmlNode &node, TempScope &scope) {
if (!nd) {
ThrowException("failure reading <world>");
}
if (!nd->mName.length) {
if (nd->mName.length == 0) {
nd->mName.Set("WORLD");
}
@@ -291,7 +252,8 @@ aiNode *XGLImporter::ReadObject(XmlNode &node, TempScope &scope) {
const std::string &s = ai_stdStrToLower(child.name());
if (s == "mesh") {
const size_t prev = scope.meshes_linear.size();
if (ReadMesh(child, scope)) {
bool empty;
if (ReadMesh(child, scope, empty)) {
const size_t newc = scope.meshes_linear.size();
for (size_t i = 0; i < newc - prev; ++i) {
meshes.push_back(static_cast<unsigned int>(i + prev));
@@ -475,12 +437,12 @@ aiMesh *XGLImporter::ToOutputMesh(const TempMaterialMesh &m) {
}
// ------------------------------------------------------------------------------------------------
bool XGLImporter::ReadMesh(XmlNode &node, TempScope &scope) {
bool XGLImporter::ReadMesh(XmlNode &node, TempScope &scope, bool &empty) {
TempMesh t;
std::map<unsigned int, TempMaterialMesh> bymat;
const unsigned int mesh_id = ReadIDAttr(node);
bool empty_mesh = true;
for (XmlNode &child : node.children()) {
const std::string &s = ai_stdStrToLower(child.name());
@@ -539,6 +501,9 @@ bool XGLImporter::ReadMesh(XmlNode &node, TempScope &scope) {
mid = ResolveMaterialRef(sub_child, scope);
}
}
if (has[0] || has[1] || has[2]) {
empty_mesh = false;
}
if (mid == ~0u) {
ThrowException("missing material index");
@@ -590,6 +555,11 @@ bool XGLImporter::ReadMesh(XmlNode &node, TempScope &scope) {
scope.meshes.insert(std::pair<unsigned int, aiMesh *>(mesh_id, m));
}
}
if (empty_mesh) {
LogWarn("Mesh is empty, skipping.");
empty = empty_mesh;
return false;
}
// no id == not a reference, insert this mesh right *here*
return mesh_id == ~0u;
@@ -759,7 +729,7 @@ aiVector2D XGLImporter::ReadVec2(XmlNode &node) {
std::string val;
XmlParser::getValueAsString(node, val);
const char *s = val.c_str();
ai_real v[2];
ai_real v[2] = {};
for (int i = 0; i < 2; ++i) {
if (!SkipSpaces(&s)) {
LogError("unexpected EOL, failed to parse vec2");
@@ -814,4 +784,4 @@ aiColor3D XGLImporter::ReadCol3(XmlNode &node) {
return aiColor3D(v.x, v.y, v.z);
}
#endif
#endif // ASSIMP_BUILD_NO_XGL_IMPORTER

View File

@@ -186,7 +186,7 @@ private:
void ReadLighting(XmlNode &node, TempScope &scope);
aiLight *ReadDirectionalLight(XmlNode &node);
aiNode *ReadObject(XmlNode &node, TempScope &scope);
bool ReadMesh(XmlNode &node, TempScope &scope);
bool ReadMesh(XmlNode &node, TempScope &scope, bool &empty);
void ReadMaterial(XmlNode &node, TempScope &scope);
aiVector2D ReadVec2(XmlNode &node);
aiVector3D ReadVec3(XmlNode &node);

View File

@@ -166,6 +166,8 @@ SET( Logging_SRCS
SOURCE_GROUP(Logging FILES ${Logging_SRCS})
SET( Common_SRCS
Common/Compression.cpp
Common/Compression.h
Common/BaseImporter.cpp
Common/BaseProcess.cpp
Common/BaseProcess.h
@@ -1315,11 +1317,10 @@ ENDIF ()
INSTALL( TARGETS assimp
EXPORT "${TARGETS_EXPORT_NAME}"
LIBRARY DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
ARCHIVE DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
RUNTIME DESTINATION ${ASSIMP_BIN_INSTALL_DIR}
FRAMEWORK DESTINATION ${ASSIMP_LIB_INSTALL_DIR}
COMPONENT ${LIBASSIMP_COMPONENT}
LIBRARY DESTINATION ${ASSIMP_LIB_INSTALL_DIR} COMPONENT ${LIBASSIMP_COMPONENT}
ARCHIVE DESTINATION ${ASSIMP_LIB_INSTALL_DIR} COMPONENT ${LIBASSIMP-DEV_COMPONENT}
RUNTIME DESTINATION ${ASSIMP_BIN_INSTALL_DIR} COMPONENT ${LIBASSIMP_COMPONENT}
FRAMEWORK DESTINATION ${ASSIMP_LIB_INSTALL_DIR} COMPONENT ${LIBASSIMP_COMPONENT}
INCLUDES DESTINATION ${ASSIMP_INCLUDE_INSTALL_DIR}
)
INSTALL( FILES ${PUBLIC_HEADERS} DESTINATION ${ASSIMP_INCLUDE_INSTALL_DIR}/assimp COMPONENT assimp-dev)

View File

@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2021, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.
@@ -57,7 +57,7 @@ static const uint8_t tableDecodeBase64[128] = {
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 0, 0, 0, 0, 0
};
static const char* tableEncodeBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
static const char *tableEncodeBase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
static inline char EncodeChar(uint8_t b) {
return tableEncodeBase64[size_t(b)];
@@ -104,17 +104,16 @@ void Encode(const uint8_t *in, size_t inLength, std::string &out) {
}
}
void Encode(const std::vector<uint8_t>& in, std::string &out) {
Encode (in.data (), in.size (), out);
void Encode(const std::vector<uint8_t> &in, std::string &out) {
Encode(in.data(), in.size(), out);
}
std::string Encode (const std::vector<uint8_t>& in) {
std::string Encode(const std::vector<uint8_t> &in) {
std::string encoded;
Encode (in, encoded);
Encode(in, encoded);
return encoded;
}
size_t Decode(const char *in, size_t inLength, uint8_t *&out) {
if (inLength % 4 != 0) {
throw DeadlyImportError("Invalid base64 encoded data: \"", std::string(in, std::min(size_t(32), inLength)), "\", length:", inLength);
@@ -159,23 +158,22 @@ size_t Decode(const char *in, size_t inLength, uint8_t *&out) {
return outLength;
}
size_t Decode(const std::string& in, std::vector<uint8_t>& out) {
uint8_t* outPtr = nullptr;
size_t decodedSize = Decode (in.data (), in.size (), outPtr);
size_t Decode(const std::string &in, std::vector<uint8_t> &out) {
uint8_t *outPtr = nullptr;
size_t decodedSize = Decode(in.data(), in.size(), outPtr);
if (outPtr == nullptr) {
return 0;
}
out.assign (outPtr, outPtr + decodedSize);
out.assign(outPtr, outPtr + decodedSize);
delete[] outPtr;
return decodedSize;
}
std::vector<uint8_t> Decode (const std::string& in) {
std::vector<uint8_t> Decode(const std::string &in) {
std::vector<uint8_t> result;
Decode (in, result);
Decode(in, result);
return result;
}
}
}
} // namespace Base64
} // namespace Assimp

214
code/Common/Compression.cpp Normal file
View File

@@ -0,0 +1,214 @@
/*
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 "Compression.h"
#include <assimp/ai_assert.h>
#include <assimp/Exceptional.h>
namespace Assimp {
struct Compression::impl {
bool mOpen;
z_stream mZSstream;
FlushMode mFlushMode;
impl() :
mOpen(false),
mZSstream(),
mFlushMode(Compression::FlushMode::NoFlush) {
// empty
}
};
Compression::Compression() :
mImpl(new impl) {
// empty
}
Compression::~Compression() {
ai_assert(mImpl != nullptr);
delete mImpl;
}
bool Compression::open(Format format, FlushMode flush, int windowBits) {
ai_assert(mImpl != nullptr);
if (mImpl->mOpen) {
return false;
}
// build a zlib stream
mImpl->mZSstream.opaque = Z_NULL;
mImpl->mZSstream.zalloc = Z_NULL;
mImpl->mZSstream.zfree = Z_NULL;
mImpl->mFlushMode = flush;
if (format == Format::Binary) {
mImpl->mZSstream.data_type = Z_BINARY;
} else {
mImpl->mZSstream.data_type = Z_ASCII;
}
// raw decompression without a zlib or gzip header
if (windowBits == 0) {
inflateInit(&mImpl->mZSstream);
} else {
inflateInit2(&mImpl->mZSstream, windowBits);
}
mImpl->mOpen = true;
return mImpl->mOpen;
}
static int getFlushMode(Compression::FlushMode flush) {
int z_flush = 0;
switch (flush) {
case Compression::FlushMode::NoFlush:
z_flush = Z_NO_FLUSH;
break;
case Compression::FlushMode::Block:
z_flush = Z_BLOCK;
break;
case Compression::FlushMode::Tree:
z_flush = Z_TREES;
break;
case Compression::FlushMode::SyncFlush:
z_flush = Z_SYNC_FLUSH;
break;
case Compression::FlushMode::Finish:
z_flush = Z_FINISH;
break;
default:
ai_assert(false);
break;
}
return z_flush;
}
constexpr size_t MYBLOCK = 32786;
size_t Compression::decompress(const void *data, size_t in, std::vector<char> &uncompressed) {
ai_assert(mImpl != nullptr);
if (data == nullptr || in == 0) {
return 0l;
}
mImpl->mZSstream.next_in = (Bytef*)(data);
mImpl->mZSstream.avail_in = (uInt)in;
int ret = 0;
size_t total = 0l;
const int flushMode = getFlushMode(mImpl->mFlushMode);
if (flushMode == Z_FINISH) {
mImpl->mZSstream.avail_out = static_cast<uInt>(uncompressed.size());
mImpl->mZSstream.next_out = reinterpret_cast<Bytef *>(&*uncompressed.begin());
ret = inflate(&mImpl->mZSstream, Z_FINISH);
if (ret != Z_STREAM_END && ret != Z_OK) {
throw DeadlyImportError("Compression", "Failure decompressing this file using gzip.");
}
total = mImpl->mZSstream.avail_out;
} else {
do {
Bytef block[MYBLOCK] = {};
mImpl->mZSstream.avail_out = MYBLOCK;
mImpl->mZSstream.next_out = block;
ret = inflate(&mImpl->mZSstream, flushMode);
if (ret != Z_STREAM_END && ret != Z_OK) {
throw DeadlyImportError("Compression", "Failure decompressing this file using gzip.");
}
const size_t have = MYBLOCK - mImpl->mZSstream.avail_out;
total += have;
uncompressed.resize(total);
::memcpy(uncompressed.data() + total - have, block, have);
} while (ret != Z_STREAM_END);
}
return total;
}
size_t Compression::decompressBlock(const void *data, size_t in, char *out, size_t availableOut) {
ai_assert(mImpl != nullptr);
if (data == nullptr || in == 0 || out == nullptr || availableOut == 0) {
return 0l;
}
// push data to the stream
mImpl->mZSstream.next_in = (Bytef *)data;
mImpl->mZSstream.avail_in = (uInt)in;
mImpl->mZSstream.next_out = (Bytef *)out;
mImpl->mZSstream.avail_out = (uInt)availableOut;
// and decompress the data ....
int ret = ::inflate(&mImpl->mZSstream, Z_SYNC_FLUSH);
if (ret != Z_OK && ret != Z_STREAM_END) {
throw DeadlyImportError("X: Failed to decompress MSZIP-compressed data");
}
::inflateReset(&mImpl->mZSstream);
::inflateSetDictionary(&mImpl->mZSstream, (const Bytef *)out, (uInt)availableOut - mImpl->mZSstream.avail_out);
return availableOut - (size_t)mImpl->mZSstream.avail_out;
}
bool Compression::isOpen() const {
ai_assert(mImpl != nullptr);
return mImpl->mOpen;
}
bool Compression::close() {
ai_assert(mImpl != nullptr);
if (!mImpl->mOpen) {
return false;
}
inflateEnd(&mImpl->mZSstream);
mImpl->mOpen = false;
return true;
}
} // namespace Assimp

121
code/Common/Compression.h Normal file
View File

@@ -0,0 +1,121 @@
/*
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.
----------------------------------------------------------------------
*/
#pragma once
#ifdef ASSIMP_BUILD_NO_OWN_ZLIB
#include <zlib.h>
#else
#include "../contrib/zlib/zlib.h"
#endif
#include <vector>
#include <cstddef> // size_t
namespace Assimp {
/// @brief This class provides the decompression of zlib-compressed data.
class Compression {
public:
static const int MaxWBits = MAX_WBITS;
/// @brief Describes the format data type
enum class Format {
InvalidFormat = -1, ///< Invalid enum type.
Binary = 0, ///< Binary format.
ASCII, ///< ASCII format.
NumFormats ///< The number of supported formats.
};
/// @brief The supported flush mode, used for blocked access.
enum class FlushMode {
InvalidFormat = -1, ///< Invalid enum type.
NoFlush = 0, ///< No flush, will be done on inflate end.
Block, ///< Assists in combination of compress.
Tree, ///< Assists in combination of compress and returns if stream is finish.
SyncFlush, ///< Synced flush mode.
Finish, ///< Finish mode, all in once, no block access.
NumModes ///< The number of supported modes.
};
/// @brief The class constructor.
Compression();
/// @brief The class destructor.
~Compression();
/// @brief Will open the access to the compression.
/// @param[in] format The format type
/// @param[in] flush The flush mode.
/// @param[in] windowBits The windows history working size, shall be between 8 and 15.
/// @return true if close was successful, false if not.
bool open(Format format, FlushMode flush, int windowBits);
/// @brief Will return the open state.
/// @return true if the access is opened, false if not.
bool isOpen() const;
/// @brief Will close the decompress access.
/// @return true if close was successful, false if not.
bool close();
/// @brief Will decompress the data buffer in one step.
/// @param[in] data The data to decompress
/// @param[in] in The size of the data.
/// @param[out uncompressed A std::vector containing the decompressed data.
size_t decompress(const void *data, size_t in, std::vector<char> &uncompressed);
/// @brief Will decompress the data buffer block-wise.
/// @param[in] data The compressed data
/// @param[in] in The size of the data buffer
/// @param[out] out The output buffer
/// @param[out] availableOut The upper limit of the output buffer.
/// @return The size of the decompressed data buffer.
size_t decompressBlock(const void *data, size_t in, char *out, size_t availableOut);
private:
struct impl;
impl *mImpl;
};
} // namespace Assimp

View File

@@ -3,7 +3,7 @@
Open Asset Import Library (assimp)
---------------------------------------------------------------------------
Copyright (c) 2006-2019, assimp team
Copyright (c) 2006-2022, assimp team
All rights reserved.

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,

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,

View File

@@ -191,9 +191,9 @@ bool CalcTangentsProcess::ProcessMesh(aiMesh *pMesh, unsigned int meshIndex) {
tangent.x = (w.x * sy - v.x * ty) * dirCorrection;
tangent.y = (w.y * sy - v.y * ty) * dirCorrection;
tangent.z = (w.z * sy - v.z * ty) * dirCorrection;
bitangent.x = (w.x * sx - v.x * tx) * dirCorrection;
bitangent.y = (w.y * sx - v.y * tx) * dirCorrection;
bitangent.z = (w.z * sx - v.z * tx) * dirCorrection;
bitangent.x = (- w.x * sx + v.x * tx) * dirCorrection;
bitangent.y = (- w.y * sx + v.y * tx) * dirCorrection;
bitangent.z = (- w.z * sx + v.z * tx) * dirCorrection;
// store for every vertex of that face
for (unsigned int b = 0; b < face.mNumIndices; ++b) {
@@ -201,7 +201,7 @@ bool CalcTangentsProcess::ProcessMesh(aiMesh *pMesh, unsigned int meshIndex) {
// project tangent and bitangent into the plane formed by the vertex' normal
aiVector3D localTangent = tangent - meshNorm[p] * (tangent * meshNorm[p]);
aiVector3D localBitangent = bitangent - meshNorm[p] * (bitangent * meshNorm[p]);
aiVector3D localBitangent = bitangent - meshNorm[p] * (bitangent * meshNorm[p]) - localTangent * (bitangent * localTangent);
localTangent.NormalizeSafe();
localBitangent.NormalizeSafe();

View File

@@ -221,7 +221,7 @@ bool FindDegeneratesProcess::ExecuteOnMesh( aiMesh* mesh) {
if ( mConfigCheckAreaOfTriangle ) {
if ( face.mNumIndices == 3 ) {
ai_real area = calculateAreaOfTriangle( face, mesh );
if ( area < 1e-6 ) {
if (area < ai_epsilon) {
if ( mConfigRemoveDegenerates ) {
remove_me[ a ] = true;
++deg;

View File

@@ -50,6 +50,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
namespace Assimp {
namespace Base64 {
/// @brief Will encode the given
/// @param in
/// @param inLength
/// @param out
void Encode(const uint8_t *in, size_t inLength, std::string &out);
void Encode(const std::vector<uint8_t>& in, std::string &out);
std::string Encode(const std::vector<uint8_t>& in);

View File

@@ -0,0 +1,77 @@
/*
---------------------------------------------------------------------------
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.
---------------------------------------------------------------------------
*/
/** @file OBJMATERIAL.h
* @brief Obj-specific material macros
*
*/
#ifndef AI_OBJMATERIAL_H_INC
#define AI_OBJMATERIAL_H_INC
#ifdef __GNUC__
# pragma GCC system_header
#endif
#include <assimp/material.h>
// ---------------------------------------------------------------------------
// Pure key names for all obj texture-related properties
//! @cond MATS_DOC_FULL
// support for bump -bm
#define _AI_MATKEY_OBJ_BUMPMULT_BASE "$tex.bumpmult"
//! @endcond
// ---------------------------------------------------------------------------
#define AI_MATKEY_OBJ_BUMPMULT(type, N) _AI_MATKEY_OBJ_BUMPMULT_BASE, type, N
//! @cond MATS_DOC_FULL
#define AI_MATKEY_OBJ_BUMPMULT_NORMALS(N) \
AI_MATKEY_OBJ_BUMPMULT(aiTextureType_NORMALS, N)
#define AI_MATKEY_OBJ_BUMPMULT_HEIGHT(N) \
AI_MATKEY_OBJ_BUMPMULT(aiTextureType_HEIGHT, N)
//! @endcond
#endif

View File

@@ -279,11 +279,11 @@ typedef unsigned int ai_uint;
#define AI_MATH_HALF_PI_F (AI_MATH_PI_F * 0.5f)
/* Tiny macro to convert from radians to degrees and back */
#define AI_DEG_TO_RAD(x) ((x) * (ai_real)0.0174532925)
#define AI_RAD_TO_DEG(x) ((x) * (ai_real)57.2957795)
#define AI_DEG_TO_RAD(x) ((x) * (ai_real) 0.0174532925)
#define AI_RAD_TO_DEG(x) ((x) * (ai_real) 57.2957795)
/* Numerical limits */
static const ai_real ai_epsilon = (ai_real)0.00001;
static const ai_real ai_epsilon = (ai_real) 1e-6;
/* Support for big-endian builds */
#if defined(__BYTE_ORDER__)

View File

@@ -95,7 +95,7 @@ public:
bool operator== (const aiMatrix3x3t<TReal>& m) const;
bool operator!= (const aiMatrix3x3t<TReal>& m) const;
bool Equal(const aiMatrix3x3t<TReal>& m, TReal epsilon = 1e-6) const;
bool Equal(const aiMatrix3x3t<TReal> &m, TReal epsilon = ai_epsilon) const;
template <typename TOther>
operator aiMatrix3x3t<TOther> () const;

View File

@@ -110,7 +110,7 @@ public:
bool operator== (const aiMatrix4x4t& m) const;
bool operator!= (const aiMatrix4x4t& m) const;
bool Equal(const aiMatrix4x4t& m, TReal epsilon = 1e-6) const;
bool Equal(const aiMatrix4x4t &m, TReal epsilon = ai_epsilon) const;
// matrix multiplication.
aiMatrix4x4t& operator *= (const aiMatrix4x4t& m);

View File

@@ -92,7 +92,7 @@ public:
// transform vector by matrix
aiQuaterniont& operator *= (const aiMatrix4x4t<TReal>& mat);
bool Equal(const aiQuaterniont& o, TReal epsilon = 1e-6) const;
bool Equal(const aiQuaterniont &o, TReal epsilon = ai_epsilon) const;
public:

View File

@@ -85,7 +85,7 @@ public:
bool operator== (const aiVector2t& other) const;
bool operator!= (const aiVector2t& other) const;
bool Equal(const aiVector2t& other, TReal epsilon = 1e-6) const;
bool Equal(const aiVector2t &other, TReal epsilon = ai_epsilon) const;
aiVector2t& operator= (TReal f);
const aiVector2t SymMul(const aiVector2t& o);

View File

@@ -114,7 +114,7 @@ public:
bool operator < (const aiVector3t& other) const;
/// @brief
bool Equal(const aiVector3t& other, TReal epsilon = 1e-6) const;
bool Equal(const aiVector3t &other, TReal epsilon = ai_epsilon) const;
template <typename TOther>
operator aiVector3t<TOther> () const;

View File

@@ -53,7 +53,7 @@ using namespace Assimp;
class utFBXImporterExporter : public AbstractImportExportBase {
public:
virtual bool importerTest() {
bool importerTest() override {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/FBX/spider.fbx", aiProcess_ValidateDataStructure);
return nullptr != scene;

View File

@@ -573,7 +573,7 @@ TEST_F(utglTF2ImportExport, export_normalized_normals) {
scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/BoxBadNormals-glTF-Binary/BoxBadNormals_out.glb", aiProcess_ValidateDataStructure);
for ( auto i = 0u; i < scene->mMeshes[0]->mNumVertices; ++i ) {
const auto length = scene->mMeshes[0]->mNormals[i].Length();
EXPECT_TRUE(abs(length) < 1e-6 || abs(length - 1) < 1e-6);
EXPECT_TRUE(abs(length) < 1e-6 || abs(length - 1) < ai_epsilon);
}
}