2016-06-30 3 views
1

Я использую библиотеку Assimp .NET для импорта файлов collada (.dae) из Blender в моем приложении C#. Проблема в том, что несколько вершин импортируются несколько раз.Assimp duplicates Vertices

Вот код, который использует FilePath моего COLLADA-файл и импортирует сетки Assimp:

public List<Mesh> GenerateMeshes(String path) 
{ 
     AssimpImporter importer = new AssimpImporter(); 
     importer.SetConfig(new RemoveComponentConfig(ExcludeComponent.Animations | ExcludeComponent.Boneweights | ExcludeComponent.Cameras | ExcludeComponent.Colors 
      | ExcludeComponent.Lights | ExcludeComponent.Materials | ExcludeComponent.Normals | 
      ExcludeComponent.TangentBasis | ExcludeComponent.TexCoords | ExcludeComponent.Textures)); 

     var scene = importer.ImportFile(path, PostProcessSteps.RemoveComponent | PostProcessSteps.JoinIdenticalVertices); 
     ProcessNode(scene.RootNode, scene); 
     return meshes; 
    } 

Как вы можете Cee исключить большинство компонентов, за исключением координат положения. Затем я использую «PostProcessSteps.RemoveComponent» и «PostProcessSteps.JoinIdenticalVertices» соответственно, чтобы присоединиться к одинаковым вершинам.

ProcessNode() - загружает каждый меш рекурсивно:

private void ProcessNode(Node node, Assimp.Scene scene) 
    { 
     for (int i = 0; i < node.MeshCount; i++) 
     { 
      // The node object only contains indices to index the actual objects in the scene. 
      // The scene contains all the data, node is just to keep stuff organized (like relations between nodes). 
      Assimp.Mesh m = scene.Meshes[node.MeshIndices[i]]; 
      meshes.Add(ProcessMesh(m, node)); 
     } 

     // After we've processed all of the meshes (if any) we then recursively process each of the children nodes 
     if (node.HasChildren) 
     { 
      for (int i = 0; i < node.Children.Length; i++) 
      { 
       ProcessNode(node.Children[i], scene); 
      } 
     } 
    } 

ProcessMesh() ничего не делает больше, чем положить все вершины и индексы в отдельном списке:

private Mesh ProcessMesh(Assimp.Mesh mesh, Node node) 
    { 
     // Data to fill 
     List<Vector3d> vertices = new List<Vector3d>(); 
     List<int> indices = new List<int>(); 

     for (var i = 0; i < mesh.VertexCount; i++) 
     { 
      Vector3d vertex = new Vector3d(mesh.Vertices[i].X, mesh.Vertices[i].Y, mesh.Vertices[i].Z); // Positions 
      vertices.Add(vertex); 
     } 

     // Now walk through each of the mesh's faces and retrieve the corresponding vertex indices. 
     for (int i = 0; i < mesh.FaceCount; i++) 
     { 
      Face face = mesh.Faces[i]; 
      // Retrieve all indices of the face and store them in the indices vector 
      for (int j = 0; j < face.IndexCount; j++) 
       indices.Add((int)face.Indices[j]); 
     } 

     //node.Transform 
     Mesh geoObject = new Mesh(vertices.ToArray(), indices.ToArray(), null, null); 
     geoObject.ModelMatrix = Convert(node.Transform); 
     return geoObject; 
    } 

Тем не менее, это работает для большинство сеток, но не для всех. Например, у меня есть следующий конус:

enter image description here

и выбранная вершина (т.е. Х: 0,84, Y: -0,55557, Z: -1.0) хранятся три раза в списке вершин. Я проверил файл collada, и эта вершина определенно существует только один раз.

+0

Эта вершина должна быть указана несколько раз в файле, возможно, мне стоит попытаться выяснить, является ли это так, и какое свойство дублируется. Кроме того, вы пытались экспортировать в разные расширения, чтобы убедиться, что это всегда одно и то же? (например, используя obj и 3ds, например) – Zouch

ответ

0

Я изучил эту проблему и нашел следующее решение: В Visual Studio 2015 я выбрал «Приложение Windows» вместо «Class Library» в качестве типа вывода. Внезапно дублированные вершины исчезли. К сожалению, я не могу сказать, почему тип приложения влияет на поведение Assimp.

1

Если у вас есть несколько вершин, которые имеют разные координаты текстуры (если у вас есть текстурные атласы и т. Д.), Эти вершины дублируются. Может быть, вы столкнулись с этим конкретным случаем?

+0

Ну, я думал с импортером. SetConfig (новый RemoveComponentConfig (ExcludeComponent.TexCoords)); это не имеет значения? – enne87

+0

Я не знаю для версии .net, но для версии C++ компоненты, которые вы хотите удалить, должны быть установлены в другом месте ('#define AI_CONFIG_PP_RVC_FLAGS YourBitField'). Тем не менее, согласно документации, это должно позволить assimp правильно объединять повторяющиеся вершины (поскольку теперь они имеют только общую позицию). – Zouch

+0

Спасибо, я попробую. – enne87