Визуализация массивного облака точек в tkinter

Передо мной стоит задача визуализировать массивное облако точек используя tkinter. Облако точек хранится в las файле. в самом большом файле находится 40 000 000 точек.

Я пробовал несколько библиотек, которые могут это сделать и вот что про них скажу: matplotlib, panda3d, vispy - их можно встроить в tkinter, но даже миллион точек отображается с трудом. Также приходится самостоятельно парсить данные из файлов.

Open3d прекрасно справляется с задачей визуализации, но я не нашёл способ встроить окно в tkinter.

Также у меня получилось вывести .ply файл используя pyopengltk в приведенным ниже коде, но тут возникает проблема с конвертацией .las в .ply

from pyopengltk import OpenGLFrame

from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GLU import *

import open3d as o3d
import numpy as np

class PCFrame(OpenGLFrame):
    def initgl(self):
        pcd = o3d.io.read_point_cloud('example.ply')
        #o3d.visualization.draw_geometries([pcd])

        points = np.asarray(pcd.points, dtype=np.float32)

        mn = np.min(points)
        mx = np.max(points)

        points = 2 * (points - mn) / (mx - mn) - 1

        self.size = points.dtype.itemsize
        self.length = len(points)

        colors = np.asarray(pcd.colors, dtype=np.float32)

        # vertexBuffer
        self.vbo = glGenBuffers(1)
        glBindBuffer(GL_ARRAY_BUFFER, self.vbo)
        glBufferData(GL_ARRAY_BUFFER, points, GL_STATIC_DRAW)

        # colorBuffer
        self.cba = glGenBuffers(1)
        glBindBuffer(GL_ARRAY_BUFFER, self.cba)
        glBufferData(GL_ARRAY_BUFFER, colors, GL_STATIC_DRAW)

        glEnableClientState(GL_VERTEX_ARRAY)
        glEnableClientState(GL_COLOR_ARRAY)

        glClearColor(255, 255, 255, 1.0)

    def redraw(self):
        glRotate(1, 3, 1, 1)
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        glBindBuffer(GL_ARRAY_BUFFER, self.vbo)
        glVertexPointer(3, GL_FLOAT, 3*4, None)
        glBindBuffer(GL_ARRAY_BUFFER, self.cba)
        glColorPointer(3, GL_FLOAT, 3*4, None)
        glDrawArrays(GL_POINTS, 0, self.length)

def main():
    root = Tk()

    root.geometry('500x500')

    pcf = PCFrame(root)
    pcf.pack(fill=BOTH, expand=True)

    pcf.animate = 10

    def zoom(event):
        scale = 1.0
        
        if event.num == 5 or event.delta == -120:
            scale /= 1.2
        elif event.num == 4 or event.delta == 120:
            scale *= 1.2
        
        glScale(scale, scale, scale)

    root.bind('<Button-5>', zoom)
    root.bind('<Button-4>', zoom)

    return root.mainloop()

if __name__=="__main__":
    main()```




 

Ответы (0 шт):