1 /****************************************************************************
2 * MeshLab o o *
3 * An extendible mesh processor o o *
4 * _ O _ *
5 * Copyright(C) 2005, 2006 \/)\/ *
6 * Visual Computing Lab /\/| *
7 * ISTI - Italian National Research Council | *
8 * \ *
9 * All rights reserved. *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
20 * for more details. *
21 * *
22 ****************************************************************************/
23 #include "io_json.h"
24
25 #include <string>
26 #include <fstream>
27
28 #include <vcg/complex/algorithms/attribute_seam.h>
29
30 #include <QString>
31 #include <QFile>
32
JSONIOPlugin(void)33 JSONIOPlugin::JSONIOPlugin(void) : MeshIOInterface()
34 {
35 ;
36 }
37
~JSONIOPlugin(void)38 JSONIOPlugin::~JSONIOPlugin(void)
39 {
40 ;
41 }
42
open(const QString & formatName,const QString & fileName,MeshModel & m,int & mask,const RichParameterSet & parlst,vcg::CallBackPos * cb,QWidget * parent)43 bool JSONIOPlugin::open(const QString & formatName, const QString & fileName, MeshModel & m, int & mask, const RichParameterSet & parlst, vcg::CallBackPos * cb, QWidget * parent)
44 {
45 (void)formatName;
46 (void)fileName;
47 (void)m;
48 (void)mask;
49 (void)parlst;
50 (void)cb;
51 (void)parent;
52
53 return false;
54 }
55
save(const QString & formatName,const QString & fileName,MeshModel & m,const int mask,const RichParameterSet & par,vcg::CallBackPos * cb,QWidget * parent)56 bool JSONIOPlugin::save(const QString & formatName,const QString & fileName, MeshModel & m, const int mask, const RichParameterSet & par, vcg::CallBackPos * cb, QWidget * parent)
57 {
58 (void)par;
59 (void)cb;
60 (void)parent;
61 vcg::tri::Allocator<CMeshO>::CompactVertexVector(m.cm);
62 vcg::tri::Allocator<CMeshO>::CompactFaceVector(m.cm);
63
64 const size_t maxValuesPerLine = 10; // must be > 0
65
66 if (formatName.toUpper() != tr("JSON")) return false;
67
68 const bool hasPerVertexPosition = true;
69 const bool hasPerVertexNormal = ((mask & vcg::tri::io::Mask::IOM_VERTNORMAL) != 0) && m.hasDataMask(MeshModel::MM_VERTNORMAL);
70 const bool hasPerVertexColor = ((mask & vcg::tri::io::Mask::IOM_VERTCOLOR) != 0) && m.hasDataMask(MeshModel::MM_VERTCOLOR);
71 const bool hasPerVertexTexCoord = ((mask & vcg::tri::io::Mask::IOM_VERTTEXCOORD) != 0) && m.hasDataMask(MeshModel::MM_VERTTEXCOORD);
72
73 const CMeshO & cm = m.cm;
74
75 const std::string filename = QFile::encodeName(fileName).constData();
76
77 std::ofstream os(filename.c_str());
78 if (!os.is_open()) return false;
79
80 os << "{" << std::endl;
81
82 os << " \"version\" : \"0.1.0\"," << std::endl;
83 os << std::endl;
84
85 os << " \"comment\" : \"Generated by MeshLab JSON Exporter\"," << std::endl;
86 os << std::endl;
87
88 os << " \"id\" : 1," << std::endl;
89 os << " \"name\" : \"mesh\"," << std::endl;
90 os << std::endl;
91
92 os << " \"vertices\" :" << std::endl;
93 os << " [" << std::endl;
94
95 bool prevDone = false;
96
97 if (hasPerVertexPosition)
98 {
99 os << " {" << std::endl;
100 os << " \"name\" : \"position_buffer\"," << std::endl;
101 os << " \"size\" : 3," << std::endl;
102 os << " \"type\" : \"float32\"," << std::endl;
103 os << " \"normalized\" : false," << std::endl;
104 os << " \"values\" :" << std::endl;
105 os << " [" << std::endl;
106
107 size_t it = 0;
108 const size_t sz = cm.vert.size();
109 while (it < sz)
110 {
111 const size_t n = std::min(it + maxValuesPerLine, sz);
112 if (n > 0)
113 {
114 os << " ";
115 {
116 const CMeshO::VertexType::CoordType & p = cm.vert[it].cP();
117 os << p[0] << ", " << p[1] << ", " << p[2];
118 it++;
119 }
120 for (; it<n; ++it)
121 {
122 const CMeshO::VertexType::CoordType & p = cm.vert[it].cP();
123 os << ", " << p[0] << ", " << p[1] << ", " << p[2];
124 }
125 if (it <= (sz - 1))
126 {
127 os << ",";
128 }
129 os << std::endl;
130 }
131 }
132
133 os << " ]" << std::endl;
134 os << " }";
135
136 prevDone = true;
137 }
138
139 if (hasPerVertexNormal)
140 {
141 if (prevDone)
142 {
143 os << "," << std::endl;
144 os << std::endl;
145 }
146 os << " {" << std::endl;
147 os << " \"name\" : \"normal_buffer\"," << std::endl;
148 os << " \"size\" : 3," << std::endl;
149 os << " \"type\" : \"float32\"," << std::endl;
150 os << " \"normalized\" : false," << std::endl;
151 os << " \"values\" :" << std::endl;
152 os << " [" << std::endl;
153
154 size_t it = 0;
155 const size_t sz = cm.vert.size();
156 while (it < sz)
157 {
158 const size_t n = std::min(it + maxValuesPerLine, sz);
159 if (n > 0)
160 {
161 os << " ";
162 {
163 const CMeshO::VertexType::NormalType & n = cm.vert[it].cN();
164 os << n[0] << ", " << n[1] << ", " << n[2];
165 it++;
166 }
167 for (; it<n; ++it)
168 {
169 const CMeshO::VertexType::NormalType & n = cm.vert[it].cN();
170 os << ", " << n[0] << ", " << n[1] << ", " << n[2];
171 }
172 if (it <= (sz - 1))
173 {
174 os << ",";
175 }
176 os << std::endl;
177 }
178 }
179
180 os << " ]" << std::endl;
181 os << " }";
182
183 prevDone = true;
184 }
185
186 if (hasPerVertexColor)
187 {
188 if (prevDone)
189 {
190 os << "," << std::endl;
191 os << std::endl;
192 }
193 os << " {" << std::endl;
194 os << " \"name\" : \"color_buffer\"," << std::endl;
195 os << " \"size\" : 4," << std::endl;
196 os << " \"type\" : \"uint8\"," << std::endl;
197 os << " \"normalized\" : true," << std::endl;
198 os << " \"values\" :" << std::endl;
199 os << " [" << std::endl;
200
201 size_t it = 0;
202 const size_t sz = cm.vert.size();
203 while (it < sz)
204 {
205 const size_t n = std::min(it + maxValuesPerLine, sz);
206 if (n > 0)
207 {
208 os << " ";
209 {
210 const CMeshO::VertexType::ColorType & c = cm.vert[it].cC();
211 os << int(c[0]) << ", " << int(c[1]) << ", " << int(c[2]) << ", " << int(c[3]);
212 it++;
213 }
214 for (; it<n; ++it)
215 {
216 const CMeshO::VertexType::ColorType & c = cm.vert[it].cC();
217 os << ", " << int(c[0]) << ", " << int(c[1]) << ", " << int(c[2]) << ", " << int(c[3]);
218 }
219 if (it <= (sz - 1))
220 {
221 os << ",";
222 }
223 os << std::endl;
224 }
225 }
226
227 os << " ]" << std::endl;
228 os << " }";
229
230 prevDone = true;
231 }
232
233 if (hasPerVertexTexCoord)
234 {
235 if (prevDone)
236 {
237 os << "," << std::endl;
238 os << std::endl;
239 }
240 os << " {" << std::endl;
241 os << " \"name\" : \"texcoord_buffer\"," << std::endl;
242 os << " \"size\" : 2," << std::endl;
243 os << " \"type\" : \"float32\"," << std::endl;
244 os << " \"normalized\" : false," << std::endl;
245 os << " \"values\" :" << std::endl;
246 os << " [" << std::endl;
247
248 size_t it = 0;
249 const size_t sz = cm.vert.size();
250 while (it < sz)
251 {
252 const size_t n = std::min(it + maxValuesPerLine, sz);
253 if (n > 0)
254 {
255 os << " ";
256 {
257 const CMeshO::VertexType::TexCoordType & t = cm.vert[it].cT();
258 os << t.P()[0] << ", " << t.P()[1];
259 it++;
260 }
261 for (; it<n; ++it)
262 {
263 const CMeshO::VertexType::TexCoordType & t = cm.vert[it].cT();
264 os << ", " << t.P()[0] << ", " << t.P()[1];
265 }
266 if (it <= (sz - 1))
267 {
268 os << ",";
269 }
270 os << std::endl;
271 }
272 }
273
274 os << " ]" << std::endl;
275 os << " }";
276
277 prevDone = true;
278 }
279
280 if (prevDone)
281 {
282 os << std::endl;
283 }
284
285 os << " ]," << std::endl;
286 os << std::endl;
287
288 os << " \"connectivity\" :" << std::endl;
289 os << " [" << std::endl;
290
291 if ((m.cm.vn > 0) && (m.cm.fn > 0))
292 {
293 os << " {" << std::endl;
294 os << " \"name\" : \"triangles\"," << std::endl;
295 os << " \"mode\" : \"triangles_list\"," << std::endl;
296 os << " \"indexed\" : true," << std::endl;
297 os << " \"indexType\" : \"uint32\"," << std::endl;
298 os << " \"indices\" :" << std::endl;
299 os << " [" << std::endl;
300 {
301 const CMeshO::VertexType * v0 = &(m.cm.vert[0]);
302
303 size_t k = 0;
304 size_t c = 0;
305 const size_t sz = cm.fn;
306 while (c < sz)
307 {
308 const size_t n = std::min(c + maxValuesPerLine, sz);
309 if (n > 0)
310 {
311 os << " ";
312 {
313 while (cm.face[k].IsD()) k++;
314 const CMeshO::FaceType & f = cm.face[k];
315 os << int(f.cV(0) - v0) << ", " << int(f.cV(1) - v0) << ", " << int(f.cV(2) - v0);
316 c++;
317 k++;
318 }
319 for (; c<n; ++c)
320 {
321 while (cm.face[k].IsD()) k++;
322 const CMeshO::FaceType & f = cm.face[k];
323 os << ", " << int(f.cV(0) - v0) << ", " << int(f.cV(1) - v0) << ", " << int(f.cV(2) - v0);
324 k++;
325 }
326 if (c <= (sz - 1))
327 {
328 os << ",";
329 }
330 os << std::endl;
331 }
332 }
333 }
334 os << " ]" << std::endl;
335 os << " }" << std::endl;
336 }
337
338 os << " ]," << std::endl;
339 os << std::endl;
340
341 os << " \"mapping\" :" << std::endl;
342 os << " [" << std::endl;
343 if ((m.cm.vn > 0) && (m.cm.fn > 0))
344 {
345 os << " {" << std::endl;
346 os << " \"name\" : \"standard\"," << std::endl;
347 os << " \"primitives\" : \"triangles\"," << std::endl;
348 os << " \"attributes\" :" << std::endl;
349 os << " [" << std::endl;
350
351 prevDone = false;
352 if (hasPerVertexPosition)
353 {
354 os << " {" << std::endl;
355 os << " \"source\" : \"position_buffer\"," << std::endl;
356 os << " \"semantic\" : \"position\"," << std::endl;
357 os << " \"set\" : 0" << std::endl;
358 os << " }";
359 prevDone = true;
360 }
361 if (hasPerVertexNormal)
362 {
363 if (prevDone)
364 {
365 os << "," << std::endl;
366 }
367 os << " {" << std::endl;
368 os << " \"source\" : \"normal_buffer\"," << std::endl;
369 os << " \"semantic\" : \"normal\"," << std::endl;
370 os << " \"set\" : 0" << std::endl;
371 os << " }";
372 prevDone = true;
373 }
374 if (hasPerVertexColor)
375 {
376 if (prevDone)
377 {
378 os << "," << std::endl;
379 }
380 os << " {" << std::endl;
381 os << " \"source\" : \"color_buffer\"," << std::endl;
382 os << " \"semantic\" : \"color\"," << std::endl;
383 os << " \"set\" : 0" << std::endl;
384 os << " }";
385 prevDone = true;
386 }
387 if (hasPerVertexTexCoord)
388 {
389 if (prevDone)
390 {
391 os << "," << std::endl;
392 }
393 os << " {" << std::endl;
394 os << " \"source\" : \"texcoord_buffer\"," << std::endl;
395 os << " \"semantic\" : \"texcoord\"," << std::endl;
396 os << " \"set\" : 0" << std::endl;
397 os << " }";
398 prevDone = true;
399 }
400
401 if (prevDone)
402 {
403 os << std::endl;
404 }
405
406 os << " ]" << std::endl;
407 os << " }" << std::endl;
408 }
409 os << " ]," << std::endl;
410 os << std::endl;
411
412 os << " \"custom\" : null" << std::endl;
413
414 os << "}" << std::endl;
415
416 os.close();
417
418 return true;
419 }
420
421 /*
422 returns the list of the file's type which can be imported
423 */
importFormats(void) const424 QList<MeshIOInterface::Format> JSONIOPlugin::importFormats(void) const
425 {
426 QList<Format> formatList;
427 //formatList << Format("JavaScript JSON", tr("JSON"));
428 return formatList;
429 }
430
431 /*
432 returns the list of the file's type which can be exported
433 */
exportFormats(void) const434 QList<MeshIOInterface::Format> JSONIOPlugin::exportFormats(void) const
435 {
436 QList<Format> formatList;
437 formatList << Format("JavaScript JSON", tr("JSON"));
438 return formatList;
439 }
440
441 /*
442 returns the mask on the basis of the file's type.
443 otherwise it returns 0 if the file format is unknown
444 */
GetExportMaskCapability(QString & format,int & capability,int & defaultBits) const445 void JSONIOPlugin::GetExportMaskCapability(QString & format, int & capability, int & defaultBits) const
446 {
447 capability = 0;
448
449 if (format.toUpper() == tr("JSON"))
450 {
451 // vertex
452 capability |= vcg::tri::io::Mask::IOM_VERTNORMAL;
453 capability |= vcg::tri::io::Mask::IOM_VERTCOLOR;
454 capability |= vcg::tri::io::Mask::IOM_VERTTEXCOORD;
455
456 // face
457 //capability |= vcg::tri::io::Mask::IOM_FACECOLOR;
458 //capability |= vcg::tri::io::Mask::IOM_FACENORMAL;
459
460 // wedge
461 //capability |= vcg::tri::io::Mask::IOM_WEDGTEXCOORD;
462 //capability |= vcg::tri::io::Mask::IOM_WEDGNORMAL;
463 //capability |= vcg::tri::io::Mask::IOM_WEDGCOLOR;
464
465 defaultBits = capability;
466 }
467 }
468
469 MESHLAB_PLUGIN_NAME_EXPORTER(JSONIOPlugin)
470