Learning Open3D→Tutorial→基礎編→Mesh
Open3D には三角メッシュのためのデータ構造がある。
注意: コードを走らせる環境に注意すること。TestData
ディレクトリがカレント(作業)ディレクトリからみて、祖先ディレクトリの下にあることを確認しよう
# examples/Python/Basic/mesh.py
import copy
import numpy as np
import open3d as o3d
if __name__ == "__main__":
# (1)Print vertices and triangles
print("Testing mesh in open3d ...")
mesh = o3d.io.read_triangle_mesh("../../TestData/knot.ply")
print(mesh)
print(np.asarray(mesh.vertices))
print(np.asarray(mesh.triangles))
print("")
# (2)Visualize 3D mesh
print("Try to render a mesh with normals (exist: " +
str(mesh.has_vertex_normals()) + ") and colors (exist: " +
str(mesh.has_vertex_colors()) + ")")
o3d.visualization.draw_geometries([mesh])
print("A mesh with no normals and no colors does not seem good.")
# (3)Surface normal estimation
print("Computing normal and rendering it.")
mesh.compute_vertex_normals()
print(np.asarray(mesh.triangle_normals))
o3d.visualization.draw_geometries([mesh])
# (4)Crop mesh
print("We make a partial mesh of only the first half triangles.")
mesh1 = copy.deepcopy(mesh)
mesh1.triangles = o3d.utility.Vector3iVector(
np.asarray(mesh1.triangles)[:len(mesh1.triangles) // 2, :])
mesh1.triangle_normals = o3d.utility.Vector3dVector(
np.asarray(mesh1.triangle_normals)[:len(mesh1.triangle_normals) //
2, :])
print(mesh1.triangles)
o3d.visualization.draw_geometries([mesh1])
# (5)Paint mesh
print("Painting the mesh")
mesh1.paint_uniform_color([1, 0.706, 0])
o3d.visualization.draw_geometries([mesh1])
# (1)Print vertices and triangles
print("Testing mesh in open3d ...")
mesh = o3d.io.read_triangle_mesh("../../TestData/knot.ply")
print(mesh)
print(np.asarray(mesh.vertices))
print(np.asarray(mesh.triangles))
print("")
この出力は
TriangleMesh with 1440 points and 2880 triangles.
[[ 4.51268387 28.68865967 -76.55680847]
[ 7.63622284 35.52046967 -69.78063965]
[ 6.21986008 44.22465134 -64.82303619]
...,
[-22.12651634 31.28466606 -87.37570953]
[-13.91188431 25.4865818 -86.25827026]
[ -5.27768707 23.36245346 -81.43279266]]
[[ 0 12 13]
[ 0 13 1]
[ 1 13 14]
...,
[1438 11 1439]
[1439 11 0]
[1439 0 1428]]
TriangleMesh
クラスには、頂点や三角形などのいくつかのデータフィールドがある。 Open3Dは、numpy
配列を介してこれらのフィールドへの直接的なメモリ・アクセスを提供する。
# (2)Visualize 3D mesh
print("Try to render a mesh with normals (exist: " +
str(mesh.has_vertex_normals()) + ") and colors (exist: " +
str(mesh.has_vertex_colors()) + ")")
o3d.visualization.draw_geometries([mesh])
print("A mesh with no normals and no colors does not seem good.")
これによりメッシュを可視化する。
メッシュを回転したり移動したりすることはできるが、灰色で均一に塗られており、「3d」のように見えない。その理由は、この時点のメッシュに頂点や面の法線がないためである。 したがって、より洗練されたPhongシェーディングの代わりに、均一なカラーシェーディングが使用される。
# (3)Surface normal estimation
print("Computing normal and rendering it.")
mesh.compute_vertex_normals()
print(np.asarray(mesh.triangle_normals))
o3d.visualization.draw_geometries([mesh])
Computing normal and rendering it.
[[ 0.79164373 -0.53951444 0.28674793]
[ 0.8319824 -0.53303008 0.15389681]
[ 0.83488162 -0.09250101 0.54260136]
...
[ 0.16269924 -0.76215917 -0.6266118 ]
[ 0.52755226 -0.83707495 -0.14489352]
[ 0.56778973 -0.76467734 -0.30476777]]
これはmeshモジュールの関数のcompute_vertex_normals
と paint_uniform_color
を用いて次のような表示を行う:
この三角メッシュとtriangle_normals
データに直接操作し、半分くらいを削除しよう。それにはnumpy
配列を介して行う。
次はexamples/Python/Basic/mesh.pyの4番目の部分コード:
# (4)Crop mesh
print("We make a partial mesh of only the first half triangles.")
mesh1 = copy.deepcopy(mesh)
mesh1.triangles = o3d.utility.Vector3iVector(
np.asarray(mesh1.triangles)[:len(mesh1.triangles) // 2, :])
mesh1.triangle_normals = o3d.utility.Vector3dVector(
np.asarray(mesh1.triangle_normals)[:len(mesh1.triangle_normals) //
2, :])
print(mesh1.triangles)
o3d.visualization.draw_geometries([mesh1])
その結果は:
# (5)Paint mesh
print("Painting the mesh")
mesh1.paint_uniform_color([1, 0.706, 0])
o3d.visualization.draw_geometries([mesh1])
その結果: