Assimp 复制顶点
Assimp duplicates Vertices
我在我的 C# 应用程序中使用 Assimp .NET 库从 Blender 导入 collada 文件 (.dae)。问题是有几个顶点被多次导入。
这是使用我的 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;
}
如您所见,我排除了位置坐标以外的大部分组件。然后我分别使用 "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;
}
尽管如此,这适用于大多数网格,但并非适用于所有网格。例如,我有以下圆锥体:
并且选中的顶点(即X:0.84,Y:-0.55557,Z:-1.0)在顶点列表中存储了三次。我检查了 collada 文件,这个顶点肯定只存在一次。
如果您有一些具有不同纹理坐标的顶点(如果您有纹理图集等),这些顶点将被复制。也许您正面临这种特殊情况?
我进一步调查了这个问题并找到了以下解决方案:在 Visual Studio 2015 年,我将 "Windows Application" 而不是 "Class Library" 设置为输出类型。突然,重复的顶点消失了。不幸的是,我无法说出应用程序类型影响 Assimp 行为的原因。
我在我的 C# 应用程序中使用 Assimp .NET 库从 Blender 导入 collada 文件 (.dae)。问题是有几个顶点被多次导入。
这是使用我的 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;
}
如您所见,我排除了位置坐标以外的大部分组件。然后我分别使用 "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;
}
尽管如此,这适用于大多数网格,但并非适用于所有网格。例如,我有以下圆锥体:
并且选中的顶点(即X:0.84,Y:-0.55557,Z:-1.0)在顶点列表中存储了三次。我检查了 collada 文件,这个顶点肯定只存在一次。
如果您有一些具有不同纹理坐标的顶点(如果您有纹理图集等),这些顶点将被复制。也许您正面临这种特殊情况?
我进一步调查了这个问题并找到了以下解决方案:在 Visual Studio 2015 年,我将 "Windows Application" 而不是 "Class Library" 设置为输出类型。突然,重复的顶点消失了。不幸的是,我无法说出应用程序类型影响 Assimp 行为的原因。