Free Support Forum - aspose.com

OBJ Imported Incorrect Mesh

Hi I imported obj with this code sample but result seems incorrect.
Did I miss something?
Can you check this and please tell me how to make this right.

I used 3 different data for mesh(Vertices, Normals, Triangles)

    public static void Load(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 meshData = new List<(Vector3[], Vector3[], int[])>();
        if ((childNodes != null) && (childNodes.Count > 0))
        {
            var nodeCount = childNodes.Count;
            for (var i = 0; i < nodeCount; i++)
            {
                var childNode = childNodes[i];
                ParseNode(childNode, meshData);
            }
        }

        // Display meshData

    }

    private static void ParseNode(Node node, List<(Vector3[], Vector3[], int[])> buffer)
    {
        foreach (var entity in node.Entities)
        {
            switch (entity)
            {
                case Mesh mesh:
                    var triMesh = TriMesh.FromMesh(mesh);
                    var vertexDeclaration = new VertexDeclaration();
                    var vertexFieldForVertex = vertexDeclaration.AddField(VertexFieldDataType.FVector3, VertexFieldSemantic.Position);
                    var vertexFieldForNormal = vertexDeclaration.AddField(VertexFieldDataType.FVector3, VertexFieldSemantic.Normal);

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

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

                    buffer.Add((vertices.ToArray(), normals.ToArray(), triangles));
                    break;
                default:
                    break;
            }
        }

        var childNodes = node.ChildNodes;
        if (childNodes != null && childNodes.Count > 0)
        {
            var childCount = childNodes.Count;
            for (var i = 0; i < childCount; i++)
            {
                var childNode = childNodes[i];
                ParseNode(childNode, buffer);
            }
        }
    }

errorMesh2.PNG (91.3 KB)

@HuePark

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

We apologize for the inconvenience.

I see the THREEDNET-816 ---- Status : Won’t Fix

can you explain why?
What should I do for fix this issue?

@HuePark

We found an issue in the code during investigation of the ticket:

It is caused by the following code:

 var triMesh = TriMesh.FromMesh(mesh);
var vertexDeclaration = new VertexDeclaration();

The triMesh contains a VertexDeclaration instance inferred from the mesh’s structure, and you have created a new vertex declaration later. If you want the triMesh to have exactly the VertexDeclaration that you manually specified, please use the following code:

var vertexDeclaration = new VertexDeclaration();
var vertexFieldForVertex = vertexDeclaration.AddField(VertexFieldDataType.FVector3, VertexFieldSemantic.Position);
var vertexFieldForNormal = vertexDeclaration.AddField(VertexFieldDataType.FVector3, VertexFieldSemantic.Normal);
var triMesh = TriMesh.FromMesh(vertexDeclaration, mesh);

We checked the ‘original avatar.obj’, there’s no normal data for it, so you need to generate it. As a result, the initialization of triMesh should become:

var vertexDeclaration = new VertexDeclaration();
var vertexFieldForVertex = vertexDeclaration.AddField(VertexFieldDataType.FVector3, VertexFieldSemantic.Position);
var vertexFieldForNormal = vertexDeclaration.AddField(VertexFieldDataType.FVector3, VertexFieldSemantic.Normal);
if(mesh.GetElement(VertexElementType.Normal) == null)//if the mesh doesn't have the normal, generate one and attach it to the mesh
{
 var normalData = PolygonModifier.GenerateNormal(mesh);
 mesh.VertexElements.Add(normalData);
}
var triMesh = TriMesh.FromMesh(vertexDeclaration, mesh);