Merge branch 'master' into issue_2390

pull/2391/head
Matias Lavik 2019-04-04 13:08:27 +02:00 committed by GitHub
commit 3abb494dd6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 70 additions and 105 deletions

View File

@ -70,6 +70,6 @@ addons:
project: project:
name: "assimp/assimp" name: "assimp/assimp"
notification_email: kim.kulling@googlemail.com notification_email: kim.kulling@googlemail.com
build_command_prepend: "cmake . -DASSIMP_ENABLE_BOOST_WORKAROUND=YES" build_command_prepend: "cmake ./"
build_command: "make -j4" build_command: "make -j4"
branch_pattern: coverity_scan branch_pattern: coverity_scan

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2012, assimp team Copyright (c) 2006-2019, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -68,8 +68,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
using namespace melange; using namespace melange;
// overload this function and fill in your own unique data // overload this function and fill in your own unique data
void GetWriterInfo(int &id, String &appname) void GetWriterInfo(int &id, String &appname) {
{
id = 2424226; id = 2424226;
appname = "Open Asset Import Library"; appname = "Open Asset Import Library";
} }
@ -78,7 +77,10 @@ using namespace Assimp;
using namespace Assimp::Formatter; using namespace Assimp::Formatter;
namespace Assimp { namespace Assimp {
template<> const std::string LogFunctions<C4DImporter>::log_prefix = "C4D: "; template<> const char* LogFunctions<C4DImporter>::Prefix() {
static auto prefix = "C4D: ";
return prefix;
}
} }
static const aiImporterDesc desc = { static const aiImporterDesc desc = {
@ -97,47 +99,44 @@ static const aiImporterDesc desc = {
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
C4DImporter::C4DImporter() C4DImporter::C4DImporter()
{} : BaseImporter() {
// empty
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
C4DImporter::~C4DImporter() C4DImporter::~C4DImporter() {
{} // empty
}
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool C4DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const bool C4DImporter::CanRead( const std::string& pFile, IOSystem* pIOHandler, bool checkSig) const {
{
const std::string& extension = GetExtension(pFile); const std::string& extension = GetExtension(pFile);
if (extension == "c4d") { if (extension == "c4d") {
return true; return true;
} } else if ((!extension.length() || checkSig) && pIOHandler) {
else if ((!extension.length() || checkSig) && pIOHandler) {
// TODO // TODO
} }
return false; return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
const aiImporterDesc* C4DImporter::GetInfo () const const aiImporterDesc* C4DImporter::GetInfo () const {
{
return &desc; return &desc;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void C4DImporter::SetupProperties(const Importer* /*pImp*/) void C4DImporter::SetupProperties(const Importer* /*pImp*/) {
{
// nothing to be done for the moment // nothing to be done for the moment
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
// Imports the given file into the given scene structure. // Imports the given file into the given scene structure.
void C4DImporter::InternReadFile( const std::string& pFile, void C4DImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) {
aiScene* pScene, IOSystem* pIOHandler)
{
std::unique_ptr<IOStream> file( pIOHandler->Open( pFile)); std::unique_ptr<IOStream> file( pIOHandler->Open( pFile));
if( file.get() == NULL) { if( file.get() == nullptr ) {
ThrowException("failed to open file " + pFile); ThrowException("failed to open file " + pFile);
} }
@ -151,7 +150,7 @@ void C4DImporter::InternReadFile( const std::string& pFile,
// open document first // open document first
BaseDocument* doc = LoadDocument(f, SCENEFILTER_OBJECTS | SCENEFILTER_MATERIALS); BaseDocument* doc = LoadDocument(f, SCENEFILTER_OBJECTS | SCENEFILTER_MATERIALS);
if(doc == NULL) { if(doc == nullptr ) {
ThrowException("failed to read document " + pFile); ThrowException("failed to read document " + pFile);
} }
@ -160,11 +159,10 @@ void C4DImporter::InternReadFile( const std::string& pFile,
// first convert all materials // first convert all materials
ReadMaterials(doc->GetFirstMaterial()); ReadMaterials(doc->GetFirstMaterial());
// process C4D scenegraph recursively // process C4D scene-graph recursively
try { try {
RecurseHierarchy(doc->GetFirstObject(), pScene->mRootNode); RecurseHierarchy(doc->GetFirstObject(), pScene->mRootNode);
} } catch(...) {
catch(...) {
for(aiMesh* mesh : meshes) { for(aiMesh* mesh : meshes) {
delete mesh; delete mesh;
} }
@ -201,8 +199,7 @@ void C4DImporter::InternReadFile( const std::string& pFile,
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
bool C4DImporter::ReadShader(aiMaterial* out, melange::BaseShader* shader) bool C4DImporter::ReadShader(aiMaterial* out, melange::BaseShader* shader) {
{
// based on Melange sample code (C4DImportExport.cpp) // based on Melange sample code (C4DImportExport.cpp)
while(shader) { while(shader) {
if(shader->GetType() == Xlayer) { if(shader->GetType() == Xlayer) {
@ -220,15 +217,12 @@ bool C4DImporter::ReadShader(aiMaterial* out, melange::BaseShader* shader)
// Ignore the actual layer blending - models for real-time rendering should not // Ignore the actual layer blending - models for real-time rendering should not
// use them in a non-trivial way. Just try to find textures that we can apply // use them in a non-trivial way. Just try to find textures that we can apply
// to the model. // to the model.
while (lsl) while (lsl) {
{ if (lsl->GetType() == TypeFolder) {
if (lsl->GetType() == TypeFolder)
{
BlendFolder* const folder = dynamic_cast<BlendFolder*>(lsl); BlendFolder* const folder = dynamic_cast<BlendFolder*>(lsl);
LayerShaderLayer *subLsl = dynamic_cast<LayerShaderLayer*>(folder->m_Children.GetObject(0)); LayerShaderLayer *subLsl = dynamic_cast<LayerShaderLayer*>(folder->m_Children.GetObject(0));
while (subLsl) while (subLsl) {
{
if (subLsl->GetType() == TypeShader) { if (subLsl->GetType() == TypeShader) {
BlendShader* const shader = dynamic_cast<BlendShader*>(subLsl); BlendShader* const shader = dynamic_cast<BlendShader*>(subLsl);
if(ReadShader(out, static_cast<BaseShader*>(shader->m_pLink->GetLink()))) { if(ReadShader(out, static_cast<BaseShader*>(shader->m_pLink->GetLink()))) {
@ -238,8 +232,7 @@ bool C4DImporter::ReadShader(aiMaterial* out, melange::BaseShader* shader)
subLsl = subLsl->GetNext(); subLsl = subLsl->GetNext();
} }
} } else if (lsl->GetType() == TypeShader) {
else if (lsl->GetType() == TypeShader) {
BlendShader* const shader = dynamic_cast<BlendShader*>(lsl); BlendShader* const shader = dynamic_cast<BlendShader*>(lsl);
if(ReadShader(out, static_cast<BaseShader*>(shader->m_pLink->GetLink()))) { if(ReadShader(out, static_cast<BaseShader*>(shader->m_pLink->GetLink()))) {
return true; return true;
@ -248,33 +241,27 @@ bool C4DImporter::ReadShader(aiMaterial* out, melange::BaseShader* shader)
lsl = lsl->GetNext(); lsl = lsl->GetNext();
} }
} } else if ( shader->GetType() == Xbitmap ) {
else if ( shader->GetType() == Xbitmap )
{
aiString path; aiString path;
shader->GetFileName().GetString().GetCString(path.data, MAXLEN-1); shader->GetFileName().GetString().GetCString(path.data, MAXLEN-1);
path.length = ::strlen(path.data); path.length = ::strlen(path.data);
out->AddProperty(&path, AI_MATKEY_TEXTURE_DIFFUSE(0)); out->AddProperty(&path, AI_MATKEY_TEXTURE_DIFFUSE(0));
return true; return true;
} } else {
else {
LogWarn("ignoring shader type: " + std::string(GetObjectTypeName(shader->GetType()))); LogWarn("ignoring shader type: " + std::string(GetObjectTypeName(shader->GetType())));
} }
shader = shader->GetNext(); shader = shader->GetNext();
} }
return false; return false;
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void C4DImporter::ReadMaterials(melange::BaseMaterial* mat) void C4DImporter::ReadMaterials(melange::BaseMaterial* mat) {
{
// based on Melange sample code // based on Melange sample code
while (mat) while (mat) {
{
const String& name = mat->GetName(); const String& name = mat->GetName();
if (mat->GetType() == Mmaterial) if (mat->GetType() == Mmaterial) {
{
aiMaterial* out = new aiMaterial(); aiMaterial* out = new aiMaterial();
material_mapping[mat] = static_cast<unsigned int>(materials.size()); material_mapping[mat] = static_cast<unsigned int>(materials.size());
materials.push_back(out); materials.push_back(out);
@ -286,8 +273,7 @@ void C4DImporter::ReadMaterials(melange::BaseMaterial* mat)
Material& m = dynamic_cast<Material&>(*mat); Material& m = dynamic_cast<Material&>(*mat);
if (m.GetChannelState(CHANNEL_COLOR)) if (m.GetChannelState(CHANNEL_COLOR)) {
{
GeData data; GeData data;
mat->GetParameter(MATERIAL_COLOR_COLOR, data); mat->GetParameter(MATERIAL_COLOR_COLOR, data);
Vector color = data.GetVector(); Vector color = data.GetVector();
@ -307,9 +293,7 @@ void C4DImporter::ReadMaterials(melange::BaseMaterial* mat)
if(shader) { if(shader) {
ReadShader(out, shader); ReadShader(out, shader);
} }
} } else {
else
{
LogWarn("ignoring plugin material: " + std::string(GetObjectTypeName(mat->GetType()))); LogWarn("ignoring plugin material: " + std::string(GetObjectTypeName(mat->GetType())));
} }
mat = mat->GetNext(); mat = mat->GetNext();
@ -317,14 +301,12 @@ void C4DImporter::ReadMaterials(melange::BaseMaterial* mat)
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void C4DImporter::RecurseHierarchy(BaseObject* object, aiNode* parent) void C4DImporter::RecurseHierarchy(BaseObject* object, aiNode* parent) {
{ ai_assert(parent != nullptr );
ai_assert(parent != NULL);
std::vector<aiNode*> nodes; std::vector<aiNode*> nodes;
// based on Melange sample code // based on Melange sample code
while (object) while (object) {
{
const String& name = object->GetName(); const String& name = object->GetName();
const LONG type = object->GetType(); const LONG type = object->GetType();
const Matrix& ml = object->GetMl(); const Matrix& ml = object->GetMl();
@ -356,26 +338,20 @@ void C4DImporter::RecurseHierarchy(BaseObject* object, aiNode* parent)
nodes.push_back(nd); nodes.push_back(nd);
GeData data; GeData data;
if (type == Ocamera) if (type == Ocamera) {
{
object->GetParameter(CAMERAOBJECT_FOV, data); object->GetParameter(CAMERAOBJECT_FOV, data);
// TODO: read camera // TODO: read camera
} } else if (type == Olight) {
else if (type == Olight)
{
// TODO: read light // TODO: read light
} } else if (type == Opolygon) {
else if (type == Opolygon)
{
aiMesh* const mesh = ReadMesh(object); aiMesh* const mesh = ReadMesh(object);
if(mesh != NULL) { if(mesh != nullptr) {
nd->mNumMeshes = 1; nd->mNumMeshes = 1;
nd->mMeshes = new unsigned int[1]; nd->mMeshes = new unsigned int[1];
nd->mMeshes[0] = static_cast<unsigned int>(meshes.size()); nd->mMeshes[0] = static_cast<unsigned int>(meshes.size());
meshes.push_back(mesh); meshes.push_back(mesh);
} }
} } else {
else {
LogWarn("ignoring object: " + std::string(GetObjectTypeName(type))); LogWarn("ignoring object: " + std::string(GetObjectTypeName(type)));
} }
@ -389,28 +365,27 @@ void C4DImporter::RecurseHierarchy(BaseObject* object, aiNode* parent)
std::copy(nodes.begin(), nodes.end(), parent->mChildren); std::copy(nodes.begin(), nodes.end(), parent->mChildren);
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
aiMesh* C4DImporter::ReadMesh(BaseObject* object) aiMesh* C4DImporter::ReadMesh(BaseObject* object) {
{ ai_assert(object != nullptr);
ai_assert(object != NULL && object->GetType() == Opolygon); ai_assert( object->GetType() == Opolygon );
// based on Melange sample code // based on Melange sample code
PolygonObject* const polyObject = dynamic_cast<PolygonObject*>(object); PolygonObject* const polyObject = dynamic_cast<PolygonObject*>(object);
ai_assert(polyObject != NULL); ai_assert(polyObject != nullptr);
const LONG pointCount = polyObject->GetPointCount(); const LONG pointCount = polyObject->GetPointCount();
const LONG polyCount = polyObject->GetPolygonCount(); const LONG polyCount = polyObject->GetPolygonCount();
if(!polyObject || !pointCount) { if(!polyObject || !pointCount) {
LogWarn("ignoring mesh with zero vertices or faces"); LogWarn("ignoring mesh with zero vertices or faces");
return NULL; return nullptr;
} }
const Vector* points = polyObject->GetPointR(); const Vector* points = polyObject->GetPointR();
ai_assert(points != NULL); ai_assert(points != nullptr);
const CPolygon* polys = polyObject->GetPolygonR(); const CPolygon* polys = polyObject->GetPolygonR();
ai_assert(polys != NULL); ai_assert(polys != nullptr);
std::unique_ptr<aiMesh> mesh(new aiMesh()); std::unique_ptr<aiMesh> mesh(new aiMesh());
mesh->mNumFaces = static_cast<unsigned int>(polyCount); mesh->mNumFaces = static_cast<unsigned int>(polyCount);
@ -443,14 +418,14 @@ aiMesh* C4DImporter::ReadMesh(BaseObject* object)
// check if there are normals, tangents or UVW coordinates // check if there are normals, tangents or UVW coordinates
BaseTag* tag = object->GetTag(Tnormal); BaseTag* tag = object->GetTag(Tnormal);
NormalTag* normals_src = NULL; NormalTag* normals_src = nullptr;
if(tag) { if(tag) {
normals_src = dynamic_cast<NormalTag*>(tag); normals_src = dynamic_cast<NormalTag*>(tag);
normals = mesh->mNormals = new aiVector3D[mesh->mNumVertices](); normals = mesh->mNormals = new aiVector3D[mesh->mNumVertices]();
} }
tag = object->GetTag(Ttangent); tag = object->GetTag(Ttangent);
TangentTag* tangents_src = NULL; TangentTag* tangents_src = nullptr;
if(tag) { if(tag) {
tangents_src = dynamic_cast<TangentTag*>(tag); tangents_src = dynamic_cast<TangentTag*>(tag);
tangents = mesh->mTangents = new aiVector3D[mesh->mNumVertices](); tangents = mesh->mTangents = new aiVector3D[mesh->mNumVertices]();
@ -458,15 +433,14 @@ aiMesh* C4DImporter::ReadMesh(BaseObject* object)
} }
tag = object->GetTag(Tuvw); tag = object->GetTag(Tuvw);
UVWTag* uvs_src = NULL; UVWTag* uvs_src = nullptr;
if(tag) { if(tag) {
uvs_src = dynamic_cast<UVWTag*>(tag); uvs_src = dynamic_cast<UVWTag*>(tag);
uvs = mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices](); uvs = mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices]();
} }
// copy vertices and extra channels over and populate faces // copy vertices and extra channels over and populate faces
for (LONG i = 0; i < polyCount; ++i, ++face) for (LONG i = 0; i < polyCount; ++i, ++face) {
{
ai_assert(polys[i].a < pointCount && polys[i].a >= 0); ai_assert(polys[i].a < pointCount && polys[i].a >= 0);
const Vector& pointA = points[polys[i].a]; const Vector& pointA = points[polys[i].a];
verts->x = pointA.x; verts->x = pointA.x;
@ -489,8 +463,7 @@ aiMesh* C4DImporter::ReadMesh(BaseObject* object)
++verts; ++verts;
// TODO: do we also need to handle lines or points with similar checks? // TODO: do we also need to handle lines or points with similar checks?
if (polys[i].c != polys[i].d) if (polys[i].c != polys[i].d) {
{
ai_assert(polys[i].d < pointCount && polys[i].d >= 0); ai_assert(polys[i].d < pointCount && polys[i].d >= 0);
face->mNumIndices = 4; face->mNumIndices = 4;
@ -500,8 +473,7 @@ aiMesh* C4DImporter::ReadMesh(BaseObject* object)
verts->y = pointD.y; verts->y = pointD.y;
verts->z = pointD.z; verts->z = pointD.z;
++verts; ++verts;
} } else {
else {
face->mNumIndices = 3; face->mNumIndices = 3;
} }
face->mIndices = new unsigned int[face->mNumIndices]; face->mIndices = new unsigned int[face->mNumIndices];
@ -513,8 +485,7 @@ aiMesh* C4DImporter::ReadMesh(BaseObject* object)
if (normals_src) { if (normals_src) {
if(i >= normals_src->GetDataCount()) { if(i >= normals_src->GetDataCount()) {
LogError("unexpected number of normals, ignoring"); LogError("unexpected number of normals, ignoring");
} } else {
else {
ConstNormalHandle normal_handle = normals_src->GetDataAddressR(); ConstNormalHandle normal_handle = normals_src->GetDataAddressR();
NormalStruct nor; NormalStruct nor;
NormalTag::Get(normal_handle, i, nor); NormalTag::Get(normal_handle, i, nor);
@ -616,26 +587,25 @@ aiMesh* C4DImporter::ReadMesh(BaseObject* object)
} }
mesh->mMaterialIndex = ResolveMaterial(polyObject); mesh->mMaterialIndex = ResolveMaterial(polyObject);
return mesh.release(); return mesh.release();
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
unsigned int C4DImporter::ResolveMaterial(PolygonObject* obj) unsigned int C4DImporter::ResolveMaterial(PolygonObject* obj) {
{ ai_assert(obj != nullptr);
ai_assert(obj != NULL);
const unsigned int mat_count = static_cast<unsigned int>(materials.size()); const unsigned int mat_count = static_cast<unsigned int>(materials.size());
BaseTag* tag = obj->GetTag(Ttexture); BaseTag* tag = obj->GetTag(Ttexture);
if(tag == NULL) { if(tag == nullptr) {
return mat_count; return mat_count;
} }
TextureTag& ttag = dynamic_cast<TextureTag&>(*tag); TextureTag& ttag = dynamic_cast<TextureTag&>(*tag);
BaseMaterial* const mat = ttag.GetMaterial(); BaseMaterial* const mat = ttag.GetMaterial();
ai_assert(mat != NULL); ai_assert(mat != nullptr);
const MaterialMap::const_iterator it = material_mapping.find(mat); const MaterialMap::const_iterator it = material_mapping.find(mat);
if(it == material_mapping.end()) { if(it == material_mapping.end()) {
@ -643,6 +613,7 @@ unsigned int C4DImporter::ResolveMaterial(PolygonObject* obj)
} }
ai_assert((*it).second < mat_count); ai_assert((*it).second < mat_count);
return (*it).second; return (*it).second;
} }

View File

@ -2,7 +2,7 @@
Open Asset Import Library (assimp) Open Asset Import Library (assimp)
---------------------------------------------------------------------- ----------------------------------------------------------------------
Copyright (c) 2006-2012, assimp team Copyright (c) 2006-2019, assimp team
All rights reserved. All rights reserved.
Redistribution and use of this software in source and binary forms, Redistribution and use of this software in source and binary forms,
@ -48,6 +48,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/LogAux.h> #include <assimp/LogAux.h>
#include <map> #include <map>
// Forward declarations
struct aiNode; struct aiNode;
struct aiMesh; struct aiMesh;
struct aiMaterial; struct aiMaterial;
@ -61,8 +63,7 @@ namespace melange {
class BaseShader; class BaseShader;
} }
namespace Assimp { namespace Assimp {
// TinyFormatter.h // TinyFormatter.h
namespace Formatter { namespace Formatter {
template <typename T,typename TR, typename A> class basic_formatter; template <typename T,typename TR, typename A> class basic_formatter;
@ -75,17 +76,10 @@ namespace Assimp {
* *
* Note that Melange is not free software. */ * Note that Melange is not free software. */
// ------------------------------------------------------------------------------------------- // -------------------------------------------------------------------------------------------
class C4DImporter : public BaseImporter, public LogFunctions<C4DImporter> class C4DImporter : public BaseImporter, public LogFunctions<C4DImporter> {
{
public: public:
C4DImporter(); C4DImporter();
~C4DImporter(); ~C4DImporter();
public:
// --------------------
bool CanRead( const std::string& pFile, IOSystem* pIOHandler, bool CanRead( const std::string& pFile, IOSystem* pIOHandler,
bool checkSig) const; bool checkSig) const;
@ -119,5 +113,5 @@ private:
}; // !class C4DImporter }; // !class C4DImporter
} // end of namespace Assimp } // end of namespace Assimp
#endif // INCLUDED_AI_CINEMA_4D_LOADER_H
#endif // INCLUDED_AI_CINEMA_4D_LOADER_H