--- /dev/null
+#!/usr/bin/env python\r
+# coding: utf-8\r
+\r
+from OpenGL.GL import *\r
+import re\r
+from .baseview import *\r
+\r
+\r
+DELEGATE_PATTERN=re.compile('^on[A-Z]')\r
+\r
+class BaseController(object):\r
+ def __init__(self, view, root):\r
+ self.view=view\r
+ self.root=root\r
+ self.isInitialized=False\r
+ self.delegate(view)\r
+ self.delegate(root)\r
+\r
+ def delegate(self, to):\r
+ for name in dir(to): \r
+ if DELEGATE_PATTERN.match(name):\r
+ method = getattr(to, name) \r
+ setattr(self, name, method)\r
+\r
+ def onUpdate(*args):pass\r
+ def onLeftDown(*args):pass\r
+ def onLeftUp(*args):pass\r
+ def onMiddleDown(*args):pass\r
+ def onMiddleUp(*args):pass\r
+ def onRightDown(*args):pass\r
+ def onRightUp(*args):pass\r
+ def onMotion(*args):pass\r
+ def onResize(*args):pass\r
+ def onWheel(*args):pass\r
+ def onKeyDown(*args):pass\r
+ def onInitialize(*args):pass\r
+\r
+ def initialize(self):\r
+ self.view.onResize()\r
+ glEnable(GL_DEPTH_TEST)\r
+ # \8f\89\8aú\89»\8e\9e\82Ì\8cÄ\82Ñ\8fo\82µ\r
+ self.onInitialize()\r
+\r
+ def draw(self):\r
+ if not self.isInitialized:\r
+ self.initialize()\r
+ self.isInitialized=True\r
+ # OpenGL\83o\83b\83t\83@\82Ì\83N\83\8a\83A\r
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)\r
+ # \93\8a\89e\8ds\97ñ\82Ì\83N\83\8a\83A\r
+ glMatrixMode(GL_PROJECTION)\r
+ glLoadIdentity()\r
+ self.view.updateProjection()\r
+ # \83\82\83f\83\8b\83r\83\85\81[\8ds\97ñ\82Ì\83N\83\8a\83A\r
+ glMatrixMode(GL_MODELVIEW)\r
+ glLoadIdentity()\r
+ # OpenGL\95`\89æ\r
+ self.view.updateView()\r
+ self.root.draw()\r
+ glFlush()\r
+\r
--- /dev/null
+#!/usr/bin/env python\r
+# coding: utf-8\r
+\r
+from OpenGL.GL import *\r
+\r
+class BaseView(object):\r
+ def __init__(self):\r
+ self.x=0\r
+ self.y=0\r
+ self.w=1\r
+ self.h=1\r
+ self.isLeftDown=False\r
+ self.isMiddelDown=False\r
+ self.isRightDown=False\r
+\r
+ def updateProjection(self):\r
+ pass\r
+\r
+ def updateView(self):\r
+ pass\r
+\r
+ def onResize(self, w=None, h=None):\r
+ self.w=w or self.w\r
+ self.h=h or self.h\r
+ glViewport(0, 0, self.w, self.h)\r
+\r
+ def onLeftDown(self, x, y):\r
+ self.isLeftDown=True\r
+ self.x=x\r
+ self.y=y\r
+\r
+ def onLeftUp(self, x, y):\r
+ self.isLeftDown=False\r
+\r
+ def onMiddleDown(self, x, y):\r
+ self.isMiddelDown=True\r
+ self.x=x\r
+ self.y=y\r
+\r
+ def onMiddleUp(self, x, y):\r
+ self.isMiddelDown=False\r
+\r
+ def onRightDown(self, x, y):\r
+ self.isRightDown=True\r
+ self.x=x\r
+ self.y=y\r
+\r
+ def onRightUp(self, x, y):\r
+ self.isRightDown=False\r
+\r
+ def onMotion(self, x, y):\r
+ print("onMotion", x, y)\r
+\r
+ def printMatrix(self, m):\r
+ print(m[0][0], m[0][1], m[0][2], m[0][3])\r
+ print(m[1][0], m[1][1], m[1][2], m[1][3])\r
+ print(m[2][0], m[2][1], m[2][2], m[2][3])\r
+ print(m[3][0], m[3][1], m[3][2], m[3][3])\r
+\r
--- /dev/null
+#!/usr/bin/python\r
+# coding: utf-8\r
+\r
+from OpenGL.GL import *\r
+from OpenGL.GLU import *\r
+\r
+from . import baseview\r
+\r
+class RokuroView(baseview.BaseView):\r
+ def __init__(self, distance):\r
+ super(RokuroView, self).__init__()\r
+ self.w=1\r
+ self.h=1\r
+ self.head=0\r
+ self.pitch=0\r
+ self.distance=distance\r
+ self.shiftX=0\r
+ self.shiftY=0\r
+ self.aspect=1\r
+ self.n=1\r
+ self.f=10000\r
+\r
+ def onResize(self, w=None, h=None):\r
+ super(RokuroView, self).onResize(w, h)\r
+ self.aspect=float(self.w)/float(self.h)\r
+\r
+ def dolly(self, d):\r
+ if d>0:\r
+ self.distance*=1.1\r
+ elif d<0:\r
+ self.distance*=0.9\r
+\r
+ def shift(self, dx, dy):\r
+ self.shiftX+=dx\r
+ self.shiftY+=dy\r
+\r
+ def rotate(self, head, pitch):\r
+ self.head+=head\r
+ self.pitch+=pitch\r
+\r
+ def updateProjection(self):\r
+ gluPerspective(30, self.aspect, self.n, self.f)\r
+\r
+ def updateView(self):\r
+ glTranslate(self.shiftX, self.shiftY, -self.distance)\r
+ glRotate(self.head, 0, 1, 0)\r
+ glRotate(self.pitch, 1, 0, 0)\r
+\r
+ def onMotion(self, x, y):\r
+ redraw=False\r
+ if self.isLeftDown:\r
+ self.dolly(y-self.y)\r
+ redraw=True\r
+ if self.isMiddelDown:\r
+ self.shift(x-self.x, self.y-y)\r
+ redraw=True\r
+ if self.isRightDown:\r
+ self.rotate(x-self.x, y-self.y)\r
+ redraw=True\r
+ self.x=x\r
+ self.y=y\r
+ return redraw\r
+\r
+ def onWheel(self, d):\r
+ if d!=0:\r
+ self.dolly(d)\r
+ return True\r
+\r
--- /dev/null
+#!/usr/bin/env python\r
+# coding: utf-8\r
+\r
+import sys\r
+import tkinter\r
+import tkinter.filedialog\r
+import togl\r
+import opengl\r
+import opengl.rokuro\r
+import triangle\r
+\r
+\r
+class Frame(tkinter.Frame):\r
+ def __init__(self, width, height, master=None, **kw):\r
+ super(Frame, self).__init__(master, **kw)\r
+ self.master.title('pymeshio viewer')\r
+ self.current='.'\r
+ # setup menu\r
+ menu_bar = tkinter.Menu(self)\r
+ self.master.config(menu=menu_bar)\r
+\r
+ menu_file = tkinter.Menu(menu_bar, tearoff=False)\r
+ menu_bar.add_cascade(label='FILE', menu=menu_file, underline=0)\r
+\r
+ menu_file.add_command(label='Open', under=0, command=self.onOpen)\r
+\r
+ # setup opengl widget\r
+ self.glworld=opengl.BaseController(opengl.rokuro.RokuroView(25), triangle.Triangle(5))\r
+ glwidget=togl.Widget(self, self.glworld, width=width, height=height)\r
+ glwidget.pack(fill=tkinter.BOTH, expand=True)\r
+\r
+ # event binding\r
+ self.bind('<Key>', self.onKeyDown)\r
+ self.bind('<MouseWheel>', lambda e: self.glworld.onWheel(-e.delta) and glwidget.onDraw())\r
+\r
+ def onOpen(self):\r
+ filename=tkinter.filedialog.askopenfilename(\r
+ filetypes=[\r
+ ('poloygon model files', '*.mqo;*.pmd'),\r
+ ], \r
+ initialdir=self.current)\r
+ print('open: %s' % filename)\r
+\r
+ def onKeyDown(self, event):\r
+ key=event.keycode\r
+ if key==27:\r
+ # Escape\r
+ sys.exit()\r
+ if key==81:\r
+ # q\r
+ sys.exit()\r
+ else:\r
+ print("keycode: %d" % key)\r
+\r
+\r
+if __name__ == '__main__':\r
+ f = Frame(width=600, height=600)\r
+ f.pack(fill=tkinter.BOTH, expand=True)\r
+ f.focus_set()\r
+ f.mainloop()\r
+\r
--- /dev/null
+#!/usr/bin/env python\r
+# coding: utf-8\r
+\r
+import OpenGL.Tk\r
+\r
+\r
+class Widget(OpenGL.Tk.RawOpengl):\r
+ def __init__(self, master, engine, *args, **kw):\r
+ super(Widget, self).__init__(master, *args, **kw)\r
+ self.engine=engine\r
+ self.bind('<Map>', self.onDraw)\r
+ self.bind('<Expose>', self.onDraw)\r
+ self.bind('<Configure>', self.onResize)\r
+ self.bind('<ButtonPress-1>', lambda e: self.engine.onLeftDown(e.x, e.y) and self.onDraw())\r
+ self.bind('<ButtonRelease-1>', lambda e: self.engine.onLeftUp(e.x, e.y) and self.onDraw())\r
+ self.bind('<B1-Motion>', lambda e: self.engine.onMotion(e.x, e.y) and self.onDraw())\r
+ self.bind('<ButtonPress-2>', lambda e: self.engine.onMiddleDown(e.x, e.y) and self.onDraw())\r
+ self.bind('<ButtonRelease-2>', lambda e: self.engine.onMiddleUp(e.x, e.y) and self.onDraw())\r
+ self.bind('<B2-Motion>', lambda e: self.engine.onMotion(e.x, e.y) and self.onDraw())\r
+ self.bind('<ButtonPress-3>', lambda e: self.engine.onRightDown(e.x, e.y) and self.onDraw())\r
+ self.bind('<ButtonRelease-3>', lambda e: self.engine.onRightUp(e.x, e.y) and self.onDraw())\r
+ self.bind('<B3-Motion>', lambda e: self.engine.onMotion(e.x, e.y) and self.onDraw())\r
+\r
+ def onDraw(self, *dummy):\r
+ self.tk.call(self._w, 'makecurrent')\r
+ self.update_idletasks()\r
+ self.engine.draw()\r
+ self.tk.call(self._w, 'swapbuffers')\r
+\r
+ def onResize(self, event):\r
+ self.engine.onResize(event.width, event.height)\r
+ self.onDraw()\r
+\r
--- /dev/null
+# coding: utf-8\r
+from OpenGL.GL import *\r
+\r
+\r
+class Triangle(object):\r
+ def __init__(self, size):\r
+ self.size=size\r
+\r
+ def draw(self):\r
+ # \8eO\8ap\8c`\95`\89æ\8aJ\8en\r
+ glBegin(GL_TRIANGLES)\r
+ # \8d¶\89º\r
+ glVertex(-self.size, -self.size)\r
+ # \89E\89º\r
+ glVertex(self.size, -self.size)\r
+ # \8fã\r
+ glVertex(0, self.size)\r
+ # \8eO\8ap\8c`\95`\89æ\8fI\97¹\r
+ glEnd()\r
+\r