gpt4 book ai didi

algorithm - 使用 Assimp 和 OpenMesh 简化网格

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:18:06 30 4
gpt4 key购买 nike

几天前,我问了一个关于如何使用 edge collapse with Assimp 的问题.平滑 obj 并删除软件中的重复顶点解决了可能使边缘折叠起作用的基本问题,我的意思是它起作用是因为它可以通过 MeshLab 像这样简化: simplified mesh

它在 MeshLab 中看起来不错,但我随后在使用 Assimp 和 OpenMesh 的引擎中完成了它。问题是Assimp 导入了指定的顶点和索引,这可能会让半边错过相反的对(这叫非流形吗?)。结果快照使用 OpenMesh 的 Quadric Decimation:

Decimation by OpenMesh

为了明确发现问题,我没有抽取,而是直接解析回 OpenMesh 数据结构。一切都按预期工作正常(我的意思是没有抽取的结果)。

Without Decimation

我用来抽取网格的代码:

Loader::BasicData Loader::TestEdgeCollapse(float vertices[], int vertexLength, int indices[], int indexLength, float texCoords[], int texCoordLength, float normals[], int normalLength)
{
// Mesh type
typedef OpenMesh::TriMesh_ArrayKernelT<> OPMesh;
// Decimater type
typedef OpenMesh::Decimater::DecimaterT< OPMesh > OPDecimater;
// Decimation Module Handle type
typedef OpenMesh::Decimater::ModQuadricT< OPMesh >::Handle HModQuadric;

OPMesh mesh;
std::vector<OPMesh::VertexHandle> vhandles;
int iteration = 0;
for (int i = 0; i < vertexLength; i += 3)
{
vhandles.push_back(mesh.add_vertex(OpenMesh::Vec3f(vertices[i], vertices[i + 1], vertices[i + 2])));
if (texCoords != nullptr)
mesh.set_texcoord2D(vhandles.back(),OpenMesh::Vec2f(texCoords[iteration * 2], texCoords[iteration * 2 + 1]));
if (normals != nullptr)
mesh.set_normal(vhandles.back(), OpenMesh::Vec3f(normals[i], normals[i + 1], normals[i + 2]));
iteration++;
}

for (int i = 0; i < indexLength; i += 3)
mesh.add_face(vhandles[indices[i]], vhandles[indices[i + 1]], vhandles[indices[i + 2]]);

OPDecimater decimater(mesh);
HModQuadric hModQuadric;
decimater.add(hModQuadric);
decimater.module(hModQuadric).unset_max_err();
decimater.initialize();
//decimater.decimate(); // without this, everything is fine as expect.
mesh.garbage_collection();

int verticesSize = mesh.n_vertices() * 3;
float* newVertices = new float[verticesSize];
int indicesSize = mesh.n_faces() * 3;
int* newIndices = new int[indicesSize];
float* newTexCoords = nullptr;
int texCoordSize = mesh.n_vertices() * 2;
if(mesh.has_vertex_texcoords2D())
newTexCoords = new float[texCoordSize];
float* newNormals = nullptr;
int normalSize = mesh.n_vertices() * 3;
if(mesh.has_vertex_normals())
newNormals = new float[normalSize];

Loader::BasicData data;

int index = 0;
for (v_it = mesh.vertices_begin(); v_it != mesh.vertices_end(); ++v_it)
{
OpenMesh::Vec3f &point = mesh.point(*v_it);
newVertices[index * 3] = point[0];
newVertices[index * 3 + 1] = point[1];
newVertices[index * 3 + 2] = point[2];
if (mesh.has_vertex_texcoords2D())
{
auto &tex = mesh.texcoord2D(*v_it);
newTexCoords[index * 2] = tex[0];
newTexCoords[index * 2 + 1] = tex[1];
}
if (mesh.has_vertex_normals())
{
auto &normal = mesh.normal(*v_it);
newNormals[index * 3] = normal[0];
newNormals[index * 3 + 1] = normal[1];
newNormals[index * 3 + 2] = normal[2];
}
index++;
}
index = 0;

for (f_it = mesh.faces_begin(); f_it != mesh.faces_end(); ++f_it)
for (fv_it = mesh.fv_ccwiter(*f_it); fv_it.is_valid(); ++fv_it)
{
int id = fv_it->idx();
newIndices[index] = id;
index++;
}

data.Indices = newIndices;
data.IndicesLength = indicesSize;
data.Vertices = newVertices;
data.VerticesLength = verticesSize;
data.TexCoords = nullptr;
data.TexCoordLength = -1;
data.Normals = nullptr;
data.NormalLength = -1;
if (mesh.has_vertex_texcoords2D())
{
data.TexCoords = newTexCoords;
data.TexCoordLength = texCoordSize;
}
if (mesh.has_vertex_normals())
{
data.Normals = newNormals;
data.NormalLength = normalSize;
}
return data;
}

同时提供 the tree obj我测试了,the face data由 Assimp 生成的,我从 visual studio 调试器中取出,它显示了一些索引找不到索引对的问题。

最佳答案

考虑了几周但失败了,我想我需要一些学术/数学解决方案来自动生成这些被破坏的网格,但现在我正试图找到简单的方法 要实现这一点,我可以做的是改变在单个自定义对象(类 obj)中加载多对象(file.obj)的结构,并在需要时切换对象.这样做的好处是我可以管理应该呈现的内容并忽略任何算法问题。

顺便说一下,我列出了一些让我回到简单方法的障碍。

  1. Assimp Unique Indices and Vertices,这没有错,但是对于算法来说,没有办法为此制作邻接半边结构。
  2. OpenMesh 只读取目标文件(*.obj),这可以在使用read_mesh 函数时完成,但缺点是缺少文档示例,难以在我的引擎中使用。<
  3. 为任何格式编写自定义 3d 模型导入器都很难。

总而言之,有两种方法可以使细节层次在引擎中起作用,一种是使用网格简化算法并进行更多测试以确保质量,另一种是切换3d软件制作的3dmodel,它不是自动的但稳定。我用的是第二种方法,我在这里展示结果:)

this work!

但是,这不是我的问题的真正解决方案,所以我不会给我分配答案。

关于algorithm - 使用 Assimp 和 OpenMesh 简化网格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40961441/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com