OBJ to GLTF - large number of vertices

Wondering if someone can help me determine why my GLTF files have a large number of vertices.

I have been using Aspose 3D for .NET to convert from a number of different file formats out to GLB. For this example, we are converting from OBJ → GLB.

We have also been testing the obj2gltf library.

When comparing the output of both libraries with the same input OBJ, the file size of the GLB when using the obj2gltf library is much smaller, when using gltf.report we can see why, everything is the same bar the number of vertices:

NAME MODE PRIMITIVES GL_PRIMITIVES VERTICES INDICES ATTRIBUTES INSTANCES SIZE
obj2gltf TRIANGLES 5 233,055 199,386 u32 POSITION:f32, TEXCOORD_0:f32 1 6.78 MB
Aspose TRIANGLES 5 233,055 605,479 u32 POSITION:f32, TEXCOORD_0:f32 1 14.91 MB

The MB difference of the Meshes above is the same difference of the overall GLB size, so we can confidently assume that the actual mesh is the culprit - not textures for example.

605479 / 199386 = 3~ , so potentially the vertices are duplicated?

FYI I’m running the below so duplicate control points shouldn’t be the case:

if (node.Entities[i] is Mesh mesh)
{
    node.Entities[i] = mesh.Optimize(true);
}

After the OBJ has been processed and exported to GLB, I run it through the following to get some stats:

if (entity is Aspose.ThreeD.Entities.Geometry geom)
{
    if (geom.GetElement(VertexElementType.Normal) is VertexElement norm)
    {
        NumberNormal += (norm.Indices.Count);
    }

    if (geom.GetElement(VertexElementType.UV) is VertexElement uv)
    {
        NumberUV += uv.Indices.Count;
    }

    if (geom.GetElement(VertexElementType.Material) is VertexElement mat)
    {
        NumberMaterial += mat.Indices.Count;
    }

    NumberVertices += geom.ControlPoints.Count;
}

The Aspose GLB export returns:
Normal.Indicies.Count: 0
UV.Indicies.Count: 0
Materials.Indicies.Count: 3
Number of Control points: 605479

obj2gltf stats:
Normal.Indicies.Count: 0
UV.Indicies.Count: 0
Materials.Indicies.Count: 3
Number of Control points: 199386

The original OBJ stats:
Normal.Indicies.Count: 0
UV.Indicies.Count: 699165
Materials.Indicies.Count: 233055
Number of Control points: 115771

If I then run mesh.Optimise(true) on the GLB which has been exported, I get the below:
Normal.Indicies.Count: 0
UV.Indicies.Count: 699165
Materials.Indicies.Count: 3
Number of Control points: 150283

So it seems like the Aspose may be duplicating control points when exporting to GLB, which would require a second pass of the file after exporting, which may still not work as we would have to save the scene back to another GLTF which could cause the same issues - or am I missing something?

Or can the vertices be shared between different vertex types instead of duplicating?

Any help is appreciated - the smaller we can get our GLB files the better, as they can get extremely large and they are to be streamed in the browser.

I will send the following via large file transfer to the support email:

  • GLB produced by Aspose from input OBJ
  • GLB produced by obj2gltf from input OBJ
  • The raw OBJ

Side note - is there a built in method within Aspose which is similar to this weld method, which can merge and index vertices to share data more efficiently?

Thanks for your help,
Tom

Also, when visually comparing the GLB files in gltf.report, it looks like the Aspose model has normal data assigned - which I don’t understand as we have no normal data reported within the file:

obj2gltf:
obj2gltf.jpg (69.3 KB)

Aspose:
aspose.jpg (113.0 KB)

@TPovey2

We have opened the following new ticket(s) in our internal issue tracking system and will deliver their fixes according to the terms mentioned in Free Support Policies.

Issue ID(s): THREEDNET-1499

You can obtain Paid Support Services if you need support on a priority basis, along with the direct access to our Paid Support management team.

Upon inspecting the Aspose_Export.glb and obj2gltf_Export.glb files, as well as attempting to convert the GLB from the OBJ file you provided, I encountered an issue. It seems that the position of the generated GLB differs significantly from that of the Aspose_Export.glb file.

Is there a possibility that transformations, such as scaling or rotation, were applied to the mesh’s control points during the conversion process? If transformations were indeed applied, could you kindly provide the code responsible for these transformations so that I may reproduce the same result as the Aspose_Export.glb file? This would greatly assist me in resolving the discrepancy and achieving consistency in the generated GLB files.


Regarding the weld operation, it is indeed a useful operation. Upon reviewing the implementation from glTF-Transform, I found that its code may lead to issues when two points of a triangle are in close proximity to each other. As a result, we need to approach the implementation of this operation with care in Aspose.3D.

We plan to incorporate this functionality into Aspose.3D thoughtfully, ensuring that it aligns seamlessly with our existing features and maintains compatibility with various mesh structures.


By examining the GLB file generated by Aspose.3D, it appears that there is no normal data present. The discrepancies observed are primarily due to variations in material properties. It’s worth noting that OBJ is an older format that lacks support for Physically Based Rendering (PBR). As a result, tools like obj2gltf and Aspose.3D must assign default PBR material properties, such as metallic and roughness factors, to ensure compatibility with the GLTF format.

You can use the following save options to create a similar material:

        GltfSaveOptions opt = new GltfSaveOptions(FileContentType.Binary);
        opt.MaterialConverter = (Material mat) => {
            var pbr = PbrMaterial.FromMaterial(mat);
            //customize your own PBR material here, you can get the original OBJ's material from the parameter mat.
            //to create a compatible material with obj2gltf, use following definition:
            pbr.MetallicFactor = 0;
            pbr.RoughnessFactor = 0.98;
            return pbr;
        };

I apologise - yes we apply a number of transformations to the model prior to saving the scene. I have sent you the two GLB files again, without the transformations this time.

I won’t be able to send you the code for these transforms unfortunately, as this relies on external dependencies and notification handlers to complete the transforms. You shouldn’t need this info now I’ve sent the updated models.

The same issues as noted before can still be observed, when using gltf.report we can still see the vertices difference. You should receive the download link for the 2 GLB files shortly, all I am doing is opening the OBJ scene and immediately saving it to the GLB format - so we’re not performing any processing on the model.
Same goes for obj2gltf, the operation was performed on the raw OBJ you received in the last email.

For completeness, this is the command I used for obj2gltf:
obj2gltf -i path/to/raw/obj_file.obj -o obj2gltf_output.glb -b


Completely understandable - I appreciate you looking into this.


Makes sense - thanks for the clarification. I’ll look into this further.


Anything else you need from me let me know

1 Like

@TPovey2

Thanks for the feedback. We will further let you know once we have some updates to share with you.

Hi @lex.chou & @asad.ali , any news on this?

@TPovey2

Regretfully, no news is available at the moment. We will surely inform you as soon as the investigation is complete. Please spare us some time.

@TPovey2
We’ve addressed the oversize issue, and now the file generated from your sample is only 24MB. This is even smaller than the output from obj2gltf(24.7MB). You can expect to see this fix included in our upcoming monthly release at the end of the month.

Excellent, thankyou for your time on this!
Tom