build
dist
pymeshio.egg-info
+*.pyc
--- /dev/null
+Metasequoia Document\r
+Format Text Ver 1.0\r
+\r
+Scene {\r
+ pos 48.0899 60.6742 2400.0000\r
+ lookat 0.0000 0.0000 0.0000\r
+ head 0.0000\r
+ pich 0.0000\r
+ ortho 1\r
+ zoom2 3.1250\r
+ amb 0.250 0.250 0.250\r
+}\r
+Material 6 {\r
+ "mat1" shader(3) col(1.000 0.000 0.000 1.000) dif(0.800) amb(0.600) emi(0.000) spc(0.000) power(5.00)\r
+ "mat2" shader(3) col(0.000 0.000 1.000 1.000) dif(0.800) amb(0.600) emi(0.000) spc(0.000) power(5.00) tex("front.jpg")\r
+ "mat3" shader(3) col(1.000 1.000 0.000 1.000) dif(0.800) amb(0.600) emi(0.000) spc(0.000) power(5.00)\r
+ "mat4" shader(3) col(0.000 0.749 0.169 1.000) dif(0.800) amb(0.600) emi(0.000) spc(0.000) power(5.00)\r
+ "mat5" shader(3) col(1.000 1.000 1.000 1.000) dif(0.800) amb(0.600) emi(0.000) spc(0.000) power(5.00)\r
+ "mat6" shader(3) col(1.000 0.000 1.000 1.000) dif(0.800) amb(0.600) emi(0.000) spc(0.000) power(5.00)\r
+}\r
+Object "obj1" {\r
+ depth 0\r
+ folding 0\r
+ scale 1.000000 1.000000 1.000000\r
+ rotation 0.000000 0.000000 0.000000\r
+ translation 0.000000 0.000000 0.000000\r
+ visible 15\r
+ locking 0\r
+ shading 1\r
+ facet 59.5\r
+ color 0.898 0.498 0.698\r
+ color_type 0\r
+ vertex 8 {\r
+ -100.0000 100.0000 100.0000\r
+ -100.0000 -100.0000 100.0000\r
+ 100.0000 100.0000 100.0000\r
+ 100.0000 -100.0000 100.0000\r
+ 100.0000 100.0000 -100.0000\r
+ 100.0000 -100.0000 -100.0000\r
+ -100.0000 100.0000 -100.0000\r
+ -100.0000 -100.0000 -100.0000\r
+ }\r
+ face 6 {\r
+ 4 V(0 2 3 1) M(1) UV(0.00000 0.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000)\r
+ 4 V(2 4 5 3) M(0) UV(0.00000 0.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000)\r
+ 4 V(4 6 7 5) M(2) UV(0.00000 0.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000)\r
+ 4 V(6 0 1 7) M(3) UV(0.00000 0.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000)\r
+ 4 V(6 4 2 0) M(4) UV(0.00000 0.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000)\r
+ 4 V(1 3 5 7) M(5) UV(0.00000 0.00000 1.00000 0.00000 1.00000 1.00000 0.00000 1.00000)\r
+ }\r
+}\r
+Eof\r
--- /dev/null
+#!/usr/bin/pyhthon
+# coding: utf-8
+
+from OpenGL.GL import *
+import texture
+
+'''
+Material
+
+* 色
+'''
+class Material(object):
+ def __init__(self, r, g, b, a):
+ self.r=r
+ self.g=g
+ self.b=b
+ self.a=a
+
+ def begin(self):
+ glColor4f(self.r, self.g, self.b, self.a)
+
+ def end(self):
+ pass
+
+ def onInitialize(self):
+ pass
+
+ @staticmethod
+ def create(src):
+ m=material.Material(*src.col)
+ return m
+
+
+'''
+Material
+
+* 色
+* テクスチャー
+'''
+class MQOMaterial(object):
+ def __init__(self, rgba):
+ self.rgba=rgba
+ self.texture=None
+
+ def begin(self):
+ glColor4f(self.rgba.r, self.rgba.g, self.rgba.b, self.rgba.a)
+ if self.texture:
+ self.texture.begin()
+
+ # backface culling
+ glEnable(GL_CULL_FACE)
+ glFrontFace(GL_CW)
+ glCullFace(GL_BACK)
+ # alpha test
+ glEnable(GL_ALPHA_TEST);
+ glAlphaFunc(GL_GREATER, 0.5);
+
+ def end(self):
+ if self.texture:
+ self.texture.end()
+
+ def onInitialize(self):
+ if self.texture:
+ self.texture.onInitialize()
+
+ @staticmethod
+ def create(src, basedir):
+ m=MQOMaterial(src.color)
+ if src.tex:
+ m.texture=texture.Texture((basedir+'/'+src.tex).replace('\\', '/'))
+ return m
+
--- /dev/null
+#!/usr/bin/env python\r
+# coding: utf-8\r
+\r
+import time\r
+import os\r
+import pymeshio.mqo\r
+import material\r
+import vertexarraymap\r
+\r
+\r
+def build(path):\r
+ # load scenee\r
+ t=time.time()\r
+ io=pymeshio.mqo.IO()\r
+ if not io.read(path):\r
+ return\r
+ print(time.time()-t, "sec")\r
+ # build\r
+ basedir=os.path.dirname(path)\r
+ vertexArrayMap=vertexarraymap.VertexArrayMapWithUV(\r
+ [material.MQOMaterial.create(m, basedir) \r
+ for m in io.materials])\r
+ for o in io.objects:\r
+ # skip mikoto objects\r
+ if o.name.startswith("anchor"):\r
+ continue\r
+ if o.name.startswith("bone:"):\r
+ continue\r
+ if o.name.startswith("MCS:"):\r
+ continue\r
+\r
+ for f in o.faces:\r
+ if f.index_count==3:\r
+ vertexArrayMap.addTriangle(\r
+ f.material_index,\r
+ o.vertices[f.indices[0]],\r
+ o.vertices[f.indices[1]],\r
+ o.vertices[f.indices[2]],\r
+ f.uv[0], f.uv[1], f.uv[2]\r
+ )\r
+ elif f.index_count==4:\r
+ # triangle 1\r
+ vertexArrayMap.addTriangle(\r
+ f.material_index,\r
+ o.vertices[f.indices[0]],\r
+ o.vertices[f.indices[1]],\r
+ o.vertices[f.indices[2]],\r
+ f.uv[0], f.uv[1], f.uv[2]\r
+ )\r
+ # triangle 2\r
+ vertexArrayMap.addTriangle(\r
+ f.material_index,\r
+ o.vertices[f.indices[2]],\r
+ o.vertices[f.indices[3]],\r
+ o.vertices[f.indices[0]],\r
+ f.uv[2], f.uv[3], f.uv[0]\r
+ )\r
+\r
+ vertexArrayMap.optimize()\r
+ return vertexArrayMap\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
+ def __init__(self, view):\r
+ self.isInitialized=False\r
+ self.setView(view)\r
+ self.root=None\r
+\r
+ def setRoot(self, root):\r
self.root=root\r
+ self.delegate(root)\r
self.isInitialized=False\r
+\r
+ def setView(self, view):\r
+ self.view=view\r
self.delegate(view)\r
- self.delegate(root)\r
\r
def delegate(self, to):\r
for name in dir(to): \r
glLoadIdentity()\r
# OpenGL\95`\89æ\r
self.view.updateView()\r
- self.root.draw()\r
+ if self.root:\r
+ self.root.draw()\r
glFlush()\r
\r
# coding: utf-8\r
\r
import sys\r
+import os\r
import tkinter\r
import tkinter.filedialog\r
import togl\r
import opengl\r
import opengl.rokuro\r
-import triangle\r
+import mqobuilder\r
\r
\r
class Frame(tkinter.Frame):\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
+ 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
+ self.glworld=opengl.BaseController(opengl.rokuro.RokuroView(25))\r
+ self.glwidget=togl.Widget(self, self.glworld, width=width, height=height)\r
+ self.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
+ self.bind('<MouseWheel>', lambda e: self.glworld.onWheel(-e.delta) and self.glwidget.onDraw())\r
\r
def onOpen(self):\r
filename=tkinter.filedialog.askopenfilename(\r
('poloygon model files', '*.mqo;*.pmd'),\r
], \r
initialdir=self.current)\r
- print('open: %s' % filename)\r
+ if filename.lower().endswith(".mqo"):\r
+ self.loadMqo(filename)\r
+ elif filename.lower().endswith(".pmd"):\r
+ self.loadPmd(filename)\r
+ self.current=os.path.dirname(filename)\r
+\r
+ def loadMqo(self, path):\r
+ # load scenee\r
+ model=mqobuilder.build(path)\r
+ if not model:\r
+ print('fail to load %s' % path)\r
+ return\r
+ self.glworld.setRoot(model)\r
+ print('loadMqo %s' % path)\r
+ self.glwidget.onDraw()\r
+\r
+ def loadPmd(self, path):\r
+ print('loadPmd %s' % path)\r
\r
def onKeyDown(self, event):\r
key=event.keycode\r
--- /dev/null
+#!/usr/bin/python
+# coding: utf-8
+
+from PIL import Image
+from OpenGL.GL import *
+
+
+class Texture(object):
+
+ def __init__(self, path):
+ self.path=path
+ self.image=None
+
+ def onInitialize(self):
+ if not self.image:
+ self.loadImage()
+
+ assert(self.image)
+ if self.createTexture():
+ return True
+
+ def loadImage(self):
+ self.image=Image.open(self.path)
+ if self.image:
+ print("load image:", self.path)
+ return True
+ else:
+ print("failt to load image:", self.path)
+ return False
+
+ def createTexture(self):
+ self.texture=glGenTextures(1)
+ if self.texture==0:
+ print("fail to glGenTextures")
+ return False
+
+ channels=len(self.image.getbands())
+ w, h=self.image.size
+ glBindTexture(GL_TEXTURE_2D, self.texture)
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
+ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
+ if channels==4:
+ print("RGBA")
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 4)
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h,
+ 0, GL_RGBA, GL_UNSIGNED_BYTE, self.image.tostring())
+ elif channels==3:
+ print("RGB")
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h,
+ 0, GL_RGB, GL_UNSIGNED_BYTE, self.image.tostring())
+
+ def begin(self):
+ glEnable(GL_TEXTURE_2D)
+ glBindTexture(GL_TEXTURE_2D, self.texture)
+
+ def end(self):
+ glDisable(GL_TEXTURE_2D)
+
+
--- /dev/null
+#!/usr/bin/python\r
+# coding: utf-8\r
+\r
+from OpenGL.GL import *\r
+\r
+'''\r
+頂点配列\r
+\r
+====\r
+属性\r
+====\r
+* 位置\r
+'''\r
+class VertexArray(object):\r
+ def __init__(self, vertices):\r
+ self.vertices=vertices\r
+\r
+ def __str__(self):\r
+ return "<VertexArray %d>" % len(self.vertices)\r
+\r
+ def draw(self):\r
+ # 位置属性\r
+ glEnableClientState(GL_VERTEX_ARRAY)\r
+ glVertexPointer(3, GL_FLOAT, 0, self.vertices)\r
+ # 描画\r
+ glDrawArrays(GL_TRIANGLES, 0, len(self.vertices))\r
+ # 後始末\r
+ glDisableClientState(GL_VERTEX_ARRAY)\r
+\r
+\r
+\r
+'''\r
+頂点配列\r
+\r
+====\r
+属性\r
+====\r
+* 位置\r
+* UV\r
+'''\r
+class VertexArrayWithUV(object):\r
+ def __init__(self, vertices, uvarray):\r
+ self.vertices=vertices\r
+ self.uvarray=uvarray\r
+\r
+ def __str__(self):\r
+ return "<VertexArrayWithUV %d>" % len(self.vertices)\r
+\r
+ def draw(self):\r
+ # 位置属性\r
+ glEnableClientState(GL_VERTEX_ARRAY)\r
+ glVertexPointer(3, GL_FLOAT, 0, self.vertices)\r
+ # UV属性\r
+ glEnableClientState(GL_TEXTURE_COORD_ARRAY)\r
+ glTexCoordPointer(2, GL_FLOAT, 0, self.uvarray)\r
+ # 描画\r
+ triangle_count=int(len(self.vertices)/3)\r
+ glDrawArrays(GL_TRIANGLES, 0, triangle_count)\r
+ # 後始末\r
+ glDisableClientState(GL_TEXTURE_COORD_ARRAY)\r
+ glDisableClientState(GL_VERTEX_ARRAY)\r
+\r
+\r
+'''\r
+インデックス参照頂点配列\r
+\r
+====\r
+属性\r
+====\r
+* 位置\r
+'''\r
+class IndexedVertexArray(object):\r
+ def __init__(self, vertices, indices):\r
+ self.vertices=vertices\r
+ self.indices=indices\r
+\r
+ def draw(self):\r
+ # 位置属性\r
+ glEnableClientState(GL_VERTEX_ARRAY)\r
+ glVertexPointer(3, GL_FLOAT, 0, self.vertices)\r
+ # indexによる描画\r
+ glDrawElements(GL_TRIANGLES, len(self.indices),\r
+ GL_UNSIGNED_INT, self.indices)\r
+ # 後始末\r
+ glDisableClientState(GL_VERTEX_ARRAY)\r
+\r
+\r
+'''\r
+インデックス参照頂点配列\r
+\r
+====\r
+属性\r
+====\r
+* 位置\r
+* 色\r
+'''\r
+class IndexedVertexArrayWithColor(object):\r
+ def __init__(self, vertices, colors, indices):\r
+ self.vertices=vertices\r
+ self.colors=colors\r
+ self.indices=indices\r
+\r
+ def draw(self):\r
+ # 位置属性\r
+ glEnableClientState(GL_VERTEX_ARRAY)\r
+ glVertexPointer(3, GL_FLOAT, 0, self.vertices)\r
+ # 色属性\r
+ glEnableClientState(GL_COLOR_ARRAY)\r
+ glColorPointer(3, GL_FLOAT, 0, self.colors)\r
+ # indexによる描画\r
+ glDrawElements(GL_TRIANGLES, len(self.indices),\r
+ GL_UNSIGNED_INT, self.indices)\r
+ # 後始末\r
+ glDisableClientState(GL_COLOR_ARRAY)\r
+ glDisableClientState(GL_VERTEX_ARRAY)\r
+\r
--- /dev/null
+#!/usr/bin/python
+# coding: utf-8
+
+import numpy
+import vertexarray
+
+
+'''
+頂点配列をマテリアル毎に分別する
+'''
+class VertexArrayMap(object):
+ def __init__(self, materials):
+ self.materials=materials
+ self.vertexArrayMap={}
+
+ def getVertexArray(self, material_index):
+ material=self.materials[material_index]
+ if not material in self.vertexArrayMap:
+ vertexArray=vertexarray.VertexArray([])
+ self.vertexArrayMap[material]=vertexArray
+ return self.vertexArrayMap[material]
+
+ def addTriangle(self, material_index, v0, v1, v2):
+ vertexArray=self.getVertexArray(material_index)
+ vertexArray.vertices.append(v0.x)
+ vertexArray.vertices.append(v0.y)
+ vertexArray.vertices.append(v0.z)
+ vertexArray.vertices.append(v1.x)
+ vertexArray.vertices.append(v1.y)
+ vertexArray.vertices.append(v1.z)
+ vertexArray.vertices.append(v2.x)
+ vertexArray.vertices.append(v2.y)
+ vertexArray.vertices.append(v2.z)
+
+ def draw(self):
+ for m, vertexArray in self.vertexArrayMap.items():
+ m.begin()
+ vertexArray.draw()
+ m.end()
+
+ def optimize(self):
+ for v in self.vertexArrayMap.values():
+ v.vertices=numpy.array(v.vertices, 'f')
+
+
+'''
+頂点配列をマテリアル毎に分別する(UV付き)
+'''
+class VertexArrayMapWithUV(object):
+ def __init__(self, materials):
+ self.materials=materials
+ self.vertexArrayWithUVMap={}
+
+ def getVertexArray(self, material_index):
+ material=self.materials[material_index]
+ if not material in self.vertexArrayWithUVMap:
+ vertexArray=vertexarray.VertexArrayWithUV([], [])
+ self.vertexArrayWithUVMap[material]=vertexArray
+ return self.vertexArrayWithUVMap[material]
+
+ def addTriangle(self, material_index, v0, v1, v2, uv0, uv1, uv2):
+ vertexArray=self.getVertexArray(material_index)
+ vertexArray.vertices.append(v0.x)
+ vertexArray.vertices.append(v0.y)
+ vertexArray.vertices.append(v0.z)
+ vertexArray.vertices.append(v1.x)
+ vertexArray.vertices.append(v1.y)
+ vertexArray.vertices.append(v1.z)
+ vertexArray.vertices.append(v2.x)
+ vertexArray.vertices.append(v2.y)
+ vertexArray.vertices.append(v2.z)
+ vertexArray.uvarray.append(uv0.x)
+ vertexArray.uvarray.append(uv0.y)
+ vertexArray.uvarray.append(uv1.x)
+ vertexArray.uvarray.append(uv1.y)
+ vertexArray.uvarray.append(uv2.x)
+ vertexArray.uvarray.append(uv2.y)
+
+ def draw(self):
+ for m, vertexArray in self.vertexArrayWithUVMap.items():
+ m.begin()
+ vertexArray.draw()
+ m.end()
+
+ def optimize(self):
+ for v in self.vertexArrayWithUVMap.values():
+ v.vertices=numpy.array(v.vertices, 'f')
+ v.uvarray=numpy.array(v.uvarray, 'f')
+
+ def onInitialize(self):
+ [m.onInitialize() for m in self.materials]
+