Saved .glb files cannot be opened

We are currently evaluating Aspose.3D for .NET and testing different file formats.

One of the reasons for choosing Aspose.3D would be the ability to create a scene in code and save it in .glb format, but we are unable to open these saved files in our tests. .fbx and .obj works just fine. We are also able to open other .glb files not produced by Aspose.3D.

The Windows 3D-viewer as well as Microsoft Word are able to correctly display these files except the .glb produced by the code below. Our code is a slight variation of the CubeScene.cs example file.

I have attached a .zip file with three exported files (.fbx, .obj, and .glb) and another working .glb file along with our test code. I also include our test code below. We have tried some variations of the calls in Test 3 as seen in your examples, but nothing seems to work.

We hope you are able to help with this problem.

Best regards,

public static void Run()
{
    Scene scene = new Scene();

    //Outer radius:
    int R = 200;

    //Inner radius:
    int r = 10;
        
    //Number of boxes in each outer ring:
    int n = 500;

    //Number of complete twists of the outer ring:
    int twists = 15;

    //Crossing bars per twist (approximate):
    int linesPerTwist = 7;

    //Side length of cubes:
    double s = 1.0;

    Mesh mesh = new Mesh();

    for (int i = 0; i < n; i++)
    {
        double theta = (Math.PI * 2.0 * i) / n;
        double phi = (twists * theta) % (Math.PI * 2.0);

        double _R1 = R + r * Math.Sin(phi);
        double _R2 = R - r * Math.Sin(phi);

        double _z1 = r * Math.Cos(phi);
        double _z2 = -r * Math.Cos(phi);

        double _x1 = Math.Cos(theta) * _R1;
        double _y1 = Math.Sin(theta) * _R1;

        double _x2 = Math.Cos(theta) * _R2;
        double _y2 = Math.Sin(theta) * _R2;

        AddBoxToMesh(mesh, s, s, s, _x1, _y1, _z1);

        AddBoxToMesh(mesh, s, s, s, _x2, _y2, _z2);

        if (i % (n / (twists * linesPerTwist)) == 0)
        {
            for (int k = 1; k < r; k++)
            {
                double f1 = (r - k) / ((double)r);
                double f2 = k / ((double)r);
                double __x = _x1 * f1 + _x2 * f2;
                double __y = _y1 * f1 + _y2 * f2;
                double __z = _z1 * f1 + _z2 * f2;

                AddBoxToMesh(mesh, s, s, s, __x, __y, __z);
            }
        }
    }

    Node meshNode = new Node
    {
        Entity = mesh
    };
    scene.RootNode.ChildNodes.Add(meshNode);

    

    //Saving:


    //Test 1:
    string output1 = RunExamples.GetOutputFilePath("Test1.fbx");
    scene.Save(output1, FileFormat.FBX7400ASCII);



    //Test 2:
    string output2 = RunExamples.GetOutputFilePath("Test2.obj");
    scene.Save(output2, FileFormat.WavefrontOBJ);



    //Test 3:
    string output3 = RunExamples.GetOutputFilePath("Test3.glb");
    GLTFSaveOptions opts = new GLTFSaveOptions(FileContentType.Binary);
    scene.Save(output3, opts);

    Console.WriteLine("Cube Scene created successfully.");
}


// ----- Helper methods:


public static Mesh AddBoxToMesh(Mesh mesh,
    double halfLength, double halfWidth, double halfHeight,
    double posX = 0, double posY = 0, double posZ = 0)
{
    Vector4[] vertices = new Vector4[]
    {
        new Vector4( -halfLength + posX, -halfWidth + posY, halfHeight + posZ, 1.0),
        new Vector4( halfLength + posX, -halfWidth + posY, halfHeight + posZ, 1.0),
        new Vector4( halfLength + posX, halfWidth + posY, halfHeight + posZ, 1.0),
        new Vector4( -halfLength + posX, halfWidth + posY, halfHeight + posZ, 1.0),
        new Vector4( -halfLength + posX, -halfWidth + posY, -halfHeight + posZ, 1.0),
        new Vector4( halfLength + posX, -halfWidth + posY, -halfHeight + posZ, 1.0),
        new Vector4( halfLength + posX, halfWidth + posY, -halfHeight + posZ, 1.0),
        new Vector4( -halfLength + posX, halfWidth + posY, -halfHeight + posZ, 1.0)
    };

    int vi = mesh.ControlPoints.Count;

    mesh.ControlPoints.AddRange(vertices);

    mesh.CreatePolygon(new int[] { vi + 0, vi + 1, vi + 2, vi + 3 });
    mesh.CreatePolygon(new int[] { vi + 1, vi + 5, vi + 6, vi + 2 });
    mesh.CreatePolygon(new int[] {vi + 5, vi + 4, vi + 7, vi + 6});
    mesh.CreatePolygon(new int[] {vi + 4, vi + 0, vi + 3, vi + 7});
    mesh.CreatePolygon(new int[] {vi + 0, vi + 4, vi + 5, vi + 1});
    mesh.CreatePolygon(new int[] {vi + 3, vi + 2, vi + 6, vi + 7});

    return mesh;
}

TestExport.zip (1.7 MB)

@MinosIllyrien

Thank you for contacting support.

We have logged a ticket with ID THREEDNET-568 in our issue management system for further investigation and resolution. The ticket ID has been linked with this thread so that you will receive notification as soon as the ticket is resolved.

We are sorry for the inconvenience.

@MinosIllyrien

We are pleased to inform you that the problem has been resolved in attached hotfix. However, you would need to specify the GLTF version as glTF 2.0 instead of glTF 1.0 if you want to view it with windows’ 3D viewer because this viewer only supports glTF 2.0.

Aspose.3D for .NET 19.9.1.zip

@Farhan.Raza

Thank you for your quick response.

We were initially happy with the fix, which works for the example we provided, but when we attempted to export a file with two nodes, the .glb export failed. The file can still be opened, but materials and components in the second node are applied and placed incorrectly. This seems to happen consistently when we try to export more than 1 node.

Correct .obj export:
obj.jpg (110.1 KB)

Incorrect .glb export:
glb.jpg (112.0 KB)

I will include our updated test code below. We hope that you can help us with this issue as well.

//Outer radius:
int R = 200;

//Inner radius:
int r = 10;

//Number of boxes in each outer ring:
int n = 500;

//Number of complete twists of the outer ring:
int twists = 15;

//Crossing bars per twist (approximate):
int linesPerTwist = 7;

//Side length of cubes:
double s = 1.0;

Mesh meshOuterRings = new Mesh();
Mesh meshInnerBars = new Mesh();

for (int i = 0; i < n; i++)
{
    double theta = (Math.PI * 2.0 * i) / n;
    double phi = (twists * theta) % (Math.PI * 2.0);

    double _R1 = R + r * Math.Sin(phi);
    double _R2 = R - r * Math.Sin(phi);

    double _z1 = r * Math.Cos(phi);
    double _z2 = -r * Math.Cos(phi);

    double _x1 = Math.Cos(theta) * _R1;
    double _y1 = Math.Sin(theta) * _R1;

    double _x2 = Math.Cos(theta) * _R2;
    double _y2 = Math.Sin(theta) * _R2;

    AddBoxToMesh(meshOuterRings, s, s, s, _x1, _y1, _z1);

    AddBoxToMesh(meshOuterRings, s, s, s, _x2, _y2, _z2);

    if (i % (n / (twists * linesPerTwist)) == 0)
    {
        for (int k = 1; k < r; k++)
        {
            double f1 = (r - k) / ((double)r);
            double f2 = k / ((double)r);
            double __x = _x1 * f1 + _x2 * f2;
            double __y = _y1 * f1 + _y2 * f2;
            double __z = _z1 * f1 + _z2 * f2;

            AddBoxToMesh(meshInnerBars, s, s, s, __x, __y, __z);
        }
    }
}


Node meshNodeOuterRings = new Node
{
    Entity = meshOuterRings
};

Node meshNodeInnerBars = new Node
{
    Entity = meshInnerBars
};


//Materials:
PhongMaterial matOuterRings = new PhongMaterial();
PhongMaterial matInnerBars = new PhongMaterial();

matOuterRings.DiffuseColor = new Vector3(Color.DarkBlue);
matInnerBars.DiffuseColor = new Vector3(Color.DarkRed);

meshNodeOuterRings.Material = matOuterRings;
meshNodeInnerBars.Material = matInnerBars;


//Add to scene:
scene.RootNode.ChildNodes.Add(meshNodeOuterRings);
scene.RootNode.ChildNodes.Add(meshNodeInnerBars);



//Export .obj:
ObjSaveOptions oso = new ObjSaveOptions();
oso.EnableMaterials = true;

string output2 = RunExamples.GetOutputFilePath("Test2.obj");
scene.Save(output2, oso);


//Export .glb:
string output3 = RunExamples.GetOutputFilePath("Test3.glb");
scene.Save(output3, FileFormat.GLTF2_Binary);

@MinosIllyrien

Would you please share your source file as ZIP so that we may investigate and assist accordingly.

@Farhan.Raza

I have attached a .zip file with a .cs source file as well as the .glb and .obj output. As previously, .obj can be opened in Windows 3D-viewer, while .glb can not. The same is true of Windows 3D model builder. It seems that the second node is somehow not written correctly to the file.

Thank you for your continued help with this matter.

TestExport2.zip (2.8 MB)

@MinosIllyrien

Thank you for the details.

We have recorded your feedback and will let you know once any update will be available in this regard.

@MinosIllyrien

Would you please try Aspose.3D for .NET 19.9.2 and then share your kind feedback with us.

Aspose.3D for .NET 19.9.2.zip

@Farhan.Raza
Thank you for your support. We can confirm that .glb export now works as expected with the included materials we have tested. Furthermore, .u3d and .obj also works fine when exporting with materials.

As far as we are concerned, this issue is resolved.

On a last note however, there seems to be a small problem with the export to .ply. We can open the exported files in Windows 3D-Builder, but we are unable to do so in Windows 3D-Viewer. We don’t plan to use .ply files, so we will not look any further into this, but if I were to hazard a guess, it could be the same hotfix made in the 19.9.1-version which should be applied to the .ply exporter.

Thank you for your assistance. We will probably end up buying a license now.

@MinosIllyrien

Thank you for your kind feedback.

We are glad to know that your problem has been resolved. We have recorded your concerns and will let you know once any further update will be available in this regard.