From: ousttrue Date: Sat, 1 Oct 2011 05:17:05 +0000 (+0900) Subject: refactoring X-Git-Url: http://git.osdn.jp/view?a=commitdiff_plain;h=e71383740ef0dabf087ddfd6643903219c8408c7;p=meshio%2Fpymeshio.git refactoring --- diff --git a/pymeshio/mqo/__init__.py b/pymeshio/mqo/__init__.py new file mode 100644 index 0000000..e986d42 --- /dev/null +++ b/pymeshio/mqo/__init__.py @@ -0,0 +1,240 @@ +# coding: utf-8 +""" +MQOの読み込み +http://www.metaseq.net/metaseq/format.html +""" + +import os +import sys +import math +import pymeshio.common +import pymeshio.mqo.loader + + +""" +MQO loader +""" +class Material(object): + """mqo material + + Attributes: + name: cp932 + shader: + color: rgba + diffuse: + ambient: + emit: + specular: + power: + tex: cp932 windows file path + """ + __slots__=[ + "name", "shader", "color", "diffuse", + "ambient", "emit", "specular", "power", + "tex", + ] + def __init__(self, name): + self.name=name + self.shader=3 + self.color=pymeshio.common.RGBA(0.5, 0.5, 0.5, 1.0) + self.diffuse=1.0 + self.ambient=0.0 + self.emit=0.0 + self.specular=0.0 + self.power=5.0 + self.tex="" + + def getName(self): return self.name + def getTexture(self): return self.tex + + def parse(self, line): + offset=0 + while True: + leftParenthesis=line.find("(", offset) + if leftParenthesis==-1: + break + key=line[offset:leftParenthesis] + rightParenthesis=line.find(")", leftParenthesis+1) + if rightParenthesis==-1: + raise ValueError("assert") + + param=line[leftParenthesis+1:rightParenthesis] + if key=="shader": + self.shader=int(param) + elif key=="col": + self.color=pymeshio.common.RGBA(*[float(e) for e in param.split()]) + elif key=="dif": + self.diffuse=float(param) + elif key=="amb": + self.ambient=float(param) + elif key=="emi": + self.emit=float(param) + elif key=="spc": + self.specular=float(param) + elif key=="power": + self.power=float(param) + elif key=="tex": + self.tex=param[1:-1] + else: + print( + "%s#parse" % self.name, + "unknown key: %s" % key + ) + + offset=rightParenthesis+2 + + def __str__(self): + return "" % ( + self.name, self.shader, + self.color[0], self.color[1], self.color[2], self.color[3], + self.diffuse) + + +class Obj(object): + """mqo object + + Attributes: + name: cp932 + depth: object hierarchy + folding: + scale: + rotation: + translation: + visible: + locking: + shading: + facet: smoothing threshold + color: + color_type: + mirror: mirroring + mirror_axis: + vertices: + faces: + edges: + smoothing: + """ + __slots__=["name", "depth", "folding", + "scale", "rotation", "translation", + "visible", "locking", "shading", "facet", + "color", "color_type", "mirror", "mirror_axis", + "vertices", "faces", "edges", "smoothing", + ] + + def __init__(self, name): + self.name=name + self.vertices=[] + self.faces=[] + self.edges=[] + self.depth=0 + self.folding=0 + self.scale=[1, 1, 1] + self.rotation=[0, 0, 0] + self.translation=[0, 0, 0] + self.visible=15 + self.locking=0 + self.shading=0 + self.facet=59.5 + self.color=[1, 1, 1] + self.color_type=0 + self.mirror=0 + self.smoothing=0 + + def getName(self): return self.name + + def addVertex(self, x, y, z): + self.vertices.append(pymeshio.common.Vector3(x, y, z)) + + def addFace(self, face): + if face.index_count==2: + self.edges.append(face) + else: + self.faces.append(face) + + def __str__(self): + return "" % ( + self.name, len(self.vertices), len(self.faces)) + + +class Face(object): + """mqo face + + Attributes: + index_count: 2 or 3 or 4 + indices: index x index_count + material_index: + col: vertex_color x index_count + uv: Vector2 x index_count + """ + __slots__=[ + "index_count", + "indices", "material_index", "col", "uv", + ] + def __init__(self, index_count, line): + if index_count<2 or index_count>4: + raise ValueError("invalid vertex count: %d" % index_count) + self.material_index=0 + self.col=[] + self.uv=[pymeshio.common.Vector2(0, 0)]*4 + self.index_count=index_count + offset=0 + while True: + leftParenthesis=line.find("(", offset) + if leftParenthesis==-1: + break + key=line[offset:leftParenthesis] + rightParenthesis=line.find(")", leftParenthesis+1) + if rightParenthesis==-1: + raise ValueError("assert") + params=line[leftParenthesis+1:rightParenthesis].split() + if key=="V": + self.indices=[int(e) for e in params] + elif key=="M": + self.material_index=int(params[0]) + elif key=="UV": + uv_list=[float(e) for e in params] + self.uv=[] + for i in range(0, len(uv_list), 2): + self.uv.append(pymeshio.common.Vector2(uv_list[i], uv_list[i+1])) + elif key=="COL": + for n in params: + d=int(n) + # R + d, m=divmod(d, 256) + self.col.append(m) + # G + d, m=divmod(d, 256) + self.col.append(m) + # B + d, m=divmod(d, 256) + self.col.append(m) + # A + d, m=divmod(d, 256) + self.col.append(m) + else: + print("Face#__init__:unknown key: %s" % key) + + offset=rightParenthesis+2 + + def getIndex(self, i): return self.indices[i] + def getUV(self, i): return self.uv[i] if i" % ( + self.lines, len(self.materials), len(self.objects)) + + def getline(self): + line=self.io.readline() + self.lines+=1 + if line=="": + self.eof=True + return None + return line.strip() + + def printError(self, method, msg): + print("%s:%s:%d" % (method, msg, self.lines)) + + def readObject(self, name): + obj=pymeshio.mqo.Obj(name) + while(True): + line=self.getline() + if line==None: + # eof + break; + if line=="": + # empty line + continue + + if line=="}": + return obj + else: + tokens=line.split() + key=tokens[0] + if key=="vertex": + if not self.readVertex(obj): + return False + elif key=="face": + if not self.readFace(obj): + return False + elif key=="depth": + obj.depth=int(tokens[1]) + else: + print( + "%s#readObject" % name, + "unknown key: %s" % key + ) + + self.printError("readObject", "invalid eof") + return False + + def readFace(self, obj): + while(True): + line=self.getline() + if line==None: + # eof + break; + if line=="": + # empty line + continue + + if line=="}": + return True + else: + # face + tokens=line.split(' ', 1) + try: + obj.addFace(pymeshio.mqo.Face(int(tokens[0]), tokens[1])) + except ValueError as ex: + self.printError("readFace", ex) + #return False + + self.printError("readFace", "invalid eof") + return False + + def readVertex(self, obj): + while(True): + line=self.getline() + if line==None: + # eof + break; + if line=="": + # empty line + continue + + if line=="}": + return True + else: + # vertex + obj.addVertex(*[float(v) for v in line.split()]) + + self.printError("readVertex", "invalid eof") + return False + + def readMaterial(self): + materials=[] + while(True): + line=self.getline() + if line==None: + # eof + break; + if line=="": + # empty line + continue + + if line=="}": + return materials + else: + # material + secondQuaote=line.find('"', 1) + material=pymeshio.mqo.Material(line[1:secondQuaote]) + try: + material.parse(line[secondQuaote+2:]) + except ValueError as ex: + self.printError("readMaterial", ex) + + materials.append(material) + + self.printError("readMaterial", "invalid eof") + return False + + def readChunk(self): + level=1 + while(True): + line=self.getline() + if line==None: + # eof + break; + if line=="": + # empty line + continue + + if line=="}": + level-=1 + if level==0: + return True + elif line.find("{")!=-1: + level+=1 + + self.printError("readChunk", "invalid eof") + return False + + +def load(path): + with open(path, 'rb') as io: + loader=Loader(io) + model=pymeshio.mqo.Model() + + line=loader.getline() + if line!="Metasequoia Document": + print("invalid signature") + return False + + line=loader.getline() + if line!="Format Text Ver 1.0": + print("unknown version: %s" % line) + + while True: + line=loader.getline() + if line==None: + # eof + break; + if line=="": + # empty line + continue + + tokens=line.split() + key=tokens[0] + if key=="Eof": + return model + elif key=="Scene": + if not loader.readChunk(): + return + elif key=="Material": + materials=loader.readMaterial() + if not materials: + return + model.materials=materials + elif key=="Object": + firstQuote=line.find('"') + secondQuote=line.find('"', firstQuote+1) + obj=loader.readObject(line[firstQuote+1:secondQuote]) + if not obj: + return + model.objects.append(obj) + elif key=="BackImage": + if not loader.readChunk(): + return + elif key=="IncludeXml": + firstQuote=line.find('"') + secondQuote=line.find('"', firstQuote+1) + print("IncludeXml", line[firstQuote+1:secondQuote]) + else: + print("unknown key: %s" % key) + if not loader.readChunk(): + return + # error not reach here + raise ParseException("invalid eof") + diff --git a/test/mqo_test.py b/test/mqo_test.py index 12daf50..5b054c8 100644 --- a/test/mqo_test.py +++ b/test/mqo_test.py @@ -1,9 +1,16 @@ import pymeshio.mqo import sys -MQO_FILE="K:/model/cube.mqo" +MQO_FILE="resources/cube.mqo" -def test_mqo_load(): +def test_old_mqo_load(): io=pymeshio.mqo.IO() assert io.read(MQO_FILE) +def test_mqo_load(): + model=pymeshio.mqo.loader.load(MQO_FILE) + print(model.materials) + assert pymeshio.mqo.Model==model.__class__ + assert 6==len(model.materials) + assert 1==len(model.objects) + diff --git a/test/mqo_test.pyc b/test/mqo_test.pyc index b11ce30..3f8c2e3 100644 Binary files a/test/mqo_test.pyc and b/test/mqo_test.pyc differ diff --git a/test/pmx_test.py b/test/pmx_test.py index e78f740..878c251 100644 --- a/test/pmx_test.py +++ b/test/pmx_test.py @@ -2,10 +2,10 @@ import pymeshio.pmx.loader -PMX_MODEL=u'resources/初音ミクVer2.pmx' +PMX_FILE=u'resources/初音ミクVer2.pmx' def test_read(): - model=pymeshio.pmx.loader.load(PMX_MODEL) + model=pymeshio.pmx.loader.load(PMX_FILE) assert model.__class__==pymeshio.pmx.Model assert model.name==u'初音ミク' assert model.english_name==u'Miku Hatsune'