【问题标题】:How to use PyMeshLab to reduce vertex number to a certain number如何使用 PyMeshLab 将顶点数减少到一定数量
【发布时间】:2021-04-01 18:40:35
【问题描述】:

我有一批三角形网格,每一个都有不同的顶点和面。我想将所有网格的顶点数减少到相同的数字,10000。

我知道我可以使用 simplification_quadric_edge_collapse_decimation 来减少面数,这意味着顶点数会相应减少。但问题是我必须多次使用该方法才能将顶点数精确到 10000。

因此,我想知道是否有另一种方法可以将顶点数直接减少到10000?

【问题讨论】:

    标签: meshlab pymeshlab


    【解决方案1】:

    Meshlab,以及据我所知任何其他能够简化的库,都使用面数作为参数来指导简化过程。

    好消息是这两个值都与网格的Euler characteristic 相关,这大致表示顶点数是没有孔的表面的面数的一半。将您的网格减少到 20000 个面将产生大约 10000 个顶点的网格,但您也可以轻松地低于 9999。由于您具有使用 python 编程的优势,您可以设计一个过程来慢慢收敛到所需的顶点数。

    我们的想法是将您的网格简化为略高于 20000 的面数,然后慢慢细化您的解决方案,直到获得正好 10000 个顶点。我建议您使用当前步骤中顶点的过量(vertex_number - 10000)来减少每个步骤中的面数。

    import pymeshlab as ml
    ms = ml.MeshSet()
    ms.load_new_mesh('input.ply')
    m = ms.current_mesh()
    print('input mesh has', m.vertex_number(), 'vertex and', m.face_number(), 'faces')
    
    #Target number of vertex
    TARGET=10000
    
    #Estimate number of faces to have 100+10000 vertex using Euler
    numFaces = 100 + 2*TARGET
    
    #Simplify the mesh. Only first simplification will be agressive
    while (ms.current_mesh().vertex_number() > TARGET):
        ms.apply_filter('simplification_quadric_edge_collapse_decimation', targetfacenum=numFaces, preservenormal=True)
        print("Decimated to", numFaces, "faces mesh has", ms.current_mesh().vertex_number(), "vertex")
        #Refine our estimation to slowly converge to TARGET vertex number
        numFaces = numFaces - (ms.current_mesh().vertex_number() - TARGET)
    
    m = ms.current_mesh()
    print('output mesh has', m.vertex_number(), 'vertex and', m.face_number(), 'faces')
    ms.save_current_mesh('output.ply')
    

    请注意:

    • 有时您不能精确地减少到 10000 个顶点,而是以 9999 个顶点结束。
    • 使用此公式,每个步骤(在第一个步骤之后)将删除大约一半超过 10000 的顶点,从而“软着陆”到您想要的顶点数量。典型的执行应该减少到大约 10050 个顶点,然后是 10025、10012、10006、10003、10001,最后是 10000 个顶点。最终的面数取决于输入模型的所述欧拉特性。
    • 只有第一个简化步骤会花费大量执行时间(取决于输入网格中三角形的数量),接下来的简化步骤会非常快。
    • 如果您仍想加快该方法的速度,您可以使用numFaces = numFaces - int(1.5*(ms.current_mesh().vertex_number() - 10000)),但这会增加在 9999 顶点下结束的机会,并且不会对执行时间造成太大影响。
    • 此方法应适用于任何基于面的抽取算法,它并非专属于二次边折叠。

    【讨论】:

    • 那么我应该感谢您在这里提出这个好问题。想起来很有趣。
    猜你喜欢
    • 1970-01-01
    • 2021-09-25
    • 2023-03-20
    • 2021-12-18
    • 2016-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多