2020-11-25 12:30:01 +01:00

474 lines
12 KiB
C++

/****************************************************************************
* MeshLab o o *
* An extendible mesh processor o o *
* _ O _ *
* Copyright(C) 2005, 2006 \/)\/ *
* Visual Computing Lab /\/| *
* ISTI - Italian National Research Council | *
* \ *
* All rights reserved. *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
* for more details. *
* *
****************************************************************************/
#include "io_json.h"
#include <string>
#include <fstream>
#include <vcg/complex/algorithms/attribute_seam.h>
#include <QString>
#include <QFile>
JSONIOPlugin::JSONIOPlugin(void) : IOMeshPluginInterface()
{
;
}
JSONIOPlugin::~JSONIOPlugin(void)
{
;
}
QString JSONIOPlugin::pluginName() const
{
return "IOJson";
}
bool JSONIOPlugin::open(const QString & formatName, const QString & fileName, MeshModel & m, int & mask, const RichParameterList & parlst, vcg::CallBackPos * cb, QWidget * /*parent*/)
{
(void)formatName;
(void)fileName;
(void)m;
(void)mask;
(void)parlst;
(void)cb;
return false;
}
bool JSONIOPlugin::save(const QString & formatName,const QString & fileName, MeshModel & m, const int mask, const RichParameterList & par, vcg::CallBackPos * cb, QWidget * parent)
{
(void)par;
(void)cb;
(void)parent;
vcg::tri::Allocator<CMeshO>::CompactVertexVector(m.cm);
vcg::tri::Allocator<CMeshO>::CompactFaceVector(m.cm);
const size_t maxValuesPerLine = 10; // must be > 0
if (formatName.toUpper() != tr("JSON")) return false;
const bool hasPerVertexPosition = true;
const bool hasPerVertexNormal = ((mask & vcg::tri::io::Mask::IOM_VERTNORMAL) != 0) && m.hasDataMask(MeshModel::MM_VERTNORMAL);
const bool hasPerVertexColor = ((mask & vcg::tri::io::Mask::IOM_VERTCOLOR) != 0) && m.hasDataMask(MeshModel::MM_VERTCOLOR);
const bool hasPerVertexTexCoord = ((mask & vcg::tri::io::Mask::IOM_VERTTEXCOORD) != 0) && m.hasDataMask(MeshModel::MM_VERTTEXCOORD);
const CMeshO & cm = m.cm;
const std::string filename = QFile::encodeName(fileName).constData();
std::ofstream os(filename.c_str());
if (!os.is_open()) return false;
os << "{" << std::endl;
os << " \"version\" : \"0.1.0\"," << std::endl;
os << std::endl;
os << " \"comment\" : \"Generated by MeshLab JSON Exporter\"," << std::endl;
os << std::endl;
os << " \"id\" : 1," << std::endl;
os << " \"name\" : \"mesh\"," << std::endl;
os << std::endl;
os << " \"vertices\" :" << std::endl;
os << " [" << std::endl;
bool prevDone = false;
if (hasPerVertexPosition)
{
os << " {" << std::endl;
os << " \"name\" : \"position_buffer\"," << std::endl;
os << " \"size\" : 3," << std::endl;
os << " \"type\" : \"float32\"," << std::endl;
os << " \"normalized\" : false," << std::endl;
os << " \"values\" :" << std::endl;
os << " [" << std::endl;
size_t it = 0;
const size_t sz = cm.vert.size();
while (it < sz)
{
const size_t n = std::min(it + maxValuesPerLine, sz);
if (n > 0)
{
os << " ";
{
const CMeshO::VertexType::CoordType & p = cm.vert[it].cP();
os << p[0] << ", " << p[1] << ", " << p[2];
it++;
}
for (; it<n; ++it)
{
const CMeshO::VertexType::CoordType & p = cm.vert[it].cP();
os << ", " << p[0] << ", " << p[1] << ", " << p[2];
}
if (it <= (sz - 1))
{
os << ",";
}
os << std::endl;
}
}
os << " ]" << std::endl;
os << " }";
prevDone = true;
}
if (hasPerVertexNormal)
{
if (prevDone)
{
os << "," << std::endl;
os << std::endl;
}
os << " {" << std::endl;
os << " \"name\" : \"normal_buffer\"," << std::endl;
os << " \"size\" : 3," << std::endl;
os << " \"type\" : \"float32\"," << std::endl;
os << " \"normalized\" : false," << std::endl;
os << " \"values\" :" << std::endl;
os << " [" << std::endl;
size_t it = 0;
const size_t sz = cm.vert.size();
while (it < sz)
{
const size_t n = std::min(it + maxValuesPerLine, sz);
if (n > 0)
{
os << " ";
{
const CMeshO::VertexType::NormalType & n = cm.vert[it].cN();
os << n[0] << ", " << n[1] << ", " << n[2];
it++;
}
for (; it<n; ++it)
{
const CMeshO::VertexType::NormalType & n = cm.vert[it].cN();
os << ", " << n[0] << ", " << n[1] << ", " << n[2];
}
if (it <= (sz - 1))
{
os << ",";
}
os << std::endl;
}
}
os << " ]" << std::endl;
os << " }";
prevDone = true;
}
if (hasPerVertexColor)
{
if (prevDone)
{
os << "," << std::endl;
os << std::endl;
}
os << " {" << std::endl;
os << " \"name\" : \"color_buffer\"," << std::endl;
os << " \"size\" : 4," << std::endl;
os << " \"type\" : \"uint8\"," << std::endl;
os << " \"normalized\" : true," << std::endl;
os << " \"values\" :" << std::endl;
os << " [" << std::endl;
size_t it = 0;
const size_t sz = cm.vert.size();
while (it < sz)
{
const size_t n = std::min(it + maxValuesPerLine, sz);
if (n > 0)
{
os << " ";
{
const CMeshO::VertexType::ColorType & c = cm.vert[it].cC();
os << int(c[0]) << ", " << int(c[1]) << ", " << int(c[2]) << ", " << int(c[3]);
it++;
}
for (; it<n; ++it)
{
const CMeshO::VertexType::ColorType & c = cm.vert[it].cC();
os << ", " << int(c[0]) << ", " << int(c[1]) << ", " << int(c[2]) << ", " << int(c[3]);
}
if (it <= (sz - 1))
{
os << ",";
}
os << std::endl;
}
}
os << " ]" << std::endl;
os << " }";
prevDone = true;
}
if (hasPerVertexTexCoord)
{
if (prevDone)
{
os << "," << std::endl;
os << std::endl;
}
os << " {" << std::endl;
os << " \"name\" : \"texcoord_buffer\"," << std::endl;
os << " \"size\" : 2," << std::endl;
os << " \"type\" : \"float32\"," << std::endl;
os << " \"normalized\" : false," << std::endl;
os << " \"values\" :" << std::endl;
os << " [" << std::endl;
size_t it = 0;
const size_t sz = cm.vert.size();
while (it < sz)
{
const size_t n = std::min(it + maxValuesPerLine, sz);
if (n > 0)
{
os << " ";
{
const CMeshO::VertexType::TexCoordType & t = cm.vert[it].cT();
os << t.P()[0] << ", " << t.P()[1];
it++;
}
for (; it<n; ++it)
{
const CMeshO::VertexType::TexCoordType & t = cm.vert[it].cT();
os << ", " << t.P()[0] << ", " << t.P()[1];
}
if (it <= (sz - 1))
{
os << ",";
}
os << std::endl;
}
}
os << " ]" << std::endl;
os << " }";
prevDone = true;
}
if (prevDone)
{
os << std::endl;
}
os << " ]," << std::endl;
os << std::endl;
os << " \"connectivity\" :" << std::endl;
os << " [" << std::endl;
if ((m.cm.vn > 0) && (m.cm.fn > 0))
{
os << " {" << std::endl;
os << " \"name\" : \"triangles\"," << std::endl;
os << " \"mode\" : \"triangles_list\"," << std::endl;
os << " \"indexed\" : true," << std::endl;
os << " \"indexType\" : \"uint32\"," << std::endl;
os << " \"indices\" :" << std::endl;
os << " [" << std::endl;
{
const CMeshO::VertexType * v0 = &(m.cm.vert[0]);
size_t k = 0;
size_t c = 0;
const size_t sz = cm.fn;
while (c < sz)
{
const size_t n = std::min(c + maxValuesPerLine, sz);
if (n > 0)
{
os << " ";
{
while (cm.face[k].IsD()) k++;
const CMeshO::FaceType & f = cm.face[k];
os << int(f.cV(0) - v0) << ", " << int(f.cV(1) - v0) << ", " << int(f.cV(2) - v0);
c++;
k++;
}
for (; c<n; ++c)
{
while (cm.face[k].IsD()) k++;
const CMeshO::FaceType & f = cm.face[k];
os << ", " << int(f.cV(0) - v0) << ", " << int(f.cV(1) - v0) << ", " << int(f.cV(2) - v0);
k++;
}
if (c <= (sz - 1))
{
os << ",";
}
os << std::endl;
}
}
}
os << " ]" << std::endl;
os << " }" << std::endl;
}
os << " ]," << std::endl;
os << std::endl;
os << " \"mapping\" :" << std::endl;
os << " [" << std::endl;
if ((m.cm.vn > 0) && (m.cm.fn > 0))
{
os << " {" << std::endl;
os << " \"name\" : \"standard\"," << std::endl;
os << " \"primitives\" : \"triangles\"," << std::endl;
os << " \"attributes\" :" << std::endl;
os << " [" << std::endl;
prevDone = false;
if (hasPerVertexPosition)
{
os << " {" << std::endl;
os << " \"source\" : \"position_buffer\"," << std::endl;
os << " \"semantic\" : \"position\"," << std::endl;
os << " \"set\" : 0" << std::endl;
os << " }";
prevDone = true;
}
if (hasPerVertexNormal)
{
if (prevDone)
{
os << "," << std::endl;
}
os << " {" << std::endl;
os << " \"source\" : \"normal_buffer\"," << std::endl;
os << " \"semantic\" : \"normal\"," << std::endl;
os << " \"set\" : 0" << std::endl;
os << " }";
prevDone = true;
}
if (hasPerVertexColor)
{
if (prevDone)
{
os << "," << std::endl;
}
os << " {" << std::endl;
os << " \"source\" : \"color_buffer\"," << std::endl;
os << " \"semantic\" : \"color\"," << std::endl;
os << " \"set\" : 0" << std::endl;
os << " }";
prevDone = true;
}
if (hasPerVertexTexCoord)
{
if (prevDone)
{
os << "," << std::endl;
}
os << " {" << std::endl;
os << " \"source\" : \"texcoord_buffer\"," << std::endl;
os << " \"semantic\" : \"texcoord\"," << std::endl;
os << " \"set\" : 0" << std::endl;
os << " }";
prevDone = true;
}
if (prevDone)
{
os << std::endl;
}
os << " ]" << std::endl;
os << " }" << std::endl;
}
os << " ]," << std::endl;
os << std::endl;
os << " \"custom\" : null" << std::endl;
os << "}" << std::endl;
os.close();
return true;
}
/*
returns the list of the file's type which can be imported
*/
QList<FileFormat> JSONIOPlugin::importFormats(void) const
{
QList<FileFormat> formatList;
//formatList << Format("JavaScript JSON", tr("JSON"));
return formatList;
}
/*
returns the list of the file's type which can be exported
*/
QList<FileFormat> JSONIOPlugin::exportFormats(void) const
{
QList<FileFormat> formatList;
formatList << FileFormat("JavaScript JSON", tr("JSON"));
return formatList;
}
/*
returns the mask on the basis of the file's type.
otherwise it returns 0 if the file format is unknown
*/
void JSONIOPlugin::GetExportMaskCapability(const QString & format, int & capability, int & defaultBits) const
{
capability = 0;
if (format.toUpper() == tr("JSON"))
{
// vertex
capability |= vcg::tri::io::Mask::IOM_VERTNORMAL;
capability |= vcg::tri::io::Mask::IOM_VERTCOLOR;
capability |= vcg::tri::io::Mask::IOM_VERTTEXCOORD;
// face
//capability |= vcg::tri::io::Mask::IOM_FACECOLOR;
//capability |= vcg::tri::io::Mask::IOM_FACENORMAL;
// wedge
//capability |= vcg::tri::io::Mask::IOM_WEDGTEXCOORD;
//capability |= vcg::tri::io::Mask::IOM_WEDGNORMAL;
//capability |= vcg::tri::io::Mask::IOM_WEDGCOLOR;
defaultBits = capability;
}
}
MESHLAB_PLUGIN_NAME_EXPORTER(JSONIOPlugin)