2

I'm working on a student project for which I want to texture a mesh that I scanned using an iPad equipped with the new LiDAR sensor.

To texture a mesh, however, I need to add texture coordinates. My current plan is to convert the scanned mesh to an MDLMesh and add all submeshes to an MDLAsset container. Afterwards, I iterate over the MDLMeshes using a foreach-loop. In each iteration I'm calling the function "MDLMesh.addUnwrappedTextureCoordinates" on the current mesh. unfortunately, it always results in a crash. Sometimes I can loop through 2 meshes before I get an error, sometimes I does not even add UV's to a single mesh.

I'm not at expert at swift or Model IO, but it seems strange to me, that this operation crashes while I can add normals just fine.

The error I'm getting looks like this:

Can't choose for edge creation 
libc++abi.dylib: terminating with uncaught exception of type std::out_of_range: unordered_map::at: key not found

The code I'm using looks like this:

private func unwrapTextureCoordinates(asset: MDLAsset) -> MDLAsset{
    let objects = asset.childObjects(of: MDLMesh.self)
    
    for object in objects{
        if let mesh = object as? MDLMesh{
            mesh.addNormals(withAttributeNamed: MDLVertexAttributeNormal, creaseThreshold: 0.5)
            mesh.addAttribute(withName: MDLVertexAttributeTextureCoordinate, format: .float2)
            mesh.addUnwrappedTextureCoordinates(forAttributeNamed: MDLVertexAttributeTextureCoordinate)
        }
    }
            
    return asset
}

Hopefully someone can tell me what's wrong or point me in the right direction.

Leon
  • 96
  • 5

1 Answers1

3

After I could not figure out what was causing the issue, I resorted to Unity and its ARFoundation wrapper to see whether I was able to calculate any UVs there. I found that Unity's equivalent to Model I/O's "addUnwrappedTextureCoordinates", namely Unwrapping.GeneratePerTriangleUV, calculates 3 UVs for each triangle.

Now, when I run this function in Unity, I also get an out-of-range-exception for my mesh, just like in Swift. The error description says that the number of UV coordinates cannot exceed the number of vertices in the mesh - which makes sense since I get three times as many UV coordinates as I have vertices in my mesh. Therefore, I highly suspect that the out-of-range-exception in Swift using Model I/O has the same cause.

Surely, there are many workarounds for this, but I resorted to a different solution since the "Unwrapping" class is part of the "UnityEngine.Editor" namespace anyways and therefore I would not be able to use it in a finished build (which is what I want).

Instead, I came across the function in this thread to calculate a single set of UVs for my mesh. I utilized it, and it worked exactly as I want it to. The code is written in C# and therefore I decided to continue my project using the Unity Engine. However, I don't think it will be a lot of trouble to translate the function into Swift.

Leon
  • 96
  • 5