summaryrefslogtreecommitdiff
path: root/libs/assimp/code/AssetLib/C4D/C4DImporter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/assimp/code/AssetLib/C4D/C4DImporter.cpp')
-rw-r--r--libs/assimp/code/AssetLib/C4D/C4DImporter.cpp620
1 files changed, 0 insertions, 620 deletions
diff --git a/libs/assimp/code/AssetLib/C4D/C4DImporter.cpp b/libs/assimp/code/AssetLib/C4D/C4DImporter.cpp
deleted file mode 100644
index 06d7a34..0000000
--- a/libs/assimp/code/AssetLib/C4D/C4DImporter.cpp
+++ /dev/null
@@ -1,620 +0,0 @@
-/*
-Open Asset Import Library (assimp)
-----------------------------------------------------------------------
-
-Copyright (c) 2006-2021, assimp team
-All rights reserved.
-
-Redistribution and use of this software in source and binary forms,
-with or without modification, are permitted provided that the
-following conditions are met:
-
-* Redistributions of source code must retain the above
- copyright notice, this list of conditions and the
- following disclaimer.
-
-* Redistributions in binary form must reproduce the above
- copyright notice, this list of conditions and the
- following disclaimer in the documentation and/or other
- materials provided with the distribution.
-
-* Neither the name of the assimp team, nor the names of its
- contributors may be used to endorse or promote products
- derived from this software without specific prior
- written permission of the assimp team.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-----------------------------------------------------------------------
-*/
-
-/** @file C4DImporter.cpp
- * @brief Implementation of the Cinema4D importer class.
- */
-#ifndef ASSIMP_BUILD_NO_C4D_IMPORTER
-
-// no #ifdefing here, Cinema4D support is carried out in a branch of assimp
-// where it is turned on in the CMake settings.
-
-#ifndef _MSC_VER
-# error C4D support is currently MSVC only
-#endif
-
-#include "C4DImporter.h"
-#include <memory>
-#include <assimp/IOSystem.hpp>
-#include <assimp/scene.h>
-#include <assimp/ai_assert.h>
-
-#if defined(_M_X64) || defined(__amd64__)
-# define __C4D_64BIT
-#endif
-
-#define __PC
-#include "c4d_file.h"
-#include "default_alien_overloads.h"
-
-namespace {
-
-aiString aiStringFrom(cineware::String const & cinestring) {
- aiString result;
- cinestring.GetCString(result.data, MAXLEN-1);
- result.length = static_cast<ai_uint32>(cinestring.GetLength());
- return result;
-}
-
-}
-
-using namespace Assimp;
-using namespace cineware;
-
-// overload this function and fill in your own unique data
-void GetWriterInfo(int &id, String &appname) {
- id = 2424226;
- appname = "Open Asset Import Library";
-}
-
-namespace Assimp {
- template<> const char* LogFunctions<C4DImporter>::Prefix() {
- static auto prefix = "C4D: ";
- return prefix;
- }
-}
-
-static const aiImporterDesc desc = {
- "Cinema4D Importer",
- "",
- "",
- "",
- aiImporterFlags_SupportBinaryFlavour,
- 0,
- 0,
- 0,
- 0,
- "c4d"
-};
-
-
-// ------------------------------------------------------------------------------------------------
-C4DImporter::C4DImporter()
-: BaseImporter() {
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-C4DImporter::~C4DImporter() {
- // empty
-}
-
-// ------------------------------------------------------------------------------------------------
-bool C4DImporter::CanRead( const std::string& pFile, IOSystem* /*pIOHandler*/, bool /*checkSig*/) const {
- const std::string& extension = GetExtension(pFile);
- if (extension == "c4d") {
- return true;
- } else if ((!extension.length() || checkSig) && pIOHandler) {
- // TODO
- }
-
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-const aiImporterDesc* C4DImporter::GetInfo () const {
- return &desc;
-}
-
-
-// ------------------------------------------------------------------------------------------------
-// Imports the given file into the given scene structure.
-void C4DImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOSystem* pIOHandler) {
- std::unique_ptr<IOStream> file( pIOHandler->Open( pFile));
-
- if( file.get() == nullptr ) {
- ThrowException("failed to open file " + pFile);
- }
-
- const size_t file_size = file->FileSize();
-
- std::vector<uint8_t> mBuffer(file_size);
- file->Read(&mBuffer[0], 1, file_size);
-
- Filename f;
- f.SetMemoryReadMode(&mBuffer[0], file_size);
-
- // open document first
- BaseDocument* doc = LoadDocument(f, SCENEFILTER_OBJECTS | SCENEFILTER_MATERIALS);
- if(doc == nullptr ) {
- ThrowException("failed to read document " + pFile);
- }
-
- // Generate the root-node
- pScene->mRootNode = new aiNode("<C4DRoot>");
-
- // convert left-handed to right-handed
- pScene->mRootNode->mTransformation.a1 = 0.01f;
- pScene->mRootNode->mTransformation.b2 = 0.01f;
- pScene->mRootNode->mTransformation.c3 = -0.01f;
-
- // first convert all materials
- ReadMaterials(doc->GetFirstMaterial());
-
- // process C4D scene-graph recursively
- try {
- RecurseHierarchy(doc->GetFirstObject(), pScene->mRootNode);
- } catch(...) {
- for(aiMesh* mesh : meshes) {
- delete mesh;
- }
- BaseDocument::Free(doc);
- throw;
- }
- BaseDocument::Free(doc);
-
- // copy meshes over
- pScene->mNumMeshes = static_cast<unsigned int>(meshes.size());
- pScene->mMeshes = new aiMesh*[pScene->mNumMeshes]();
- std::copy(meshes.begin(), meshes.end(), pScene->mMeshes);
-
- // copy materials over, adding a default material if necessary
- unsigned int mat_count = static_cast<unsigned int>(materials.size());
- for(aiMesh* mesh : meshes) {
- ai_assert(mesh->mMaterialIndex <= mat_count);
- if(mesh->mMaterialIndex >= mat_count) {
- ++mat_count;
-
- std::unique_ptr<aiMaterial> def_material(new aiMaterial());
- const aiString name(AI_DEFAULT_MATERIAL_NAME);
- def_material->AddProperty(&name, AI_MATKEY_NAME);
-
- materials.push_back(def_material.release());
- break;
- }
- }
-
- pScene->mNumMaterials = static_cast<unsigned int>(materials.size());
- pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials]();
- std::copy(materials.begin(), materials.end(), pScene->mMaterials);
-}
-
-
-// ------------------------------------------------------------------------------------------------
-bool C4DImporter::ReadShader(aiMaterial* out, BaseShader* shader) {
- // based on Cineware sample code (C4DImportExport.cpp)
- while(shader) {
- if(shader->GetType() == Xlayer) {
- BaseContainer* container = shader->GetDataInstance();
- GeData blend = container->GetData(SLA_LAYER_BLEND);
- iBlendDataType* blend_list = reinterpret_cast<iBlendDataType*>(blend.GetCustomDataType(CUSTOMDATA_BLEND_LIST));
- if (!blend_list)
- {
- LogWarn("ignoring XLayer shader: no blend list given");
- continue;
- }
-
- LayerShaderLayer *lsl = dynamic_cast<LayerShaderLayer*>(blend_list->m_BlendLayers.GetObject(0));
-
- // 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
- // to the model.
- while (lsl) {
- if (lsl->GetType() == TypeFolder) {
- BlendFolder* const folder = dynamic_cast<BlendFolder*>(lsl);
- LayerShaderLayer *subLsl = dynamic_cast<LayerShaderLayer*>(folder->m_Children.GetObject(0));
-
- while (subLsl) {
- if (subLsl->GetType() == TypeShader) {
- BlendShader* const shader = dynamic_cast<BlendShader*>(subLsl);
- if(ReadShader(out, static_cast<BaseShader*>(shader->m_pLink->GetLink()))) {
- return true;
- }
- }
-
- subLsl = subLsl->GetNext();
- }
- } else if (lsl->GetType() == TypeShader) {
- BlendShader* const shader = dynamic_cast<BlendShader*>(lsl);
- if(ReadShader(out, static_cast<BaseShader*>(shader->m_pLink->GetLink()))) {
- return true;
- }
- }
-
- lsl = lsl->GetNext();
- }
- } else if ( shader->GetType() == Xbitmap ) {
- auto const path = aiStringFrom(shader->GetFileName().GetString());
- out->AddProperty(&path, AI_MATKEY_TEXTURE_DIFFUSE(0));
- return true;
- } else {
- LogWarn("ignoring shader type: ", GetObjectTypeName(shader->GetType()));
- }
- shader = shader->GetNext();
- }
-
- return false;
-}
-
-// ------------------------------------------------------------------------------------------------
-void C4DImporter::ReadMaterials(BaseMaterial* mat) {
- // based on Cineware sample code
- while (mat) {
- if (mat->GetType() == Mmaterial) {
- aiMaterial* out = new aiMaterial();
- material_mapping[mat] = static_cast<unsigned int>(materials.size());
- materials.push_back(out);
-
- auto const ai_name = aiStringFrom(mat->GetName());
- out->AddProperty(&ai_name, AI_MATKEY_NAME);
-
- Material& m = dynamic_cast<Material&>(*mat);
-
- if (m.GetChannelState(CHANNEL_COLOR)) {
- GeData data;
- mat->GetParameter(MATERIAL_COLOR_COLOR, data);
- Vector color = data.GetVector();
- mat->GetParameter(MATERIAL_COLOR_BRIGHTNESS, data);
- const Float brightness = data.GetFloat();
-
- color *= brightness;
-
- aiVector3D v;
- v.x = color.x;
- v.y = color.y;
- v.z = color.z;
- out->AddProperty(&v, 1, AI_MATKEY_COLOR_DIFFUSE);
- }
-
- BaseShader* const shader = m.GetShader(MATERIAL_COLOR_SHADER);
- if(shader) {
- ReadShader(out, shader);
- }
- } else {
- LogWarn("ignoring plugin material: ", GetObjectTypeName(mat->GetType()));
- }
- mat = mat->GetNext();
- }
-}
-
-// ------------------------------------------------------------------------------------------------
-void C4DImporter::RecurseHierarchy(BaseObject* object, aiNode* parent) {
- ai_assert(parent != nullptr );
- std::vector<aiNode*> nodes;
-
- // based on Cineware sample code
- while (object) {
- const LONG type = object->GetType();
- const Matrix& ml = object->GetMl();
-
- aiNode* const nd = new aiNode();
-
- nd->mParent = parent;
- nd->mName = aiStringFrom(object->GetName());
-
- nd->mTransformation.a1 = ml.v1.x;
- nd->mTransformation.b1 = ml.v1.y;
- nd->mTransformation.c1 = ml.v1.z;
-
- nd->mTransformation.a2 = ml.v2.x;
- nd->mTransformation.b2 = ml.v2.y;
- nd->mTransformation.c2 = ml.v2.z;
-
- nd->mTransformation.a3 = ml.v3.x;
- nd->mTransformation.b3 = ml.v3.y;
- nd->mTransformation.c3 = ml.v3.z;
-
- nd->mTransformation.a4 = ml.off.x;
- nd->mTransformation.b4 = ml.off.y;
- nd->mTransformation.c4 = ml.off.z;
-
- nodes.push_back(nd);
-
- GeData data;
- if (type == Ocamera) {
- object->GetParameter(CAMERAOBJECT_FOV, data);
- // TODO: read camera
- } else if (type == Olight) {
- // TODO: read light
- } else if (type == Opolygon) {
- aiMesh* const mesh = ReadMesh(object);
- if(mesh != nullptr) {
- nd->mNumMeshes = 1;
- nd->mMeshes = new unsigned int[1];
- nd->mMeshes[0] = static_cast<unsigned int>(meshes.size());
- meshes.push_back(mesh);
- }
- } else {
- LogWarn("ignoring object: ", GetObjectTypeName(type));
- }
-
- RecurseHierarchy(object->GetDown(), nd);
- object = object->GetNext();
- }
-
- // copy nodes over to parent
- parent->mNumChildren = static_cast<unsigned int>(nodes.size());
- parent->mChildren = new aiNode*[parent->mNumChildren]();
- std::copy(nodes.begin(), nodes.end(), parent->mChildren);
-}
-
-// ------------------------------------------------------------------------------------------------
-aiMesh* C4DImporter::ReadMesh(BaseObject* object) {
- ai_assert(object != nullptr);
- ai_assert( object->GetType() == Opolygon );
-
- // based on Cineware sample code
- PolygonObject* const polyObject = dynamic_cast<PolygonObject*>(object);
- ai_assert(polyObject != nullptr);
-
- const LONG pointCount = polyObject->GetPointCount();
- const LONG polyCount = polyObject->GetPolygonCount();
- if(!polyObject || !pointCount) {
- LogWarn("ignoring mesh with zero vertices or faces");
- return nullptr;
- }
-
- const Vector* points = polyObject->GetPointR();
- ai_assert(points != nullptr);
-
- const CPolygon* polys = polyObject->GetPolygonR();
- ai_assert(polys != nullptr);
-
- std::unique_ptr<aiMesh> mesh(new aiMesh());
- mesh->mNumFaces = static_cast<unsigned int>(polyCount);
- aiFace* face = mesh->mFaces = new aiFace[mesh->mNumFaces]();
-
- mesh->mPrimitiveTypes = aiPrimitiveType_TRIANGLE;
- mesh->mMaterialIndex = 0;
-
- unsigned int vcount = 0;
-
- // first count vertices
- for (LONG i = 0; i < polyCount; i++)
- {
- vcount += 3;
-
- // TODO: do we also need to handle lines or points with similar checks?
- if (polys[i].c != polys[i].d)
- {
- mesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
- ++vcount;
- }
- }
-
- ai_assert(vcount > 0);
-
- mesh->mNumVertices = vcount;
- aiVector3D* verts = mesh->mVertices = new aiVector3D[mesh->mNumVertices];
- aiVector3D* normals, *uvs, *tangents, *bitangents;
- unsigned int n = 0;
-
- // check if there are normals, tangents or UVW coordinates
- BaseTag* tag = object->GetTag(Tnormal);
- NormalTag* normals_src = nullptr;
- if(tag) {
- normals_src = dynamic_cast<NormalTag*>(tag);
- normals = mesh->mNormals = new aiVector3D[mesh->mNumVertices]();
- }
-
- tag = object->GetTag(Ttangent);
- TangentTag* tangents_src = nullptr;
- if(tag) {
- tangents_src = dynamic_cast<TangentTag*>(tag);
- tangents = mesh->mTangents = new aiVector3D[mesh->mNumVertices]();
- bitangents = mesh->mBitangents = new aiVector3D[mesh->mNumVertices]();
- }
-
- tag = object->GetTag(Tuvw);
- UVWTag* uvs_src = nullptr;
- if(tag) {
- uvs_src = dynamic_cast<UVWTag*>(tag);
- uvs = mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices]();
- }
-
- // copy vertices and extra channels over and populate faces
- for (LONG i = 0; i < polyCount; ++i, ++face) {
- ai_assert(polys[i].a < pointCount && polys[i].a >= 0);
- const Vector& pointA = points[polys[i].a];
- verts->x = pointA.x;
- verts->y = pointA.y;
- verts->z = pointA.z;
- ++verts;
-
- ai_assert(polys[i].b < pointCount && polys[i].b >= 0);
- const Vector& pointB = points[polys[i].b];
- verts->x = pointB.x;
- verts->y = pointB.y;
- verts->z = pointB.z;
- ++verts;
-
- ai_assert(polys[i].c < pointCount && polys[i].c >= 0);
- const Vector& pointC = points[polys[i].c];
- verts->x = pointC.x;
- verts->y = pointC.y;
- verts->z = pointC.z;
- ++verts;
-
- // TODO: do we also need to handle lines or points with similar checks?
- if (polys[i].c != polys[i].d) {
- ai_assert(polys[i].d < pointCount && polys[i].d >= 0);
-
- face->mNumIndices = 4;
- mesh->mPrimitiveTypes |= aiPrimitiveType_POLYGON;
- const Vector& pointD = points[polys[i].d];
- verts->x = pointD.x;
- verts->y = pointD.y;
- verts->z = pointD.z;
- ++verts;
- } else {
- face->mNumIndices = 3;
- }
- face->mIndices = new unsigned int[face->mNumIndices];
- for(unsigned int j = 0; j < face->mNumIndices; ++j) {
- face->mIndices[j] = n++;
- }
-
- // copy normals
- if (normals_src) {
- if(i >= normals_src->GetDataCount()) {
- LogError("unexpected number of normals, ignoring");
- } else {
- ConstNormalHandle normal_handle = normals_src->GetDataAddressR();
- NormalStruct nor;
- NormalTag::Get(normal_handle, i, nor);
- normals->x = nor.a.x;
- normals->y = nor.a.y;
- normals->z = nor.a.z;
- ++normals;
-
- normals->x = nor.b.x;
- normals->y = nor.b.y;
- normals->z = nor.b.z;
- ++normals;
-
- normals->x = nor.c.x;
- normals->y = nor.c.y;
- normals->z = nor.c.z;
- ++normals;
-
- if(face->mNumIndices == 4) {
- normals->x = nor.d.x;
- normals->y = nor.d.y;
- normals->z = nor.d.z;
- ++normals;
- }
- }
- }
-
- // copy tangents and bitangents
- if (tangents_src) {
-
- for(unsigned int k = 0; k < face->mNumIndices; ++k) {
- LONG l;
- switch(k) {
- case 0:
- l = polys[i].a;
- break;
- case 1:
- l = polys[i].b;
- break;
- case 2:
- l = polys[i].c;
- break;
- case 3:
- l = polys[i].d;
- break;
- default:
- ai_assert(false);
- }
- if(l >= tangents_src->GetDataCount()) {
- LogError("unexpected number of tangents, ignoring");
- break;
- }
-
- Tangent tan = tangents_src->GetDataR()[l];
- tangents->x = tan.vl.x;
- tangents->y = tan.vl.y;
- tangents->z = tan.vl.z;
- ++tangents;
-
- bitangents->x = tan.vr.x;
- bitangents->y = tan.vr.y;
- bitangents->z = tan.vr.z;
- ++bitangents;
- }
- }
-
- // copy UVs
- if (uvs_src) {
- if(i >= uvs_src->GetDataCount()) {
- LogError("unexpected number of UV coordinates, ignoring");
- }
- else {
- UVWStruct uvw;
- uvs_src->Get(uvs_src->GetDataAddressR(),i,uvw);
-
- uvs->x = uvw.a.x;
- uvs->y = 1.0f-uvw.a.y;
- uvs->z = uvw.a.z;
- ++uvs;
-
- uvs->x = uvw.b.x;
- uvs->y = 1.0f-uvw.b.y;
- uvs->z = uvw.b.z;
- ++uvs;
-
- uvs->x = uvw.c.x;
- uvs->y = 1.0f-uvw.c.y;
- uvs->z = uvw.c.z;
- ++uvs;
-
- if(face->mNumIndices == 4) {
- uvs->x = uvw.d.x;
- uvs->y = 1.0f-uvw.d.y;
- uvs->z = uvw.d.z;
- ++uvs;
- }
- }
- }
- }
-
- mesh->mMaterialIndex = ResolveMaterial(polyObject);
-
- return mesh.release();
-}
-
-// ------------------------------------------------------------------------------------------------
-unsigned int C4DImporter::ResolveMaterial(PolygonObject* obj) {
- ai_assert(obj != nullptr);
-
- const unsigned int mat_count = static_cast<unsigned int>(materials.size());
-
- BaseTag* tag = obj->GetTag(Ttexture);
- if(tag == nullptr) {
- return mat_count;
- }
-
- TextureTag& ttag = dynamic_cast<TextureTag&>(*tag);
-
- BaseMaterial* const mat = ttag.GetMaterial();
- ai_assert(mat != nullptr);
-
- const MaterialMap::const_iterator it = material_mapping.find(mat);
- if(it == material_mapping.end()) {
- return mat_count;
- }
-
- ai_assert((*it).second < mat_count);
-
- return (*it).second;
-}
-
-#endif // ASSIMP_BUILD_NO_C4D_IMPORTER