OpenGLを使わずに.obj形式のメッシュの可視化を自由にしたい。vispyを試してみたところ、簡単だがOpenGLなしでは自由な表現が出来なかった。開発中で実装が充実している最中なので今後もっと使いやすくなるかも。以下メモ。
インストール
過不足があるかもしれない。condaでインストールすることが推奨されているが使いたくなかった。
sudo apt install python3-pyqt5 python3-pyside python3-pyqt5.opengl python3-pyqt5.qtopengl python3-QtOpenGL python3-pyqt4.qtopengl python3-pyglet
git clone https://github.com/vispy/vispy.git && cd vispy
sudo python3 setup.py install
ドキュメント
スクリプト
vispy.use()で使用するライブラリを選択できる。今回はPyQt4が一番安定していたので選択した。
import numpy as np import vispy from vispy import scene from vispy.scene.visuals import Markers from vispy.geometry import MeshData from vispy.color import Color import sys #========== IO ========== # read .obj file with open("bunny.obj", 'r') as f: obj = f.readlines() vertices_loc = [[float(x) for x in line[2:].strip('\n').split(' ')]\ for line in obj if line[0] == 'v'] vertices_loc = np.array(vertices_loc) faces_id = [[int(v)-1 for v in line[2:].strip('\n').split(' ')]\ for line in obj if line[0] == 'f'] faces_id = np.array(faces_id) nF = len(faces_id) nV = len(vertices_loc) # read data with open("rho.txt", 'r') as f: rho = f.readlines() rho = np.array([float(line.strip('\n')) for line in rho]) #========== MESH CREATION ========= # create mesh mesh = MeshData(vertices_loc, faces_id) #face_color = np.array([[1, 0.5, 0, 1] for i in range(nF)]) face_color = np.array([[1, 1, 1, 0.9] for i in range(nF)]) mesh.set_face_colors(face_color) #========== VERTICES ========== # convex(凸):red, concave(凹): green # normalize color if rho.max() == rho.min(): vertex_color = np.array([[0.5, 0.5, 0, 1] for i in range(nV)]) else: if len(rho) != nV: print("false") rho = (rho - rho.min()) / (rho.max() - rho.min()) # just for now rho = rho[:nV] vertex_color = np.array([[i, 1 - i, 0, 1] for i in rho]) vertices = Markers() vertices.set_data(vertices_loc, edge_color=None, face_color=vertex_color, size=10) #========== VISUALIZATION ========== vispy.use("PyQt4") canvas = scene.SceneCanvas(keys = "interactive", size=(800, 800), show=True) view = canvas.central_widget.add_view() mesh = scene.visuals.Mesh(meshdata=mesh, shading="flat") #mesh = scene.visuals.Mesh(meshdata=mesh, shading="smooth") view.add(mesh) view.add(vertices) view.bgcolor = "grey" view.camera = "turntable" view.padding = 100 canvas.show() if __name__ == "__main__": if sys.flags.interactive != 1: canvas.app.run()
拡大してもそれなりに見える。ただ今のところvispy.geometry.MeshDataはエッジの太さや色、頂点の塗り方をあまりいじれない。これは面だけに色をつけている。
頂点上の値をvispy.scene.visuals.Markersでプロットしようとしたもの。頂点のうち一部しかプロットされず失敗。
追記
MeshLabというものがあるらしい。