【问题标题】:Assimp duplicates VerticesAssimp 重复顶点
【发布时间】:2016-11-02 22:17:21
【问题描述】:

我在我的 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 文件,这个顶点肯定只存在一次。

【问题讨论】:

  • 这个顶点必须在文件中被多次引用,也许我值得尝试找出是否是这种情况,以及哪个属性是重复的。另外,您是否尝试过导出到不同的扩展程序以查看它是否始终相同? (例如使用 obj 和 3ds)

标签: c# opengl assimp


【解决方案1】:

如果您有一些具有不同纹理坐标的顶点(如果您有纹理图集等),则会复制这些顶点。也许您正面临这种特殊情况?

【讨论】:

  • 好吧,我想用 importer.SetConfig(new RemoveComponentConfig(ExcludeComponent.TexCoords));这应该没关系?
  • .net 版本我不知道,但对于 C++ 版本,您要删除的组件必须设置在另一个位置 (#define AI_CONFIG_PP_RVC_FLAGS YourBitField)。仍然根据文档,这应该允许 assimp 正确合并重复的顶点(因为它们现在只有共同的位置)。
  • 谢谢,我试试看。
  • 这个有点老了,不过AI_CONFIG_PP_RVC_FLAGS的定义千万别改,其实是这样使用的:importer.SetPropertyInteger(AI_CONFIG_PP_RVC_FLAGS, aiComponent_BITFLAGSGOHERE)
【解决方案2】:

我进一步调查了这个问题并找到了以下解决方案:在 Visual Studio 2015 中,我将“Windows 应用程序”而不是“类库”设置为输出类型。突然,重复的顶点消失了。不幸的是,我无法说出应用程序类型影响 Assimp 行为的原因。

【讨论】:

    猜你喜欢
    • 2019-11-02
    • 2018-03-05
    • 2016-12-26
    • 2014-09-23
    • 2019-05-18
    • 2021-07-17
    • 2017-01-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多