Meshlab 스크립트를 통해 자동으로 격자 필터 조작하는 방법

개시하다


MeshLab에서 스크립트를 사용하여 자동으로 작동하는 기사입니다.예를 들어, 네트 필터(quadric edge collapse decimation)를 사용하여 remeshing을 수행합니다.

만든 물건



이번에는 스크립트로 이 조작을 진행한다.

독자 대상


Meshlab 작업을 자동화하려는 사람

create python script


개발 환경은 다음과 같다.
Ubuntu 16.04
python 3.6
먼저 meshlab를 설치합니다.
$ sudo apt-get update
$ sudo apt-get install meshlab
meshlab의 스크립트는 meshlab를 실제로 조작할 때 저장됩니다.따라서 우선 meshlab로 상기gif와 같은 조작을 직접 진행한다. 
그런 다음 메뉴 태그의 Filters->Showcurrent filter script를 선택합니다.

그런 다음 방금 작업한 필터 이름이 표시되었는지 확인하고 Save Script를 사용하여 적절한 위치에 저장합니다.

저장된 mlx 파일을 보십시오. 위에 방금 필터의 매개 변수 등이 기재되어 있습니다.
temp.mxl
<!DOCTYPE FilterScript>
<FilterScript>
 <filter name="Quadric Edge Collapse Decimation">
  <Param type="RichInt" value="100" name="TargetFaceNum"/>
  <Param type="RichFloat" value="0" name="TargetPerc"/>
  <Param type="RichFloat" value="0.3" name="QualityThr"/>
  <Param type="RichBool" value="false" name="PreserveBoundary"/>
  <Param type="RichFloat" value="1" name="BoundaryWeight"/>
  <Param type="RichBool" value="false" name="PreserveNormal"/>
  <Param type="RichBool" value="false" name="PreserveTopology"/>
  <Param type="RichBool" value="true" name="OptimalPlacement"/>
  <Param type="RichBool" value="false" name="PlanarQuadric"/>
  <Param type="RichBool" value="false" name="QualityWeight"/>
  <Param type="RichBool" value="true" name="AutoClean"/>
  <Param type="RichBool" value="false" name="Selected"/>
 </filter>
</FilterScript>
meshlab에서 meshlabserver 명령으로 meshlab를 조작합니다.
명령의 매개 변수는 다음과 같습니다.
-i[filename...] 열려 있는 경로 + 파일 이름
-o[filename...] 쓰기 경로 + 파일 이름
-s filename에 적용된 스크립트 경로 + 파일 이름
명령 프롬프트에서 다음 명령을 실행할 수 있습니다.
meshlabserver -i input.obj -o output.ply -s temp.mlx
따라서 여러 개의 파일을 실행할 때 ptyhon 스크립트로 for문 등으로 이 파일을 실행합니다. 
ptyhon 스크립트는 선조https://gist.github.com/tylerlindell/7435ca2261e7c404ccc1241f18e483aa에서 제작되었으니 수정해서 사용하세요.
#!/usr/bin/env python

import sys
import os
import subprocess

# Script taken from doing the needed operation
# (Filters > Remeshing, Simplification and Reconstruction >
# Quadric Edge Collapse Decimation, with parameters:
# 0.9 percentage reduction (10%), 0.3 Quality threshold (70%)
# Target number of faces is ignored with those parameters
# conserving face normals, planar simplification and
# post-simplimfication cleaning)
# And going to Filter > Show current filter script
filter_script_mlx = """<!DOCTYPE FilterScript>
<FilterScript>
 <filter name="Simplification: Quadric Edge Collapse Decimation (with texture)">
  <Param type="RichInt" value="60000" name="TargetFaceNum"/>
  <Param type="RichFloat" value="0" name="TargetPerc"/>
  <Param type="RichFloat" value="1" name="QualityThr"/>
  <Param type="RichBool" value="true" name="PreserveBoundary"/>
  <Param type="RichFloat" value="1" name="BoundaryWeight"/>
  <Param type="RichBool" value="true" name="OptimalPlacement"/>
  <Param type="RichBool" value="true" name="PreserveNormal"/>
  <Param type="RichBool" value="true" name="PlanarSimplification"/>
 </filter>
</FilterScript>
"""

cwd = os.getcwd()

def create_tmp_filter_file(filename='filter_file_tmp.mlx'):
    with open(cwd + 'tmp_' + filename, 'w') as f:
        f.write(filter_script_mlx)
    return cwd + 'tmp_' + filename


def reduce_faces(in_file, out_file,
                 filter_script_path=create_tmp_filter_file()):
    # Add input mesh
    command = "meshlabserver -i " + in_file
    # Add the filter script
    command += " -s " + filter_script_path
    # Add the output filename and output flags
    command += " -o " + out_file
    # Execute command
    print("Going to execute: " + command)
    output = subprocess.call(command, shell=True)
    last_line = output
    print()
    print("Done:")
    print(in_file + " > " + out_file + ": " + str(last_line))


if __name__ == '__main__':
    if len(sys.argv) < 3:
        print("Usage:")
        print(sys.argv[0] + " /path/to/input_mesh num_iterations")
        print("For example, reduce 10 times:")
        print(sys.argv[0] + " /home/myuser/mymesh.dae 10")
        exit(0)

    in_mesh = sys.argv[1]
    filename = in_mesh.split('\\')[-1]
    num_iterations = int(sys.argv[2])

    folder_name = filename.replace('.', '_')
    tmp_folder_name = cwd + '\\tmp\\' + folder_name + '_meshes\\'

    print("Input mesh: " + in_mesh + " (filename: " + filename + ")")
    print("Num iterations: " + str(num_iterations))
    print("Output folder: " + tmp_folder_name)
    try:
        os.mkdir(tmp_folder_name)
    except OSError as e:
        print(sys.stderr, "Exception creating folder for meshes: " + str(e))
    for it in range(num_iterations):
        if num_iterations == 1:
            out_mesh = tmp_folder_name + folder_name + "_it" + str(it) + ".obj"
            reduce_faces(in_mesh, out_mesh)
        else:
            out_mesh = tmp_folder_name + folder_name + "_it" + str(it) + ".obj"
            reduce_faces(last_out_mesh, out_mesh)
        last_out_mesh = out_mesh

    print()
    print("Done reducing, find the files at: " + tmp_folder_name)

끝말


간단하지만 meshlab를 통해 격자 필터 조작을 자동화했습니다.blender와 기타 3D 소프트웨어 API도 풍부하니 가능한 한 자동화하세요.

사이트 축소판 그림

좋은 웹페이지 즐겨찾기