closes https://github.com/assimp/assimp/issues/1044: set default value in case of light intensity envelopes-

pull/3495/head
Kim Kulling 2020-11-11 19:38:42 +01:00
parent de610b8ce9
commit 456b54988a
14 changed files with 2039 additions and 2374 deletions

View File

@ -123,20 +123,20 @@ const aiImporterDesc *FBXImporter::GetInfo() const {
// ------------------------------------------------------------------------------------------------
// Setup configuration properties for the loader
void FBXImporter::SetupProperties(const Importer *pImp) {
settings.readAllLayers = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_GEOMETRY_LAYERS, true);
settings.readAllMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_MATERIALS, false);
settings.readMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_MATERIALS, true);
settings.readTextures = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_TEXTURES, true);
settings.readCameras = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_CAMERAS, true);
settings.readLights = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_LIGHTS, true);
settings.readAnimations = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ANIMATIONS, true);
settings.readWeights = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_WEIGHTS, true);
settings.strictMode = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_STRICT_MODE, false);
settings.preservePivots = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS, true);
settings.optimizeEmptyAnimationCurves = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES, true);
settings.useLegacyEmbeddedTextureNaming = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING, false);
settings.removeEmptyBones = pImp->GetPropertyBool(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true);
settings.convertToMeters = pImp->GetPropertyBool(AI_CONFIG_FBX_CONVERT_TO_M, false);
mSettings.readAllLayers = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_GEOMETRY_LAYERS, true);
mSettings.readAllMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_MATERIALS, false);
mSettings.readMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_MATERIALS, true);
mSettings.readTextures = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_TEXTURES, true);
mSettings.readCameras = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_CAMERAS, true);
mSettings.readLights = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_LIGHTS, true);
mSettings.readAnimations = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ANIMATIONS, true);
mSettings.readWeights = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_WEIGHTS, true);
mSettings.strictMode = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_STRICT_MODE, false);
mSettings.preservePivots = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS, true);
mSettings.optimizeEmptyAnimationCurves = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES, true);
mSettings.useLegacyEmbeddedTextureNaming = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING, false);
mSettings.removeEmptyBones = pImp->GetPropertyBool(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true);
mSettings.convertToMeters = pImp->GetPropertyBool(AI_CONFIG_FBX_CONVERT_TO_M, false);
}
// ------------------------------------------------------------------------------------------------
@ -181,10 +181,10 @@ void FBXImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
Parser parser(tokens, is_binary);
// take the raw parse-tree and convert it to a FBX DOM
Document doc(parser, settings);
Document doc(parser, mSettings);
// convert the FBX DOM to aiScene
ConvertToAssimpScene(pScene, doc, settings.removeEmptyBones);
ConvertToAssimpScene(pScene, doc, mSettings.removeEmptyBones);
// size relative to cm
float size_relative_to_cm = doc.GlobalSettings().UnitScaleFactor();

View File

@ -70,27 +70,16 @@ typedef class basic_formatter<char, std::char_traits<char>, std::allocator<char>
class FBXImporter : public BaseImporter, public LogFunctions<FBXImporter> {
public:
FBXImporter();
virtual ~FBXImporter();
// --------------------
bool CanRead(const std::string &pFile,
IOSystem *pIOHandler,
bool checkSig) const;
~FBXImporter() override;
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const;
protected:
// --------------------
const aiImporterDesc *GetInfo() const;
// --------------------
void SetupProperties(const Importer *pImp);
// --------------------
void InternReadFile(const std::string &pFile,
aiScene *pScene,
IOSystem *pIOHandler);
void InternReadFile(const std::string &pFile, aiScene *pScene, IOSystem *pIOHandler);
private:
FBX::ImportSettings settings;
FBX::ImportSettings mSettings;
}; // !class FBXImporter
} // end of namespace Assimp

View File

@ -48,12 +48,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <functional>
#include "FBXMeshGeometry.h"
#include "FBXDocument.h"
#include "FBXImporter.h"
#include "FBXImportSettings.h"
#include "FBXDocumentUtil.h"
#include "FBXImportSettings.h"
#include "FBXImporter.h"
#include "FBXMeshGeometry.h"
namespace Assimp {
namespace FBX {
@ -61,10 +60,8 @@ namespace FBX {
using namespace Util;
// ------------------------------------------------------------------------------------------------
Geometry::Geometry(uint64_t id, const Element& element, const std::string& name, const Document& doc)
: Object(id, element, name)
, skin()
{
Geometry::Geometry(uint64_t id, const Element &element, const std::string &name, const Document &doc) :
Object(id, element, name), skin() {
const std::vector<const Connection *> &conns = doc.GetConnectionsByDestinationSequenced(ID(), "Deformer");
for (const Connection *con : conns) {
const Skin *const sk = ProcessSimpleConnection<Skin>(*con, false, "Skin -> Geometry", element);
@ -79,8 +76,7 @@ Geometry::Geometry(uint64_t id, const Element& element, const std::string& name,
}
// ------------------------------------------------------------------------------------------------
Geometry::~Geometry()
{
Geometry::~Geometry() {
// empty
}
@ -95,9 +91,8 @@ const Skin* Geometry::DeformerSkin() const {
}
// ------------------------------------------------------------------------------------------------
MeshGeometry::MeshGeometry(uint64_t id, const Element& element, const std::string& name, const Document& doc)
: Geometry(id, element,name, doc)
{
MeshGeometry::MeshGeometry(uint64_t id, const Element &element, const std::string &name, const Document &doc) :
Geometry(id, element, name, doc) {
const Scope *sc = element.Compound();
if (!sc) {
DOMError("failed to read Geometry object (class: Mesh), no data scope found");
@ -183,8 +178,7 @@ MeshGeometry::MeshGeometry(uint64_t id, const Element& element, const std::strin
if (doc.Settings().readAllLayers || index == 0) {
const Scope &layer = GetRequiredScope(*(*it).second);
ReadLayer(layer);
}
else {
} else {
FBXImporter::LogWarn("ignoring additional geometry layers");
}
}
@ -269,15 +263,13 @@ unsigned int MeshGeometry::FaceForVertexIndex( unsigned int in_index ) const {
const std::vector<unsigned int>::iterator it = std::upper_bound(
m_facesVertexStartIndices.begin(),
m_facesVertexStartIndices.end(),
in_index
);
in_index);
return static_cast<unsigned int>(std::distance(m_facesVertexStartIndices.begin(), it - 1));
}
// ------------------------------------------------------------------------------------------------
void MeshGeometry::ReadLayer(const Scope& layer)
{
void MeshGeometry::ReadLayer(const Scope &layer) {
const ElementCollection &LayerElement = layer.GetCollection("LayerElement");
for (ElementMap::const_iterator eit = LayerElement.first; eit != LayerElement.second; ++eit) {
const Scope &elayer = GetRequiredScope(*(*eit).second);
@ -286,10 +278,8 @@ void MeshGeometry::ReadLayer(const Scope& layer)
}
}
// ------------------------------------------------------------------------------------------------
void MeshGeometry::ReadLayerElement(const Scope& layerElement)
{
void MeshGeometry::ReadLayerElement(const Scope &layerElement) {
const Element &Type = GetRequiredElement(layerElement, "Type");
const Element &TypedIndex = GetRequiredElement(layerElement, "TypedIndex");
@ -312,15 +302,12 @@ void MeshGeometry::ReadLayerElement(const Scope& layerElement)
}
// ------------------------------------------------------------------------------------------------
void MeshGeometry::ReadVertexData(const std::string& type, int index, const Scope& source)
{
void MeshGeometry::ReadVertexData(const std::string &type, int index, const Scope &source) {
const std::string &MappingInformationType = ParseTokenAsString(GetRequiredToken(
GetRequiredElement(source,"MappingInformationType"),0)
);
GetRequiredElement(source, "MappingInformationType"), 0));
const std::string &ReferenceInformationType = ParseTokenAsString(GetRequiredToken(
GetRequiredElement(source,"ReferenceInformationType"),0)
);
GetRequiredElement(source, "ReferenceInformationType"), 0));
if (type == "LayerElementUV") {
if (index >= AI_MAX_NUMBER_OF_TEXTURECOORDS) {
@ -337,10 +324,8 @@ void MeshGeometry::ReadVertexData(const std::string& type, int index, const Scop
ReadVertexDataUV(m_uvs[index], source,
MappingInformationType,
ReferenceInformationType
);
}
else if (type == "LayerElementMaterial") {
ReferenceInformationType);
} else if (type == "LayerElementMaterial") {
if (m_materials.size() > 0) {
FBXImporter::LogError("ignoring additional material layer");
return;
@ -350,8 +335,7 @@ void MeshGeometry::ReadVertexData(const std::string& type, int index, const Scop
ReadVertexDataMaterials(temp_materials, source,
MappingInformationType,
ReferenceInformationType
);
ReferenceInformationType);
// sometimes, there will be only negative entries. Drop the material
// layer in such a case (I guess it means a default material should
@ -366,8 +350,7 @@ void MeshGeometry::ReadVertexData(const std::string& type, int index, const Scop
}
std::swap(temp_materials, m_materials);
}
else if (type == "LayerElementNormal") {
} else if (type == "LayerElementNormal") {
if (m_normals.size() > 0) {
FBXImporter::LogError("ignoring additional normal layer");
return;
@ -375,10 +358,8 @@ void MeshGeometry::ReadVertexData(const std::string& type, int index, const Scop
ReadVertexDataNormals(m_normals, source,
MappingInformationType,
ReferenceInformationType
);
}
else if (type == "LayerElementTangent") {
ReferenceInformationType);
} else if (type == "LayerElementTangent") {
if (m_tangents.size() > 0) {
FBXImporter::LogError("ignoring additional tangent layer");
return;
@ -386,10 +367,8 @@ void MeshGeometry::ReadVertexData(const std::string& type, int index, const Scop
ReadVertexDataTangents(m_tangents, source,
MappingInformationType,
ReferenceInformationType
);
}
else if (type == "LayerElementBinormal") {
ReferenceInformationType);
} else if (type == "LayerElementBinormal") {
if (m_binormals.size() > 0) {
FBXImporter::LogError("ignoring additional binormal layer");
return;
@ -397,10 +376,8 @@ void MeshGeometry::ReadVertexData(const std::string& type, int index, const Scop
ReadVertexDataBinormals(m_binormals, source,
MappingInformationType,
ReferenceInformationType
);
}
else if (type == "LayerElementColor") {
ReferenceInformationType);
} else if (type == "LayerElementColor") {
if (index >= AI_MAX_NUMBER_OF_COLOR_SETS) {
FBXImporter::LogError(Formatter::format("ignoring vertex color layer, maximum number of color sets exceeded: ")
<< index << " (limit is " << AI_MAX_NUMBER_OF_COLOR_SETS << ")");
@ -409,8 +386,7 @@ void MeshGeometry::ReadVertexData(const std::string& type, int index, const Scop
ReadVertexDataColors(m_colors[index], source,
MappingInformationType,
ReferenceInformationType
);
ReferenceInformationType);
}
}
@ -427,8 +403,7 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
size_t vertex_count,
const std::vector<unsigned int> &mapping_counts,
const std::vector<unsigned int> &mapping_offsets,
const std::vector<unsigned int>& mappings)
{
const std::vector<unsigned int> &mappings) {
bool isDirect = ReferenceInformationType == "Direct";
bool isIndexToDirect = ReferenceInformationType == "IndexToDirect";
@ -461,8 +436,7 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
data_out[mappings[j]] = tempData[i];
}
}
}
else if (MappingInformationType == "ByVertice" && isIndexToDirect) {
} else if (MappingInformationType == "ByVertice" && isIndexToDirect) {
std::vector<T> tempData;
ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName));
@ -487,21 +461,18 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
data_out[mappings[j]] = tempData[uvIndices[i]];
}
}
}
else if (MappingInformationType == "ByPolygonVertex" && isDirect) {
} else if (MappingInformationType == "ByPolygonVertex" && isDirect) {
std::vector<T> tempData;
ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName));
if (tempData.size() != vertex_count) {
FBXImporter::LogError(Formatter::format("length of input data unexpected for ByPolygon mapping: ")
<< tempData.size() << ", expected " << vertex_count
);
<< tempData.size() << ", expected " << vertex_count);
return;
}
data_out.swap(tempData);
}
else if (MappingInformationType == "ByPolygonVertex" && isIndexToDirect) {
} else if (MappingInformationType == "ByPolygonVertex" && isIndexToDirect) {
std::vector<T> tempData;
ParseVectorDataArray(tempData, GetRequiredElement(source, dataElementName));
@ -529,8 +500,7 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
data_out[next++] = tempData[i];
}
}
else {
} else {
FBXImporter::LogError(Formatter::format("ignoring vertex data channel, access type not implemented: ")
<< MappingInformationType << "," << ReferenceInformationType);
}
@ -539,8 +509,7 @@ void ResolveVertexDataArray(std::vector<T>& data_out, const Scope& source,
// ------------------------------------------------------------------------------------------------
void MeshGeometry::ReadVertexDataNormals(std::vector<aiVector3D> &normals_out, const Scope &source,
const std::string &MappingInformationType,
const std::string& ReferenceInformationType)
{
const std::string &ReferenceInformationType) {
ResolveVertexDataArray(normals_out, source, MappingInformationType, ReferenceInformationType,
"Normals",
"NormalsIndex",
@ -553,8 +522,7 @@ void MeshGeometry::ReadVertexDataNormals(std::vector<aiVector3D>& normals_out, c
// ------------------------------------------------------------------------------------------------
void MeshGeometry::ReadVertexDataUV(std::vector<aiVector2D> &uv_out, const Scope &source,
const std::string &MappingInformationType,
const std::string& ReferenceInformationType)
{
const std::string &ReferenceInformationType) {
ResolveVertexDataArray(uv_out, source, MappingInformationType, ReferenceInformationType,
"UV",
"UVIndex",
@ -567,8 +535,7 @@ void MeshGeometry::ReadVertexDataUV(std::vector<aiVector2D>& uv_out, const Scope
// ------------------------------------------------------------------------------------------------
void MeshGeometry::ReadVertexDataColors(std::vector<aiColor4D> &colors_out, const Scope &source,
const std::string &MappingInformationType,
const std::string& ReferenceInformationType)
{
const std::string &ReferenceInformationType) {
ResolveVertexDataArray(colors_out, source, MappingInformationType, ReferenceInformationType,
"Colors",
"ColorIndex",
@ -584,8 +551,7 @@ static const char *TangentsIndexToken = "TangentsIndex";
void MeshGeometry::ReadVertexDataTangents(std::vector<aiVector3D> &tangents_out, const Scope &source,
const std::string &MappingInformationType,
const std::string& ReferenceInformationType)
{
const std::string &ReferenceInformationType) {
const char *str = source.Elements().count("Tangents") > 0 ? "Tangents" : "Tangent";
const char *strIdx = source.Elements().count("Tangents") > 0 ? TangentsIndexToken : TangentIndexToken;
ResolveVertexDataArray(tangents_out, source, MappingInformationType, ReferenceInformationType,
@ -603,8 +569,7 @@ static const std::string BinormalsIndexToken = "BinormalsIndex";
void MeshGeometry::ReadVertexDataBinormals(std::vector<aiVector3D> &binormals_out, const Scope &source,
const std::string &MappingInformationType,
const std::string& ReferenceInformationType)
{
const std::string &ReferenceInformationType) {
const char *str = source.Elements().count("Binormals") > 0 ? "Binormals" : "Binormal";
const char *strIdx = source.Elements().count("Binormals") > 0 ? BinormalsIndexToken.c_str() : BinormalIndexToken.c_str();
ResolveVertexDataArray(binormals_out, source, MappingInformationType, ReferenceInformationType,
@ -616,15 +581,12 @@ void MeshGeometry::ReadVertexDataBinormals(std::vector<aiVector3D>& binormals_ou
m_mappings);
}
// ------------------------------------------------------------------------------------------------
void MeshGeometry::ReadVertexDataMaterials(std::vector<int> &materials_out, const Scope &source,
const std::string &MappingInformationType,
const std::string& ReferenceInformationType)
{
const std::string &ReferenceInformationType) {
const size_t face_count = m_faces.size();
if( 0 == face_count )
{
if (0 == face_count) {
return;
}
@ -650,8 +612,7 @@ void MeshGeometry::ReadVertexDataMaterials(std::vector<int>& materials_out, cons
if (materials_out.size() != face_count) {
FBXImporter::LogError(Formatter::format("length of input data unexpected for ByPolygon mapping: ")
<< materials_out.size() << ", expected " << face_count
);
<< materials_out.size() << ", expected " << face_count);
return;
}
} else {
@ -660,8 +621,8 @@ void MeshGeometry::ReadVertexDataMaterials(std::vector<int>& materials_out, cons
}
}
// ------------------------------------------------------------------------------------------------
ShapeGeometry::ShapeGeometry(uint64_t id, const Element& element, const std::string& name, const Document& doc)
: Geometry(id, element, name, doc) {
ShapeGeometry::ShapeGeometry(uint64_t id, const Element &element, const std::string &name, const Document &doc) :
Geometry(id, element, name, doc) {
const Scope *sc = element.Compound();
if (nullptr == sc) {
DOMError("failed to read Geometry object (class: Shape), no data scope found");
@ -691,9 +652,8 @@ const std::vector<unsigned int>& ShapeGeometry::GetIndices() const {
return m_indices;
}
// ------------------------------------------------------------------------------------------------
LineGeometry::LineGeometry(uint64_t id, const Element& element, const std::string& name, const Document& doc)
: Geometry(id, element, name, doc)
{
LineGeometry::LineGeometry(uint64_t id, const Element &element, const std::string &name, const Document &doc) :
Geometry(id, element, name, doc) {
const Scope *sc = element.Compound();
if (!sc) {
DOMError("failed to read Geometry object (class: Line), no data scope found");
@ -716,7 +676,6 @@ const std::vector<aiVector3D>& LineGeometry::GetVertices() const {
const std::vector<int> &LineGeometry::GetIndices() const {
return m_indices;
}
} // !FBX
} // !Assimp
} // namespace FBX
} // namespace Assimp
#endif

View File

@ -52,13 +52,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "../contrib/zlib/zlib.h"
#endif
#include "FBXTokenizer.h"
#include "FBXParser.h"
#include "FBXTokenizer.h"
#include "FBXUtil.h"
#include <assimp/ByteSwapper.h>
#include <assimp/ParsingUtils.h>
#include <assimp/fast_atof.h>
#include <assimp/ByteSwapper.h>
#include <assimp/DefaultLogger.hpp>
#include <iostream>
@ -71,25 +71,21 @@ namespace {
// ------------------------------------------------------------------------------------------------
// signal parse error, this is always unrecoverable. Throws DeadlyImportError.
AI_WONT_RETURN void ParseError(const std::string &message, const Token &token) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void ParseError(const std::string& message, const Token& token)
{
AI_WONT_RETURN void ParseError(const std::string &message, const Token &token) {
throw DeadlyImportError("FBX-Parser", Util::GetTokenText(&token), message);
}
// ------------------------------------------------------------------------------------------------
AI_WONT_RETURN void ParseError(const std::string &message, const Element *element = nullptr) AI_WONT_RETURN_SUFFIX;
AI_WONT_RETURN void ParseError(const std::string& message, const Element* element)
{
AI_WONT_RETURN void ParseError(const std::string &message, const Element *element) {
if (element) {
ParseError(message, element->KeyToken());
}
throw DeadlyImportError("FBX-Parser ", message);
}
// ------------------------------------------------------------------------------------------------
void ParseError(const std::string& message, TokenPtr token)
{
void ParseError(const std::string &message, TokenPtr token) {
if (token) {
ParseError(message, *token);
}
@ -109,15 +105,14 @@ namespace {
::memcpy(&result, data, sizeof(T));
return result;
}
}
} // namespace
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();
@ -160,19 +155,16 @@ Element::Element(const Token& key_token, Parser& parser)
parser.AdvanceToNextToken();
return;
}
}
while(n->Type() != TokenType_KEY && n->Type() != TokenType_CLOSE_BRACKET);
} while (n->Type() != TokenType_KEY && n->Type() != TokenType_CLOSE_BRACKET);
}
// ------------------------------------------------------------------------------------------------
Element::~Element()
{
Element::~Element() {
// no need to delete tokens, they are owned by the parser
}
// ------------------------------------------------------------------------------------------------
Scope::Scope(Parser& parser,bool topLevel)
{
Scope::Scope(Parser &parser, bool topLevel) {
if (!topLevel) {
TokenPtr t = parser.CurrentToken();
if (t->Type() != TokenType_OPEN_BRACKET) {
@ -206,34 +198,26 @@ Scope::Scope(Parser& parser,bool topLevel)
}
// ------------------------------------------------------------------------------------------------
Scope::~Scope()
{
Scope::~Scope() {
for (ElementMap::value_type &v : elements) {
delete v.second;
}
}
// ------------------------------------------------------------------------------------------------
Parser::Parser (const TokenList& tokens, bool is_binary)
: tokens(tokens)
, last()
, current()
, cursor(tokens.begin())
, is_binary(is_binary)
{
Parser::Parser(const TokenList &tokens, bool is_binary) :
tokens(tokens), last(), current(), cursor(tokens.begin()), is_binary(is_binary) {
ASSIMP_LOG_DEBUG("Parsing FBX tokens");
root.reset(new Scope(*this, true));
}
// ------------------------------------------------------------------------------------------------
Parser::~Parser()
{
Parser::~Parser() {
// empty
}
// ------------------------------------------------------------------------------------------------
TokenPtr Parser::AdvanceToNextToken()
{
TokenPtr Parser::AdvanceToNextToken() {
last = current;
if (cursor == tokens.end()) {
current = nullptr;
@ -244,20 +228,17 @@ TokenPtr Parser::AdvanceToNextToken()
}
// ------------------------------------------------------------------------------------------------
TokenPtr Parser::CurrentToken() const
{
TokenPtr Parser::CurrentToken() const {
return current;
}
// ------------------------------------------------------------------------------------------------
TokenPtr Parser::LastToken() const
{
TokenPtr Parser::LastToken() const {
return last;
}
// ------------------------------------------------------------------------------------------------
uint64_t ParseTokenAsID(const Token& t, const char*& err_out)
{
uint64_t ParseTokenAsID(const Token &t, const char *&err_out) {
err_out = nullptr;
if (t.Type() != TokenType_DATA) {
@ -265,8 +246,7 @@ uint64_t ParseTokenAsID(const Token& t, const char*& err_out)
return 0L;
}
if(t.IsBinary())
{
if (t.IsBinary()) {
const char *data = t.begin();
if (data[0] != 'L') {
err_out = "failed to parse ID, unexpected data type, expected L(ong) (binary)";
@ -293,8 +273,7 @@ uint64_t ParseTokenAsID(const Token& t, const char*& err_out)
}
// ------------------------------------------------------------------------------------------------
size_t ParseTokenAsDim(const Token& t, const char*& err_out)
{
size_t ParseTokenAsDim(const Token &t, const char *&err_out) {
// same as ID parsing, except there is a trailing asterisk
err_out = nullptr;
@ -303,8 +282,7 @@ size_t ParseTokenAsDim(const Token& t, const char*& err_out)
return 0;
}
if(t.IsBinary())
{
if (t.IsBinary()) {
const char *data = t.begin();
if (data[0] != 'L') {
err_out = "failed to parse ID, unexpected data type, expected L(ong) (binary)";
@ -338,10 +316,8 @@ size_t ParseTokenAsDim(const Token& t, const char*& err_out)
return id;
}
// ------------------------------------------------------------------------------------------------
float ParseTokenAsFloat(const Token& t, const char*& err_out)
{
float ParseTokenAsFloat(const Token &t, const char *&err_out) {
err_out = nullptr;
if (t.Type() != TokenType_DATA) {
@ -349,8 +325,7 @@ float ParseTokenAsFloat(const Token& t, const char*& err_out)
return 0.0f;
}
if(t.IsBinary())
{
if (t.IsBinary()) {
const char *data = t.begin();
if (data[0] != 'F' && data[0] != 'D') {
err_out = "failed to parse F(loat) or D(ouble), unexpected data type (binary)";
@ -359,8 +334,7 @@ float ParseTokenAsFloat(const Token& t, const char*& err_out)
if (data[0] == 'F') {
return SafeParse<float>(data + 1, t.end());
}
else {
} else {
return static_cast<float>(SafeParse<double>(data + 1, t.end()));
}
}
@ -381,10 +355,8 @@ float ParseTokenAsFloat(const Token& t, const char*& err_out)
return fast_atof(temp);
}
// ------------------------------------------------------------------------------------------------
int ParseTokenAsInt(const Token& t, const char*& err_out)
{
int ParseTokenAsInt(const Token &t, const char *&err_out) {
err_out = nullptr;
if (t.Type() != TokenType_DATA) {
@ -392,8 +364,7 @@ int ParseTokenAsInt(const Token& t, const char*& err_out)
return 0;
}
if(t.IsBinary())
{
if (t.IsBinary()) {
const char *data = t.begin();
if (data[0] != 'I') {
err_out = "failed to parse I(nt), unexpected data type (binary)";
@ -417,10 +388,8 @@ int ParseTokenAsInt(const Token& t, const char*& err_out)
return intval;
}
// ------------------------------------------------------------------------------------------------
int64_t ParseTokenAsInt64(const Token& t, const char*& err_out)
{
int64_t ParseTokenAsInt64(const Token &t, const char *&err_out) {
err_out = nullptr;
if (t.Type() != TokenType_DATA) {
@ -428,8 +397,7 @@ int64_t ParseTokenAsInt64(const Token& t, const char*& err_out)
return 0L;
}
if (t.IsBinary())
{
if (t.IsBinary()) {
const char *data = t.begin();
if (data[0] != 'L') {
err_out = "failed to parse Int64, unexpected data type";
@ -456,8 +424,7 @@ int64_t ParseTokenAsInt64(const Token& t, const char*& err_out)
}
// ------------------------------------------------------------------------------------------------
std::string ParseTokenAsString(const Token& t, const char*& err_out)
{
std::string ParseTokenAsString(const Token &t, const char *&err_out) {
err_out = nullptr;
if (t.Type() != TokenType_DATA) {
@ -465,8 +432,7 @@ std::string ParseTokenAsString(const Token& t, const char*& err_out)
return "";
}
if(t.IsBinary())
{
if (t.IsBinary()) {
const char *data = t.begin();
if (data[0] != 'S') {
err_out = "failed to parse S(tring), unexpected data type (binary)";
@ -496,14 +462,12 @@ std::string ParseTokenAsString(const Token& t, const char*& err_out)
return std::string(s + 1, length - 2);
}
namespace {
// ------------------------------------------------------------------------------------------------
// read the type code and element count of a binary data array and stop there
void ReadBinaryDataArrayHead(const char *&data, const char *end, char &type, uint32_t &count,
const Element& el)
{
const Element &el) {
if (static_cast<size_t>(end - data) < 5) {
ParseError("binary data array is too short, need five (5) bytes for type signature and element count", &el);
}
@ -519,13 +483,11 @@ void ReadBinaryDataArrayHead(const char*& data, const char* end, char& type, uin
data += 5;
}
// ------------------------------------------------------------------------------------------------
// 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*/)
{
const Element & /*el*/) {
BE_NCONST uint32_t encmode = SafeParse<uint32_t>(data, end);
AI_SWAP4(encmode);
data += 4;
@ -539,8 +501,7 @@ void ReadBinaryDataArray(char type, uint32_t count, const char*& data, const cha
// determine the length of the uncompressed data by looking at the type signature
uint32_t stride = 0;
switch(type)
{
switch (type) {
case 'f':
case 'i':
stride = 4;
@ -563,8 +524,7 @@ void ReadBinaryDataArray(char type, uint32_t count, const char*& data, const cha
// plain data, no compression
std::copy(data, end, buff.begin());
}
else if(encmode == 1) {
} else if (encmode == 1) {
// zlib/deflate, next comes ZIP head (0x78 0x01)
// see http://www.ietf.org/rfc/rfc1950.txt
@ -604,13 +564,11 @@ void ReadBinaryDataArray(char type, uint32_t count, const char*& data, const cha
ai_assert(data == end);
}
} // !anon
} // namespace
// ------------------------------------------------------------------------------------------------
// read an array of float3 tuples
void ParseVectorDataArray(std::vector<aiVector3D>& out, const Element& el)
{
void ParseVectorDataArray(std::vector<aiVector3D> &out, const Element &el) {
out.resize(0);
const TokenList &tok = el.Tokens();
@ -660,8 +618,7 @@ void ParseVectorDataArray(std::vector<aiVector3D>& out, const Element& el)
stream << " vec3.x = " << vec3.x << " vec3.y = " << vec3.y << " vec3.z = " << vec3.z << std::endl;
DefaultLogger::get()->info( stream.str() );
}*/
}
else if (type == 'f') {
} else if (type == 'f') {
const float *f = reinterpret_cast<const float *>(&buff[0]);
for (unsigned int i = 0; i < count3; ++i, f += 3) {
out.push_back(aiVector3D(f[0], f[1], f[2]));
@ -694,11 +651,9 @@ void ParseVectorDataArray(std::vector<aiVector3D>& out, const Element& el)
}
}
// ------------------------------------------------------------------------------------------------
// read an array of color4 tuples
void ParseVectorDataArray(std::vector<aiColor4D>& out, const Element& el)
{
void ParseVectorDataArray(std::vector<aiColor4D> &out, const Element &el) {
out.resize(0);
const TokenList &tok = el.Tokens();
if (tok.empty()) {
@ -741,8 +696,7 @@ void ParseVectorDataArray(std::vector<aiColor4D>& out, const Element& el)
static_cast<float>(d[2]),
static_cast<float>(d[3])));
}
}
else if (type == 'f') {
} else if (type == 'f') {
const float *f = reinterpret_cast<const float *>(&buff[0]);
for (unsigned int i = 0; i < count4; ++i, f += 4) {
out.push_back(aiColor4D(f[0], f[1], f[2], f[3]));
@ -773,11 +727,9 @@ 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()) {
@ -818,8 +770,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]));
@ -849,11 +800,9 @@ 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()) {
@ -907,11 +856,9 @@ void ParseVectorDataArray(std::vector<int>& out, const Element& el)
}
}
// ------------------------------------------------------------------------------------------------
// read an array of floats
void ParseVectorDataArray(std::vector<float>& out, const Element& el)
{
void ParseVectorDataArray(std::vector<float> &out, const Element &el) {
out.resize(0);
const TokenList &tok = el.Tokens();
if (tok.empty()) {
@ -944,8 +891,7 @@ void ParseVectorDataArray(std::vector<float>& out, const Element& el)
for (unsigned int i = 0; i < count; ++i, ++d) {
out.push_back(static_cast<float>(*d));
}
}
else if (type == 'f') {
} else if (type == 'f') {
const float *f = reinterpret_cast<const float *>(&buff[0]);
for (unsigned int i = 0; i < count; ++i, ++f) {
out.push_back(*f);
@ -971,8 +917,7 @@ void ParseVectorDataArray(std::vector<float>& out, const Element& el)
// ------------------------------------------------------------------------------------------------
// read an array of uints
void ParseVectorDataArray(std::vector<unsigned int>& out, const Element& el)
{
void ParseVectorDataArray(std::vector<unsigned int> &out, const Element &el) {
out.resize(0);
const TokenList &tok = el.Tokens();
if (tok.empty()) {
@ -1033,11 +978,9 @@ void ParseVectorDataArray(std::vector<unsigned int>& out, const Element& el)
}
}
// ------------------------------------------------------------------------------------------------
// read an array of uint64_ts
void ParseVectorDataArray(std::vector<uint64_t>& out, const Element& el)
{
void ParseVectorDataArray(std::vector<uint64_t> &out, const Element &el) {
out.resize(0);
const TokenList &tok = el.Tokens();
if (tok.empty()) {
@ -1094,8 +1037,7 @@ void ParseVectorDataArray(std::vector<uint64_t>& out, const Element& el)
// ------------------------------------------------------------------------------------------------
// read an array of int64_ts
void ParseVectorDataArray(std::vector<int64_t>& out, const Element& el)
{
void ParseVectorDataArray(std::vector<int64_t> &out, const Element &el) {
out.resize(0);
const TokenList &tok = el.Tokens();
if (tok.empty()) {
@ -1151,8 +1093,7 @@ void ParseVectorDataArray(std::vector<int64_t>& out, const Element& el)
}
// ------------------------------------------------------------------------------------------------
aiMatrix4x4 ReadMatrix(const Element& element)
{
aiMatrix4x4 ReadMatrix(const Element &element) {
std::vector<float> values;
ParseVectorDataArray(values, element);
@ -1162,7 +1103,6 @@ aiMatrix4x4 ReadMatrix(const Element& element)
aiMatrix4x4 result;
result.a1 = values[0];
result.a2 = values[1];
result.a3 = values[2];
@ -1187,11 +1127,9 @@ aiMatrix4x4 ReadMatrix(const Element& element)
return result;
}
// ------------------------------------------------------------------------------------------------
// wrapper around ParseTokenAsString() with ParseError handling
std::string ParseTokenAsString(const Token& t)
{
std::string ParseTokenAsString(const Token &t) {
const char *err;
const std::string &i = ParseTokenAsString(t, err);
if (err) {
@ -1211,8 +1149,7 @@ bool HasElement( const Scope& sc, const std::string& index ) {
// ------------------------------------------------------------------------------------------------
// extract a required element from a scope, abort if the element cannot be found
const Element& GetRequiredElement(const Scope& sc, const std::string& index, const Element* element /*= nullptr*/)
{
const Element &GetRequiredElement(const Scope &sc, const std::string &index, const Element *element /*= nullptr*/) {
const Element *el = sc[index];
if (!el) {
ParseError("did not find required element \"" + index + "\"", element);
@ -1220,11 +1157,9 @@ const Element& GetRequiredElement(const Scope& sc, const std::string& index, con
return *el;
}
// ------------------------------------------------------------------------------------------------
// extract required compound scope
const Scope& GetRequiredScope(const Element& el)
{
const Scope &GetRequiredScope(const Element &el) {
const Scope *const s = el.Compound();
if (!s) {
ParseError("expected compound scope", &el);
@ -1233,11 +1168,9 @@ const Scope& GetRequiredScope(const Element& el)
return *s;
}
// ------------------------------------------------------------------------------------------------
// get token at a particular index
const Token& GetRequiredToken(const Element& el, unsigned int index)
{
const Token &GetRequiredToken(const Element &el, unsigned int index) {
const TokenList &t = el.Tokens();
if (index >= t.size()) {
ParseError(Formatter::format("missing token at index ") << index, &el);
@ -1246,11 +1179,9 @@ const Token& GetRequiredToken(const Element& el, unsigned int index)
return *t[index];
}
// ------------------------------------------------------------------------------------------------
// wrapper around ParseTokenAsID() with ParseError handling
uint64_t ParseTokenAsID(const Token& t)
{
uint64_t ParseTokenAsID(const Token &t) {
const char *err;
const uint64_t i = ParseTokenAsID(t, err);
if (err) {
@ -1259,11 +1190,9 @@ uint64_t ParseTokenAsID(const Token& t)
return i;
}
// ------------------------------------------------------------------------------------------------
// wrapper around ParseTokenAsDim() with ParseError handling
size_t ParseTokenAsDim(const Token& t)
{
size_t ParseTokenAsDim(const Token &t) {
const char *err;
const size_t i = ParseTokenAsDim(t, err);
if (err) {
@ -1272,11 +1201,9 @@ size_t ParseTokenAsDim(const Token& t)
return i;
}
// ------------------------------------------------------------------------------------------------
// wrapper around ParseTokenAsFloat() with ParseError handling
float ParseTokenAsFloat(const Token& t)
{
float ParseTokenAsFloat(const Token &t) {
const char *err;
const float i = ParseTokenAsFloat(t, err);
if (err) {
@ -1287,8 +1214,7 @@ float ParseTokenAsFloat(const Token& t)
// ------------------------------------------------------------------------------------------------
// wrapper around ParseTokenAsInt() with ParseError handling
int ParseTokenAsInt(const Token& t)
{
int ParseTokenAsInt(const Token &t) {
const char *err;
const int i = ParseTokenAsInt(t, err);
if (err) {
@ -1299,8 +1225,7 @@ int ParseTokenAsInt(const Token& t)
// ------------------------------------------------------------------------------------------------
// wrapper around ParseTokenAsInt64() with ParseError handling
int64_t ParseTokenAsInt64(const Token& t)
{
int64_t ParseTokenAsInt64(const Token &t) {
const char *err;
const int64_t i = ParseTokenAsInt64(t, err);
if (err) {
@ -1309,7 +1234,7 @@ int64_t ParseTokenAsInt64(const Token& t)
return i;
}
} // !FBX
} // !Assimp
} // namespace FBX
} // namespace Assimp
#endif

View File

@ -66,8 +66,7 @@ void TempOpening::Transform(const IfcMatrix4& mat) {
}
// ------------------------------------------------------------------------------------------------
aiMesh* TempMesh::ToMesh()
{
aiMesh *TempMesh::ToMesh() {
ai_assert(mVerts.size() == std::accumulate(mVertcnt.begin(), mVertcnt.end(), size_t(0)));
if (mVerts.empty()) {
@ -105,36 +104,31 @@ aiMesh* TempMesh::ToMesh()
}
// ------------------------------------------------------------------------------------------------
void TempMesh::Clear()
{
void TempMesh::Clear() {
mVerts.clear();
mVertcnt.clear();
}
// ------------------------------------------------------------------------------------------------
void TempMesh::Transform(const IfcMatrix4& mat)
{
void TempMesh::Transform(const IfcMatrix4 &mat) {
for (IfcVector3 &v : mVerts) {
v *= mat;
}
}
// ------------------------------------------------------------------------------
IfcVector3 TempMesh::Center() const
{
IfcVector3 TempMesh::Center() const {
return (mVerts.size() == 0) ? IfcVector3(0.0f, 0.0f, 0.0f) : (std::accumulate(mVerts.begin(), mVerts.end(), IfcVector3()) / static_cast<IfcFloat>(mVerts.size()));
}
// ------------------------------------------------------------------------------------------------
void TempMesh::Append(const TempMesh& other)
{
void TempMesh::Append(const TempMesh &other) {
mVerts.insert(mVerts.end(), other.mVerts.begin(), other.mVerts.end());
mVertcnt.insert(mVertcnt.end(), other.mVertcnt.begin(), other.mVertcnt.end());
}
// ------------------------------------------------------------------------------------------------
void TempMesh::RemoveDegenerates()
{
void TempMesh::RemoveDegenerates() {
// The strategy is simple: walk the mesh and compute normals using
// Newell's algorithm. The length of the normals gives the area
// of the polygons, which is close to zero for lines.
@ -167,11 +161,10 @@ void TempMesh::RemoveDegenerates()
}
// ------------------------------------------------------------------------------------------------
IfcVector3 TempMesh::ComputePolygonNormal(const IfcVector3* vtcs, size_t cnt, bool normalize)
{
std::vector<IfcFloat> temp((cnt+2)*3);
for( size_t vofs = 0, i = 0; vofs < cnt; ++vofs )
{
IfcVector3 TempMesh::ComputePolygonNormal(const IfcVector3 *vtcs, size_t cnt, bool normalize) {
const size_t Capa = cnt + 2;
std::vector<IfcFloat> temp((Capa)*3);
for (size_t vofs = 0, i = 0; vofs < cnt; ++vofs) {
const IfcVector3 &v = vtcs[vofs];
temp[i++] = v.x;
temp[i++] = v.y;
@ -179,22 +172,19 @@ IfcVector3 TempMesh::ComputePolygonNormal(const IfcVector3* vtcs, size_t cnt, bo
}
IfcVector3 nor;
NewellNormal<3, 3, 3>(nor, static_cast<int>(cnt), &temp[0], &temp[1], &temp[2]);
NewellNormal<3, 3, 3>(nor, static_cast<int>(cnt), &temp[0], &temp[1], &temp[2], Capa);
return normalize ? nor.Normalize() : nor;
}
// ------------------------------------------------------------------------------------------------
void TempMesh::ComputePolygonNormals(std::vector<IfcVector3>& normals,
bool normalize,
size_t ofs) const
{
void TempMesh::ComputePolygonNormals(std::vector<IfcVector3> &normals, bool normalize, size_t ofs) const {
size_t max_vcount = 0;
std::vector<unsigned int>::const_iterator begin = mVertcnt.begin() + ofs, end = mVertcnt.end(), iit;
for (iit = begin; iit != end; ++iit) {
max_vcount = std::max(max_vcount, static_cast<size_t>(*iit));
}
std::vector<IfcFloat> temp((max_vcount+2)*4);
const size_t Capa = max_vcount + 2;
std::vector<IfcFloat> temp(Capa * 4);
normals.reserve(normals.size() + mVertcnt.size() - ofs);
// `NewellNormal()` currently has a relatively strange interface and need to
@ -217,7 +207,7 @@ void TempMesh::ComputePolygonNormals(std::vector<IfcVector3>& normals,
}
normals.push_back(IfcVector3());
NewellNormal<4,4,4>(normals.back(),*iit,&temp[0],&temp[1],&temp[2]);
NewellNormal<4, 4, 4>(normals.back(), *iit, &temp[0], &temp[1], &temp[2], Capa);
}
if (normalize) {
@ -229,30 +219,26 @@ 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;
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) { }
FindVector(const IfcVector3 &p) :
v(p) {}
bool operator()(const IfcVector3 &p) { return FuzzyVectorCompare(1e-6)(p, v); }
};
// ------------------------------------------------------------------------------------------------
void TempMesh::FixupFaceOrientation()
{
void TempMesh::FixupFaceOrientation() {
const IfcVector3 vavg = Center();
// create a list of start indices for all faces to allow random access to faces
@ -262,18 +248,15 @@ void TempMesh::FixupFaceOrientation()
// list all faces on a vertex
std::map<IfcVector3, std::vector<size_t>, CompareVector> facesByVertex;
for( size_t a = 0; a < mVertcnt.size(); ++a )
{
for (size_t a = 0; a < mVertcnt.size(); ++a) {
for (size_t b = 0; b < mVertcnt[a]; ++b)
facesByVertex[mVerts[faceStartIndices[a] + b]].push_back(a);
}
// determine neighbourhood for all polys
std::vector<size_t> neighbour(mVerts.size(), SIZE_MAX);
std::vector<size_t> tempIntersect(10);
for( size_t a = 0; a < mVertcnt.size(); ++a )
{
for( size_t b = 0; b < mVertcnt[a]; ++b )
{
for (size_t a = 0; a < mVertcnt.size(); ++a) {
for (size_t b = 0; b < mVertcnt[a]; ++b) {
size_t ib = faceStartIndices[a] + b, nib = faceStartIndices[a] + (b + 1) % mVertcnt[a];
const std::vector<size_t> &facesOnB = facesByVertex[mVerts[ib]];
const std::vector<size_t> &facesOnNB = facesByVertex[mVerts[nib]];
@ -294,30 +277,31 @@ void TempMesh::FixupFaceOrientation()
// facing outwards. So we reverse this face to point outwards in relation to the center. Then we adapt neighbouring
// faces to have the same winding until all faces have been tested.
std::vector<bool> faceDone(mVertcnt.size(), false);
while( std::count(faceDone.begin(), faceDone.end(), false) != 0 )
{
while (std::count(faceDone.begin(), faceDone.end(), false) != 0) {
// find the farthest of the remaining faces
size_t farthestIndex = SIZE_MAX;
IfcFloat farthestDistance = -1.0;
for( size_t a = 0; a < mVertcnt.size(); ++a )
{
for (size_t a = 0; a < mVertcnt.size(); ++a) {
if (faceDone[a])
continue;
IfcVector3 faceCenter = std::accumulate(mVerts.begin() + faceStartIndices[a],
mVerts.begin() + faceStartIndices[a] + mVertcnt[a], IfcVector3(0.0)) / IfcFloat(mVertcnt[a]);
mVerts.begin() + faceStartIndices[a] + mVertcnt[a], IfcVector3(0.0)) /
IfcFloat(mVertcnt[a]);
IfcFloat dst = (faceCenter - vavg).SquareLength();
if( dst > farthestDistance ) { farthestDistance = dst; farthestIndex = a; }
if (dst > farthestDistance) {
farthestDistance = dst;
farthestIndex = a;
}
}
// calculate its normal and reverse the poly if its facing towards the mesh center
IfcVector3 farthestNormal = ComputePolygonNormal(mVerts.data() + faceStartIndices[farthestIndex], mVertcnt[farthestIndex]);
IfcVector3 farthestCenter = std::accumulate(mVerts.begin() + faceStartIndices[farthestIndex],
mVerts.begin() + faceStartIndices[farthestIndex] + mVertcnt[farthestIndex], IfcVector3(0.0))
/ IfcFloat(mVertcnt[farthestIndex]);
mVerts.begin() + faceStartIndices[farthestIndex] + mVertcnt[farthestIndex], IfcVector3(0.0)) /
IfcFloat(mVertcnt[farthestIndex]);
// We accept a bit of negative orientation without reversing. In case of doubt, prefer the orientation given in
// the file.
if( (farthestNormal * (farthestCenter - vavg).Normalize()) < -0.4 )
{
if ((farthestNormal * (farthestCenter - vavg).Normalize()) < -0.4) {
size_t fsi = faceStartIndices[farthestIndex], fvc = mVertcnt[farthestIndex];
std::reverse(mVerts.begin() + fsi, mVerts.begin() + fsi + fvc);
std::reverse(neighbour.begin() + fsi, neighbour.begin() + fsi + fvc);
@ -334,15 +318,13 @@ void TempMesh::FixupFaceOrientation()
todo.push_back(farthestIndex);
// go over its neighbour faces recursively and adapt their winding order to match the farthest face
while( !todo.empty() )
{
while (!todo.empty()) {
size_t tdf = todo.back();
size_t vsi = faceStartIndices[tdf], vc = mVertcnt[tdf];
todo.pop_back();
// check its neighbours
for( size_t a = 0; a < vc; ++a )
{
for (size_t a = 0; a < vc; ++a) {
// ignore neighbours if we already checked them
size_t nbi = neighbour[vsi + a];
if (nbi == SIZE_MAX || faceDone[nbi])
@ -358,8 +340,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(1e-6)(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) {
@ -390,7 +371,6 @@ void TempMesh::RemoveAdjacentDuplicates() {
IfcVector3 vmin, vmax;
ArrayBounds(&*base, cnt, vmin, vmax);
const IfcFloat epsilon = (vmax - vmin).SquareLength() / static_cast<IfcFloat>(1e9);
//const IfcFloat dotepsilon = 1e-9;
@ -442,78 +422,58 @@ void TempMesh::RemoveAdjacentDuplicates() {
}
// ------------------------------------------------------------------------------------------------
void TempMesh::Swap(TempMesh& other)
{
void TempMesh::Swap(TempMesh &other) {
mVertcnt.swap(other.mVertcnt);
mVerts.swap(other.mVerts);
}
// ------------------------------------------------------------------------------------------------
bool IsTrue(const ::Assimp::STEP::EXPRESS::BOOLEAN& in)
{
bool IsTrue(const ::Assimp::STEP::EXPRESS::BOOLEAN &in) {
return (std::string)in == "TRUE" || (std::string)in == "T";
}
// ------------------------------------------------------------------------------------------------
IfcFloat ConvertSIPrefix(const std::string& prefix)
{
IfcFloat ConvertSIPrefix(const std::string &prefix) {
if (prefix == "EXA") {
return 1e18f;
}
else if (prefix == "PETA") {
} else if (prefix == "PETA") {
return 1e15f;
}
else if (prefix == "TERA") {
} else if (prefix == "TERA") {
return 1e12f;
}
else if (prefix == "GIGA") {
} else if (prefix == "GIGA") {
return 1e9f;
}
else if (prefix == "MEGA") {
} else if (prefix == "MEGA") {
return 1e6f;
}
else if (prefix == "KILO") {
} else if (prefix == "KILO") {
return 1e3f;
}
else if (prefix == "HECTO") {
} else if (prefix == "HECTO") {
return 1e2f;
}
else if (prefix == "DECA") {
} else if (prefix == "DECA") {
return 1e-0f;
}
else if (prefix == "DECI") {
} else if (prefix == "DECI") {
return 1e-1f;
}
else if (prefix == "CENTI") {
} else if (prefix == "CENTI") {
return 1e-2f;
}
else if (prefix == "MILLI") {
} else if (prefix == "MILLI") {
return 1e-3f;
}
else if (prefix == "MICRO") {
} else if (prefix == "MICRO") {
return 1e-6f;
}
else if (prefix == "NANO") {
} else if (prefix == "NANO") {
return 1e-9f;
}
else if (prefix == "PICO") {
} else if (prefix == "PICO") {
return 1e-12f;
}
else if (prefix == "FEMTO") {
} else if (prefix == "FEMTO") {
return 1e-15f;
}
else if (prefix == "ATTO") {
} else if (prefix == "ATTO") {
return 1e-18f;
}
else {
} else {
IFCImporter::LogError("Unrecognized SI prefix: " + prefix);
return 1;
}
}
// ------------------------------------------------------------------------------------------------
void ConvertColor(aiColor4D& out, const Schema_2x3::IfcColourRgb& in)
{
void ConvertColor(aiColor4D &out, const Schema_2x3::IfcColourRgb &in) {
out.r = static_cast<float>(in.Red);
out.g = static_cast<float>(in.Green);
out.b = static_cast<float>(in.Blue);
@ -521,8 +481,7 @@ void ConvertColor(aiColor4D& out, const Schema_2x3::IfcColourRgb& in)
}
// ------------------------------------------------------------------------------------------------
void ConvertColor(aiColor4D& out, const Schema_2x3::IfcColourOrFactor& in,ConversionData& conv,const aiColor4D* base)
{
void ConvertColor(aiColor4D &out, const Schema_2x3::IfcColourOrFactor &in, ConversionData &conv, const aiColor4D *base) {
if (const ::Assimp::STEP::EXPRESS::REAL *const r = in.ToPtr<::Assimp::STEP::EXPRESS::REAL>()) {
out.r = out.g = out.b = static_cast<float>(*r);
if (base) {
@ -530,20 +489,17 @@ void ConvertColor(aiColor4D& out, const Schema_2x3::IfcColourOrFactor& in,Conver
out.g *= static_cast<float>(base->g);
out.b *= static_cast<float>(base->b);
out.a = static_cast<float>(base->a);
}
else out.a = 1.0;
}
else if (const Schema_2x3::IfcColourRgb* const rgb = in.ResolveSelectPtr<Schema_2x3::IfcColourRgb>(conv.db)) {
} else
out.a = 1.0;
} else if (const Schema_2x3::IfcColourRgb *const rgb = in.ResolveSelectPtr<Schema_2x3::IfcColourRgb>(conv.db)) {
ConvertColor(out, *rgb);
}
else {
} else {
IFCImporter::LogWarn("skipping unknown IfcColourOrFactor entity");
}
}
// ------------------------------------------------------------------------------------------------
void ConvertCartesianPoint(IfcVector3& out, const Schema_2x3::IfcCartesianPoint& in)
{
void ConvertCartesianPoint(IfcVector3 &out, const Schema_2x3::IfcCartesianPoint &in) {
out = IfcVector3();
for (size_t i = 0; i < in.Coordinates.size(); ++i) {
out[static_cast<unsigned int>(i)] = in.Coordinates[i];
@ -551,15 +507,13 @@ void ConvertCartesianPoint(IfcVector3& out, const Schema_2x3::IfcCartesianPoint&
}
// ------------------------------------------------------------------------------------------------
void ConvertVector(IfcVector3& out, const Schema_2x3::IfcVector& in)
{
void ConvertVector(IfcVector3 &out, const Schema_2x3::IfcVector &in) {
ConvertDirection(out, in.Orientation);
out *= in.Magnitude;
}
// ------------------------------------------------------------------------------------------------
void ConvertDirection(IfcVector3& out, const Schema_2x3::IfcDirection& in)
{
void ConvertDirection(IfcVector3 &out, const Schema_2x3::IfcDirection &in) {
out = IfcVector3();
for (size_t i = 0; i < in.DirectionRatios.size(); ++i) {
out[static_cast<unsigned int>(i)] = in.DirectionRatios[i];
@ -573,8 +527,7 @@ void ConvertDirection(IfcVector3& out, const Schema_2x3::IfcDirection& in)
}
// ------------------------------------------------------------------------------------------------
void AssignMatrixAxes(IfcMatrix4& out, const IfcVector3& x, const IfcVector3& y, const IfcVector3& z)
{
void AssignMatrixAxes(IfcMatrix4 &out, const IfcVector3 &x, const IfcVector3 &y, const IfcVector3 &z) {
out.a1 = x.x;
out.b1 = x.y;
out.c1 = x.z;
@ -589,8 +542,7 @@ void AssignMatrixAxes(IfcMatrix4& out, const IfcVector3& x, const IfcVector3& y,
}
// ------------------------------------------------------------------------------------------------
void ConvertAxisPlacement(IfcMatrix4& out, const Schema_2x3::IfcAxis2Placement3D& in)
{
void ConvertAxisPlacement(IfcMatrix4 &out, const Schema_2x3::IfcAxis2Placement3D &in) {
IfcVector3 loc;
ConvertCartesianPoint(loc, in.Location);
@ -614,8 +566,7 @@ void ConvertAxisPlacement(IfcMatrix4& out, const Schema_2x3::IfcAxis2Placement3D
}
// ------------------------------------------------------------------------------------------------
void ConvertAxisPlacement(IfcMatrix4& out, const Schema_2x3::IfcAxis2Placement2D& in)
{
void ConvertAxisPlacement(IfcMatrix4 &out, const Schema_2x3::IfcAxis2Placement2D &in) {
IfcVector3 loc;
ConvertCartesianPoint(loc, in.Location);
@ -631,34 +582,28 @@ void ConvertAxisPlacement(IfcMatrix4& out, const Schema_2x3::IfcAxis2Placement2D
}
// ------------------------------------------------------------------------------------------------
void ConvertAxisPlacement(IfcVector3& axis, IfcVector3& pos, const Schema_2x3::IfcAxis1Placement& in)
{
void ConvertAxisPlacement(IfcVector3 &axis, IfcVector3 &pos, const Schema_2x3::IfcAxis1Placement &in) {
ConvertCartesianPoint(pos, in.Location);
if (in.Axis) {
ConvertDirection(axis, in.Axis.Get());
}
else {
} else {
axis = IfcVector3(0.f, 0.f, 1.f);
}
}
// ------------------------------------------------------------------------------------------------
void ConvertAxisPlacement(IfcMatrix4& out, const Schema_2x3::IfcAxis2Placement& in, ConversionData& conv)
{
void ConvertAxisPlacement(IfcMatrix4 &out, const Schema_2x3::IfcAxis2Placement &in, ConversionData &conv) {
if (const Schema_2x3::IfcAxis2Placement3D *pl3 = in.ResolveSelectPtr<Schema_2x3::IfcAxis2Placement3D>(conv.db)) {
ConvertAxisPlacement(out, *pl3);
}
else if(const Schema_2x3::IfcAxis2Placement2D* pl2 = in.ResolveSelectPtr<Schema_2x3::IfcAxis2Placement2D>(conv.db)) {
} else if (const Schema_2x3::IfcAxis2Placement2D *pl2 = in.ResolveSelectPtr<Schema_2x3::IfcAxis2Placement2D>(conv.db)) {
ConvertAxisPlacement(out, *pl2);
}
else {
} else {
IFCImporter::LogWarn("skipping unknown IfcAxis2Placement entity");
}
}
// ------------------------------------------------------------------------------------------------
void ConvertTransformOperator(IfcMatrix4& out, const Schema_2x3::IfcCartesianTransformationOperator& op)
{
void ConvertTransformOperator(IfcMatrix4 &out, const Schema_2x3::IfcCartesianTransformationOperator &op) {
IfcVector3 loc;
ConvertCartesianPoint(loc, op.LocalOrigin);
@ -679,14 +624,12 @@ void ConvertTransformOperator(IfcMatrix4& out, const Schema_2x3::IfcCartesianTra
IfcMatrix4::Translation(loc, locm);
AssignMatrixAxes(out, x, y, z);
IfcVector3 vscale;
if (const Schema_2x3::IfcCartesianTransformationOperator3DnonUniform *nuni = op.ToPtr<Schema_2x3::IfcCartesianTransformationOperator3DnonUniform>()) {
vscale.x = nuni->Scale ? op.Scale.Get() : 1.f;
vscale.y = nuni->Scale2 ? nuni->Scale2.Get() : 1.f;
vscale.z = nuni->Scale3 ? nuni->Scale3.Get() : 1.f;
}
else {
} else {
const IfcFloat sc = op.Scale ? op.Scale.Get() : 1.f;
vscale = IfcVector3(sc, sc, sc);
}
@ -697,8 +640,7 @@ void ConvertTransformOperator(IfcMatrix4& out, const Schema_2x3::IfcCartesianTra
out = locm * out * s;
}
} // ! IFC
} // ! Assimp
} // namespace IFC
} // namespace Assimp
#endif

View File

@ -43,9 +43,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* @brief Implementation of the CPP-API class #Importer
*/
#include <assimp/version.h>
#include <assimp/config.h>
#include <assimp/importerdesc.h>
#include <assimp/version.h>
// ------------------------------------------------------------------------------------------------
/* Uncomment this line to prevent Assimp from catching unknown exceptions.
@ -62,29 +62,30 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ------------------------------------------------------------------------------------------------
// Internal headers
// ------------------------------------------------------------------------------------------------
#include "Common/Importer.h"
#include "Common/BaseProcess.h"
#include "Common/DefaultProgressHandler.h"
#include "PostProcessing/ProcessHelper.h"
#include "Common/Importer.h"
#include "Common/ScenePreprocessor.h"
#include "Common/ScenePrivate.h"
#include "PostProcessing/ProcessHelper.h"
#include <assimp/BaseImporter.h>
#include <assimp/Exceptional.h>
#include <assimp/GenericProperty.h>
#include <assimp/MemoryIOWrapper.h>
#include <assimp/Profiler.h>
#include <assimp/TinyFormatter.h>
#include <assimp/Exceptional.h>
#include <assimp/Profiler.h>
#include <assimp/commonMetaData.h>
#include <set>
#include <memory>
#include <cctype>
#include <memory>
#include <set>
#include <assimp/DefaultIOStream.h>
#include <assimp/DefaultIOSystem.h>
// clang-format off
#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
# include "PostProcessing/ValidateDataStructure.h"
#endif
@ -99,8 +100,9 @@ namespace Assimp {
// PostStepRegistry.cpp
void GetPostProcessingStepInstanceList(std::vector<BaseProcess *> &out);
}
} // namespace Assimp
// clang-format on
using namespace Assimp;
using namespace Assimp::Intern;
@ -117,8 +119,7 @@ void* AllocateFromAssimpHeap::operator new ( size_t num_bytes) {
void *AllocateFromAssimpHeap::operator new(size_t num_bytes, const std::nothrow_t &) throw() {
try {
return AllocateFromAssimpHeap::operator new(num_bytes);
}
catch( ... ) {
} catch (...) {
return nullptr;
}
}
@ -145,8 +146,8 @@ void AllocateFromAssimpHeap::operator delete[] ( void* data) {
// ------------------------------------------------------------------------------------------------
// Importer constructor.
Importer::Importer()
: pimpl( new ImporterPimpl ) {
Importer::Importer() :
pimpl(new ImporterPimpl) {
pimpl->mScene = nullptr;
pimpl->mErrorString = "";
@ -652,8 +653,7 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) {
// Get file size for progress handler
IOStream *fileIO = pimpl->mIOHandler->Open(pFile);
uint32_t fileSize = 0;
if (fileIO)
{
if (fileIO) {
fileSize = static_cast<uint32_t>(fileIO->FileSize());
pimpl->mIOHandler->Close(fileIO);
}
@ -738,7 +738,8 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) {
#endif
ASSIMP_LOG_ERROR(pimpl->mErrorString);
delete pimpl->mScene; pimpl->mScene = nullptr;
delete pimpl->mScene;
pimpl->mScene = nullptr;
}
#endif // ! ASSIMP_CATCH_GLOBAL_EXCEPTIONS
@ -748,7 +749,6 @@ const aiScene* Importer::ReadFile( const char* _pFile, unsigned int pFlags) {
return pimpl->mScene;
}
// ------------------------------------------------------------------------------------------------
// Apply post-processing to the currently bound scene
const aiScene *Importer::ApplyPostProcessing(unsigned int pFlags) {
@ -781,8 +781,7 @@ const aiScene* Importer::ApplyPostProcessing(unsigned int pFlags) {
}
#endif // no validation
#ifdef ASSIMP_BUILD_DEBUG
if (pimpl->bExtraVerbose)
{
if (pimpl->bExtraVerbose) {
#ifdef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
ASSIMP_LOG_ERROR("Verbose Import is not available due to build settings");
#endif // no validation
@ -870,8 +869,7 @@ const aiScene* Importer::ApplyCustomizedPostProcessing( BaseProcess *rootProcess
#ifndef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
// The ValidateDS process plays an exceptional role. It isn't contained in the global
// list of post-processing steps, so we need to call it manually.
if ( requestValidation )
{
if (requestValidation) {
ValidateDSProcess ds;
ds.ExecuteOnScene(this);
if (!pimpl->mScene) {
@ -880,8 +878,7 @@ const aiScene* Importer::ApplyCustomizedPostProcessing( BaseProcess *rootProcess
}
#endif // no validation
#ifdef ASSIMP_BUILD_DEBUG
if ( pimpl->bExtraVerbose )
{
if (pimpl->bExtraVerbose) {
#ifdef ASSIMP_BUILD_NO_VALIDATEDS_PROCESS
ASSIMP_LOG_ERROR("Verbose Import is not available due to build settings");
#endif // no validation
@ -947,7 +944,6 @@ const aiImporterDesc* Importer::GetImporterInfo(size_t index) const {
return pimpl->mImporter[index]->GetInfo();
}
// ------------------------------------------------------------------------------------------------
BaseImporter *Importer::GetImporter(size_t index) const {
ai_assert(nullptr != pimpl);
@ -975,7 +971,8 @@ size_t Importer::GetImporterIndex (const char* szExtension) const {
ASSIMP_BEGIN_EXCEPTION_REGION();
// skip over wildcard and dot characters at string head --
for ( ; *szExtension == '*' || *szExtension == '.'; ++szExtension );
for (; *szExtension == '*' || *szExtension == '.'; ++szExtension)
;
std::string ext(szExtension);
if (ext.empty()) {
@ -1106,8 +1103,7 @@ aiMatrix4x4 Importer::GetPropertyMatrix(const char* szName, const aiMatrix4x4& i
// ------------------------------------------------------------------------------------------------
// Get the memory requirements of a single node
inline
void AddNodeWeight(unsigned int& iScene,const aiNode* pcNode) {
inline void AddNodeWeight(unsigned int &iScene, const aiNode *pcNode) {
if (nullptr == pcNode) {
return;
}

View File

@ -44,10 +44,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef INCLUDED_AI_IMPORTER_H
#define INCLUDED_AI_IMPORTER_H
#include <map>
#include <vector>
#include <string>
#include <assimp/matrix4x4.h>
#include <map>
#include <string>
#include <vector>
struct aiScene;
@ -58,7 +58,6 @@ namespace Assimp {
class BaseProcess;
class SharedPostProcessInfo;
//! @cond never
// ---------------------------------------------------------------------------
/** @brief Internal PIMPL implementation for Assimp::Importer
@ -70,7 +69,7 @@ namespace Assimp {
class ImporterPimpl {
public:
// Data type to store the key hash
typedef unsigned int KeyType;
using KeyType = unsigned int;
// typedefs for our four configuration maps.
// We don't need more, so there is no need for a generic solution
@ -126,9 +125,7 @@ public:
ImporterPimpl() AI_NO_EXCEPT;
};
inline
ImporterPimpl::ImporterPimpl() AI_NO_EXCEPT :
mIOHandler( nullptr ),
inline ImporterPimpl::ImporterPimpl() AI_NO_EXCEPT : mIOHandler(nullptr),
mIsDefaultHandler(false),
mProgressHandler(nullptr),
mIsDefaultProgressHandler(false),
@ -214,8 +211,7 @@ public:
unsigned int AddLoadRequest(
const std::string &file,
unsigned int steps = 0,
const PropertyMap *map = nullptr
);
const PropertyMap *map = nullptr);
// -------------------------------------------------------------------
/** Get an imported scene.
@ -227,8 +223,7 @@ public:
* @return nullptr if there is no scene with this file name
* in the queue of the scene hasn't been loaded yet. */
aiScene *GetImport(
unsigned int which
);
unsigned int which);
// -------------------------------------------------------------------
/** Waits until all scenes have been loaded. This returns

View File

@ -45,8 +45,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AI_POLYTOOLS_H_INCLUDED
#define AI_POLYTOOLS_H_INCLUDED
#include <assimp/material.h>
#include <assimp/ai_assert.h>
#include <assimp/material.h>
#include <assimp/vector3.h>
namespace Assimp {
@ -55,8 +56,7 @@ namespace Assimp {
* The function accepts an unconstrained template parameter for use with
* both aiVector3D and aiVector2D, but generally ignores the third coordinate.*/
template <typename T>
inline double GetArea2D(const T& v1, const T& v2, const T& v3)
{
inline double GetArea2D(const T &v1, const T &v2, const T &v3) {
return 0.5 * (v1.x * ((double)v3.y - v2.y) + v2.x * ((double)v1.y - v3.y) + v3.x * ((double)v2.y - v1.y));
}
@ -65,8 +65,7 @@ inline double GetArea2D(const T& v1, const T& v2, const T& v3)
* The function accepts an unconstrained template parameter for use with
* both aiVector3D and aiVector2D, but generally ignores the third coordinate.*/
template <typename T>
inline bool OnLeftSideOfLine2D(const T& p0, const T& p1,const T& p2)
{
inline bool OnLeftSideOfLine2D(const T &p0, const T &p1, const T &p2) {
return GetArea2D(p0, p2, p1) > 0;
}
@ -75,8 +74,7 @@ inline bool OnLeftSideOfLine2D(const T& p0, const T& p1,const T& p2)
* The function accepts an unconstrained template parameter for use with
* both aiVector3D and aiVector2D, but generally ignores the third coordinate.*/
template <typename T>
inline bool PointInTriangle2D(const T& p0, const T& p1,const T& p2, const T& pp)
{
inline bool PointInTriangle2D(const T &p0, const T &p1, const T &p2, const T &pp) {
// Point in triangle test using baryzentric coordinates
const aiVector2D v0 = p1 - p0;
const aiVector2D v1 = p2 - p0;
@ -95,7 +93,6 @@ inline bool PointInTriangle2D(const T& p0, const T& p1,const T& p2, const T& pp)
return (dot11 > 0) && (dot00 > 0) && (dot11 + dot00 < 1);
}
// -------------------------------------------------------------------------------
/** Check whether the winding order of a given polygon is counter-clockwise.
* The function accepts an unconstrained template parameter, but is intended
@ -133,8 +130,7 @@ inline bool IsCCW(T* in, size_t npoints) {
// in[i+2].x, in[i+2].y)) {
convex_turn = AI_MATH_PI_F - theta;
convex_sum += convex_turn;
}
else {
} else {
convex_sum -= AI_MATH_PI_F - theta;
}
}
@ -161,15 +157,13 @@ inline bool IsCCW(T* in, size_t npoints) {
if (OnLeftSideOfLine2D(in[npoints - 2], in[1], in[0])) {
convex_turn = AI_MATH_PI_F - theta;
convex_sum += convex_turn;
}
else {
} else {
convex_sum -= AI_MATH_PI_F - theta;
}
return convex_sum >= (2 * AI_MATH_PI_F);
}
// -------------------------------------------------------------------------------
/** Compute the normal of an arbitrary polygon in R3.
*
@ -185,9 +179,14 @@ inline bool IsCCW(T* in, size_t npoints) {
* @note The data arrays must have storage for at least num+2 elements. Using
* this method is much faster than the 'other' NewellNormal()
*/
template <int ofs_x, int ofs_y, int ofs_z, typename TReal>
inline void NewellNormal (aiVector3t<TReal>& out, int num, TReal* x, TReal* y, TReal* z)
{
template <size_t ofs_x, size_t ofs_y, size_t ofs_z, typename TReal>
inline void NewellNormal(aiVector3t<TReal> &out, size_t num, TReal *x, TReal *y, TReal *z, size_t bufferSize) {
ai_assert(bufferSize > num);
if (nullptr == x || nullptr == y || nullptr == z || 0 == bufferSize || 0 == num) {
return;
}
// Duplicate the first two vertices at the end
x[(num + 0) * ofs_x] = x[0];
x[(num + 1) * ofs_x] = x[ofs_x];
@ -204,7 +203,7 @@ inline void NewellNormal (aiVector3t<TReal>& out, int num, TReal* x, TReal* y, T
TReal *yptr = y + ofs_y, *ylow = y, *yhigh = y + ofs_y * 2;
TReal *zptr = z + ofs_z, *zlow = z, *zhigh = z + ofs_z * 2;
for (int tmp=0; tmp < num; tmp++) {
for (size_t tmp = 0; tmp < num; ++tmp ) {
sum_xy += (*xptr) * ((*yhigh) - (*ylow));
sum_yz += (*yptr) * ((*zhigh) - (*zlow));
sum_zx += (*zptr) * ((*xhigh) - (*xlow));
@ -224,6 +223,6 @@ inline void NewellNormal (aiVector3t<TReal>& out, int num, TReal* x, TReal* y, T
out = aiVector3t<TReal>(sum_yz, sum_zx, sum_xy);
}
} // ! Assimp
} // namespace Assimp
#endif

View File

@ -60,14 +60,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef ASSIMP_BUILD_NO_TRIANGULATE_PROCESS
#include "PostProcessing/TriangulateProcess.h"
#include "PostProcessing/ProcessHelper.h"
#include "Common/PolyTools.h"
#include "PostProcessing/ProcessHelper.h"
#include <memory>
#include <cstdint>
#include <memory>
//#define AI_BUILD_TRIANGULATE_COLOR_FACE_WINDING
//#define AI_BUILD_TRIANGULATE_DEBUG_POLYS
#define AI_BUILD_TRIANGULATE_DEBUG_POLYS
#define POLY_GRID_Y 40
#define POLY_GRID_X 70
@ -78,34 +78,29 @@ using namespace Assimp;
// ------------------------------------------------------------------------------------------------
// Constructor to be privately used by Importer
TriangulateProcess::TriangulateProcess()
{
TriangulateProcess::TriangulateProcess() {
// nothing to do here
}
// ------------------------------------------------------------------------------------------------
// Destructor, private as well
TriangulateProcess::~TriangulateProcess()
{
TriangulateProcess::~TriangulateProcess() {
// nothing to do here
}
// ------------------------------------------------------------------------------------------------
// 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;
for( unsigned int a = 0; a < pScene->mNumMeshes; a++)
{
for (unsigned int a = 0; a < pScene->mNumMeshes; a++) {
if (pScene->mMeshes[a]) {
if (TriangulateMesh(pScene->mMeshes[a])) {
bHas = true;
@ -120,44 +115,54 @@ void TriangulateProcess::Execute( aiScene* pScene)
}
// ------------------------------------------------------------------------------------------------
// Triangulates the given mesh.
bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
{
// Now we have aiMesh::mPrimitiveTypes, so this is only here for test cases
if (!pMesh->mPrimitiveTypes) {
static bool validateNumIndices(aiMesh *mesh) {
bool bNeed = false;
for( unsigned int a = 0; a < pMesh->mNumFaces; a++) {
const aiFace& face = pMesh->mFaces[a];
for (unsigned int a = 0; a < mesh->mNumFaces; a++) {
const aiFace &face = mesh->mFaces[a];
if (face.mNumIndices != 3) {
bNeed = true;
break;
}
}
if (!bNeed)
return false;
}
else if (!(pMesh->mPrimitiveTypes & aiPrimitiveType_POLYGON)) {
return false;
}
// Find out how many output faces we'll get
uint32_t numOut = 0, max_out = 0;
bool get_normals = true;
for( unsigned int a = 0; a < pMesh->mNumFaces; a++) {
aiFace& face = pMesh->mFaces[a];
return bNeed;
}
static void calulateNumOutputFaces(aiMesh *mesh, size_t &numOut, size_t &maxOut, bool &getNormals) {
numOut = maxOut = 0;
getNormals = true;
for (unsigned int a = 0; a < mesh->mNumFaces; a++) {
aiFace &face = mesh->mFaces[a];
if (face.mNumIndices <= 4) {
get_normals = false;
getNormals = false;
}
if (face.mNumIndices <= 3) {
numOut++;
}
else {
} else {
numOut += face.mNumIndices - 2;
max_out = std::max(max_out,face.mNumIndices);
maxOut = std::max(maxOut, static_cast<size_t>(face.mNumIndices));
}
}
}
// ------------------------------------------------------------------------------------------------
// Triangulates the given mesh.
bool TriangulateProcess::TriangulateMesh(aiMesh *pMesh) {
// Now we have aiMesh::mPrimitiveTypes, so this is only here for test cases
if (!pMesh->mPrimitiveTypes) {
if (!validateNumIndices(pMesh)) {
return false;
}
} else if (!(pMesh->mPrimitiveTypes & aiPrimitiveType_POLYGON)) {
return false;
}
// Find out how many output faces we'll get
size_t numOut = 0, max_out = 0;
bool getNormals = true;
calulateNumOutputFaces(pMesh, numOut, max_out, getNormals);
// Just another check whether aiMesh::mPrimitiveTypes is correct
ai_assert(numOut != pMesh->mNumFaces);
@ -166,7 +171,7 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
// if we don't have normals yet, but expect them to be a cheap side
// product of triangulation anyway, allocate storage for them.
if (!pMesh->mNormals && get_normals) {
if (!pMesh->mNormals && getNormals) {
// XXX need a mechanism to inform the GenVertexNormals process to treat these normals as preprocessed per-face normals
// nor_out = pMesh->mNormals = new aiVector3D[pMesh->mNumVertices];
}
@ -176,6 +181,7 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
pMesh->mPrimitiveTypes &= ~aiPrimitiveType_POLYGON;
aiFace *out = new aiFace[numOut](), *curOut = out;
const size_t Capa = max_out + 2;
std::vector<aiVector3D> temp_verts3d(max_out + 2); /* temporary storage for vertices */
std::vector<aiVector2D> temp_verts(max_out + 2);
@ -215,8 +221,7 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
aiFace *const last_face = curOut;
// if it's a simple point,line or triangle: just copy it
if( face.mNumIndices <= 3)
{
if (face.mNumIndices <= 3) {
aiFace &nface = *curOut++;
nface.mNumIndices = face.mNumIndices;
nface.mIndices = face.mIndices;
@ -275,9 +280,7 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
// prevent double deletion of the indices field
face.mIndices = nullptr;
continue;
}
else
{
} else {
// A polygon with more than 3 vertices can be either concave or convex.
// Usually everything we're getting is convex and we could easily
// triangulate by tri-fanning. However, LightWave is probably the only
@ -292,9 +295,9 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
temp_verts3d[tmp] = verts[idx[tmp]];
}
// Get newell normal of the polygon. Store it for future use if it's a polygon-only mesh
// Get Newell-Normal of the polygon. Store it for future use if it's a polygon-only mesh
aiVector3D n;
NewellNormal<3,3,3>(n,max,&temp_verts3d.front().x,&temp_verts3d.front().y,&temp_verts3d.front().z);
NewellNormal<3, 3, 3>(n, max, &temp_verts3d.front().x, &temp_verts3d.front().y, &temp_verts3d.front().z, Capa);
if (nor_out) {
for (tmp = 0; tmp < max; ++tmp)
nor_out[idx[tmp]] = n;
@ -305,16 +308,17 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
const float ay = (n.y > 0 ? n.y : -n.y);
const float az = (n.z > 0 ? n.z : -n.z);
unsigned int ac = 0, bc = 1; /* no z coord. projection to xy */
unsigned int ac = 0, bc = 1; // no z coord. projection to xy
float inv = n.z;
if (ax > ay) {
if (ax > az) { /* no x coord. projection to yz */
ac = 1; bc = 2;
if (ax > az) { // no x coord. projection to yz
ac = 1;
bc = 2;
inv = n.x;
}
}
else if (ay > az) { /* no y coord. projection to zy */
ac = 2; bc = 0;
} else if (ay > az) { // no y coord. projection to zy
ac = 2;
bc = 0;
inv = n.y;
}
@ -342,13 +346,13 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
const size_t x = static_cast<size_t>(v.x * (POLY_GRID_X - 1)), y = static_cast<size_t>(v.y * (POLY_GRID_Y - 1));
char *loc = grid[y] + x;
if (grid[y][x] != ' ') {
for(;*loc != ' '; ++loc);
for (; *loc != ' '; ++loc)
;
*loc++ = '_';
}
*(loc + ::ai_snprintf(loc, POLY_GRID_XPAD, "%i", i)) = ' ';
}
for (size_t y = 0; y < POLY_GRID_Y; ++y) {
grid[y][POLY_GRID_X + POLY_GRID_XPAD - 1] = '\0';
fprintf(fout, "%s\n", grid[y]);
@ -367,7 +371,8 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
for (ear = next;; prev = ear, ear = next) {
// break after we looped two times without a positive match
for (next=ear+1;done[(next>=max?next=0:next)];++next);
for (next = ear + 1; done[(next >= max ? next = 0 : next)]; ++next)
;
if (next < ear) {
if (++num_found == 2) {
break;
@ -419,22 +424,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++;
@ -461,15 +450,17 @@ bool TriangulateProcess::TriangulateMesh( aiMesh* pMesh)
nface.mIndices = new unsigned int[3];
}
for (tmp = 0; done[tmp]; ++tmp);
for (tmp = 0; done[tmp]; ++tmp)
;
nface.mIndices[0] = tmp;
for (++tmp; done[tmp]; ++tmp);
for (++tmp; done[tmp]; ++tmp)
;
nface.mIndices[1] = tmp;
for (++tmp; done[tmp]; ++tmp);
for (++tmp; done[tmp]; ++tmp)
;
nface.mIndices[2] = tmp;
}
}
@ -487,24 +478,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

@ -96,6 +96,7 @@ SET( COMMON
unit/Common/utSpatialSort.cpp
unit/Common/utAssertHandler.cpp
unit/Common/utXmlParser.cpp
unit/Common/utPolyTools.cpp
)
SET( IMPORTERS

View File

@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
Copyright (c) 2006-2020, assimp team
All rights reserved.
Redistribution and use of this software in source and binary forms,

View File

@ -43,9 +43,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AV_ANIMEVALUATOR_H_INCLUDED
#define AV_ANIMEVALUATOR_H_INCLUDED
#include <assimp/matrix4x4.h>
#include <tuple>
#include <vector>
struct aiAnimation;
namespace AssimpView {
/**
@ -74,7 +78,7 @@ public:
* the aiAnimation. */
const std::vector<aiMatrix4x4> &GetTransformations() const { return mTransforms; }
protected:
private:
const aiAnimation *mAnim;
double mLastTime;
std::vector<std::tuple<unsigned int, unsigned int, unsigned int>> mLastPositions;

File diff suppressed because it is too large Load Diff

View File

@ -47,7 +47,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef AV_SCENEANIMATOR_H_INCLUDED
#define AV_SCENEANIMATOR_H_INCLUDED
#include <assimp/scene.h>
#include <map>
#include <string>
namespace AssimpView {
@ -72,13 +75,23 @@ struct SceneAnimNode {
//! Default construction
SceneAnimNode() :
mName(), mParent(nullptr), mChildren(), mLocalTransform(), mGlobalTransform(), mChannelIndex(-1) {
mName(),
mParent(nullptr),
mChildren(),
mLocalTransform(),
mGlobalTransform(),
mChannelIndex(-1) {
// empty
}
//! Construction from a given name
SceneAnimNode(const std::string &pName) :
mName(pName), mParent(nullptr), mChildren(), mLocalTransform(), mGlobalTransform(), mChannelIndex(-1) {
mName(pName),
mParent(nullptr),
mChildren(),
mLocalTransform(),
mGlobalTransform(),
mChannelIndex(-1) {
// empty
}
@ -125,7 +138,7 @@ public:
// ----------------------------------------------------------------------------
/** Calculates the node transformations for the scene. Call this to get
* uptodate results before calling one of the getters.
* up-to-date results before calling one of the getters.
* @param pTime Current time. Can be an arbitrary range.
*/
void Calculate(double pTime);
@ -136,7 +149,7 @@ public:
* The returned matrix is in the node's parent's local space, just like the
* original node's transformation matrix. If the node is not animated, the
* node's original transformation is returned so that you can safely use or
* assign it to the node itsself. If there is no node with the given name,
* assign it to the node itself. If there is no node with the given name,
* the identity matrix is returned. All transformations are updated whenever
* Calculate() is called.
* @param pNodeName Name of the node
@ -151,7 +164,7 @@ public:
* The returned matrix is in world space, which is the same coordinate space
* as the transformation of the scene's root node. If the node is not animated,
* the node's original transformation is returned so that you can safely use or
* assign it to the node itsself. If there is no node with the given name, the
* assign it to the node itself. If there is no node with the given name, the
* identity matrix is returned. All transformations are updated whenever
* Calculate() is called.
* @param pNodeName Name of the node
@ -190,7 +203,7 @@ public:
/** @brief Get the current animation or NULL
*/
aiAnimation *CurrentAnim() const {
return static_cast<unsigned int>(mCurrentAnimIndex) < mScene->mNumAnimations ? mScene->mAnimations[mCurrentAnimIndex] : NULL;
return static_cast<unsigned int>(mCurrentAnimIndex) < mScene->mNumAnimations ? mScene->mAnimations[mCurrentAnimIndex] : nullptr;
}
protected: