OSDN Git Service

fix
[meshio/pymeshio.git] / pymeshio / mqo / reader.py
1 # coding: utf-8\r
2 """\r
3 mqo reader\r
4 """\r
5 import io\r
6 from .. import mqo\r
7 \r
8 class Reader(object):\r
9     """mqo reader\r
10     """\r
11     __slots__=[\r
12             "has_mikoto",\r
13             "eof", "ios", "lines",\r
14             "materials", "objects",\r
15             ]\r
16     def __init__(self, ios):\r
17         self.ios=ios\r
18         self.eof=False\r
19         self.lines=0\r
20 \r
21     def __str__(self):\r
22         return "<MQO %d lines, %d materials, %d objects>" % (\r
23                 self.lines, len(self.materials), len(self.objects))\r
24 \r
25     def getline(self):\r
26         line=self.ios.readline()\r
27         self.lines+=1\r
28         if line==b"":\r
29             self.eof=True\r
30             return None\r
31         return line.strip()\r
32 \r
33     def printError(self, method, msg):\r
34         print("%s:%s:%d" % (method, msg, self.lines))\r
35 \r
36     def readObject(self, name):\r
37         obj=mqo.Obj(name)\r
38         while(True):\r
39             line=self.getline()\r
40             if line==None:\r
41                 # eof\r
42                 break;\r
43             if line==b"":\r
44                 # empty line\r
45                 continue\r
46 \r
47             if line==b"}":\r
48                 return obj\r
49             else:\r
50                 tokens=line.split()\r
51                 key=tokens[0]\r
52                 if key==b"vertex":\r
53                     if not self.readVertex(obj):\r
54                         return False\r
55                 elif key==b"face":\r
56                     if not self.readFace(obj):\r
57                         return False\r
58                 elif key==b"depth":\r
59                     obj.depth=int(tokens[1])\r
60                 else:\r
61                     print(\r
62                             "%s#readObject" % name,\r
63                             "unknown key: %s" % key\r
64                             )\r
65 \r
66         self.printError("readObject", "invalid eof")\r
67         return False\r
68 \r
69     def readFace(self, obj):\r
70         while(True):\r
71             line=self.getline()\r
72             if line==None:\r
73                 # eof\r
74                 break;\r
75             if line==b"":\r
76                 # empty line\r
77                 continue\r
78 \r
79             if line==b"}":\r
80                 return True\r
81             else:\r
82                 # face\r
83                 tokens=line.split(b' ', 1)\r
84                 try:\r
85                     obj.addFace(mqo.Face(int(tokens[0]), tokens[1]))\r
86                 except ValueError as ex:\r
87                     self.printError("readFace", ex)\r
88                     #return False\r
89 \r
90         self.printError("readFace", "invalid eof")\r
91         return False\r
92 \r
93     def readVertex(self, obj):\r
94         while(True):\r
95             line=self.getline()\r
96             if line==None:\r
97                 # eof\r
98                 break;\r
99             if line==b"":\r
100                 # empty line\r
101                 continue\r
102 \r
103             if line==b"}":\r
104                 return True\r
105             else:\r
106                 # vertex\r
107                 obj.addVertex(*[float(v) for v in line.split()])\r
108 \r
109         self.printError("readVertex", "invalid eof")\r
110         return False\r
111 \r
112     def readMaterial(self):\r
113         materials=[]\r
114         while(True):\r
115             line=self.getline()\r
116             if line==None:\r
117                 # eof\r
118                 break;\r
119             if line==b"":\r
120                 # empty line\r
121                 continue\r
122 \r
123             if line==b"}":\r
124                 return materials\r
125             else:\r
126                 # material\r
127                 secondQuaote=line.find(b'"', 1)                \r
128                 material=mqo.Material(line[1:secondQuaote])\r
129                 try:\r
130                     material.parse(line[secondQuaote+2:])\r
131                 except ValueError as ex:\r
132                     self.printError("readMaterial", ex)\r
133 \r
134                 materials.append(material)\r
135 \r
136         self.printError("readMaterial", "invalid eof")\r
137         return False\r
138 \r
139     def readChunk(self):\r
140         level=1\r
141         while(True):\r
142             line=self.getline()\r
143             if line==None:\r
144                 # eof\r
145                 break;\r
146             if line==b"":\r
147                 # empty line\r
148                 continue\r
149 \r
150             if line==b"}":\r
151                 level-=1\r
152                 if level==0:\r
153                     return True\r
154             elif line.find(b"{")!=-1:\r
155                 level+=1\r
156 \r
157         self.printError("readChunk", "invalid eof")\r
158         return False\r
159 \r
160 \r
161 def read_from_file(path):\r
162     with io.open(path, 'rb') as ios:\r
163         return read(ios)\r
164 \r
165 \r
166 def read(ios):\r
167     print(type(ios), ios)\r
168     assert(isinstance(ios, io.IOBase))\r
169     reader=Reader(ios)\r
170     model=mqo.Model()\r
171 \r
172     line=reader.getline()\r
173     if line!=b"Metasequoia Document":\r
174         print("invalid signature")\r
175         return False\r
176 \r
177     line=reader.getline()\r
178     if line!=b"Format Text Ver 1.0":\r
179         print("unknown version: %s" % line)\r
180 \r
181     while True:\r
182         line=reader.getline()\r
183         if line==None:\r
184             # eof\r
185             break;\r
186         if line==b"":\r
187             # empty line\r
188             continue\r
189 \r
190         tokens=line.split()\r
191         key=tokens[0]\r
192         if key==b"Eof":\r
193             return model\r
194         elif key==b"Scene":\r
195             if not reader.readChunk():\r
196                 return\r
197         elif key==b"Material":\r
198             materials=reader.readMaterial()\r
199             if not materials:\r
200                 return\r
201             model.materials=materials\r
202         elif key==b"Object":\r
203             firstQuote=line.find(b'"')\r
204             secondQuote=line.find(b'"', firstQuote+1)\r
205             obj=reader.readObject(line[firstQuote+1:secondQuote])\r
206             if not obj:\r
207                 return\r
208             model.objects.append(obj)\r
209         elif key==b"BackImage":\r
210             if not reader.readChunk():\r
211                 return\r
212         elif key==b"IncludeXml":\r
213             firstQuote=line.find(b'"')\r
214             secondQuote=line.find(b'"', firstQuote+1)\r
215             print("IncludeXml", line[firstQuote+1:secondQuote])\r
216         else:\r
217             print("unknown key: %s" % key)\r
218             if not reader.readChunk():\r
219                 return\r
220     # error not reach here\r
221     raise ParseException("invalid eof")\r
222 \r