2006-06-14 11:47:21 +02:00
|
|
|
#ifndef __VCGLIB_IMPORTERDAE
|
|
|
|
#define __VCGLIB_IMPORTERDAE
|
|
|
|
|
|
|
|
//importer for collada's files
|
|
|
|
|
2008-02-04 23:29:02 +01:00
|
|
|
#include<wrap/dae/util_dae.h>
|
2006-06-14 11:47:21 +02:00
|
|
|
|
|
|
|
namespace vcg {
|
|
|
|
namespace tri {
|
|
|
|
namespace io {
|
|
|
|
|
2006-11-02 19:15:55 +01:00
|
|
|
template<typename OpenMeshType>
|
2006-11-03 00:58:33 +01:00
|
|
|
class ImporterDAE : public UtilDAE
|
2006-11-02 19:15:55 +01:00
|
|
|
{
|
2006-11-05 16:40:51 +01:00
|
|
|
|
|
|
|
private:
|
2007-08-16 18:09:23 +02:00
|
|
|
static int WedgeNormalAttribute(OpenMeshType& m,const QStringList face,const QStringList wn,const QDomNode wnsrc,const int meshfaceind,const int faceind,const int component)
|
|
|
|
{
|
|
|
|
int indnm = -1;
|
|
|
|
if (!wnsrc.isNull())
|
|
|
|
{
|
|
|
|
indnm = face.at(faceind).toInt();
|
|
|
|
assert(indnm * 3 < wn.size());
|
|
|
|
m.face[meshfaceind].WN(component) = vcg::Point3f(wn.at(indnm * 3).toFloat(),wn.at(indnm * 3 + 1).toFloat(),wn.at(indnm * 3 + 2).toFloat());
|
|
|
|
}
|
|
|
|
return indnm;
|
|
|
|
}
|
|
|
|
|
2007-12-18 12:06:46 +01:00
|
|
|
static int WedgeTextureAttribute(OpenMeshType& m,const QStringList face,int ind_txt,const QStringList wt,const QDomNode wtsrc,const int meshfaceind,const int faceind,const int component,const int stride = 2)
|
2007-08-16 18:09:23 +02:00
|
|
|
{
|
|
|
|
int indtx = -1;
|
|
|
|
if (!wtsrc.isNull())
|
|
|
|
{
|
|
|
|
indtx = face.at(faceind).toInt();
|
2008-02-28 11:44:47 +01:00
|
|
|
int num = wt.size();
|
2007-12-18 12:06:46 +01:00
|
|
|
assert(indtx * stride < wt.size());
|
2007-08-16 18:09:23 +02:00
|
|
|
m.face[meshfaceind].WT(component) = vcg::TexCoord2<float>();
|
2007-12-18 12:06:46 +01:00
|
|
|
m.face[meshfaceind].WT(component).U() = wt.at(indtx * stride).toFloat();
|
|
|
|
m.face[meshfaceind].WT(component).V() = wt.at(indtx * stride + 1).toFloat();
|
2007-09-19 13:18:08 +02:00
|
|
|
|
2007-09-25 12:29:29 +02:00
|
|
|
m.face[meshfaceind].WT(component).N() = ind_txt;
|
|
|
|
|
2007-08-16 18:09:23 +02:00
|
|
|
}
|
|
|
|
return indtx;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int WedgeColorAttribute(OpenMeshType& m,const QStringList face,const QStringList wc,const QDomNode wcsrc,const int meshfaceind,const int faceind,const int component)
|
|
|
|
{
|
|
|
|
int indcl;
|
|
|
|
if (!wcsrc.isNull())
|
|
|
|
{
|
|
|
|
indcl = face.at(faceind).toInt();
|
|
|
|
assert(indcl * 4 < wc.size());
|
|
|
|
m.face[meshfaceind].WC(component) = vcg::Color4b(wc.at(indcl * 4).toFloat(),wc.at(indcl * 4 + 1).toFloat(),wc.at(indcl * 4 + 2).toFloat(),wc.at(indcl * 4 + 3).toFloat());
|
|
|
|
}
|
|
|
|
return indcl;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void FindStandardWedgeAttributes(WedgeAttribute& wed,const QDomNode nd,const QDomDocument doc)
|
|
|
|
{
|
|
|
|
wed.wnsrc = findNodeBySpecificAttributeValue(nd,"input","semantic","NORMAL");
|
|
|
|
wed.offnm = findStringListAttribute(wed.wn,wed.wnsrc,nd,doc,"NORMAL");
|
|
|
|
|
|
|
|
wed.wtsrc = findNodeBySpecificAttributeValue(nd,"input","semantic","TEXCOORD");
|
2007-12-18 12:06:46 +01:00
|
|
|
if (!wed.wtsrc.isNull())
|
|
|
|
{
|
|
|
|
QDomNode src = attributeSourcePerSimplex(nd,doc,"TEXCOORD");
|
|
|
|
if (isThereTag(src,"accessor"))
|
|
|
|
{
|
|
|
|
QDomNodeList wedatts = src.toElement().elementsByTagName("accessor");
|
|
|
|
wed.stride = wedatts.at(0).toElement().attribute("stride").toInt();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
wed.stride = 2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
wed.stride = 2;
|
|
|
|
|
2007-08-16 18:09:23 +02:00
|
|
|
wed.offtx = findStringListAttribute(wed.wt,wed.wtsrc,nd,doc,"TEXCOORD");
|
|
|
|
|
|
|
|
wed.wcsrc = findNodeBySpecificAttributeValue(nd,"input","semantic","COLOR");
|
|
|
|
wed.offcl = findStringListAttribute(wed.wc,wed.wcsrc,nd,doc,"COLOR");
|
|
|
|
}
|
2007-12-18 12:06:46 +01:00
|
|
|
|
2007-08-16 18:09:23 +02:00
|
|
|
static DAEError LoadPolygonalMesh(QDomNodeList& polypatch,OpenMeshType& m,const size_t offset,AdditionalInfoDAE* info)
|
|
|
|
{
|
|
|
|
return E_NOERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
static DAEError LoadPolygonalListMesh(QDomNodeList& polylist,OpenMeshType& m,const size_t offset,AdditionalInfoDAE* info)
|
|
|
|
{
|
2007-09-27 15:53:32 +02:00
|
|
|
typedef PolygonalMesh< MyPolygon<typename OpenMeshType::VertexType> > PolyMesh;
|
|
|
|
PolyMesh pm;
|
2007-12-18 12:06:46 +01:00
|
|
|
|
|
|
|
//copying vertices
|
2007-08-25 10:42:10 +02:00
|
|
|
for(typename OpenMeshType::VertexIterator itv = m.vert.begin();itv != m.vert.end();++itv)
|
2007-08-16 18:09:23 +02:00
|
|
|
{
|
|
|
|
vcg::Point3f p(itv->P().X(),itv->P().Y(),itv->P().Z());
|
2007-10-02 09:52:00 +02:00
|
|
|
typename PolyMesh::VertexType v;
|
2007-09-27 15:53:32 +02:00
|
|
|
v.P() = p;
|
|
|
|
pm.vert.push_back(v);
|
2007-08-16 18:09:23 +02:00
|
|
|
}
|
2007-12-18 12:06:46 +01:00
|
|
|
|
2007-08-16 18:09:23 +02:00
|
|
|
int polylist_size = polylist.size();
|
|
|
|
for(int pl = 0; pl < polylist_size;++pl)
|
|
|
|
{
|
2007-12-18 12:06:46 +01:00
|
|
|
QString mat = polylist.at(pl).toElement().attribute(QString("material"));
|
|
|
|
QDomNode txt_node = textureFinder(mat,*(info->dae->doc));
|
|
|
|
int ind_txt = -1;
|
|
|
|
if (!txt_node.isNull())
|
|
|
|
ind_txt = indexTextureByImgNode(*(info->dae->doc),txt_node);
|
|
|
|
|
|
|
|
//PolyMesh::PERWEDGEATTRIBUTETYPE att = PolyMesh::NONE;
|
2007-08-16 18:09:23 +02:00
|
|
|
WedgeAttribute wa;
|
|
|
|
FindStandardWedgeAttributes(wa,polylist.at(pl),*(info->dae->doc));
|
|
|
|
QStringList vertcount;
|
|
|
|
valueStringList(vertcount,polylist.at(pl),"vcount");
|
|
|
|
int indforpol = findOffSetForASingleSimplex(polylist.at(pl));
|
|
|
|
int offpols = 0;
|
|
|
|
int npolig = vertcount.size();
|
|
|
|
QStringList polyind;
|
|
|
|
valueStringList(polyind,polylist.at(pl),"p");
|
2007-12-18 12:06:46 +01:00
|
|
|
for(int ii = 0;ii < npolig;++ii)
|
2007-08-16 18:09:23 +02:00
|
|
|
{
|
|
|
|
int nvert = vertcount.at(ii).toInt();
|
2007-09-27 15:53:32 +02:00
|
|
|
typename PolyMesh::FaceType p(nvert);
|
2007-12-18 12:06:46 +01:00
|
|
|
|
|
|
|
for(int iv = 0;iv < nvert;++iv)
|
2007-08-16 18:09:23 +02:00
|
|
|
{
|
|
|
|
int index = offset + polyind.at(offpols + iv * indforpol).toInt();
|
|
|
|
p._pv[iv] = &(pm.vert[index]);
|
2007-09-27 15:53:32 +02:00
|
|
|
int nmindex = -1;
|
2007-12-18 12:06:46 +01:00
|
|
|
|
|
|
|
if (!wa.wnsrc.isNull())
|
2007-09-27 15:53:32 +02:00
|
|
|
nmindex = offset + polyind.at(offpols + iv * indforpol + wa.offnm).toInt();
|
|
|
|
|
|
|
|
int txindex = -1;
|
|
|
|
if (!wa.wtsrc.isNull())
|
|
|
|
{
|
|
|
|
txindex = offset + polyind.at(offpols + iv * indforpol + wa.offtx).toInt();
|
2007-12-18 12:06:46 +01:00
|
|
|
/*p._txc[iv].U() = wa.wt.at(txindex * 2).toFloat();
|
|
|
|
p._txc[iv].V() = wa.wt.at(txindex * 2 + 1).toFloat();
|
|
|
|
p._txc[iv].N() = ind_txt;*/
|
2007-09-27 15:53:32 +02:00
|
|
|
}
|
2007-08-16 18:09:23 +02:00
|
|
|
}
|
|
|
|
pm._pols.push_back(p);
|
|
|
|
offpols += nvert * indforpol;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
pm.triangulate(m);
|
|
|
|
return E_NOERROR;
|
|
|
|
}
|
|
|
|
|
|
|
|
static DAEError LoadTriangularMesh(QDomNodeList& tripatch,OpenMeshType& m,const size_t offset,AdditionalInfoDAE* info)
|
|
|
|
{
|
|
|
|
int tripatch_size = tripatch.size();
|
|
|
|
for(int tript = 0; tript < tripatch_size;++tript)
|
|
|
|
{
|
2007-09-19 13:18:08 +02:00
|
|
|
QString mat = tripatch.at(tript).toElement().attribute(QString("material"));
|
2007-09-25 12:29:29 +02:00
|
|
|
QDomNode txt_node = textureFinder(mat,*(info->dae->doc));
|
|
|
|
int ind_txt = -1;
|
|
|
|
if (!txt_node.isNull())
|
|
|
|
ind_txt = indexTextureByImgNode(*(info->dae->doc),txt_node);
|
|
|
|
|
2007-08-16 18:09:23 +02:00
|
|
|
int nfcatt = tripatch.at(tript).toElement().elementsByTagName("input").size();
|
|
|
|
|
|
|
|
QStringList face;
|
|
|
|
valueStringList(face,tripatch.at(tript),"p");
|
|
|
|
int face_size = face.size();
|
|
|
|
int offsetface = (int)m.face.size();
|
2008-02-05 00:50:07 +01:00
|
|
|
if (face_size != 0)
|
|
|
|
{
|
|
|
|
vcg::tri::Allocator<OpenMeshType>::AddFaces(m,face_size / (nfcatt * 3));
|
|
|
|
WedgeAttribute wa;
|
|
|
|
FindStandardWedgeAttributes(wa,tripatch.at(tript),*(info->dae->doc));
|
|
|
|
|
|
|
|
int jj = 0;
|
|
|
|
//int dd = m.face.size();
|
|
|
|
for(int ff = offsetface;ff < (int) m.face.size();++ff)
|
|
|
|
{
|
|
|
|
|
|
|
|
for(unsigned int tt = 0;tt < 3;++tt)
|
|
|
|
{
|
|
|
|
int indvt = face.at(jj).toInt();
|
|
|
|
assert(indvt + offset < m.vert.size());
|
|
|
|
m.face[ff].V(tt) = &(m.vert[indvt + offset]);
|
2007-08-16 18:09:23 +02:00
|
|
|
|
2008-02-05 00:50:07 +01:00
|
|
|
if(tri::HasPerWedgeNormal(m))
|
|
|
|
WedgeNormalAttribute(m,face,wa.wn,wa.wnsrc,ff,jj + wa.offnm,tt);
|
|
|
|
if(tri::HasPerWedgeTexCoord(m) && ind_txt != -1)
|
|
|
|
{
|
|
|
|
WedgeTextureAttribute(m,face,ind_txt,wa.wt,wa.wtsrc,ff,jj + wa.offtx,tt,wa.stride);
|
|
|
|
}
|
|
|
|
if(tri::HasPerWedgeColor(m))
|
|
|
|
WedgeColorAttribute(m,face,wa.wc,wa.wcsrc,ff,jj + wa.offcl,tt);
|
2007-08-16 18:09:23 +02:00
|
|
|
|
2008-02-05 00:50:07 +01:00
|
|
|
jj += nfcatt;
|
2007-12-18 12:06:46 +01:00
|
|
|
}
|
2007-08-16 18:09:23 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return E_NOERROR;
|
|
|
|
}
|
|
|
|
|
2006-11-05 20:09:04 +01:00
|
|
|
|
2006-11-09 03:24:41 +01:00
|
|
|
static int LoadMesh(OpenMeshType& m,AdditionalInfoDAE* info,const QDomNode& geo,const vcg::Matrix44f& t, CallBackPos *cb=0)
|
2006-11-05 16:40:51 +01:00
|
|
|
{
|
|
|
|
if (isThereTag(geo,"mesh"))
|
|
|
|
{
|
2006-11-08 17:59:22 +01:00
|
|
|
if ((cb !=NULL) && (((info->numvert + info->numface)%100)==0) && !(*cb)((100*(info->numvert + info->numface))/(info->numvert + info->numface), "Vertex Loading"))
|
|
|
|
return E_CANTOPEN;
|
2006-11-05 16:40:51 +01:00
|
|
|
/*QDomNodeList geosrc = geo.toElement().elementsByTagName("source");
|
|
|
|
int geosrc_size = geosrc.size();
|
|
|
|
if (geosrc_size < 1)
|
|
|
|
return E_NOVERTEXPOSITION;*/
|
|
|
|
|
|
|
|
QDomNodeList vertices = geo.toElement().elementsByTagName("vertices");
|
|
|
|
int vertices_size = vertices.size();
|
|
|
|
if (vertices_size != 1)
|
|
|
|
return E_INCOMPATIBLECOLLADA141FORMAT;
|
|
|
|
|
2006-11-09 03:24:41 +01:00
|
|
|
QDomNode srcnode = attributeSourcePerSimplex(vertices.at(0),*(info->dae->doc),"POSITION");
|
2006-11-05 16:40:51 +01:00
|
|
|
if (srcnode.isNull())
|
|
|
|
return E_NOVERTEXPOSITION;
|
|
|
|
|
|
|
|
QStringList geosrcposarr;
|
|
|
|
valueStringList(geosrcposarr,srcnode,"float_array");
|
|
|
|
|
|
|
|
int geosrcposarr_size = geosrcposarr.size();
|
|
|
|
if ((geosrcposarr_size % 3) != 0)
|
|
|
|
return E_CANTOPEN;
|
|
|
|
int nvert = geosrcposarr_size / 3;
|
|
|
|
size_t offset = m.vert.size();
|
2006-11-09 03:24:41 +01:00
|
|
|
if (geosrcposarr_size != 0)
|
2006-11-05 16:40:51 +01:00
|
|
|
{
|
2006-11-09 03:24:41 +01:00
|
|
|
vcg::tri::Allocator<OpenMeshType>::AddVertices(m,nvert);
|
2006-11-05 16:40:51 +01:00
|
|
|
|
2006-11-09 03:24:41 +01:00
|
|
|
QDomNode srcnodenorm = attributeSourcePerSimplex(vertices.at(0),*(info->dae->doc),"NORMAL");
|
|
|
|
QStringList geosrcvertnorm;
|
2006-11-05 16:40:51 +01:00
|
|
|
if (!srcnodenorm.isNull())
|
2006-11-09 03:24:41 +01:00
|
|
|
valueStringList(geosrcvertnorm,srcnodenorm,"float_array");
|
2006-11-05 16:40:51 +01:00
|
|
|
|
2006-11-09 03:24:41 +01:00
|
|
|
QDomNode srcnodetext = attributeSourcePerSimplex(vertices.at(0),*(info->dae->doc),"TEXCOORD");
|
|
|
|
QStringList geosrcverttext;
|
2006-11-05 16:40:51 +01:00
|
|
|
if (!srcnodetext.isNull())
|
2006-11-09 03:24:41 +01:00
|
|
|
valueStringList(geosrcverttext,srcnodetext,"float_array");
|
|
|
|
|
|
|
|
QDomNode srcnodecolor = attributeSourcePerSimplex(vertices.at(0),*(info->dae->doc),"COLOR");
|
|
|
|
QStringList geosrcvertcol;
|
|
|
|
if (!srcnodecolor.isNull())
|
|
|
|
valueStringList(geosrcvertcol,srcnodecolor,"float_array");
|
|
|
|
|
|
|
|
int ii = 0;
|
|
|
|
for(size_t vv = offset;vv < m.vert.size();++vv)
|
2006-11-05 16:40:51 +01:00
|
|
|
{
|
2006-11-09 03:24:41 +01:00
|
|
|
|
|
|
|
assert((ii * 3 < geosrcposarr_size) && (ii * 3 + 1 < geosrcposarr_size) && (ii * 3 + 2 < geosrcposarr_size));
|
|
|
|
vcg::Point4f tmp = t * vcg::Point4f(geosrcposarr[ii * 3].toFloat(),geosrcposarr[ii * 3 + 1].toFloat(),geosrcposarr[ii * 3 + 2].toFloat(),1.0f);
|
|
|
|
m.vert[vv].P() = vcg::Point3f(tmp.X(),tmp.Y(),tmp.Z());
|
2006-11-05 16:40:51 +01:00
|
|
|
|
2006-11-09 03:24:41 +01:00
|
|
|
if (!srcnodenorm.isNull())
|
|
|
|
{
|
|
|
|
assert((ii * 3 < geosrcvertnorm.size()) && (ii * 3 + 1 < geosrcvertnorm.size()) && (ii * 3 + 2 < geosrcvertnorm.size()));
|
|
|
|
vcg::Matrix44f intr44 = vcg::Inverse(t);
|
|
|
|
vcg::Transpose(intr44);
|
|
|
|
Matrix33f intr33;
|
|
|
|
for(unsigned int rr = 0; rr < 2; ++rr)
|
|
|
|
{
|
|
|
|
for(unsigned int cc = 0;cc < 2;++cc)
|
|
|
|
intr33[rr][cc] = intr44[rr][cc];
|
|
|
|
}
|
|
|
|
m.vert[vv].N() = (intr33 * vcg::Point3f(geosrcvertnorm[ii * 3].toFloat(),geosrcvertnorm[ii * 3 + 1].toFloat(),geosrcvertnorm[ii * 3 + 2].toFloat())).Normalize();
|
|
|
|
}
|
2006-11-05 16:40:51 +01:00
|
|
|
|
2006-11-09 03:24:41 +01:00
|
|
|
/*if (!srcnodecolor.isNull())
|
|
|
|
{
|
|
|
|
assert((ii * 4 < geosrcvertcol.size()) && (ii * 4 + 1 < geosrcvertcol.size()) && (ii * 4 + 2 < geosrcvertcol.size()) && (ii * 4 + 1 < geosrcvertcol.size()));
|
|
|
|
m.vert[vv].C() = vcg::Color4b(geosrcvertcol[ii * 4].toFloat(),geosrcvertcol[ii * 4 + 1].toFloat(),geosrcvertcol[ii * 4 + 2].toFloat(),geosrcvertcol[ii * 4 + 3].toFloat());
|
|
|
|
}*/
|
2006-11-05 16:40:51 +01:00
|
|
|
|
2006-11-09 03:24:41 +01:00
|
|
|
if (!srcnodetext.isNull())
|
|
|
|
{
|
2007-12-18 12:06:46 +01:00
|
|
|
|
2006-11-09 03:24:41 +01:00
|
|
|
assert((ii * 2 < geosrcverttext.size()) && (ii * 2 + 1 < geosrcverttext.size()));
|
2007-03-12 17:40:17 +01:00
|
|
|
m.vert[vv].T() = vcg::TexCoord2<float>();
|
2006-11-09 03:24:41 +01:00
|
|
|
m.vert[vv].T().u() = geosrcverttext[ii * 2].toFloat();
|
|
|
|
m.vert[vv].T().v() = geosrcverttext[ii * 2 + 1].toFloat();
|
|
|
|
}
|
|
|
|
++ii;
|
2006-11-05 16:40:51 +01:00
|
|
|
}
|
|
|
|
|
2006-11-09 03:24:41 +01:00
|
|
|
QDomNodeList tripatch = geo.toElement().elementsByTagName("triangles");
|
|
|
|
int tripatch_size = tripatch.size();
|
2007-08-16 18:09:23 +02:00
|
|
|
QDomNodeList polypatch = geo.toElement().elementsByTagName("polygons");
|
|
|
|
int polypatch_size = polypatch.size();
|
|
|
|
QDomNodeList polylist = geo.toElement().elementsByTagName("polylist");
|
|
|
|
int polylist_size = polylist.size();
|
|
|
|
if ((tripatch_size == 0) && (polypatch_size == 0) && (polylist_size == 0))
|
|
|
|
return E_NOPOLYGONALMESH;
|
|
|
|
|
|
|
|
DAEError err = E_NOERROR;
|
2008-02-04 23:29:02 +01:00
|
|
|
if (tripatch_size != 0)
|
|
|
|
err = LoadTriangularMesh(tripatch,m,offset,info);
|
2007-08-16 18:09:23 +02:00
|
|
|
else
|
2008-02-04 23:29:02 +01:00
|
|
|
if (polypatch_size != 0)
|
|
|
|
err = LoadPolygonalMesh(polypatch,m,offset,info);
|
2007-08-16 18:09:23 +02:00
|
|
|
else
|
2008-02-04 23:29:02 +01:00
|
|
|
if (polylist_size != 0)
|
|
|
|
err = LoadPolygonalListMesh(polylist,m,offset,info);
|
2008-02-05 00:50:07 +01:00
|
|
|
if (err != E_NOERROR)
|
|
|
|
return err;
|
2006-11-05 16:40:51 +01:00
|
|
|
}
|
|
|
|
return E_NOERROR;
|
|
|
|
}
|
|
|
|
else return E_NOMESH;
|
|
|
|
}
|
2006-11-06 10:31:43 +01:00
|
|
|
|
2007-03-12 17:40:17 +01:00
|
|
|
static void GetTexCoord(const QDomDocument& doc,AdditionalInfoDAE* inf)
|
2006-11-06 10:31:43 +01:00
|
|
|
{
|
|
|
|
QDomNodeList txlst = doc.elementsByTagName("library_images");
|
2007-09-19 13:18:08 +02:00
|
|
|
for(int img = 0;img < txlst.at(0).childNodes().size();++img)
|
2006-11-06 10:31:43 +01:00
|
|
|
{
|
2007-09-19 13:18:08 +02:00
|
|
|
QDomNodeList nlst = txlst.at(0).childNodes().at(img).toElement().elementsByTagName("init_from");
|
2006-11-06 10:31:43 +01:00
|
|
|
if (nlst.size() > 0)
|
|
|
|
{
|
2006-11-09 03:24:41 +01:00
|
|
|
inf->texturefile.push_back(nlst.at(0).firstChild().nodeValue());
|
2006-11-06 10:31:43 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2006-11-08 17:59:22 +01:00
|
|
|
|
2006-11-02 19:15:55 +01:00
|
|
|
public:
|
2006-09-22 08:01:40 +02:00
|
|
|
|
2006-11-02 19:15:55 +01:00
|
|
|
//merge all meshes in the collada's file in the templeted mesh m
|
|
|
|
//I assume the mesh
|
2006-11-05 16:40:51 +01:00
|
|
|
|
2006-11-09 03:24:41 +01:00
|
|
|
static int Open(OpenMeshType& m,const char* filename,AdditionalInfo*& info, CallBackPos *cb=0)
|
2006-08-11 13:09:40 +02:00
|
|
|
{
|
2006-11-02 19:15:55 +01:00
|
|
|
AdditionalInfoDAE* inf = new AdditionalInfoDAE();
|
|
|
|
inf->dae = new InfoDAE();
|
2006-11-09 03:24:41 +01:00
|
|
|
|
2006-11-02 19:15:55 +01:00
|
|
|
QDomDocument* doc = new QDomDocument(filename);
|
|
|
|
QFile file(filename);
|
|
|
|
if (!file.open(QIODevice::ReadOnly))
|
|
|
|
return E_CANTOPEN;
|
|
|
|
if (!doc->setContent(&file))
|
2006-08-11 13:09:40 +02:00
|
|
|
{
|
2006-11-02 19:15:55 +01:00
|
|
|
file.close();
|
|
|
|
return E_CANTOPEN;
|
2006-08-11 13:09:40 +02:00
|
|
|
}
|
2006-11-02 19:15:55 +01:00
|
|
|
file.close();
|
2006-11-03 00:58:33 +01:00
|
|
|
|
2006-11-09 03:24:41 +01:00
|
|
|
inf->dae->doc = doc;
|
2006-11-06 10:31:43 +01:00
|
|
|
//GetTexture(*(info->doc),inf);
|
|
|
|
|
2008-02-28 11:44:47 +01:00
|
|
|
//scene->instance_visual_scene
|
2006-11-09 03:24:41 +01:00
|
|
|
QDomNodeList scenes = inf->dae->doc->elementsByTagName("scene");
|
2006-11-02 19:15:55 +01:00
|
|
|
int scn_size = scenes.size();
|
|
|
|
if (scn_size == 0)
|
|
|
|
return E_NO3DSCENE;
|
|
|
|
|
2008-02-05 00:50:07 +01:00
|
|
|
int problem = E_NOERROR;
|
|
|
|
bool found_a_mesh = false;
|
2006-11-02 19:15:55 +01:00
|
|
|
//Is there geometry in the file?
|
|
|
|
bool geoinst_found = false;
|
|
|
|
//for each scene in COLLADA FILE
|
|
|
|
for(int scn = 0;scn < scn_size;++scn)
|
2006-08-11 13:09:40 +02:00
|
|
|
{
|
2006-11-07 18:22:53 +01:00
|
|
|
QDomNodeList instscenes = scenes.at(scn).toElement().elementsByTagName("instance_visual_scene");
|
2006-11-02 19:15:55 +01:00
|
|
|
int instscn_size = instscenes.size();
|
|
|
|
if (instscn_size == 0)
|
|
|
|
return E_INCOMPATIBLECOLLADA141FORMAT;
|
|
|
|
|
|
|
|
//for each scene instance in a COLLADA scene
|
|
|
|
for(int instscn = 0;instscn < instscn_size; ++instscn)
|
2006-08-11 13:09:40 +02:00
|
|
|
{
|
2006-11-02 19:15:55 +01:00
|
|
|
QString libscn_url;
|
|
|
|
referenceToANodeAttribute(instscenes.at(instscn),"url",libscn_url);
|
2006-11-09 03:24:41 +01:00
|
|
|
QDomNode nd = QDomNode(*(inf->dae->doc));
|
|
|
|
QDomNode visscn = findNodeBySpecificAttributeValue(*(inf->dae->doc),"visual_scene","id",libscn_url);
|
2006-11-02 19:15:55 +01:00
|
|
|
if(visscn.isNull())
|
|
|
|
return E_UNREFERENCEBLEDCOLLADAATTRIBUTE;
|
2006-08-11 13:09:40 +02:00
|
|
|
|
2006-11-02 19:15:55 +01:00
|
|
|
//for each node in the libscn_url visual scene
|
2006-11-07 18:22:53 +01:00
|
|
|
QDomNodeList visscn_child = visscn.childNodes();
|
2006-11-02 19:15:55 +01:00
|
|
|
|
|
|
|
//for each direct child of a libscn_url visual scene find if there is some geometry instance
|
|
|
|
for(int chdind = 0; chdind < visscn_child.size();++chdind)
|
2006-08-11 13:09:40 +02:00
|
|
|
{
|
2006-11-07 18:22:53 +01:00
|
|
|
QDomNodeList geoinst = visscn_child.at(chdind).toElement().elementsByTagName("instance_geometry");
|
2006-11-02 19:15:55 +01:00
|
|
|
int geoinst_size = geoinst.size();
|
|
|
|
if (geoinst_size != 0)
|
2006-08-11 13:09:40 +02:00
|
|
|
{
|
2006-11-05 20:09:04 +01:00
|
|
|
|
2006-11-02 19:15:55 +01:00
|
|
|
geoinst_found |= true;
|
2006-11-09 03:24:41 +01:00
|
|
|
QDomNodeList geolib = inf->dae->doc->elementsByTagName("library_geometries");
|
|
|
|
assert(geolib.size() == 1);
|
2006-11-02 19:15:55 +01:00
|
|
|
//!!!!!!!!!!!!!!!!!here will be the code for geometry transformations!!!!!!!!!!!!!!!!!!!!!!
|
|
|
|
for(int geoinst_ind = 0;geoinst_ind < geoinst_size;++geoinst_ind)
|
2006-09-22 08:01:40 +02:00
|
|
|
{
|
2006-11-02 19:15:55 +01:00
|
|
|
QString geo_url;
|
|
|
|
referenceToANodeAttribute(geoinst.at(geoinst_ind),"url",geo_url);
|
2006-11-05 20:09:04 +01:00
|
|
|
|
2006-11-02 19:15:55 +01:00
|
|
|
QDomNode geo = findNodeBySpecificAttributeValue(geolib.at(0),"geometry","id",geo_url);
|
|
|
|
if (geo.isNull())
|
|
|
|
return E_UNREFERENCEBLEDCOLLADAATTRIBUTE;
|
2006-11-05 20:09:04 +01:00
|
|
|
vcg::Matrix44f tr;
|
|
|
|
tr.SetIdentity();
|
|
|
|
TransfMatrix(visscn,geoinst.at(geoinst_ind),tr);
|
2006-11-09 03:24:41 +01:00
|
|
|
problem |= LoadMesh(m,inf,geo,tr);
|
2008-02-05 00:50:07 +01:00
|
|
|
if (problem & E_NOMESH)
|
|
|
|
found_a_mesh |= false;
|
|
|
|
else
|
|
|
|
found_a_mesh = true;
|
2006-08-11 13:09:40 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2008-02-05 00:50:07 +01:00
|
|
|
//if there is at least a mesh I clean the problem status variable from E_NOMESH ERROR
|
2008-02-28 11:44:47 +01:00
|
|
|
|
|
|
|
if (((problem & E_NOMESH) || (problem & E_NOPOLYGONALMESH)) && (found_a_mesh))
|
|
|
|
{
|
|
|
|
if (problem & E_NOMESH)
|
|
|
|
problem = problem & ~E_NOMESH;
|
|
|
|
if (problem & E_NOPOLYGONALMESH)
|
|
|
|
problem = problem & ~E_NOPOLYGONALMESH;
|
|
|
|
}
|
2006-08-11 13:09:40 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-11-02 19:15:55 +01:00
|
|
|
if (!geoinst_found)
|
2006-11-05 16:40:51 +01:00
|
|
|
{
|
2006-11-09 03:24:41 +01:00
|
|
|
QDomNodeList geolib = inf->dae->doc->elementsByTagName("library_geometries");
|
|
|
|
assert(geolib.size() == 1);
|
2006-11-07 18:22:53 +01:00
|
|
|
QDomNodeList geochild = geolib.at(0).childNodes();
|
2006-11-05 16:40:51 +01:00
|
|
|
int geochild_size = geochild.size();
|
|
|
|
int problem = 0;
|
|
|
|
for(int chd = 0;chd < geochild_size;++chd)
|
|
|
|
{
|
2006-11-05 20:09:04 +01:00
|
|
|
vcg::Matrix44f tmp;
|
|
|
|
tmp.SetIdentity();
|
2006-11-09 03:24:41 +01:00
|
|
|
problem |= LoadMesh(m,inf,geochild.at(chd),tmp);
|
2006-11-05 16:40:51 +01:00
|
|
|
}
|
|
|
|
}
|
2008-02-28 11:44:47 +01:00
|
|
|
//if there is at least a mesh I clean the problem status variable from E_NOMESH or E_NOPOLYGONALMESH ERROR
|
|
|
|
if (((problem & E_NOMESH) || (problem & E_NOPOLYGONALMESH)) && (found_a_mesh))
|
|
|
|
{
|
|
|
|
if (problem & E_NOMESH)
|
|
|
|
problem = problem & ~E_NOMESH;
|
|
|
|
if (problem & E_NOPOLYGONALMESH)
|
|
|
|
problem = problem & ~E_NOPOLYGONALMESH;
|
|
|
|
}
|
2006-11-09 03:24:41 +01:00
|
|
|
info = inf;
|
2008-02-05 00:50:07 +01:00
|
|
|
return problem;
|
2006-09-22 08:01:40 +02:00
|
|
|
}
|
|
|
|
|
2006-11-06 06:29:40 +01:00
|
|
|
static bool LoadMask(const char * filename, AdditionalInfoDAE*& addinfo)
|
2006-11-02 19:15:55 +01:00
|
|
|
{
|
|
|
|
bool bHasPerWedgeTexCoord = false;
|
|
|
|
bool bHasPerWedgeNormal = false;
|
|
|
|
bool bHasPerVertexColor = false;
|
|
|
|
bool bHasPerFaceColor = false;
|
2006-11-06 06:29:40 +01:00
|
|
|
bool bHasPerVertexNormal = false;
|
|
|
|
bool bHasPerVertexText = false;
|
|
|
|
|
2006-11-09 03:24:41 +01:00
|
|
|
AdditionalInfoDAE* info = new AdditionalInfoDAE();
|
|
|
|
info->dae = new InfoDAE();
|
|
|
|
|
2006-09-22 08:01:40 +02:00
|
|
|
|
2006-11-06 06:29:40 +01:00
|
|
|
QDomDocument* doc = new QDomDocument(filename);
|
|
|
|
QFile file(filename);
|
|
|
|
if (!file.open(QIODevice::ReadOnly))
|
2006-11-08 20:49:57 +01:00
|
|
|
return false;
|
2006-11-06 06:29:40 +01:00
|
|
|
if (!doc->setContent(&file))
|
2006-09-22 08:01:40 +02:00
|
|
|
{
|
2006-11-06 06:29:40 +01:00
|
|
|
file.close();
|
2006-11-08 20:49:57 +01:00
|
|
|
return false;
|
2006-09-22 08:01:40 +02:00
|
|
|
}
|
2006-11-06 06:29:40 +01:00
|
|
|
file.close();
|
|
|
|
|
2006-11-02 19:15:55 +01:00
|
|
|
|
2006-11-09 03:24:41 +01:00
|
|
|
info->dae->doc = doc;
|
2007-03-20 17:47:50 +01:00
|
|
|
GetTexCoord(*(info->dae->doc),info);
|
2006-11-09 03:24:41 +01:00
|
|
|
QDomNodeList scenes = info->dae->doc->elementsByTagName("scene");
|
2006-11-06 06:29:40 +01:00
|
|
|
int scn_size = scenes.size();
|
|
|
|
|
2006-11-02 19:15:55 +01:00
|
|
|
|
2006-11-06 06:29:40 +01:00
|
|
|
//Is there geometry in the file?
|
|
|
|
bool geoinst_found = false;
|
|
|
|
//for each scene in COLLADA FILE
|
|
|
|
for(int scn = 0;scn < scn_size;++scn)
|
2006-09-22 08:01:40 +02:00
|
|
|
{
|
2006-11-07 18:22:53 +01:00
|
|
|
QDomNodeList instscenes = scenes.at(scn).toElement().elementsByTagName("instance_visual_scene");
|
2006-11-06 06:29:40 +01:00
|
|
|
int instscn_size = instscenes.size();
|
|
|
|
if (instscn_size == 0)
|
2006-11-06 09:45:13 +01:00
|
|
|
return false;
|
2006-11-02 19:15:55 +01:00
|
|
|
|
2006-11-06 06:29:40 +01:00
|
|
|
//for each scene instance in a COLLADA scene
|
|
|
|
for(int instscn = 0;instscn < instscn_size; ++instscn)
|
|
|
|
{
|
|
|
|
QString libscn_url;
|
|
|
|
referenceToANodeAttribute(instscenes.at(instscn),"url",libscn_url);
|
2006-11-09 03:24:41 +01:00
|
|
|
QDomNode nd = QDomNode(*(info->dae->doc));
|
|
|
|
QDomNode visscn = findNodeBySpecificAttributeValue(*(info->dae->doc),"visual_scene","id",libscn_url);
|
2006-11-06 06:29:40 +01:00
|
|
|
if(visscn.isNull())
|
2006-11-06 09:45:13 +01:00
|
|
|
return false;
|
2006-11-06 06:29:40 +01:00
|
|
|
|
|
|
|
//for each node in the libscn_url visual scene
|
2006-11-07 18:22:53 +01:00
|
|
|
//QDomNodeList& visscn_child = visscn.childNodes();
|
|
|
|
QDomNodeList visscn_child = visscn.childNodes();
|
2006-11-06 06:29:40 +01:00
|
|
|
|
|
|
|
//for each direct child of a libscn_url visual scene find if there is some geometry instance
|
|
|
|
for(int chdind = 0; chdind < visscn_child.size();++chdind)
|
2006-09-22 08:01:40 +02:00
|
|
|
{
|
2006-11-07 18:22:53 +01:00
|
|
|
//QDomNodeList& geoinst = visscn_child.at(chdind).toElement().elementsByTagName("instance_geometry");
|
|
|
|
QDomNodeList geoinst = visscn_child.at(chdind).toElement().elementsByTagName("instance_geometry");
|
2006-11-06 06:29:40 +01:00
|
|
|
int geoinst_size = geoinst.size();
|
|
|
|
if (geoinst_size != 0)
|
2006-11-02 19:15:55 +01:00
|
|
|
{
|
2006-11-06 06:29:40 +01:00
|
|
|
|
|
|
|
geoinst_found |= true;
|
2006-11-09 03:24:41 +01:00
|
|
|
QDomNodeList geolib = info->dae->doc->elementsByTagName("library_geometries");
|
|
|
|
assert(geolib.size() == 1);
|
2006-11-06 06:29:40 +01:00
|
|
|
//!!!!!!!!!!!!!!!!!here will be the code for geometry transformations!!!!!!!!!!!!!!!!!!!!!!
|
|
|
|
info->numvert = 0;
|
|
|
|
info->numface = 0;
|
|
|
|
for(int geoinst_ind = 0;geoinst_ind < geoinst_size;++geoinst_ind)
|
2006-11-02 19:15:55 +01:00
|
|
|
{
|
2006-11-06 06:29:40 +01:00
|
|
|
QString geo_url;
|
|
|
|
referenceToANodeAttribute(geoinst.at(geoinst_ind),"url",geo_url);
|
|
|
|
|
|
|
|
QDomNode geo = findNodeBySpecificAttributeValue(geolib.at(0),"geometry","id",geo_url);
|
|
|
|
if (geo.isNull())
|
2006-11-06 09:45:13 +01:00
|
|
|
return false;
|
2006-11-06 06:29:40 +01:00
|
|
|
|
|
|
|
QDomNodeList vertlist = geo.toElement().elementsByTagName("vertices");
|
|
|
|
|
|
|
|
for(int vert = 0;vert < vertlist.size();++vert)
|
|
|
|
{
|
|
|
|
QDomNode no;
|
|
|
|
no = findNodeBySpecificAttributeValue(vertlist.at(vert),"input","semantic","POSITION");
|
|
|
|
QString srcurl;
|
|
|
|
referenceToANodeAttribute(no,"source",srcurl);
|
|
|
|
no = findNodeBySpecificAttributeValue(geo,"source","id",srcurl);
|
|
|
|
QDomNodeList fa = no.toElement().elementsByTagName("float_array");
|
|
|
|
assert(fa.size() == 1);
|
|
|
|
info->numvert += (fa.at(0).toElement().attribute("count").toInt() / 3);
|
|
|
|
no = findNodeBySpecificAttributeValue(vertlist.at(vert),"input","semantic","COLOR");
|
|
|
|
if (!no.isNull())
|
|
|
|
bHasPerVertexColor = true;
|
|
|
|
no = findNodeBySpecificAttributeValue(vertlist.at(vert),"input","semantic","NORMAL");
|
|
|
|
if (!no.isNull())
|
|
|
|
bHasPerVertexNormal = true;
|
|
|
|
no = findNodeBySpecificAttributeValue(vertlist.at(vert),"input","semantic","TEXCOORD");
|
|
|
|
if (!no.isNull())
|
|
|
|
bHasPerVertexText = true;
|
|
|
|
}
|
|
|
|
|
2007-08-16 18:09:23 +02:00
|
|
|
const char* arr[] = {"triangles","polylist","polygons"};
|
|
|
|
|
|
|
|
for(unsigned int tt= 0;tt < 3;++tt)
|
2006-11-06 06:29:40 +01:00
|
|
|
{
|
2007-08-16 18:09:23 +02:00
|
|
|
QDomNodeList facelist = geo.toElement().elementsByTagName(arr[tt]);
|
|
|
|
for(int face = 0;face < facelist.size();++face)
|
|
|
|
{
|
|
|
|
info->numface += facelist.at(face).toElement().attribute("count").toInt() ;
|
|
|
|
QDomNode no;
|
|
|
|
no = findNodeBySpecificAttributeValue(facelist.at(face),"input","semantic","NORMAL");
|
|
|
|
if (!no.isNull())
|
|
|
|
bHasPerWedgeNormal = true;
|
|
|
|
no = findNodeBySpecificAttributeValue(facelist.at(face),"input","semantic","TEXCOORD");
|
|
|
|
if (!no.isNull())
|
|
|
|
bHasPerWedgeTexCoord = true;
|
|
|
|
}
|
2006-11-06 06:29:40 +01:00
|
|
|
}
|
2006-11-02 19:15:55 +01:00
|
|
|
}
|
|
|
|
}
|
2006-09-22 08:01:40 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2006-11-06 09:45:13 +01:00
|
|
|
|
|
|
|
if (!geoinst_found)
|
|
|
|
{
|
2006-11-09 03:24:41 +01:00
|
|
|
QDomNodeList geolib = info->dae->doc->elementsByTagName("library_geometries");
|
|
|
|
assert(geolib.size() == 1);
|
2006-11-07 18:22:53 +01:00
|
|
|
QDomNodeList geochild = geolib.at(0).toElement().elementsByTagName("geometry");
|
2006-11-06 09:45:13 +01:00
|
|
|
//!!!!!!!!!!!!!!!!!here will be the code for geometry transformations!!!!!!!!!!!!!!!!!!!!!!
|
|
|
|
info->numvert = 0;
|
|
|
|
info->numface = 0;
|
|
|
|
for(int geoinst_ind = 0;geoinst_ind < geochild.size();++geoinst_ind)
|
|
|
|
{
|
|
|
|
QDomNodeList vertlist = geochild.at(geoinst_ind).toElement().elementsByTagName("vertices");
|
|
|
|
|
|
|
|
for(int vert = 0;vert < vertlist.size();++vert)
|
|
|
|
{
|
|
|
|
QDomNode no;
|
|
|
|
no = findNodeBySpecificAttributeValue(vertlist.at(vert),"input","semantic","POSITION");
|
|
|
|
QString srcurl;
|
|
|
|
referenceToANodeAttribute(no,"source",srcurl);
|
|
|
|
no = findNodeBySpecificAttributeValue(geochild.at(geoinst_ind),"source","id",srcurl);
|
|
|
|
QDomNodeList fa = no.toElement().elementsByTagName("float_array");
|
|
|
|
assert(fa.size() == 1);
|
|
|
|
info->numvert += (fa.at(0).toElement().attribute("count").toInt() / 3);
|
|
|
|
no = findNodeBySpecificAttributeValue(vertlist.at(vert),"input","semantic","COLOR");
|
|
|
|
if (!no.isNull())
|
|
|
|
bHasPerVertexColor = true;
|
|
|
|
no = findNodeBySpecificAttributeValue(vertlist.at(vert),"input","semantic","NORMAL");
|
|
|
|
if (!no.isNull())
|
|
|
|
bHasPerVertexNormal = true;
|
|
|
|
no = findNodeBySpecificAttributeValue(vertlist.at(vert),"input","semantic","TEXCOORD");
|
|
|
|
if (!no.isNull())
|
|
|
|
bHasPerVertexText = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
QDomNodeList facelist = geochild.at(geoinst_ind).toElement().elementsByTagName("triangles");
|
|
|
|
for(int face = 0;face < facelist.size();++face)
|
|
|
|
{
|
|
|
|
info->numface += facelist.at(face).toElement().attribute("count").toInt() ;
|
|
|
|
QDomNode no;
|
|
|
|
no = findNodeBySpecificAttributeValue(facelist.at(face),"input","semantic","NORMAL");
|
|
|
|
if (!no.isNull())
|
|
|
|
bHasPerWedgeNormal = true;
|
|
|
|
no = findNodeBySpecificAttributeValue(facelist.at(face),"input","semantic","TEXCOORD");
|
|
|
|
if (!no.isNull())
|
|
|
|
bHasPerWedgeTexCoord = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2006-11-06 06:29:40 +01:00
|
|
|
|
|
|
|
info->mask = 0;
|
2006-11-06 09:45:13 +01:00
|
|
|
|
2006-11-06 06:29:40 +01:00
|
|
|
if (bHasPerWedgeTexCoord)
|
|
|
|
info->mask |= vcg::tri::io::Mask::IOM_WEDGTEXCOORD;
|
|
|
|
if (bHasPerWedgeNormal)
|
|
|
|
info->mask |= vcg::tri::io::Mask::IOM_WEDGNORMAL;
|
|
|
|
if (bHasPerVertexColor)
|
|
|
|
info->mask |= vcg::tri::io::Mask::IOM_VERTCOLOR;
|
|
|
|
if (bHasPerFaceColor)
|
|
|
|
info->mask |= vcg::tri::io::Mask::IOM_FACECOLOR;
|
|
|
|
if (bHasPerVertexNormal)
|
|
|
|
info->mask |= vcg::tri::io::Mask::IOM_VERTNORMAL;
|
|
|
|
if (bHasPerVertexText)
|
|
|
|
info->mask |= vcg::tri::io::Mask::IOM_VERTTEXCOORD;
|
|
|
|
|
2006-11-06 09:45:13 +01:00
|
|
|
|
|
|
|
|
2006-11-09 03:24:41 +01:00
|
|
|
delete (info->dae->doc);
|
|
|
|
info->dae->doc = NULL;
|
|
|
|
addinfo = info;
|
2006-11-02 19:15:55 +01:00
|
|
|
return true;
|
2006-09-22 08:01:40 +02:00
|
|
|
}
|
|
|
|
};
|
2006-06-14 11:47:21 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-07-12 14:12:36 +02:00
|
|
|
#endif
|