Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to Convert OBJ with Texture to GLB Format #5872

Open
AyushBharadwaj opened this issue Nov 11, 2024 · 3 comments
Open

Unable to Convert OBJ with Texture to GLB Format #5872

AyushBharadwaj opened this issue Nov 11, 2024 · 3 comments
Labels
Techdebt Technical dept which needs to get solved.

Comments

@AyushBharadwaj
Copy link

AyushBharadwaj commented Nov 11, 2024

I am using the following C++ code to convert an OBJ model to a GLB format while embedding the textures. However, the texture is not correctly embedded into the output GLB file. Here is the code I'm using:

#include <assimp/Importer.hpp>
#include <assimp/Exporter.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>
#include <string>
#include <filesystem>
#include <iostream>

extern "C" {

int convertedObjToGlb(const char* inputPath, const char* outputPath, const char* mtlPath, const char* texturePath) {
    try {
        Assimp::Importer importer;
        Assimp::Exporter exporter;
        
        // Get absolute paths
        std::filesystem::path inputFilePath(inputPath);
        std::filesystem::path mtlFilePath(mtlPath);
        std::filesystem::path baseDir = inputFilePath.parent_path();
        
        // Print debug information
        std::cout << "Input OBJ: " << inputFilePath.string() << std::endl;
        std::cout << "MTL File: " << mtlFilePath.string() << std::endl;
        std::cout << "Base Dir: " << baseDir.string() << std::endl;
        
        // Set import properties
        importer.SetPropertyString("IMPORT_MTL", mtlFilePath.string().c_str());
        importer.SetPropertyString("OBJ_BASE_DIR", baseDir.string().c_str());
        importer.SetPropertyInteger("OBJ_USE_MTL", 1);
        
        // Import the OBJ file
        unsigned int importFlags =
            aiProcess_Triangulate |
            aiProcess_JoinIdenticalVertices |
            aiProcess_GenNormals |
            aiProcess_ValidateDataStructure |
            aiProcess_OptimizeMeshes |
            aiProcess_CalcTangentSpace;
            
        const aiScene* scene = importer.ReadFile(inputFilePath.string(), importFlags);
        
        if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) {
            std::cout << "Error importing OBJ: " << importer.GetErrorString() << std::endl;
            return 0;
        }
        
        // Debug materials
        std::cout << "Number of materials: " << scene->mNumMaterials << std::endl;
        
        aiScene* modifiableScene = importer.GetOrphanedScene();
        
        // Process materials
        for (unsigned int i = 0; i < modifiableScene->mNumMaterials; i++) {
            aiMaterial* material = modifiableScene->mMaterials[i];
            
            // Debug material properties
            aiString matName;
            material->Get(AI_MATKEY_NAME, matName);
            std::cout << "Material " << i << " name: " << matName.C_Str() << std::endl;
            
            // Check for existing textures
            aiString texPath;
            if (material->GetTexture(aiTextureType_DIFFUSE, 0, &texPath) == AI_SUCCESS) {
                std::cout << "Material " << i << " has texture: " << texPath.C_Str() << std::endl;
                
                // If texture path is relative, make it absolute
                std::filesystem::path texturePath = baseDir / texPath.C_Str();
                if (std::filesystem::exists(texturePath)) {
                    aiString newTexPath;
                    newTexPath.Set(texturePath.string());
                    material->RemoveProperty(AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0));
                    material->AddProperty(&newTexPath, AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE, 0));
                    std::cout << "Updated texture path to: " << texturePath.string() << std::endl;
                } else {
                    std::cout << "Texture file not found: " << texturePath.string() << std::endl;
                }
            } else {
                std::cout << "Material " << i << " has no diffuse texture" << std::endl;
            }
        }
        
        // Set up export properties
        Assimp::ExportProperties exportProps;
        exportProps.SetPropertyBool("EXPORT_TEXTURE_EMBEDDED", true);
        exportProps.SetPropertyBool("EXPORT_COLORS", true);
        exportProps.SetPropertyInteger("EXPORT_TEXTURE_FORMAT", 0);
        
        // Export to GLB
        std::cout << "Exporting to: " << outputPath << std::endl;
        aiReturn exportResult = exporter.Export(
            modifiableScene,
            "glb2",
            outputPath,
            aiProcess_EmbedTextures,
            &exportProps
        );
        
        if (exportResult != aiReturn_SUCCESS) {
            std::cout << "Error exporting to GLB: " << exporter.GetErrorString() << std::endl;
            return 0;
        }
        
        std::cout << "Conversion completed successfully" << std::endl;
        return 1;
    }
    catch (const std::exception& e) {
        std::cout << "Exception occurred: " << e.what() << std::endl;
        return 0;
    }
}

}

```@assimp-mirror 
@AyushBharadwaj AyushBharadwaj added the Techdebt Technical dept which needs to get solved. label Nov 11, 2024
@AyushBharadwaj
Copy link
Author

@kimkulling

@kimkulling
Copy link
Member

I have looked into the code. The embedded texture export step is missing.

@AyushBharadwaj
Copy link
Author

Okay, @kimkulling. Thank you! The issue has been resolved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Techdebt Technical dept which needs to get solved.
Projects
None yet
Development

No branches or pull requests

2 participants