Beispiel #1
1
TEST_F(utSTLImporterExporter, test_export_pointclouds) {
    struct XYZ {
        float x, y, z;
    };

    std::vector<XYZ> points;

    for (size_t i = 0; i < 10; ++i) {
        XYZ current;
        current.x = static_cast<float>(i);
        current.y = static_cast<float>(i);
        current.z = static_cast<float>(i);
        points.push_back(current);
    }
    aiScene scene;
    scene.mRootNode = new aiNode();

    scene.mMeshes = new aiMesh*[1];
    scene.mMeshes[0] = nullptr;
    scene.mNumMeshes = 1;

    scene.mMaterials = new aiMaterial*[1];
    scene.mMaterials[0] = nullptr;
    scene.mNumMaterials = 1;

    scene.mMaterials[0] = new aiMaterial();

    scene.mMeshes[0] = new aiMesh();
    scene.mMeshes[0]->mMaterialIndex = 0;

    scene.mRootNode->mMeshes = new unsigned int[1];
    scene.mRootNode->mMeshes[0] = 0;
    scene.mRootNode->mNumMeshes = 1;

    auto pMesh = scene.mMeshes[0];

    size_t numValidPoints = points.size();

    pMesh->mVertices = new aiVector3D[numValidPoints];
    pMesh->mNumVertices = static_cast<unsigned int>( numValidPoints );

    int i = 0;
    for (XYZ &p : points) {
        pMesh->mVertices[i] = aiVector3D(p.x, p.y, p.z);
        ++i;
    }

    Assimp::Exporter mAiExporter;
    ExportProperties *properties = new ExportProperties;
    properties->SetPropertyBool(AI_CONFIG_EXPORT_POINT_CLOUDS, true);
    mAiExporter.Export(&scene, "stl", "testExport.stl", 0, properties );

    delete properties;
}
    virtual bool exporterTest() {
        Assimp::Importer importer;
        Assimp::Exporter exporter;
        const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTextured-glTF/BoxTextured.gltf", aiProcess_ValidateDataStructure );
        EXPECT_NE( nullptr, scene );
        EXPECT_EQ( aiReturn_SUCCESS, exporter.Export( scene, "gltf2", ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTextured-glTF/BoxTextured_out.gltf" ) );

        return true;
    }
Beispiel #3
0
TEST_F(utSTLImporterExporter, exporterTest) {
    Assimp::Importer importer;
    const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/STL/Spider_ascii.stl", aiProcess_ValidateDataStructure);

    Assimp::Exporter mAiExporter;
    mAiExporter.Export( scene, "stl", "spiderExport.stl" );

    const aiScene *scene2 = importer.ReadFile("spiderExport.stl", aiProcess_ValidateDataStructure);
    EXPECT_NE(nullptr, scene2);
}
Beispiel #4
0
const bool aiExport::aiExecute( const aiScene * scene )
{
	// Retrieves the file path.
	const boost::filesystem::path path = getPath();

	// If there is a file path, we can export.
	if( !path.empty() )
	{
		Assimp::Exporter		exporter;
		Formats::const_iterator format = findFormat( path );

		vgAssertN( format != m_formats.end(), "Export format must be specified." );
		exporter.Export( scene, format->aiId, path.string().c_str(), 0u );
		// We should do some error checking !
	}

	return false; // We never need to refresh the scene.
}
Beispiel #5
0
bool mesh::export_to_file(const std::string& format, const std::string& filepath, const std::string & filename) {
    Assimp::Exporter exporter;

    // TODO: fix the memory leak from not deleting temp
    // Note that aiScene::~aiScene() is not exported by the library
    //      and as such fixing this leak is hard/impossible

    aiScene * temp;
    aiCopyScene(this->scene, &temp);
    keep_faces(this->walkable_faces, temp);

    if(AI_SUCCESS == exporter.Export(temp, format, filepath+filename)) {
        return true;
    }

    std::cerr << exporter.GetErrorString() << std::endl;
    return false;
}
Beispiel #6
0
TEST_F( utIssues, OpacityBugWhenExporting_727 ) {
    float opacity;
    aiScene *scene( TestModelFacttory::createDefaultTestModel( opacity ) );
    Assimp::Importer importer;
    Assimp::Exporter exporter;
                
    std::string path = "dae";
    const aiExportFormatDesc *desc( exporter.GetExportFormatDescription( 0 ) );
    EXPECT_NE( desc, nullptr );
    path.append( desc->fileExtension );
    EXPECT_EQ( AI_SUCCESS, exporter.Export( scene, desc->id, path ) );
    const aiScene *newScene( importer.ReadFile( path, 0 ) );
    EXPECT_TRUE( NULL != newScene );
    float newOpacity;
    if ( newScene->mNumMaterials > 0 ) {
        std::cout << "Desc = " << desc->description << "\n";
        EXPECT_EQ( AI_SUCCESS, newScene->mMaterials[ 0 ]->Get( AI_MATKEY_OPACITY, newOpacity ) );
        EXPECT_EQ( opacity, newOpacity );
    }
}
void ColladaExporter::save(const TMD::PostProcessed::Data_t& data, const std::vector<CAT::ResourceEntry_t::SubEntry_t>& references) {
	boost::filesystem::path output_path(_export_folder);
	output_path /= "tmd";
	boost::filesystem::path dae_filename(output_path);
	dae_filename += _dae_suffix;

	/*std::ofstream dae_out;
	open_to_write(dae_out, dae_filename);
	LeftPad_t pad{ 0 };
	PaddedOstream pad_out(dae_out, pad);
	write_document(pad_out, data);
	dae_out.close();*/

	aiScene scene;
	create_assimp_scene(scene, data);

	Assimp::Exporter exporter;
	auto export_format = exporter.GetExportFormatDescription(0);

	exporter.Export(&scene, export_format->id, dae_filename.string().c_str());

}
Beispiel #8
0
void IrrAssimpExport::writeFile(irr::scene::IMesh* mesh, irr::core::stringc format, irr::core::stringc filename)
{
    Assimp::Exporter exporter;

    aiScene* scene = new aiScene();
    scene->mRootNode = new aiNode();
    scene->mRootNode->mNumMeshes = mesh->getMeshBufferCount();
    scene->mRootNode->mMeshes = new unsigned int[mesh->getMeshBufferCount()];
    for (unsigned int i = 0; i < mesh->getMeshBufferCount(); ++i)
        scene->mRootNode->mMeshes[i] = i;

    scene->mNumMeshes = mesh->getMeshBufferCount();
    scene->mMeshes = new aiMesh*[scene->mNumMeshes];

    scene->mNumMaterials = scene->mNumMeshes;
    scene->mMaterials = new aiMaterial*[scene->mNumMeshes];

    for (unsigned int i = 0; i < mesh->getMeshBufferCount(); ++i)
    {
        aiMesh* assMesh = new aiMesh();
        irr::scene::IMeshBuffer* buffer = mesh->getMeshBuffer(i);
        video::E_VERTEX_TYPE verticesType = buffer->getVertexType();

        assMesh->mNumVertices = buffer->getVertexCount();
        assMesh->mVertices = new aiVector3D[assMesh->mNumVertices];
        assMesh->mNormals = new aiVector3D[assMesh->mNumVertices];

        assMesh->mTextureCoords[0] = new aiVector3D[assMesh->mNumVertices];
        assMesh->mNumUVComponents[0] = 2;

        assMesh->mColors[0] = new aiColor4D[assMesh->mNumVertices];

        if (verticesType == video::EVT_2TCOORDS)
        {
            assMesh->mTextureCoords[1] = new aiVector3D[assMesh->mNumVertices];
            assMesh->mNumUVComponents[1] = 2;
        }
        if (verticesType == video::EVT_TANGENTS)
        {
            assMesh->mTangents = new aiVector3D[assMesh->mNumVertices];
            assMesh->mBitangents = new aiVector3D[assMesh->mNumVertices];
        }

        video::S3DVertex* vertices = (video::S3DVertex*)buffer->getVertices();

        video::S3DVertex2TCoords* tCoordsVertices;
        verticesType == video::EVT_2TCOORDS ? tCoordsVertices = (video::S3DVertex2TCoords*) vertices : tCoordsVertices = 0;

        video::S3DVertexTangents* tangentsVertices;
        verticesType == video::EVT_TANGENTS ? tangentsVertices = (video::S3DVertexTangents*) vertices : tangentsVertices = 0;

        for (unsigned int j = 0; j < buffer->getVertexCount(); ++j)
        {
            video::S3DVertex vertex = vertices[j];

            core::vector3df position = vertex.Pos;
            core::vector3df normal = vertex.Normal;
            core::vector2df uv = vertex.TCoords;
            video::SColor color = vertex.Color;

            assMesh->mVertices[j] = aiVector3D(position.X, position.Y, position.Z);
            assMesh->mNormals[j] = aiVector3D(normal.X, normal.Y, normal.Z);
            assMesh->mTextureCoords[0][j] = aiVector3D(uv.X, uv.Y, 0);
            assMesh->mColors[0][j] = aiColor4D(color.getRed() / 255.f, color.getGreen() / 255.f, color.getBlue() / 255.f, color.getAlpha() / 255.f);

            if (verticesType == video::EVT_2TCOORDS)
            {
                video::S3DVertex2TCoords tCoordsVertex = tCoordsVertices[j];
                core::vector2df uv2 = tCoordsVertex.TCoords2;
                assMesh->mTextureCoords[1][j] = aiVector3D(uv2.X, uv2.Y, 0);
            }
            if (verticesType == video::EVT_TANGENTS)
            {
                video::S3DVertexTangents tangentsVertex = tangentsVertices[j];
                core::vector3df tangent = tangentsVertex.Tangent;
                core::vector3df binormal = tangentsVertex.Binormal;

                assMesh->mTangents[j] = aiVector3D(tangent.X, tangent.Y, tangent.Z);
                assMesh->mBitangents[j] = aiVector3D(binormal.X, binormal.Y, binormal.Z);
            }
        }

        assMesh->mNumFaces = buffer->getIndexCount() / 3;
        assMesh->mFaces = new aiFace[assMesh->mNumFaces];
        for (unsigned int j = 0; j < assMesh->mNumFaces; ++j)
        {
            aiFace face;
            face.mNumIndices = 3;
            face.mIndices = new unsigned int[3];
            face.mIndices[0] = buffer->getIndices()[3 * j + 0];
            face.mIndices[1] = buffer->getIndices()[3 * j + 1];
            face.mIndices[2] = buffer->getIndices()[3 * j + 2];
            assMesh->mFaces[j] = face;
        }

        scene->mMaterials[i] = new aiMaterial();
        scene->mMaterials[i]->mNumProperties = 0;
        assMesh->mMaterialIndex = i;

        video::SMaterial mat = buffer->getMaterial();

        aiColor3D diffuseColor = IrrToAssimpColor(mat.DiffuseColor);
        aiColor3D ambiantColor = IrrToAssimpColor(mat.AmbientColor);
        aiColor3D emissiveColor = IrrToAssimpColor(mat.EmissiveColor);
        aiColor3D specularColor = IrrToAssimpColor(mat.SpecularColor);
        float shininess = mat.Shininess;

        scene->mMaterials[i]->AddProperty(&diffuseColor, 1, AI_MATKEY_COLOR_DIFFUSE);
        scene->mMaterials[i]->AddProperty(&ambiantColor, 1, AI_MATKEY_COLOR_AMBIENT);
        scene->mMaterials[i]->AddProperty(&emissiveColor, 1, AI_MATKEY_COLOR_EMISSIVE);
        scene->mMaterials[i]->AddProperty(&specularColor, 1, AI_MATKEY_COLOR_SPECULAR);
        scene->mMaterials[i]->AddProperty(&shininess, 1, AI_MATKEY_SHININESS);

        if (mat.getTexture(0))
        {
            aiString textureName = aiString(mat.getTexture(0)->getName().getPath().c_str());
            scene->mMaterials[i]->AddProperty(&textureName, AI_MATKEY_TEXTURE_DIFFUSE(0));
        }
        if (mat.getTexture(1))
        {
            // Normal map
            if (   mat.MaterialType == video::EMT_NORMAL_MAP_SOLID
                || mat.MaterialType == video::EMT_NORMAL_MAP_TRANSPARENT_ADD_COLOR
                || mat.MaterialType == video::EMT_NORMAL_MAP_TRANSPARENT_VERTEX_ALPHA
                || mat.MaterialType == video::EMT_PARALLAX_MAP_SOLID
                || mat.MaterialType == video::EMT_PARALLAX_MAP_TRANSPARENT_ADD_COLOR
                || mat.MaterialType == video::EMT_PARALLAX_MAP_TRANSPARENT_VERTEX_ALPHA)
            {
                aiString textureName = aiString(mat.getTexture(1)->getName().getPath().c_str());
                scene->mMaterials[i]->AddProperty(&textureName, AI_MATKEY_TEXTURE_NORMALS(0));
            }

        }


        scene->mMeshes[i] = assMesh;
    }

    exporter.Export(scene, format.c_str(), filename.c_str(), aiProcess_FlipUVs);

    delete scene;
}
bool AssimpModelExport::writeSceneToFile(
	const aiScene     *scene,
	const std::string &filePath)
{
	bool success = false;
	if (scene)
	{
		boost::filesystem::path boostPath(filePath);
		//--------------------------------------------------------------------------
		// NOTE: This modifies links to textures, so after export, the
		// scene for rendering won't be valid any more!
		//--------------------------------------------------------------------------
		if (scene->HasTextures())
		{ // embedded textures found, replace pointers such as "*0" with "0.jpg"
			aiReturn texFound;
			int texIndex;
			for (unsigned int i = 0; i < scene->mNumMaterials; ++i)
			{
				aiString path;	// filename
				texIndex = 0;
				texFound = AI_SUCCESS;
				while (texFound == AI_SUCCESS)
				{
					texFound = scene->mMaterials[i]->GetTexture(aiTextureType_DIFFUSE, texIndex, &path);
					std::string name(path.data);
					if (!name.empty())
					{
						name = name.substr(1, name.size()) + REPO_DEFAULT_TEXTURE_EXT; // remove leading '*' char
						scene->mMaterials[i]->RemoveProperty(AI_MATKEY_TEXTURE_DIFFUSE(texIndex));
						// TODO: watch out for mem-leak
						scene->mMaterials[i]->AddProperty(new aiString(name.c_str()), AI_MATKEY_TEXTURE_DIFFUSE(texIndex));
						texIndex++;
					}
				}
			}
		}

		Assimp::Exporter exporter;
		std::string extension = boostPath.extension().string();

		std::string exportFormat = getExportFormatID(extension.substr(1, extension.size() - 1));
		repoTrace << "Exporting repo scene using ASSIMP: export format = " << exportFormat << " to " << filePath;
		if (exportFormat.empty())
		{
			repoError << "Unrecognised export format: " << boostPath.extension().string();
		}
		else
		{
			aiReturn ret = exporter.Export(scene, exportFormat, filePath, scene->mFlags);
			switch (ret)
			{
			case aiReturn_FAILURE:
				repoError << "Export failed due to unknown reason.";
				break;
			case aiReturn_OUTOFMEMORY:
				repoError << "Export failed due to running out of memory.";
				break;
			case aiReturn_SUCCESS:
				repoTrace << "Export completed successfully";
				break;
			case _AI_ENFORCE_ENUM_SIZE:
				// Silently handle assimp's bogus enum-size-enforcing value.
				break;
			}
			success = (ret == aiReturn_SUCCESS);
		}
	}
	else{
		repoError << "Trying to write a null pointer assimp scene!";
	}

	return success;
}
/*!
*  \brief      Export a cad model (vertices and faces) with the assimp library
*  \author     Sascha Kaden
*  \param[in]  format
*  \param[in]  filePath
*  \param[in]  list of vertices
*  \param[in]  list of faces
*  \date       2017-02-19
*/
bool exportCad(ExportFormat format, const std::string &filePath, const std::vector<Vector3> &vertices,
               const std::vector<Vector3i> &faces) {
    if (filePath.empty()) {
        Logging::warning("Empty output file path", "CadProcessing");
        return false;
    }

    Assimp::Exporter exporter;
    size_t maxFormatCount = exporter.GetExportFormatCount();
    size_t formatCount;
    switch (format) {
        case ExportFormat::COLLADA:
            formatCount = 0;
            break;
        case ExportFormat::X_FILES:
            formatCount = 1;
            break;
        case ExportFormat::STEP:
            formatCount = 2;
            break;
        case ExportFormat::OBJ:
            formatCount = 3;
            break;
        case ExportFormat::STEREOLITHOGRAPHY:
            formatCount = 4;
            break;
        case ExportFormat::STEREOLITHOGRAPHY_BINARY:
            formatCount = 5;
            break;
        case ExportFormat::STANFORD_POLYGON_LIBRARY:
            formatCount = 6;
            break;
        case ExportFormat::STANFORD_POLYGON_LIBRARY_BINARY:
            formatCount = 7;
            break;
        case ExportFormat::AUTODESK_3DS:
            formatCount = 8;
            break;
        case ExportFormat::GL_TRANSMISSION_FORMAT:
            formatCount = 9;
            break;
        case ExportFormat::GL_TRANSMISSION_FORMAT_BINARY:
            formatCount = 10;
            break;
        case ExportFormat::ASSIMP_BINARY:
            formatCount = 11;
            break;
        case ExportFormat::ASSXML_DOCUMENT:
            formatCount = 12;
            break;
        case ExportFormat::EXTENSIBLE_3D:
            formatCount = 13;
            break;
    }

    if (formatCount > maxFormatCount) {
        Logging::warning("Selected format is not supported", "CadProcessing");
        return false;
    }

    aiScene scene = generateScene(vertices, faces);

    const aiExportFormatDesc *formatDesc = exporter.GetExportFormatDescription(formatCount);
    exporter.Export(&scene, formatDesc->id, filePath + "." + formatDesc->fileExtension, aiProcess_Triangulate);
    return true;
}
Beispiel #11
0
int run(int argc, char* argv[])
{
	Arguments args;

	args.add("help", 'h').description("Shows this help message.").flag(true);
	args.add("input", 'i').description("Input filename").required(true);
	args.add("output", 'o').description("Output filename").required(true);
	args.add("format", 'f').description("Output format. Overrides file extension.");
	args.add("axis", 'x').description("Change axis order of the cordinate system and polarity. (like +x+y+z, +x-z+y, ... )");
	args.add("textures", 't').description("Strip path from texture filenames").flag(true);

	// parse args
	if (!args.evaluate(argc, argv)) {
		cout << args.getErrorMessage() << endl;
		cout << args.getHelpMessage() << endl;
		return 1;
	}

	// print help
	if (argc == 1 || args.get("help").isFound()) {
		cout << args.getHelpMessage() << endl;
		return 0;
	}
 
	string inFileName = args.get("input").value();
	string outFileName = args.get("output").value();
	string outExtension;

	// determine file format
	if (!args.get("format").isFound())
	{
		string::size_type n;
		string s = outFileName;

		n = s.find_last_of('.');
		if (n != string::npos) {
			s = s.substr(n + 1);
		}
		if (s.empty()) {
			outExtension = "assbin";
			cout << "WARNING: No file extension was given. Using assbin format for default." << endl;
		}
		else {
			outExtension = s;
		}
	}
	else {
		outExtension = args.get("format").value();
	}

	// import scene 
	Assimp::Importer aiImporter;
	aiScene const * scene = aiImporter.ReadFile(inFileName.c_str(),
		aiProcessPreset_TargetRealtime_Quality |
		aiProcess_ConvertToLeftHanded |
		0);

	if (scene == nullptr) {
		cout << "Could not load model file" << inFileName << endl;
		cout << aiImporter.GetErrorString() << endl;
		return 1;
	}

	// flip axes
	if (args.get("axis").isFound() && scene->HasMeshes()) {
		string axesOrder = args.get("axis").value();
		if (axesOrder.length() != 6) {
			cout << args.getHelpMessage() << endl;
			return 1;
		}

		char order[3];
		char polarity[3];
		uint k = 3;
		while (k--) {
			char c = axesOrder.at(2*k), b = -1;
			char a = axesOrder.at(2*k+1), d = 1;
			switch (a) {
				case 'x': case 'X': b = 0; break;
				case 'y': case 'Y': b = 1; break;
				case 'z': case 'Z': b = 2; break;
				default:
					cout << args.getHelpMessage() << endl;
					return 1;
			}

			switch (c) {
				case '+': d = +1; break;
				case '-': d = -1; break;
			default:
				cout << args.getHelpMessage() << endl;
				return 1;
			}

			order[k] = b;
			polarity[k] = d;
		}

		for (uint i = 0; i < scene->mNumMeshes; i++) {
			aiMesh * const mesh = scene->mMeshes[i];
			for (uint j = 0; j < mesh->mNumVertices; j++) {
				swap_vertices(&mesh->mVertices[j], order, polarity);
				swap_vertices(&mesh->mNormals[j], order, polarity);
			}
		}
	}

	// strip texture filenames
	if (args.get("textures").isFound() && scene->HasMaterials()) {
		for (uint i = 0; i < scene->mNumMaterials; i++) {
			aiMaterial const * material = scene->mMaterials[i];
			for (uint j = 0; j < sizeof(textureTypes) / sizeof(textureTypes[0]); j++) {
				aiTextureType tt = textureTypes[j];
				for (uint k = 0; k < material->GetTextureCount(tt); k++) {
					aiString aiPath;
					material->GetTexture(tt, k, &aiPath);
					string path = aiPath.C_Str();
					{
						string s = path;
						string::size_type n, m;
						n = s.find_last_of('/');
						m = s.find_last_of('\\');
						if (n != string::npos) {
							s  = s.substr(n + 1);
						}
						else if (m != string::npos) {
							s = s.substr(m + 1);
						}

						if (!s.empty()) {
							path = s;
						}
					}

					// textura filenev vissza
					const aiMaterialProperty* pp = nullptr;
					if (aiGetMaterialProperty(material, AI_MATKEY_TEXTURE(tt, k), &pp) == AI_SUCCESS) {
						aiMaterialProperty* pProp = const_cast<aiMaterialProperty*>(pp);
						if (aiPTI_String == pProp->mType) {
							size_t newLen = path.length() + 4;
							char* newData = (char*)malloc(newLen);
							(*(uint*)(&newData[0])) = path.length();
							memcpy_s(&newData[4], newLen, path.c_str(), path.length());
							free(pProp->mData);
							pProp->mData = newData;
							pProp->mDataLength = newLen;
						}
					}
				}
			}
		}
	}

	// save 
	Assimp::Exporter aiExporter;

	if (aiExporter.Export(scene, outExtension, outFileName) != aiReturn_SUCCESS) {
		cout << "Could not save model file" << endl;
		cout << aiExporter.GetErrorString() << endl;
		return 1;
	}

	return 0;
}
Beispiel #12
0
    void OBJWriter::write(const std::shared_ptr<gameplay::Model>& model,
                          const std::string& baseName,
                          const std::map<loader::TextureLayoutProxy::TextureKey, std::shared_ptr<gameplay::Material>>& mtlMap1,
                          const std::map<loader::TextureLayoutProxy::TextureKey, std::shared_ptr<gameplay::Material>>& mtlMap2,
                          const glm::vec3& ambientColor) const
    {
        Expects(model != nullptr);

        auto fullPath = m_basePath / baseName;

        Assimp::Exporter exporter;
        std::string formatIdentifier;
        for(size_t i = 0; i < exporter.GetExportFormatCount(); ++i)
        {
            auto descr = exporter.GetExportFormatDescription(i);
            BOOST_ASSERT(descr != nullptr);

            std::string exporterExtension = std::string(".") + descr->fileExtension;

            if(exporterExtension == fullPath.extension().string())
            {
                formatIdentifier = descr->id;
                break;
            }
        }

        if(formatIdentifier.empty())
        {
            BOOST_LOG_TRIVIAL(error) << "Failed to find an exporter for the supplied file extension";
            BOOST_LOG_TRIVIAL(info) << "Here's the list of registered exporters";

            for(size_t i = 0; i < exporter.GetExportFormatCount(); ++i)
            {
                auto descr = exporter.GetExportFormatDescription(i);
                BOOST_ASSERT(descr != nullptr);

                BOOST_LOG_TRIVIAL(info) << descr->description << ", extension `" << descr->fileExtension << "`, id `" << descr->id << "`";
            }

            BOOST_THROW_EXCEPTION(std::runtime_error("Failed to find an exporter for the supplied file extension"));
        }

        std::unique_ptr<aiScene> scene = std::make_unique<aiScene>();
        BOOST_ASSERT(scene->mRootNode == nullptr);
        scene->mRootNode = new aiNode();

        {
            size_t totalPartCount = 0;
            for( const auto& mesh : model->getMeshes() )
            {
                totalPartCount += mesh->getPartCount();
            }

            scene->mNumMaterials = totalPartCount;
            scene->mMaterials = new aiMaterial*[totalPartCount];
            std::fill_n(scene->mMaterials, totalPartCount, nullptr);

            scene->mNumMeshes = totalPartCount;
            scene->mMeshes = new aiMesh*[totalPartCount];
            std::fill_n(scene->mMeshes, totalPartCount, nullptr);

            scene->mRootNode->mNumMeshes = totalPartCount;
            scene->mRootNode->mMeshes = new unsigned int[totalPartCount];
            for( size_t i = 0; i < totalPartCount; ++i )
                scene->mRootNode->mMeshes[i] = i;
        }

        for( size_t mi = 0, globalPartIndex = 0; mi < model->getMeshes().size(); ++mi )
        {
            BOOST_ASSERT(mi < scene->mNumMeshes);
            const auto& mesh = model->getMeshes()[mi];

            for( size_t pi = 0; pi < mesh->getPartCount(); ++pi , ++globalPartIndex )
            {
                BOOST_ASSERT(globalPartIndex < scene->mNumMaterials);
                const std::shared_ptr<gameplay::MeshPart>& part = mesh->getPart(pi);

                scene->mMeshes[globalPartIndex] = new aiMesh();
                aiMesh* outMesh = scene->mMeshes[globalPartIndex];

                allocateElementMemory(mesh, outMesh);
                copyVertexData(mesh, outMesh);

                BOOST_ASSERT(part->getPrimitiveType() == gameplay::Mesh::PrimitiveType::TRIANGLES && part->getIndexCount() % 3 == 0);
                outMesh->mMaterialIndex = globalPartIndex;
                scene->mMaterials[globalPartIndex] = new aiMaterial();
                scene->mMaterials[globalPartIndex]->AddProperty(new aiColor4D(ambientColor.r, ambientColor.g, ambientColor.b, 1), 1, AI_MATKEY_COLOR_AMBIENT);

                {
                    // try to find the texture for our material

                    using Entry = decltype(*mtlMap1.begin());
                    auto finder = [&part](const Entry& entry)
                        {
                            return entry.second == part->getMaterial();
                        };

                    auto texIt = std::find_if(mtlMap1.begin(), mtlMap1.end(), finder);

                    bool found = false;
                    if( texIt != mtlMap1.end() )
                    {
                        scene->mMaterials[globalPartIndex]->AddProperty(new aiString(makeTextureName(texIt->first.tileAndFlag & TextureIndexMask) + ".png"), AI_MATKEY_TEXTURE_DIFFUSE(0));
                        found = true;
                    }

                    if( !found )
                    {
                        texIt = std::find_if(mtlMap2.begin(), mtlMap2.end(), finder);
                        if( texIt != mtlMap2.end() )
                        {
                            scene->mMaterials[globalPartIndex]->AddProperty(new aiString(makeTextureName(texIt->first.tileAndFlag & TextureIndexMask) + ".png"), AI_MATKEY_TEXTURE_DIFFUSE(0));
                        }
                    }
                }

                outMesh->mNumFaces = part->getIndexCount() / 3;
                outMesh->mFaces = new aiFace[outMesh->mNumFaces];

                switch( part->getIndexFormat() )
                {
                    case gameplay::Mesh::INDEX8:
                        copyIndices<uint8_t>(part, outMesh);
                        break;
                    case gameplay::Mesh::INDEX16:
                        copyIndices<uint16_t>(part, outMesh);
                        break;
                    case gameplay::Mesh::INDEX32:
                        copyIndices<uint32_t>(part, outMesh);
                        break;
                    default:
                        break;
                }
            }
        }

        exporter.Export(scene.get(), formatIdentifier.c_str(), fullPath.string(), aiProcess_JoinIdenticalVertices | aiProcess_ValidateDataStructure | aiProcess_FlipUVs);
    }
Beispiel #13
-1
/* Exports the scene to the given filename */
int Exporter::writeToFile(Scene *scene, const std::string filename) {
    if (!scene || filename.empty()) {
        LOGW("Exporting to invalid filename or current scene is invalid.");
        return -1;
    }

    Assimp::Exporter exporter;
    const char *format_description_id = findFormatDescription(exporter, filename);

    if (!format_description_id) {
        LOGW("Failure to find supported format description to %s", filename.c_str());
        return -1;
    }

    aiScene aiscene;

    gvr2aiScene(*scene, aiscene);

    if (aiscene.mNumMeshes > 0) {
        LOGD("Exporting scene to %s\n", filename.c_str());
        exporter.Export(&aiscene, format_description_id, filename);
    }

    return 0;
}