OSDN Git Service

1fe8603a80144bdd2b89998cd132291a9339dd2d
[meshio/meshio.git] / src / mqo.cpp
1 #include "mqo.h"
2 #include <iostream>
3 #include <fstream>
4 #include <vector>
5
6 namespace meshio {
7 namespace mqo {
8
9 //! Tokenizer
10 struct DELIMITER
11 {
12         bool operator()(char c)
13         {
14                 switch(c)
15                 {
16                 case ' ':
17                 case '\t':
18                 case '(':
19                 case ')':
20                         return true;
21                 default:
22                         return false;
23                 }
24         }
25 };
26 typedef text::LineSplitter<DELIMITER> SPLITTER;
27
28
29 //! \8eÀ\91\95
30 class Implementation
31 {
32         Scene &scene;
33         std::vector<Material> &materials;
34         std::vector<Object> &objects;
35
36 public:
37         Implementation(Scene &_scene, std::vector<Material> &_materials,
38                         std::vector<Object> &_objects)
39                 : scene(_scene), materials(_materials), objects(_objects)
40                 {}
41
42         template<class READER> bool 
43                 parse(READER reader)
44                 {
45                         while(!reader.isEnd()){
46                                 text::cstr line=reader.getLine();
47                                 SPLITTER splitter(line);
48                                 text::cstr key=splitter.get();
49                                 if(key=="Scene"){
50                                         if(!readSceneChunk(reader)){
51                                                 return false;
52                                         }
53                                 }
54                                 else if(key=="Material"){
55                                         if(!readMaterialChunk(reader, splitter.getInt())){
56                                                 return false;
57                                         }
58                                 }
59                                 else if(key=="Object"){
60                                         if(!readObjectChunk(reader, splitter.getQuated())){
61                                                 return false;
62                                         }
63                                 }
64                                 else if(key=="Eof"){
65                                         if(materials.empty()){
66                                                 // fallback
67                                                 materials.push_back(Material());
68                                         }
69                                         return true;
70                                 }
71                         }
72                         std::cout << "not found 'EOF'" << std::endl;
73                         return true;
74                 }
75
76
77 private:
78         template<class READER> bool 
79                 readObjectChunk(READER &reader, text::cstr name)
80                 {
81                         objects.push_back(Object());
82                         Object &object=objects.back();
83                         object.name=name.str();
84                         while(!reader.isEnd()){
85                                 text::cstr line=reader.getLine();
86                                 if(line=="}"){
87                                         return true;
88                                 }
89                                 SPLITTER splitter(line);
90                                 text::cstr key=splitter.get();
91                                 if(key=="depth"){
92                                         object.depth=splitter.getInt();
93                                 }
94                                 else if(key=="folding"){
95                                         object.folding=splitter.getInt();
96                                 }
97                                 else if(key=="scale"){
98                                         object.scale=splitter.getVector3();
99                                 }
100                                 else if(key=="rotation"){
101                                         object.rotation=splitter.getVector3();
102                                 }
103                                 else if(key=="translation"){
104                                         object.translation=splitter.getVector3();
105                                 }
106                                 else if(key=="visible"){
107                                         object.visible=splitter.getInt();
108                                 }
109                                 else if(key=="locking"){
110                                         object.locking=splitter.getInt();
111                                 }
112                                 else if(key=="shading"){
113                                         object.shading=splitter.getInt();
114                                 }
115                                 else if(key=="facet"){
116                                         object.smoothing=splitter.getFloat();
117                                 }
118                                 else if(key=="color"){
119                                         object.color=splitter.getVector3();
120                                 }
121                                 else if(key=="color_type"){
122                                         object.color_type=splitter.getInt();
123                                 }
124                                 else if(key=="vertex"){
125                                         if(!readObjectVertexChunk(reader, object, splitter.getInt())){
126                                                 return false;
127                                         }
128                                 }
129                                 else if(key=="face"){
130                                         if(!readObjectFaceChunk(reader, object, splitter.getInt())){
131                                                 return false;
132                                         }
133                                 }
134                                 else if(key=="segment"){
135                                         // ToDo
136                                         continue;
137                                 }
138                                 else if(key=="patch"){
139                                         // ToDo
140                                         continue;
141                                 }
142                                 else if(key=="mirror"){
143                                         object.mirror=splitter.getInt();
144                                 }
145                                 else{
146                                         std::cout << "unknown object key: " << key << std::endl;
147                                 }
148                         }
149                         std::cout << "fail to readObjectChunk" << std::endl;
150                         return false;
151                 }
152         template<class READER> bool 
153                 readObjectVertexChunk(READER &reader, 
154                                 Object &object, size_t vertex_count)
155                 {
156                         while(!reader.isEnd()){
157                                 text::cstr line=reader.getLine();
158                                 if(line=="}"){
159                                         if(object.vertices.size()!=vertex_count){
160                                                 std::cout << "invalid vertex count." 
161                                                         << " expected " << vertex_count
162                                                         << ", but " << object.vertices.size()
163                                                         << std::endl;
164                                                 return false;
165                                         }
166                                         return true;
167                                 }
168                                 object.vertices.push_back(SPLITTER(line).getVector3());
169                         }
170                         std::cout << "fail to readObjectVertexChunk" << std::endl;
171                         return false;
172                 }
173
174         template<class READER> bool 
175                 readObjectFaceChunk(READER &reader,
176                                 Object &object, size_t face_count)
177                 {
178                         while(!reader.isEnd()){
179                                 text::cstr line=reader.getLine();
180                                 if(line=="}"){
181                                         if(object.faces.size()!=face_count){
182                                                 std::cout << "invalid face count."
183                                                         << " expected " << face_count
184                                                         << ", but " << object.faces.size()
185                                                         << std::endl;
186                                                 return false;
187                                         }
188                                         return true;
189                                 }
190                                 if(!readObjectFaceLine(object, line)){
191                                         return false;
192                                 }
193                         }
194                         std::cout << "fail to readFaceChunk" << std::endl;
195                         return false;
196                 }
197
198         bool 
199                 readObjectFaceLine(Object &object, text::cstr line)
200                 {
201                         object.faces.push_back(Face());
202                         Face &face=object.faces.back();
203                         SPLITTER splitter(line);
204                         face.index_count=splitter.getInt();
205                         while(true){
206                                 text::cstr key=splitter.get();
207                                 if(key==""){
208                                         break;
209                                 }
210
211                                 if(key=="V"){
212                                         for(size_t i=0; i<face.index_count; ++i){
213                                                 face.indices[i]=splitter.getInt();
214                                         }
215                                 }
216                                 else if(key=="M"){
217                                         face.material_index=splitter.getInt();
218                                 }
219                                 else if(key=="UV"){
220                                         for(size_t i=0; i<face.index_count; ++i){
221                                                 face.uv[i]=splitter.getVector2();
222                                         }
223                                 }
224                                 else if(key=="COL"){
225                                         for(size_t i=0; i<face.index_count; ++i){
226                                                 face.color[i]=
227                                                         color::fRGBA::createFromUInt(splitter.getInt());
228                                         }
229                                 }
230                                 else{
231                                         std::cout << "unknown face key: " 
232                                                 << '"' << key << '"'  << std::endl
233                                                 ;
234                                         //return false;
235                                         break;
236                                 }
237                         }
238                         return true;
239                 }
240
241         template<class READER> bool 
242                 readMaterialChunk(READER &reader, size_t material_count)
243                 {
244                         while(!reader.isEnd()){
245                                 text::cstr line=reader.getLine();
246                                 if(line=="}"){
247                                         if(materials.size()!=material_count){
248                                                 std::cout << "invalid material count." 
249                                                         << " expected " << material_count
250                                                         << ", but " << materials.size()
251                                                         << std::endl;
252                                                 return false;
253                                         }
254                                         return true;
255                                 }
256                                 readMaterialLine(line);
257                         }
258                         std::cout << "fail to readMaterialChunk" << std::endl;
259                         return false;
260                 }
261
262         void 
263                 readMaterialLine(text::cstr line)
264                 {
265                         materials.push_back(Material());
266                         Material &material=materials.back();
267
268                         SPLITTER splitter(line);
269                         material.name=splitter.getQuated().str();
270                         while(true){
271                                 text::cstr key=splitter.get();
272                                 if(key==""){
273                                         break;
274                                 }
275                                 else if(key=="shader"){
276                                         material.shader=splitter.getInt();
277                                 }
278                                 else if(key=="col"){
279                                         material.color=splitter.getFloatRGBA();
280                                 }
281                                 else if(key=="dif"){
282                                         material.diffuse=splitter.getFloat();
283                                 }
284                                 else if(key=="amb"){
285                                         material.ambient=splitter.getFloat();
286                                 }
287                                 else if(key=="emi"){
288                                         material.emmit=splitter.getFloat();
289                                 }
290                                 else if(key=="spc"){
291                                         material.specular=splitter.getFloat();
292                                 }
293                                 else if(key=="power"){
294                                         material.power=splitter.getFloat();
295                                 }
296                                 else if(key=="tex"){
297                                         material.texture=splitter.getQuated().str();
298                                 }
299                                 else if(key=="aplane"){
300                                         material.alphamap=splitter.getQuated().str();
301                                 }
302                                 else if(key=="bump"){
303                                         material.bumpmap=splitter.getQuated().str();
304                                 }
305                                 else if(key=="vcol"){
306                                         material.vcol=splitter.getInt();
307                                 }
308                                 else{
309                                         std::cout << "unknown material key: \"" << key << '"' << std::endl;
310                                         //assert(false);
311                                         return;
312                                 }
313                         }
314                 }
315
316         template<class READER> bool 
317                 readSceneChunk(READER &reader)
318                 {
319                         while(!reader.isEnd()){
320                                 text::cstr line=reader.getLine();
321                                 if(line=="}"){
322                                         return true;
323                                 }
324                                 SPLITTER splitter(line);
325                                 text::cstr key=splitter.get();
326                                 if(key=="pos"){
327                                         scene.pos=splitter.getVector3();
328                                 }
329                                 else if(key=="lookat"){
330                                         scene.lookat=splitter.getVector3();
331                                 }
332                                 else if(key=="head"){
333                                         scene.head=splitter.getFloat();
334                                 }
335                                 else if(key=="pich") {
336                                         scene.pitch=splitter.getFloat();
337                                 }
338                                 else if(key=="ortho"){
339                                         scene.ortho=splitter.getInt();
340                                 }
341                                 else if(key=="zoom2"){
342                                         scene.zoom2=splitter.getFloat();
343                                 }
344                                 else if(key=="amb"){
345                                         scene.ambient=splitter.getVector3();
346                                 }
347                                 else{
348                                         std::cout << "unknown scene key: " << key << std::endl;
349                                 }
350                         }
351                         std::cout << "fail to readSceneChunk" << std::endl;
352                         return false;
353                 }
354
355         template<class READER> bool 
356                 readChunk(READER &reader)
357                 {
358                         int level=1;
359                         while(!reader.isEnd()){
360                                 text::cstr line=reader.getLine();
361                                 if(line=="}"){
362                                         level--;
363                                         if(level==0){
364                                                 return true;
365                                         }
366                                 }
367                                 else if(line.include('{')){
368                                         level+=1;
369                                 }
370                         }
371                         return false;
372                 }
373
374 };
375
376
377 ///////////////////////////////////////////////////////////////////////////////
378 // IO
379 ///////////////////////////////////////////////////////////////////////////////
380 bool IO::read(binary::IReader &input)
381 {
382         text::LineReader<text::IsCRLF, text::IsWhiteSpace, text::IsEmpty> 
383                 reader(input);
384         text::cstr line=reader.getLine();
385         if(line!="Metasequoia Document"){
386                 return false;
387         }
388         line=reader.getLine();
389         if(line!="Format Text Ver 1.0"){
390                 return false;
391         }
392
393         return Implementation(scene, materials, objects).parse(reader);
394 }
395
396 bool IO::read(const char *path)
397 {
398         std::vector<char> all;
399         binary::readAll(path, all);
400         if(all.empty()){
401                 return false;
402         }
403         binary::MemoryReader reader(&all[0], all.size());
404         return read(reader);
405 }
406
407 bool IO::write(std::ostream &os)
408 {
409         return false;
410 }
411
412
413 }
414 }