2006-11-03 00:57:42 +01:00
|
|
|
#ifndef __VCGLIB_UTILDAE
|
|
|
|
#define __VCGLIB_UTILDAE
|
|
|
|
|
|
|
|
#include <wrap/io_trimesh/additionalinfo.h>
|
|
|
|
#include <vcg/complex/trimesh/update/normal.h>
|
|
|
|
#include <vcg/complex/trimesh/allocate.h>
|
|
|
|
|
2006-11-06 06:29:40 +01:00
|
|
|
#include <wrap/io_trimesh/io_mask.h>
|
|
|
|
|
2006-11-03 00:57:42 +01:00
|
|
|
#include<QtXml/QDomDocument>
|
|
|
|
#include<QtCore/QFile>
|
|
|
|
#include <QtCore/QStringList>
|
|
|
|
|
|
|
|
#include<vcg/space/point3.h>
|
|
|
|
#include<vcg/space/tcoord2.h>
|
|
|
|
#include<vcg/space/color4.h>
|
2006-11-08 17:59:22 +01:00
|
|
|
#include <wrap/callback.h>
|
2006-11-03 00:57:42 +01:00
|
|
|
|
|
|
|
namespace vcg {
|
|
|
|
namespace tri {
|
|
|
|
namespace io {
|
2006-11-09 03:24:41 +01:00
|
|
|
class InfoDAE
|
2006-11-03 00:57:42 +01:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
InfoDAE()
|
|
|
|
{
|
|
|
|
doc = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
~InfoDAE()
|
|
|
|
{
|
|
|
|
delete doc;
|
|
|
|
}
|
|
|
|
|
|
|
|
QDomDocument* doc;
|
|
|
|
};
|
|
|
|
|
|
|
|
class AdditionalInfoDAE : public AdditionalInfo
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
vcg::tri::io::InfoDAE* dae;
|
2006-11-09 03:24:41 +01:00
|
|
|
std::vector<QString> texturefile;
|
2006-11-03 00:57:42 +01:00
|
|
|
|
|
|
|
AdditionalInfoDAE()
|
|
|
|
:AdditionalInfo()
|
|
|
|
{
|
2006-11-09 03:24:41 +01:00
|
|
|
mask = 0;
|
|
|
|
numvert = 0;
|
|
|
|
numface = 0;
|
2006-11-03 00:57:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
~AdditionalInfoDAE()
|
|
|
|
{
|
|
|
|
delete dae;
|
2006-11-09 03:24:41 +01:00
|
|
|
texturefile.clear();
|
2006-11-03 00:57:42 +01:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
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_NOTRIANGLES
|
|
|
|
};
|
|
|
|
|
|
|
|
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 referece an attribute that is not in the file",
|
|
|
|
"This version of Collada Importer support only triangular mesh file"
|
|
|
|
};
|
|
|
|
|
|
|
|
if(error>9 || error<0) return "Unknown error";
|
|
|
|
else return dae_error_msg[error];
|
|
|
|
};
|
|
|
|
protected:
|
2006-11-09 03:24:41 +01:00
|
|
|
inline static void referenceToANodeAttribute(const QDomNode n,const QString& attr,QString& url_st)
|
2006-11-03 00:57:42 +01:00
|
|
|
{
|
|
|
|
url_st = n.toElement().attribute(attr);
|
|
|
|
int sz = url_st.size() - 1;
|
|
|
|
url_st = url_st.right(sz);
|
|
|
|
assert(url_st.size() != 0);
|
|
|
|
}
|
|
|
|
|
2006-11-08 23:25:35 +01:00
|
|
|
inline static QDomNode findNodeBySpecificAttributeValue(const QDomNodeList& ndl,const QString& attrname,const QString& attrvalue)
|
2006-11-03 00:57:42 +01:00
|
|
|
{
|
|
|
|
int ndl_size = ndl.size();
|
|
|
|
assert(ndl_size != 0);
|
|
|
|
int ind = 0;
|
|
|
|
while(ind < ndl_size)
|
|
|
|
{
|
|
|
|
if (ndl.at(ind).toElement().attribute(attrname) == attrvalue)
|
|
|
|
return ndl.at(ind);
|
|
|
|
++ind;
|
|
|
|
}
|
|
|
|
return QDomNode();
|
|
|
|
}
|
|
|
|
|
2006-11-09 03:24:41 +01:00
|
|
|
inline static QDomNode findNodeBySpecificAttributeValue(const QDomNode n,const QString& tag,const QString& attrname,const QString& attrvalue)
|
2006-11-08 23:25:35 +01:00
|
|
|
{
|
|
|
|
return findNodeBySpecificAttributeValue(n.toElement().elementsByTagName(tag),attrname,attrvalue);
|
|
|
|
}
|
|
|
|
|
2006-11-09 03:24:41 +01:00
|
|
|
inline static QDomNode findNodeBySpecificAttributeValue(const QDomDocument n,const QString& tag,const QString& attrname,const QString& attrvalue)
|
2006-11-08 23:25:35 +01:00
|
|
|
{
|
|
|
|
return findNodeBySpecificAttributeValue(n.elementsByTagName(tag),attrname,attrvalue);
|
|
|
|
}
|
|
|
|
|
|
|
|
inline static bool isThereTag(const QDomNodeList& list)
|
|
|
|
{
|
|
|
|
return ((list.size() > 0) ? true : false);
|
|
|
|
}
|
|
|
|
|
2006-11-09 03:24:41 +01:00
|
|
|
inline static bool isThereTag(const QDomNode n,const QString& tagname)
|
2006-11-03 00:57:42 +01:00
|
|
|
{
|
2006-11-08 23:25:35 +01:00
|
|
|
return isThereTag(n.toElement().elementsByTagName(tagname));
|
2006-11-03 00:57:42 +01:00
|
|
|
}
|
|
|
|
|
2006-11-09 03:24:41 +01:00
|
|
|
inline static bool isThereTag(const QDomDocument n,const QString& tagname)
|
2006-11-03 00:57:42 +01:00
|
|
|
{
|
2006-11-08 23:25:35 +01:00
|
|
|
return isThereTag(n.elementsByTagName(tagname));
|
2006-11-03 00:57:42 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-11-09 03:24:41 +01:00
|
|
|
inline static QDomNode attributeSourcePerSimplex(const QDomNode n,const QDomDocument startpoint,const QString& sem)
|
2006-11-03 00:57:42 +01:00
|
|
|
{
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2006-11-09 03:24:41 +01:00
|
|
|
inline static void valueStringList(QStringList& res,const QDomNode srcnode,const QString& tag)
|
2006-11-03 00:57:42 +01:00
|
|
|
{
|
|
|
|
QDomNodeList list = srcnode.toElement().elementsByTagName(tag);
|
2006-11-09 03:24:41 +01:00
|
|
|
assert(list.size() == 1);
|
2006-11-03 00:57:42 +01:00
|
|
|
QString nd = list.at(0).firstChild().nodeValue();
|
|
|
|
res = nd.split(" ");
|
|
|
|
if (res.last() == "")
|
|
|
|
res.removeLast();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2006-11-08 23:25:35 +01:00
|
|
|
/*inline static bool removeChildNode(QDomNodeList*/
|
|
|
|
|
2006-11-07 18:22:53 +01:00
|
|
|
inline static bool removeChildNodeList(QDomNodeList& nodelst,const QString& tag = "", const QString& attribname = "", const QString& attribvalue = "")
|
2006-11-03 00:57:42 +01:00
|
|
|
{
|
|
|
|
for(int jj = 0;jj < nodelst.size();++jj)
|
|
|
|
{
|
2006-11-09 03:24:41 +01:00
|
|
|
removeChildNode(nodelst.at(jj),tag,attribname,attribvalue);
|
2006-11-03 00:57:42 +01:00
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2006-11-09 03:24:41 +01:00
|
|
|
inline static bool removeChildNode(QDomNode node,const QString& tag = "", const QString& attribname = "", const QString& attribvalue = "")
|
2006-11-03 00:57:42 +01:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
2006-11-08 20:49:57 +01:00
|
|
|
else
|
|
|
|
{
|
|
|
|
QString nm = clst.at(ii).nodeName();
|
|
|
|
if (clst.at(ii).nodeName() == tag)
|
|
|
|
{
|
2006-11-03 00:57:42 +01:00
|
|
|
node.removeChild(oldchild);
|
2006-11-08 20:49:57 +01:00
|
|
|
}
|
|
|
|
}
|
2006-11-03 00:57:42 +01:00
|
|
|
}
|
|
|
|
else node.removeChild(oldchild);
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2006-11-05 20:09:04 +01:00
|
|
|
|
|
|
|
static void ParseRotationMatrix(vcg::Matrix44f& m,const std::vector<QDomNode>& t)
|
|
|
|
{
|
|
|
|
vcg::Matrix44f tmp;
|
|
|
|
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.SetRotate(rtl.at(3).toFloat(),vcg::Point3f(rtl.at(0).toFloat(),rtl.at(1).toFloat(),rtl.at(2).toFloat()));
|
|
|
|
tmp *= tmp;
|
|
|
|
}
|
|
|
|
m = m * tmp;
|
|
|
|
}
|
|
|
|
|
2006-11-09 03:24:41 +01:00
|
|
|
static void AddTranslation(vcg::Matrix44f& m,const QDomNode t)
|
2006-11-05 20:09:04 +01:00
|
|
|
{
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2006-11-09 03:24:41 +01:00
|
|
|
static void TransfMatrix(const QDomNode parentnode,const QDomNode presentnode,vcg::Matrix44f& m)
|
2006-11-05 20:09:04 +01:00
|
|
|
{
|
|
|
|
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()) AddTranslation(tmp,trans);
|
|
|
|
ParseRotationMatrix(tmp,rotlist);
|
|
|
|
m = m * tmp;
|
|
|
|
TransfMatrix(parentnode,par,m);
|
|
|
|
}
|
|
|
|
}
|
2006-11-03 00:57:42 +01:00
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|