Free Support Forum - aspose.com

Triangle indices are not correct

when I try to read triangle indices from TriMesh object indices are nor correct value.
Can you check this?
here is sample code and sample import file

    public static void LoadMesh(string filePath)
    {
        var fullPath = Path.GetFullPath(filePath);
        var directory = Path.GetDirectoryName(fullPath);
        var scene = new Scene();
        scene.Open(filePath);
        var rootNode = scene.RootNode;
        var childNodes = rootNode.ChildNodes;
        var childNodeCount = childNodes.Count;
        for (var i = 0; i < childNodeCount; i++)
        {
            var node = childNodes[i];
            foreach (var entity in node.Entities)
            {
                switch (entity)
                {
                    case Mesh mesh:
                        var vertexDeclaration = new VertexDeclaration();
                        var vertexFieldForVertex = vertexDeclaration.AddField(VertexFieldDataType.FVector3, VertexFieldSemantic.Position);
                        var vertexFieldForNormal = vertexDeclaration.AddField(VertexFieldDataType.FVector3, VertexFieldSemantic.Normal);
                        var vertexFieldForUv = vertexDeclaration.AddField(VertexFieldDataType.FVector2, VertexFieldSemantic.UV);

                        var triMesh = TriMesh.FromMesh(mesh);
                        var vertices = new List<Vector3>();
                        var normals = new List<Vector3>();
                        var uvs = new List<Vector2>();
                        triMesh.IndicesToArray(out int[] triangles);

                        foreach (var vertex in triMesh)
                        {
                            var vertexRaw = vertex.ReadFVector3(vertexFieldForVertex);
                            var normalRaw = vertex.ReadFVector3(vertexFieldForNormal);
                            var uvRaw = vertex.ReadFVector2(vertexFieldForUv);
                            vertices.Add(new Vector3(vertexRaw.x, vertexRaw.y, vertexRaw.z));
                            normals.Add(new Vector3(normalRaw.x, normalRaw.y, normalRaw.z));
                            uvs.Add(new Vector2(uvRaw.x, uvRaw.y));
                        }

                        var vertexCount = vertices.Count;
                        foreach (var triangleIndex in triangles)
                        {
                            if (triangleIndex >= vertexCount)
                            {
                                throw new Exception("Triangle Index is bigger then vertexCount!");
                            }
                        }
                        break;
                    default:
                        break;
                }
            }
        }
    }

@HuePark

We have logged an issue as THREEDNET-814 in our issue tracking system for further investigation on this scenario. We will look into its details and keep you posted with the status of its correction. Please be patient and spare us some time.

We are sorry for the inconvenience.

@HuePark

Please use following code snippet as a workaround at the moment. We will expose more information in 21.2 version of the API:

struct MyVertex
{
 [Semantic(VertexFieldSemantic.Position)]
 public FVector3 position;
 [Semantic(VertexFieldSemantic.Normal)]
 public FVector3 normal;
 [Semantic(VertexFieldSemantic.UV)]
 public FVector2 uv;
}

    public static void LoadMesh(string filePath)
    {
        var fullPath = Path.GetFullPath(filePath);
        var directory = Path.GetDirectoryName(fullPath);
        var scene = new Scene();
        scene.Open(filePath);
        var rootNode = scene.RootNode;
        var childNodes = rootNode.ChildNodes;
        var childNodeCount = childNodes.Count;
        for (var i = 0; i < childNodeCount; i++)
        {
            var node = childNodes[i];
            foreach (var entity in node.Entities)
            {
                switch (entity)
                {
                    case Mesh mesh:
                        //var vertexDeclaration = new VertexDeclaration();
                        //var vertexFieldForVertex = vertexDeclaration.AddField(VertexFieldDataType.FVector3, VertexFieldSemantic.Position);
                        //var vertexFieldForNormal = vertexDeclaration.AddField(VertexFieldDataType.FVector3, VertexFieldSemantic.Normal);
                        //var vertexFieldForUv = vertexDeclaration.AddField(VertexFieldDataType.FVector2, VertexFieldSemantic.UV);

                        //var triMesh = TriMesh.FromMesh(mesh);
                        TriMesh<MyVertex> triMesh = TriMesh<MyVertex>.FromMesh(mesh);
                        var vertices = new List<Vector3>();
                        var normals = new List<Vector3>();
                        var uvs = new List<Vector2>();
                        triMesh.IndicesToArray(out int[] triangles);
                        MyVertex[] typedVertices = triMesh.VerticesToTypedArray();

                        foreach (var vertex in typedVertices)
                        {
                            var vertexRaw = vertex.position;
                            var normalRaw = vertex.normal;
                            var uvRaw = vertex.uv;
                            vertices.Add(new Vector3(vertexRaw.x, vertexRaw.y, vertexRaw.z));
                            normals.Add(new Vector3(normalRaw.x, normalRaw.y, normalRaw.z));
                            uvs.Add(new Vector2(uvRaw.x, uvRaw.y));
                        }

                        var vertexCount = vertices.Count;
                        foreach (var triangleIndex in triangles)
                        {
                            if (triangleIndex >= vertexCount)
                            {
                                throw new Exception("Triangle Index is bigger then vertexCount!");
                            }
                        }
                        break;
                    default:
                        break;
                }
            }
        }
    }

The following code snippet would work under 21.2. The IEnumerator<Vertex> issue has been fixed, and it also exposed a set of internal interfaces for better performances.

    public static void LoadMesh(string filePath)
    {
        var fullPath = Path.GetFullPath(filePath);
        var directory = Path.GetDirectoryName(fullPath);
        var scene = new Scene();
        scene.Open(filePath);
        var rootNode = scene.RootNode;
        var childNodes = rootNode.ChildNodes;
        var childNodeCount = childNodes.Count;
        for (var i = 0; i < childNodeCount; i++)
        {
            var node = childNodes[i];
            foreach (var entity in node.Entities)
            {
                switch (entity)
                {
                    case Mesh mesh:
                        var vertexDeclaration = new VertexDeclaration();
                        var vertexFieldForVertex = vertexDeclaration.AddField(VertexFieldDataType.FVector3, VertexFieldSemantic.Position);
                        var vertexFieldForNormal = vertexDeclaration.AddField(VertexFieldDataType.FVector3, VertexFieldSemantic.Normal);
                        var vertexFieldForUv = vertexDeclaration.AddField(VertexFieldDataType.FVector2, VertexFieldSemantic.UV);

                        //Vertex declaration must be specified here, otherwise the inferred vertex declaration may
                        //have different layout than the manually specified.
                        var triMesh = TriMesh.FromMesh(vertexDeclaration, mesh);
                        var vertices = new List<Vector3>(triMesh.VerticesCount);
                        var normals = new List<Vector3>(triMesh.VerticesCount);
                        var uvs = new List<Vector2>(triMesh.VerticesCount);
                        triMesh.IndicesToArray(out int[] triangles);

                        //use for loop other than the for-each to avoid temporary Vertex object creation
                        const bool useForLoop = true;
                        if (useForLoop)
                        {
                            for (int j = 0; j < triMesh.VerticesCount; j++)
                            {
                                //you can use ReadVector3 instead of ReadFVector3
                                //it will handle type casting internally
                                var vertexRaw = triMesh.ReadVector3(j, vertexFieldForVertex);
                                var normalRaw = triMesh.ReadVector3(j, vertexFieldForNormal);
                                var uvRaw = triMesh.ReadVector2(j, vertexFieldForUv);

                                vertices.Add(vertexRaw);
                                normals.Add(normalRaw);
                                uvs.Add(uvRaw);
                            }
                        }
                        else
                        {
                            //foreach issue has been fixed in 21.1
                            //but it's a bit slower than the for-loop
                            //because a Vertex instance in heap will be allocated in each iteration.
                            foreach (var vertex in triMesh)
                            {
                                //There would be explicit conversional operators between Vector/FVector types
                                vertices.Add((Vector3)vertex.ReadFVector3(vertexFieldForVertex));
                                normals.Add((Vector3)vertex.ReadFVector3(vertexFieldForNormal));
                                uvs.Add((Vector2)vertex.ReadFVector2(vertexFieldForUv));
                            }
                        }

                        var vertexCount = vertices.Count;
                        foreach (var triangleIndex in triangles)
                        {
                            if (triangleIndex >= vertexCount)
                            {
                                throw new Exception("Triangle Index is bigger then vertexCount!");
                            }
                        }
                        break;
                    default:
                        break;
                }
            }
        }
    }

@HuePark

We would like to share with you that the issue has been resolved in Aspose.3D for .NET 21.1.1 hotfix. Please try using the suggested code with this hotfix and let us know if you face any issue.

I was try code you which suggested .
but it giving me some new error.

NullReferenceException: Object reference not set to an instance of an object
#=zv1Koky6GGF8EApVt$EXe4OLtczeT.#=zrXM9l6k= (Aspose.ThreeD.Entities.VertexElementType #=zQ_T$UiM=, System.Int32 #=zs6o_Y94=) (at :0)
Aspose.ThreeD.Entities.TriMesh.#=zNT$26Gz5uBktbILe7w== (#=zv1Koky6GGF8EApVt$EXe4OLtczeT #=zTh$Wop0=, Aspose.ThreeD.Utilities.VertexFieldSemantic #=zhJeDUKY=, System.Int32 #=zs6o_Y94=) (at :0)
Aspose.ThreeD.Entities.TriMesh.#=zFx1eQet6BuLq (Aspose.ThreeD.Entities.Mesh #=zIqgy3sI=, #=zv1Koky6GGF8EApVt$EXe4OLtczeT #=zWp7WvRFJ6wPEyKjULg==, System.Boolean #=zp8Y__p8=) (at :0)
Aspose.ThreeD.Entities.TriMesh.#=zFx1eQet6BuLq (Aspose.ThreeD.Entities.Mesh #=zIqgy3sI=, System.Boolean #=zp8Y__p8=) (at :0)
Aspose.ThreeD.Entities.TriMesh`1[T].FromMesh (Aspose.ThreeD.Entities.Mesh mesh) (at :0)

I tried this code below

var triMesh = TriMesh.FromMesh(originMesh);
var vertices = new List();
var normals = new List();
var uvs = new List();
triMesh.IndicesToArray(out int[] triangles);

        var typedVertices = triMesh.VerticesToTypedArray();

#pragma warning disable 649
private struct AsposeVertex
{
[Semantic(VertexFieldSemantic.Position)]
// ReSharper disable once InconsistentNaming
public FVector3 position;
[Semantic(VertexFieldSemantic.Normal)]
// ReSharper disable once InconsistentNaming
public FVector3 normal;
[Semantic(VertexFieldSemantic.UV)]
// ReSharper disable once InconsistentNaming
public FVector2 uv;
[Semantic(VertexFieldSemantic.VertexColor)]
// ReSharper disable once InconsistentNaming
public FVector4 color;
}
#pragma warning restore 649

Error came out from TriMesh.FromMesh(Mesh)
here I attached where error came from.

image.png (46.2 KB)

I used dll which you replied (21.1.1) => https://drive.google.com/file/d/12xcCgmkL8ig2cOVc7kqw0IweSBVc-J_u/view?usp=sharing

I was also try to update nuget package but in nuget latest version is 21.1.0 I can not see the later version in nuget

image.png (145.8 KB)

Can you check this issue and please give me a solution?
Thanks.

@HuePark

Could you please also specify the file which you are using in your code snippet?

The 21.1.1 hotfix is not uploaded to NuGet. However, all fixes will be included in the upcoming version of the API i.e. Aspose.3D for .NET 21.2 which will be uploaded to NuGet as well.