add vcglib
This commit is contained in:
1 parent
6f6c0c8eb7
commit
af8100f851
1537 files changed
+634197
No files matched your search
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,139 @@
|
||||
#ifndef POLY_TRIANGULATOR_H
|
||||
#define POLY_TRIANGULATOR_H
|
||||
|
||||
#include "util_dae.h"
|
||||
#include <wrap/gl/glu_tesselator.h>
|
||||
|
||||
namespace vcg {
|
||||
namespace tri {
|
||||
namespace io {
|
||||
// These two classes is used for temporary storing of the
|
||||
// collected data of the polgons during the reading of files.
|
||||
|
||||
template<typename VERTEX_TYPE>
|
||||
class MyPolygon
|
||||
{
|
||||
public:
|
||||
typedef VERTEX_TYPE BaseVertexType;
|
||||
|
||||
int _nvert;
|
||||
std::vector<VERTEX_TYPE*> _pv;
|
||||
std::vector< vcg::TexCoord2<float> > _txc;
|
||||
|
||||
|
||||
MyPolygon(int n)
|
||||
:_nvert(n),_pv(_nvert),_txc(_nvert)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template<typename POLYGONAL_TYPE>
|
||||
class PolygonalMesh
|
||||
{
|
||||
public:
|
||||
typedef POLYGONAL_TYPE FaceType;
|
||||
|
||||
enum PERWEDGEATTRIBUTETYPE {NONE = 0,NORMAL = 1,MULTITEXTURECOORD = 2,MULTICOLOR = 4};
|
||||
|
||||
typedef typename FaceType::BaseVertexType VertexType;
|
||||
typedef VertexType* VertexPointer;
|
||||
typedef typename std::vector<VertexType>::iterator VertexIterator;
|
||||
typedef typename std::vector<FaceType>::iterator PolygonIterator;
|
||||
|
||||
vcg::Box3<float> bbox;
|
||||
|
||||
std::vector<VertexType> vert;
|
||||
std::vector<FaceType> _pols;
|
||||
|
||||
void generatePointsVector(std::vector<std::vector<vcg::Point3f> >& v)
|
||||
{
|
||||
for(typename PolygonalMesh::PolygonIterator itp = _pols.begin();itp != _pols.end();++itp)
|
||||
{
|
||||
v.push_back(std::vector<vcg::Point3f>());
|
||||
for(typename std::vector<VertexPointer>::iterator itv = itp->_pv.begin();itv != itp->_pv.end();++itv)
|
||||
{
|
||||
v[v.size() - 1].push_back((*itv)->P());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void usePerWedgeAttributes(PERWEDGEATTRIBUTETYPE att,const unsigned int multitexture = 1,const unsigned int multicolor = 1)
|
||||
{
|
||||
if (att != NONE)
|
||||
{
|
||||
for(PolygonIterator itp = _pols.begin();itp != _pols.end();++itp)
|
||||
{
|
||||
if (att & MULTICOLOR) itp->usePerWedgeColor(multicolor);
|
||||
if (att & MULTITEXTURECOORD) itp->usePerWedgeMultiTexture(multitexture);
|
||||
if (att & NORMAL) itp->usePerWedgeNormal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<class TRIMESH>
|
||||
void triangulate(TRIMESH& mesh)
|
||||
{
|
||||
std::vector<std::vector<vcg::Point3f> > pl;
|
||||
mesh.vert.resize(vert.size());
|
||||
int multicoor = 0;
|
||||
//PolygonalMesh's points has been copied in TriangularMesh
|
||||
for(size_t jj = 0;jj < mesh.vert.size();++jj)
|
||||
mesh.vert[jj].P() = vert[jj].P();
|
||||
|
||||
bool texen = mesh.face.IsWedgeTexEnabled();
|
||||
unsigned int totaltri = 0;
|
||||
for(size_t ii = 0;ii < _pols.size();++ii)
|
||||
totaltri += _pols[ii]._nvert - 2;
|
||||
|
||||
mesh.face.resize(totaltri);
|
||||
|
||||
//transform the polygonal mesh in a vector<vector<Point>>
|
||||
generatePointsVector(pl);
|
||||
|
||||
|
||||
int trioff = 0;
|
||||
//foreach Polygon
|
||||
for(size_t ii = 0;ii < pl.size();++ii)
|
||||
{
|
||||
std::vector<int> tx;
|
||||
std::vector<std::vector<vcg::Point3f> > pl2(1);
|
||||
pl2[0] = pl[ii];
|
||||
|
||||
vcg::glu_tesselator::tesselate(pl2,tx);
|
||||
size_t ntri = tx.size() / 3;
|
||||
assert(tx.size() % 3 == 0);
|
||||
|
||||
|
||||
int polvert = 0;
|
||||
//foreach triangle
|
||||
for(size_t tr = 0;tr < ntri;++tr)
|
||||
{
|
||||
|
||||
//typename TRIMESH::FaceType& f = mesh.face[tr];
|
||||
|
||||
//typename TRIMESH::FaceType& f = mesh.face[tr];
|
||||
for(unsigned int tt = 0;tt < 3; ++tt)
|
||||
{
|
||||
mesh.face[trioff + tr].V(tt) = &(mesh.vert[_pols[ii]._pv[tx[3 * tr + tt]] - &(vert[0])]);
|
||||
//vcg::Point3f ppp = mesh.face[tr].V(tt)->P();
|
||||
if (texen)
|
||||
{
|
||||
/* f.WT(multicoor).U() = _pols[ii]._txc[polvert].U();
|
||||
f.WT(multicoor).V() = _pols[ii]._txc[polvert].V();
|
||||
f.WT(multicoor).N() = _pols[ii]._txc[polvert].N();*/
|
||||
|
||||
}
|
||||
polvert = (polvert + 1) % _pols[ii]._nvert;
|
||||
}
|
||||
//mesh.face.push_back(f);
|
||||
}
|
||||
trioff += ntri;
|
||||
}
|
||||
assert(trioff == totaltri);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,442 @@
|
||||
/****************************************************************************
|
||||
* VCGLib o o *
|
||||
* Visual and Computer Graphics Library o o *
|
||||
* _ O _ *
|
||||
* Copyright(C) 2004-2008 \/)\/ *
|
||||
* 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. *
|
||||
* *
|
||||
****************************************************************************/
|
||||
#ifndef __VCGLIB_UTILDAE
|
||||
#define __VCGLIB_UTILDAE
|
||||
|
||||
|
||||
#include <wrap/io_trimesh/additionalinfo.h>
|
||||
#include <vcg/complex/algorithms/update/normal.h>
|
||||
#include <vcg/complex/algorithms/update/position.h>
|
||||
|
||||
#include <wrap/io_trimesh/io_mask.h>
|
||||
|
||||
#include <QDomDocument>
|
||||
#include <QFile>
|
||||
#include <QXmlStreamWriter>
|
||||
#include <QStringList>
|
||||
#include <QMap>
|
||||
|
||||
#include <vcg/space/point3.h>
|
||||
#include <vcg/space/texcoord2.h>
|
||||
#include <vcg/space/color4.h>
|
||||
#include <vcg/space/texcoord2.h>
|
||||
#include <wrap/callback.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace vcg {
|
||||
namespace tri {
|
||||
namespace io {
|
||||
class InfoDAE : public AdditionalInfo
|
||||
{
|
||||
public:
|
||||
|
||||
InfoDAE() :AdditionalInfo(){
|
||||
doc = NULL;
|
||||
textureIdMap.clear();
|
||||
}
|
||||
|
||||
~InfoDAE(){
|
||||
if(doc!=NULL) delete doc;
|
||||
}
|
||||
|
||||
QDomDocument* doc;
|
||||
QMap<QString,int> textureIdMap;
|
||||
};
|
||||
|
||||
class UtilDAE
|
||||
{
|
||||
public:
|
||||
enum DAEError
|
||||
{
|
||||
E_NOERROR, // 0
|
||||
E_CANTOPEN, // 1
|
||||
E_NOGEOMETRYLIBRARY, // 2
|
||||
E_NOMESH, // 3
|
||||
E_NOVERTEXPOSITION, // 4
|
||||
E_NO3DVERTEXPOSITION, // 5
|
||||
E_NO3DSCENE, // 6
|
||||
E_INCOMPATIBLECOLLADA141FORMAT, //7
|
||||
E_UNREFERENCEBLEDCOLLADAATTRIBUTE, // 8
|
||||
E_NOPOLYGONALMESH, //9
|
||||
E_CANTSAVE, //10
|
||||
E_NOACCESSORELEMENT
|
||||
};
|
||||
|
||||
|
||||
static const char *ErrorMsg(int error)
|
||||
{
|
||||
static const char * dae_error_msg[] =
|
||||
{
|
||||
"No errors",
|
||||
"Can't open file",
|
||||
"File without a geometry library",
|
||||
"There isn't mesh in file",
|
||||
"The meshes in file haven't the vertex position attribute",
|
||||
"The importer assumes that the OpenMeshType uses a 3D point for the vertex position",
|
||||
"There isn't any scene in Collada file",
|
||||
"The input file is not compatible with COLLADA 1.41 standard format",
|
||||
"Collada file is trying to reference an attribute that is not in the file",
|
||||
"This version of Collada Importer support only triangular and polygonal mesh file"
|
||||
};
|
||||
|
||||
if(error>9 || error<0) return "Unknown error";
|
||||
else return dae_error_msg[error];
|
||||
};
|
||||
protected:
|
||||
// This function take care of removing the standard '#' from the beginning of the url
|
||||
// For example
|
||||
// <instance_geometry url="#shape0-lib">
|
||||
// means that you have to search in the <library_geometries> for a node <geometry> with id = "shape0-lib"
|
||||
// you have to call this function to get the right reference name
|
||||
|
||||
inline static void referenceToANodeAttribute(const QDomNode n,const QString& attr,QString& url_st)
|
||||
{
|
||||
url_st = n.toElement().attribute(attr);
|
||||
int sz = url_st.size() - 1;
|
||||
url_st = url_st.right(sz);
|
||||
assert(url_st.size() != 0);
|
||||
}
|
||||
|
||||
inline static QDomNode findNodeBySpecificAttributeValue(const QDomNodeList& ndl,const QString& attrname,const QString& attrvalue)
|
||||
{
|
||||
int ndl_size = ndl.size();
|
||||
int ind = 0;
|
||||
while(ind < ndl_size)
|
||||
{
|
||||
QString st = ndl.at(ind).toElement().attribute(attrname);
|
||||
if (st == attrvalue)
|
||||
return ndl.at(ind);
|
||||
++ind;
|
||||
}
|
||||
return QDomNode();
|
||||
}
|
||||
|
||||
inline static QDomNode findNodeBySpecificAttributeValue(const QDomNode n,const QString& tag,const QString& attrname,const QString& attrvalue)
|
||||
{
|
||||
return findNodeBySpecificAttributeValue(n.toElement().elementsByTagName(tag),attrname,attrvalue);
|
||||
}
|
||||
|
||||
inline static QDomNode findNodeBySpecificAttributeValue(const QDomDocument n,const QString& tag,const QString& attrname,const QString& attrvalue)
|
||||
{
|
||||
return findNodeBySpecificAttributeValue(n.elementsByTagName(tag),attrname,attrvalue);
|
||||
}
|
||||
|
||||
inline static bool isThereTag(const QDomNodeList& list)
|
||||
{
|
||||
return ((list.size() > 0) ? true : false);
|
||||
}
|
||||
|
||||
inline static bool isThereTag(const QDomNode n,const QString& tagname)
|
||||
{
|
||||
return isThereTag(n.toElement().elementsByTagName(tagname));
|
||||
}
|
||||
|
||||
inline static bool isThereTag(const QDomDocument n,const QString& tagname)
|
||||
{
|
||||
return isThereTag(n.elementsByTagName(tagname));
|
||||
}
|
||||
|
||||
// Very important function that given a <vertices> element find one of the its attribute (like position, color etc)
|
||||
inline static QDomNode attributeSourcePerSimplex(const QDomNode n,const QDomDocument startpoint,const QString& sem)
|
||||
{
|
||||
QDomNodeList vertattr = n.toElement().elementsByTagName("input");
|
||||
for(int ind = 0;ind < vertattr.size();++ind)
|
||||
{
|
||||
if (vertattr.at(ind).toElement().attribute("semantic") == sem)
|
||||
{
|
||||
QString url;
|
||||
referenceToANodeAttribute(vertattr.at(ind),"source",url);
|
||||
return findNodeBySpecificAttributeValue(startpoint,"source","id",url);
|
||||
}
|
||||
}
|
||||
return QDomNode();
|
||||
}
|
||||
|
||||
// This function is used to build up a list of strings that are scalar values.
|
||||
inline static void valueStringList(QStringList& res,const QDomNode srcnode,const QString& tag)
|
||||
{
|
||||
QDomNodeList list = srcnode.toElement().elementsByTagName(tag);
|
||||
//assert(list.size() == 1);
|
||||
QString nd = list.at(0).firstChild().nodeValue();
|
||||
res = nd.simplified().split(" ",QString::SkipEmptyParts);
|
||||
if(res.empty())
|
||||
{
|
||||
qDebug("Warning valueStringList returned and empty list. nothing inside element with tag '%s'", qPrintable(tag));
|
||||
return;
|
||||
}
|
||||
if (res.last() == "")
|
||||
res.removeLast();
|
||||
|
||||
// int emptyCount = res.removeAll(QString(""));
|
||||
// if(emptyCount>0) qDebug("- - - - - - - - valueStringList: Removed %i null strings when parsing tag %s",emptyCount,qPrintable(tag));
|
||||
// for(int i =0;i<res.size();++i)
|
||||
// qDebug("- - - - - - - - - - - - %3i = '%s'",i,qPrintable(res.at(i)));
|
||||
|
||||
}
|
||||
|
||||
/*inline static bool removeChildNode(QDomNodeList*/
|
||||
|
||||
inline static bool removeChildNodeList(QDomNodeList& nodelst,const QString& tag = "", const QString& attribname = "", const QString& attribvalue = "")
|
||||
{
|
||||
for(int jj = 0;jj < nodelst.size();++jj)
|
||||
{
|
||||
removeChildNode(nodelst.at(jj),tag,attribname,attribvalue);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
inline static bool removeChildNode(QDomNode node,const QString& tag = "", const QString& attribname = "", const QString& attribvalue = "")
|
||||
{
|
||||
QDomNodeList clst = node.childNodes();
|
||||
for(int ii = 0;ii < clst.size();++ii)
|
||||
{
|
||||
QDomNode oldchild = node.childNodes().at(ii);
|
||||
if (tag != "")
|
||||
{
|
||||
if ((attribname != "") && (attribvalue != ""))
|
||||
{
|
||||
if (clst.at(ii).toElement().attribute(attribname) == attribvalue)
|
||||
node.removeChild(oldchild);
|
||||
}
|
||||
else
|
||||
{
|
||||
QString nm = clst.at(ii).nodeName();
|
||||
if (clst.at(ii).nodeName() == tag)
|
||||
{
|
||||
node.removeChild(oldchild);
|
||||
}
|
||||
}
|
||||
}
|
||||
else node.removeChild(oldchild);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void ParseRotationMatrix(vcg::Matrix44f& m,const std::vector<QDomNode>& t)
|
||||
{
|
||||
vcg::Matrix44f rotTmp;
|
||||
vcg::Matrix44f tmp;
|
||||
rotTmp.SetIdentity();
|
||||
tmp.SetIdentity();
|
||||
for(unsigned int ii = 0;ii < t.size();++ii)
|
||||
{
|
||||
QString rt = t[ii].firstChild().nodeValue();
|
||||
QStringList rtl = rt.split(" ");
|
||||
if (rtl.last() == "") rtl.removeLast();
|
||||
assert(rtl.size() == 4);
|
||||
tmp.SetRotateDeg(rtl.at(3).toFloat(),vcg::Point3f(rtl.at(0).toFloat(),rtl.at(1).toFloat(),rtl.at(2).toFloat()));
|
||||
rotTmp = rotTmp*tmp;
|
||||
}
|
||||
m = m * rotTmp;
|
||||
}
|
||||
|
||||
static void ParseTranslation(vcg::Matrix44f& m,const QDomNode t)
|
||||
{
|
||||
assert(t.toElement().tagName() == "translate");
|
||||
QDomNode tr = t.firstChild();
|
||||
QString coord = tr.nodeValue();
|
||||
QStringList coordlist = coord.split(" ");
|
||||
if (coordlist.last() == "")
|
||||
coordlist.removeLast();
|
||||
assert(coordlist.size() == 3);
|
||||
m[0][0] = 1.0f;
|
||||
m[1][1] = 1.0f;
|
||||
m[2][2] = 1.0f;
|
||||
m[3][3] = 1.0f;
|
||||
m[0][3] = coordlist.at(0).toFloat();
|
||||
m[1][3] = coordlist.at(1).toFloat();
|
||||
m[2][3] = coordlist.at(2).toFloat();
|
||||
}
|
||||
|
||||
static void ParseMatrixNode(vcg::Matrix44f& m,const QDomNode t)
|
||||
{
|
||||
assert(t.toElement().tagName() == "matrix");
|
||||
QDomNode tr = t.firstChild();
|
||||
QString coord = tr.nodeValue().simplified();
|
||||
qDebug("Parsing matrix node; text value is '%s'",qPrintable(coord));
|
||||
QStringList coordlist = coord.split(" ");
|
||||
if (coordlist.last() == "")
|
||||
coordlist.removeLast();
|
||||
assert(coordlist.size() == 16);
|
||||
for(int i=0;i<4;++i)
|
||||
{
|
||||
m[i][0] = coordlist.at(i*4+0).toFloat();
|
||||
m[i][1] = coordlist.at(i*4+1).toFloat();
|
||||
m[i][2] = coordlist.at(i*4+2).toFloat();
|
||||
m[i][3] = coordlist.at(i*4+3).toFloat();
|
||||
}
|
||||
}
|
||||
|
||||
static void TransfMatrix(const QDomNode parentnode,const QDomNode presentnode,vcg::Matrix44f& m)
|
||||
{
|
||||
if (presentnode == parentnode) return;
|
||||
else
|
||||
{
|
||||
QDomNode par = presentnode.parentNode();
|
||||
std::vector<QDomNode> rotlist;
|
||||
QDomNode trans;
|
||||
for(int ch = 0;ch < par.childNodes().size();++ch)
|
||||
{
|
||||
if (par.childNodes().at(ch).nodeName() == "rotate")
|
||||
rotlist.push_back(par.childNodes().at(ch));
|
||||
else if (par.childNodes().at(ch).nodeName() == "translate")
|
||||
{
|
||||
trans = par.childNodes().at(ch);
|
||||
}
|
||||
}
|
||||
vcg::Matrix44f tmp;
|
||||
tmp.SetIdentity();
|
||||
if (!trans.isNull()) ParseTranslation(tmp,trans);
|
||||
ParseRotationMatrix(tmp,rotlist);
|
||||
m = m * tmp;
|
||||
TransfMatrix(parentnode,par,m);
|
||||
}
|
||||
}
|
||||
|
||||
inline static int findOffSetForASingleSimplex(QDomNode node)
|
||||
{
|
||||
QDomNodeList wedatts = node.toElement().elementsByTagName("input");
|
||||
int max = 0;
|
||||
if (wedatts.size() == 0) return -1;
|
||||
else
|
||||
{
|
||||
for(int ii = 0;ii < wedatts.size();++ii)
|
||||
{
|
||||
int tmp = wedatts.at(ii).toElement().attribute("offset").toInt();
|
||||
if (tmp > max) max = tmp;
|
||||
}
|
||||
}
|
||||
return max + 1;
|
||||
}
|
||||
|
||||
inline static int findStringListAttribute(QStringList& list,const QDomNode node,const QDomNode poly,const QDomDocument startpoint,const char* token)
|
||||
{
|
||||
int offset = 0;
|
||||
if (!node.isNull())
|
||||
{
|
||||
offset = node.toElement().attribute("offset").toInt();
|
||||
QDomNode st = attributeSourcePerSimplex(poly,startpoint,token);
|
||||
valueStringList(list,st,"float_array");
|
||||
}
|
||||
return offset;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* Very important procedure
|
||||
it has the task to find the name of the image node corresponding to a given material id,
|
||||
it assuemes that the material name that is passed have already been bound with the current bindings
|
||||
*/
|
||||
|
||||
inline static QDomNode textureFinder(QString& boundMaterialName, QString &textureFileName, const QDomDocument doc)
|
||||
{
|
||||
boundMaterialName.remove('#');
|
||||
//library_material -> material -> instance_effect
|
||||
QDomNodeList lib_mat = doc.elementsByTagName("library_materials");
|
||||
if (lib_mat.size() != 1)
|
||||
return QDomNode();
|
||||
QDomNode material = findNodeBySpecificAttributeValue(lib_mat.at(0),QString("material"),QString("id"),boundMaterialName);
|
||||
if (material.isNull())
|
||||
return QDomNode();
|
||||
QDomNodeList in_eff = material.toElement().elementsByTagName("instance_effect");
|
||||
if (in_eff.size() == 0)
|
||||
return QDomNode();
|
||||
QString url = in_eff.at(0).toElement().attribute("url");
|
||||
if ((url.isNull()) || (url == ""))
|
||||
return QDomNode();
|
||||
url = url.remove('#');
|
||||
qDebug("====== searching among library_effects the effect with id '%s' ",qPrintable(url));
|
||||
//library_effects -> effect -> instance_effect
|
||||
QDomNodeList lib_eff = doc.elementsByTagName("library_effects");
|
||||
if (lib_eff.size() != 1)
|
||||
return QDomNode();
|
||||
QDomNode effect = findNodeBySpecificAttributeValue(lib_eff.at(0),QString("effect"),QString("id"),url);
|
||||
if (effect.isNull())
|
||||
return QDomNode();
|
||||
QDomNodeList init_from = effect.toElement().elementsByTagName("init_from");
|
||||
if (init_from.size() == 0)
|
||||
return QDomNode();
|
||||
QString img_id = init_from.at(0).toElement().text();
|
||||
if ((img_id.isNull()) || (img_id == ""))
|
||||
return QDomNode();
|
||||
|
||||
//library_images -> image
|
||||
QDomNodeList libraryImageNodeList = doc.elementsByTagName("library_images");
|
||||
qDebug("====== searching among library_images the effect with id '%s' ",qPrintable(img_id));
|
||||
if (libraryImageNodeList.size() != 1)
|
||||
return QDomNode();
|
||||
QDomNode imageNode = findNodeBySpecificAttributeValue(libraryImageNodeList.at(0),QString("image"),QString("id"),img_id);
|
||||
QDomNodeList initfromNode = imageNode.toElement().elementsByTagName("init_from");
|
||||
textureFileName= initfromNode.at(0).firstChild().nodeValue();
|
||||
qDebug("====== the image '%s' has a %i init_from nodes text '%s'",qPrintable(img_id),initfromNode.size(),qPrintable(textureFileName));
|
||||
|
||||
return imageNode;
|
||||
}
|
||||
|
||||
static int indexTextureByImgNode(const QDomDocument doc,const QDomNode node)
|
||||
{
|
||||
QDomNodeList libim = doc.elementsByTagName(QString("library_images"));
|
||||
if (libim.size() != 1)
|
||||
return -1;
|
||||
QDomNodeList imgs = libim.at(0).toElement().elementsByTagName("image");
|
||||
|
||||
int ii = 0;
|
||||
bool found = false;
|
||||
while((ii < imgs.size()) && (!found))
|
||||
{
|
||||
if (imgs.at(ii) == node)
|
||||
found = true;
|
||||
else ++ii;
|
||||
}
|
||||
if (found)
|
||||
return ii;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct WedgeAttribute
|
||||
{
|
||||
QDomNode wnsrc;
|
||||
QStringList wn;
|
||||
int offnm;
|
||||
|
||||
QDomNode wtsrc;
|
||||
QStringList wt;
|
||||
int stridetx;
|
||||
int offtx;
|
||||
|
||||
QDomNode wcsrc;
|
||||
QStringList wc;
|
||||
int stridecl;
|
||||
int offcl;
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,77 @@
|
||||
/****************************************************************************
|
||||
* VCGLib o o *
|
||||
* Visual and Computer Graphics Library o o *
|
||||
* _ O _ *
|
||||
* Copyright(C) 2004-2008 \/)\/ *
|
||||
* 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 <wrap/dae/xmldocumentmanaging.h>
|
||||
#include <cassert>
|
||||
|
||||
XMLNode::XMLNode(XMLTag* tag)
|
||||
:_tag(tag)
|
||||
{
|
||||
}
|
||||
|
||||
XMLNode::~XMLNode()
|
||||
{
|
||||
delete _tag;
|
||||
}
|
||||
|
||||
XMLLeafNode::XMLLeafNode(XMLLeafTag* leaftag)
|
||||
:XMLNode(leaftag)
|
||||
{
|
||||
}
|
||||
|
||||
XMLLeafNode::~XMLLeafNode()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void XMLLeafNode::applyProcedure(XMLVisitor& v)
|
||||
{
|
||||
v(*this);
|
||||
}
|
||||
|
||||
XMLInteriorNode::XMLInteriorNode(XMLTag* tag)
|
||||
:XMLNode(tag)
|
||||
{
|
||||
}
|
||||
|
||||
XMLNode* XMLInteriorNode::son(int ii)
|
||||
{
|
||||
assert((ii > 0) && (ii < _sons.size()));
|
||||
return _sons[ii];
|
||||
}
|
||||
|
||||
QVector< XMLNode* > XMLInteriorNode::sons()
|
||||
{
|
||||
return _sons;
|
||||
}
|
||||
|
||||
XMLInteriorNode::~XMLInteriorNode()
|
||||
{
|
||||
for(QVector< XMLNode* >::iterator it = _sons.begin();it != _sons.end();++it)
|
||||
delete (*it);
|
||||
}
|
||||
|
||||
void XMLInteriorNode::applyProcedure(XMLVisitor& v)
|
||||
{
|
||||
v(*this);
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
/****************************************************************************
|
||||
* VCGLib o o *
|
||||
* Visual and Computer Graphics Library o o *
|
||||
* _ O _ *
|
||||
* Copyright(C) 2004-2008 \/)\/ *
|
||||
* 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. *
|
||||
* *
|
||||
****************************************************************************/
|
||||
#ifndef _XML_DOCUMENT_MANAGING_H
|
||||
#define _XML_DOCUMENT_MANAGING_H
|
||||
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <QDomDocument>
|
||||
#include<QFile>
|
||||
#include<QVector>
|
||||
#include <QXmlStreamWriter>
|
||||
#include <QString>
|
||||
|
||||
class XMLTag
|
||||
{
|
||||
public:
|
||||
typedef std::pair<QString,QString> TagAttribute;
|
||||
typedef QVector<TagAttribute> TagAttributes;
|
||||
QString _tagname;
|
||||
TagAttributes _attributes;
|
||||
|
||||
XMLTag(const QString& tagname = QString(),const TagAttributes& attr = TagAttributes())
|
||||
:_tagname(tagname),_attributes(attr)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~XMLTag()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class XMLLeafTag : public XMLTag
|
||||
{
|
||||
public:
|
||||
QVector<QString> _text;
|
||||
|
||||
XMLLeafTag(const QString& tagname = QString(),const QVector<QString>& text = QVector<QString>())
|
||||
:XMLTag(tagname),_text(text)
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~XMLLeafTag()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class XMLDocumentWriter;
|
||||
|
||||
class XMLVisitor;
|
||||
|
||||
class XMLNode
|
||||
{
|
||||
public:
|
||||
XMLNode(XMLTag* tag);
|
||||
virtual ~XMLNode();
|
||||
|
||||
virtual void applyProcedure(XMLVisitor& v) = 0;
|
||||
|
||||
XMLTag* _tag;
|
||||
};
|
||||
|
||||
class XMLInteriorNode : public XMLNode
|
||||
{
|
||||
public:
|
||||
XMLInteriorNode(XMLTag* tag);
|
||||
|
||||
XMLNode* son(int ii);
|
||||
|
||||
QVector< XMLNode* > sons();
|
||||
|
||||
void applyProcedure(XMLVisitor& v);
|
||||
|
||||
~XMLInteriorNode();
|
||||
|
||||
QVector< XMLNode* > _sons;
|
||||
};
|
||||
|
||||
class XMLLeafNode : public XMLNode
|
||||
{
|
||||
public:
|
||||
XMLLeafNode(XMLLeafTag* leaftag);
|
||||
|
||||
void applyProcedure(XMLVisitor& v);
|
||||
virtual ~XMLLeafNode();
|
||||
};
|
||||
|
||||
class XMLDocument
|
||||
{
|
||||
public:
|
||||
XMLDocument(XMLInteriorNode* root)
|
||||
:_root(root)
|
||||
{
|
||||
}
|
||||
|
||||
~XMLDocument()
|
||||
{
|
||||
delete (_root);
|
||||
}
|
||||
|
||||
XMLInteriorNode* _root;
|
||||
};
|
||||
|
||||
|
||||
class XMLVisitor
|
||||
{
|
||||
public:
|
||||
virtual void operator()(XMLLeafNode& leaf) = 0;
|
||||
virtual void operator()(XMLInteriorNode& intnode) = 0;
|
||||
};
|
||||
|
||||
|
||||
class XMLDocumentWriter : public XMLVisitor
|
||||
{
|
||||
private:
|
||||
QXmlStreamWriter _stream;
|
||||
QFile _file;
|
||||
bool _error;
|
||||
|
||||
void writeText(XMLLeafNode& node)
|
||||
{
|
||||
XMLLeafTag* leaftag = static_cast<XMLLeafTag*>(node._tag);
|
||||
for(QVector<QString>::iterator it = leaftag->_text.begin();it != leaftag->_text.end();++it)
|
||||
{
|
||||
QString tmp = "";
|
||||
if (it != leaftag->_text.begin())
|
||||
tmp = QString(" ");
|
||||
_stream.writeCharacters(tmp + *it);
|
||||
}
|
||||
}
|
||||
|
||||
void writeAttributes(XMLNode& node)
|
||||
{
|
||||
QXmlStreamAttributes attr;
|
||||
for(XMLTag::TagAttributes::iterator it = node._tag->_attributes.begin();it != node._tag->_attributes.end();++it)
|
||||
attr.append(it->first,it->second);
|
||||
_stream.writeAttributes(attr);
|
||||
}
|
||||
|
||||
void recursiveStep(XMLInteriorNode& intnode)
|
||||
{
|
||||
QVector< XMLNode* > sons = intnode.sons();
|
||||
for(QVector< XMLNode* >::iterator its = sons.begin();its != sons.end();++its)
|
||||
(*its)->applyProcedure(*this);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
void operator()(XMLLeafNode& node)
|
||||
{
|
||||
_stream.writeStartElement(node._tag->_tagname);
|
||||
writeAttributes(node);
|
||||
writeText(node);
|
||||
_stream.writeEndElement();
|
||||
}
|
||||
|
||||
void operator()(XMLInteriorNode& intnode)
|
||||
{
|
||||
_stream.writeStartElement(intnode._tag->_tagname);
|
||||
writeAttributes(intnode);
|
||||
recursiveStep(intnode);
|
||||
_stream.writeEndElement();
|
||||
}
|
||||
|
||||
void operator()(XMLDocument& doc)
|
||||
{
|
||||
_stream.writeStartDocument();
|
||||
operator()(*(doc._root));
|
||||
_stream.writeEndDocument();
|
||||
}
|
||||
|
||||
void write(XMLDocument& doc)
|
||||
{
|
||||
(*this)(doc);
|
||||
}
|
||||
|
||||
bool isReliable() const
|
||||
{
|
||||
return !_error;
|
||||
}
|
||||
|
||||
XMLDocumentWriter(const char* filename,const bool autoformatting = true)
|
||||
:_stream(),_file(filename),_error(false)
|
||||
{
|
||||
if (!_file.open(QIODevice::WriteOnly | QIODevice::Text))
|
||||
_error = true;
|
||||
_stream.setDevice(&_file);
|
||||
_stream.setAutoFormatting(autoformatting);
|
||||
}
|
||||
|
||||
virtual ~XMLDocumentWriter()
|
||||
{
|
||||
_file.close();
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
Reference in new issue
Block a user