points.py
author Dmitriy Morozov <dmitriy@mrzv.org>
Sat, 05 Mar 2011 15:09:50 -0800
changeset 2 56a5778c903c
parent 1 da08d9c69f4b
child 3 6f1239040a06
permissions -rw-r--r--
Switched from QDialog to QMainWindow

from    OpenGL.GL   import glGenLists, glNewList, GL_COMPILE, glEndList, glCallList, \
                           glBegin, glEnd, GL_POINTS, glVertex3f, glColor3f, \
                           glEnable, glDisable, GL_LIGHTING
from    PyQt4       import QtGui, QtCore
from    ViewerItem  import ViewerItem
from    os.path     import basename

class Point(object):
    __slots__ = ('x','y','z')

    def __init__(self, lst = [0,0,0]):
        self.x = lst[0]
        self.y = lst[1]
        self.z = lst[2]

    def __iadd__(self, p):
        self.x += p.x
        self.y += p.y
        self.z += p.z
        return self

    def __idiv__(self, s):
        self.x /= s
        self.y /= s
        self.z /= s
        return self

    def __repr__(self):
        return "%f %f %f" % (self.x, self.y, self.z)

    def min(self, p):
        return Point((min(self.x, p.x), min(self.y, p.y), min(self.z, p.z)))
    
    def max(self, p):
        return Point((max(self.x, p.x), max(self.y, p.y), max(self.z, p.z)))


class Points(ViewerItem):
    def __init__(self, filename, parent = None):
        super(Points, self).__init__(basename(filename), parent)

        self.points = []
        with open(filename) as f:
            for line in f:
                if line.startswith('#'): continue
                self.points.append(Point(map(float, line.split())))
        self.create_display_list()
        self.color = QtGui.QColor(255, 0, 255)
        self.visible = True
        self.setChecked()
        self.center, self.min, self.max = centerMinMax(self.points)

    def create_display_list(self):
        self.display_list = glGenLists(1)
        glNewList(self.display_list, GL_COMPILE)
        glBegin(GL_POINTS)
        for p in self.points:
            glVertex3f(p.x, p.y, p.z)
        glEnd()
        glEndList()

    def contextMenu(self, position):
        menu = QtGui.QMenu()
        colorAction = menu.addAction("Color")
        action = menu.exec_(position)
        if action == colorAction:
            color = QtGui.QColorDialog.getColor(self.color)
            if color.isValid():
                self.color = color

    def draw(self):
        if not self.visible: return
        r,g,b,a = self.color.getRgb()
        glColor3f(r,g,b)
        glDisable(GL_LIGHTING)
        glCallList(self.display_list)
        glEnable(GL_LIGHTING)

    def __iter__(self):
        return self.points

def centerMinMax(it):
    count = 0
    center, min, max = Point(), Point(), Point()
    for p in it:
        count += 1
        center += p
        min = p.min(min)
        max = p.max(max)
    if count: center /= count        

    return center, min, max

def reduceCMM(it):
    center, min_, max_ = Point(), Point(), Point()
    count = 0
    for c,min,max in it:
        count += 1
        center += c
        min_ = min.min(min_)
        max_ = max.max(max_)
    if count: center /= count

    return center, min_, max_