2016-06-30 57 views
1

我正在使用Assimp .NET庫在C#應用程序中從Blender導入collada文件(.dae)。問題是幾個頂點被多次導入。Assimp duplicate Vertices

下面是一個使用文件路徑來我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

和所選擇的頂點(即X:0.84,Y:-0.55557,Z:-1.0)被存儲三次在頂點一覽表。我檢查了collada文件,這個頂點絕對只存在一次。

+0

這個頂點必須在文件中多次引用,也許我可能值得嘗試查明是否是這種情況,以及哪個屬性是重複的。另外,你有沒有嘗試導出到不同的擴展名,看看它是否總是一樣? (如使用obj和3ds爲例) – Zouch

回答

0

我進一步調查了這個問題,發現了以下解決方案:在Visual Studio 2015中,我將「Windows應用程序」而不是「類庫」設置爲輸出類型。突然重複的頂點消失了。不幸的是,我無法告訴應用程序類型爲什麼影響Assimp行爲的原因。

1

如果你有一些頂點具有不同的紋理座標(如果你有紋理地圖等),那些頂點是重複的。也許你正面臨這個特殊情況?

+0

那麼,我認爲與importer.SetConfig(新的RemoveComponentConfig(ExcludeComponent.TexCoords));這應該不重要? – enne87

+0

我不知道.net版本,但對於C++版本,您要刪除的組件必須設置在另一個位置('#define AI_CONFIG_PP_RVC_FLAGS YourBitField')。仍然根據文檔,這應該允許assimp正確地合併重複的頂點(因爲它們現在只有共同的位置)。 – Zouch

+0

謝謝,我會試試看。 – enne87