예제 #1
0
// ------------------------------------------------------------------------------------------------
// 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() == NULL) {
        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 == NULL) {
        ThrowException("failed to read document " + pFile);
    }

    pScene->mRootNode = new aiNode("<C4DRoot>");

    // first convert all materials
    ReadMaterials(doc->GetFirstMaterial());

    // process C4D scenegraph 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;

            ScopeGuard<aiMaterial> def_material(new aiMaterial());
            const aiString name(AI_DEFAULT_MATERIAL_NAME);
            def_material->AddProperty(&name, AI_MATKEY_NAME);

            materials.push_back(def_material.dismiss());
            break;
        }
    }

    pScene->mNumMaterials = static_cast<unsigned int>(materials.size());
    pScene->mMaterials = new aiMaterial*[pScene->mNumMaterials]();
    std::copy(materials.begin(), materials.end(), pScene->mMaterials);
}